I'm on a new M2 Mac Mini. I have this simple test c++ file:
% cat conftest.cpp
#include <limits>
#include <cmath>
#include <algorithm>
int main(int argc, char **argv) { return 0;}
I need to compile it with c++ rather than clang++ (the actual problem is building a conan dependency that does this, so I can't easily switch it).
I have XCode 14.2 (latest, I think) and this c++
% g++ --version
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.3.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
From my reading, I know that since Catalina XCode's g++ doesn't automatically find the standard header and lib dirs the way clang does on Mac, so I think I need to set CPATH and LIBPATH.
% echo $LIBRARY_PATH
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
% echo $CPATH
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
Unfortunately, compiling this gives an error, which appears to be a conflict between cmath and algorithm because removing either of those makes it compile and link OK:
% /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ conftest.cpp
In file included from conftest.cpp:4:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:653:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:499:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional/bind_back.h:15:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional/perfect_forward.h:17:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:159:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_base:22:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/exception:83:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cstdlib:130:9: error: target of using declaration conflicts with declaration already in scope
using ::abs _LIBCPP_USING_IF_EXISTS;
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdlib.h:132:6: note: target of using declaration
int abs(int) __pure2;
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cmath:338:1: note: conflicting declaration
using ::abs _LIBCPP_USING_IF_EXISTS;
^
I must be missing something simple. That test program compiles and runs fine on godbolt and Windows. Any ideas, anyone?
The issue here is one of wrapping. When you invoke the toolchain compiler directly, it uses a specific set of headers for the toolchain itself, and omits the headers for the platform. When we use
-###to see all the include paths specified for the toolchain compiler, we see the following from the direct toolchain compiler:So compiling with
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++:Compiling with the
/usr/bin/c++wrapper, we get the following headers:It's adding in the headers for macOS, because it assumes it's building for MacOS, because it's the local wrapper.
We can successfully compile using the toolchain compiler, when we pass in an additional
-isysrootoption as extracted using:so:
builds and runs cleanly. In the case of trying to get dependencies to build properly you're going to need to pick the appropriate compiler for the target.
If you want to work around building, the two variables that matter in this case are generally
CPPFLAGSandCXXFLAGS- flags for the preprocessor and C++ compiler. You should be able to set CPPFLAGS to:and it should build for you, if the standard makefile logic is in effect in the tools you're using.