Clang的-stdlib参数功能解析及Xcode9编译问题咨询
-stdlib Flag: Compilation, Linking, and Your Cross-Compile Woes Let's break down your questions about this flag, then connect it to the issue you ran into with Xcode 9 and cross-compiling to i686-linux-elf.
1. How -stdlib impacts the compilation process
This flag isn't just a trivial setting—it reshapes how Clang handles standard library headers and code interpretation:
- Header path reordering: When you specify
-stdlib=libc++, Clang rearranges its header search priority to look first at thelibc++header directories, overriding the default (which on pre-Xcode 9 setups might have leaned towardlibstdc++for cross-compiles). This means if your system has bothlibc++andlibstdc++headers, the selected library's headers will be picked up first. - Library-specific macros and features: It defines macros that tailor the compiler's behavior to the chosen library. For example,
-stdlib=libc++sets_LIBCPP_VERSIONand disableslibstdc++-specific macros like_GLIBCXX_USE_C99. This changes how the compiler parses code that relies on library-specific extensions or behavior. - Inline function dependencies: As your error shows,
libc++'s inline functions (like theabswrapper callinglabs) assume certain system symbols exist. If your target sysroot doesn't expose those symbols (as was the case with youri686-linux-elfenvironment), the compiler throws an undeclared identifier error because it's using the host macOSlibc++headers instead of your target's compatible version.
2. How -stdlib impacts the linking process
It's more than just a shortcut for -lc++—here's why:
- Automatic library selection & dependency linking: Specifying
-stdlib=libc++tells the linker to uselibc++instead of the default library (usuallylibstdc++on non-Apple systems,libc++on macOS). But it also pulls in auxiliary libraries thatlibc++requires—likelibc++abion macOS. For cross-compiling, it ensures the linker looks for the target-specific version of the standard library, not the host's. - Header-library consistency: The flag enforces that the linker uses a library matching the headers used during compilation. Mismatching (e.g., compiling with
libc++headers but linking tolibstdc++) leads to undefined behavior or linker errors.
Why your Xcode 9 cross-compile setup broke
After upgrading Xcode 9, adding -stdlib=libc++ made Clang prioritize the host macOS libc++ headers over your target i686-linux-elf libc++ headers. The macOS headers expect system symbols like labs to be available, but your target sysroot doesn't expose them in a way that matches the host's setup.
Your fix—restricting include paths to only ${STAGING.nao}/usr/local/include/c++/v1—works because it forces Clang to use your target's libc++ headers, which are compatible with i686-linux-elf, overriding the -stdlib flag's default path ordering.
For a more robust long-term fix, consider using the --sysroot flag to explicitly point Clang to your target's entire sysroot. This ensures both compilation and linking use the target's libraries and headers consistently:
clang++ --sysroot=/usr/local/our-target/sysroot -target i686-linux-elf -stdlib=libc++ ...
内容的提问来源于stack exchange,提问作者gone

