How to find and provide C++ library headers for clang? - c++

I've built LLVM and Clang from sources using following instruction in order to try some of the latest C++ features.
When I try to compile basic C++ program using this clang I get errors about missing basic headers:
% /usr/local/bin/clang++ -std=c++20 main.cpp
In file included from main.cpp:1:
main.cpp:3:10: fatal error: 'array' file not found
#include <array>
I similarly have brew installed clang, which works perfectly.
The instruction mentions providing C++ library headers to clang, but I don't understand:
How to locate those?
How to make sure, that they are also up to date to support latest C++ features?
I have MacOS Monterey 12.4

You should specify a path to the sdk for your target platform.
You can retreive this by relying on xcrun:
/usr/local/bin/clang++ -isysroot $(xcrun --show-sdk-path) -std=c++20 main.cpp
In case you want to target other platforms (in the example bellow, for iphone) you have to specify both the target triple and the path to the appropiate sdk:
/usr/local/bin/clang++ -target arm64-apple-ios -isysroot $(xcrun --sdk iphoneos --show-sdk-path) -std=c++20 main.cpp
There is also an alternative to the -isysroot option. You could set up the SDKROOT environment variable to point to the target sdk path:
export SDKPATH=$(xcrun --show-sdk-path)
/usr/local/bin/clang++ -std=c++20 main.cpp

Related

Can't compile a simple c++ file with g++ on MacOS 13, XCode 14

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++:
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1"
"/usr/local/include"
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include"
"/usr/include"
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include"
Compiling with the /usr/bin/c++ wrapper, we get the following headers:
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
"-I/usr/local/include"
"-stdlib=libc++"
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1"
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include"
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include"
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include"
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include"
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 -isysroot option as extracted using:
-isysroot $(xcrun --sdk macosx --show-sdk-path)
so:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -isysroot $(xcrun --sdk macosx --show-sdk-path) -o conftest conftest.cpp
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 CPPFLAGS and CXXFLAGS - flags for the preprocessor and C++ compiler. You should be able to set CPPFLAGS to:
-isysroot $(xcrun --sdk macosx --show-sdk-path)
and it should build for you, if the standard makefile logic is in effect in the tools you're using.
$ export CPPFLAGS="-isysroot $(xcrun --sdk macosx --show-sdk-path)"
$ export CXX=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
$ make conftest
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk conftest.cpp -o conftest

Controlling scons environment checking options

I'm trying to build mongodb (open source version 4.2) which uses python and scons for building. The problem relates to scons rather than mongodb.
My build fails very early with Couldn't find OpenSSL crypto.h header and library. Verbose details are:
file /.../SConstruct,line 3042:
Configure(confdir = build/scons/opt/sconf_temp)
scons: Configure: Checking for SSLeay_version(0) in C library crypto...
build/scons/opt/sconf_temp/conftest_d6743137aeb7fb2674cc9632f9989034_0.c <-
|
|
|#include "openssl/crypto.h"
|
|int
|main() {
| SSLeay_version(0);
|return 0;
|}
|
gcc -o build/scons/opt/sconf_temp/conftest_d6743137aeb7fb2674cc9632f9989034_0.o -c -std=c11 -ffp-contract=off -fno-omit-frame-pointer -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch -Werror -O2 -Wno-unused-local-typedefs -Wno-unused-function -Wno-deprecated-declarations -Wno-unused-const-variable -Wno-unused-but-set-variable -Wno-missing-braces -Wno-exceptions -fstack-protector-strong -fno-builtin-memcmp -fPIE -DNDEBUG -D_XOPEN_SOURCE=700 -D_GNU_SOURCE build/scons/opt/sconf_temp/conftest_d6743137aeb7fb2674cc9632f9989034_0.c
cc1: error: command-line option '-Wno-exceptions' is valid for C++/ObjC++ but not for C [-Werror]
cc1: all warnings being treated as errors
scons: Configure: no
I'm using Arch Linux which has multiple OpenSSL packages, and the default 3.0 is not compatible with mongodb source. I also have OpenSSL 1.1 and 1.0 installed, and can switch with e.g. gcc -I/usr/include/openssl-1.1.
Unfortunately I have not found a way to instruct SConstruct to use this flag in the command lines it generates to check the environment. I have tried CFLAGS, CCFLAGS, CPPPATH both as environment variables and scons command line parameters.
I also tried reverse enginering it, and tracked this to Conftest and TryBuild but it's not obvious how I can influance theses from the command line, so I'm trying my luck with you guys before going deeper in scons code.
If you look at the SConstruct and search for openssl, you'll find this blurb under the logic to detect on macOS
NOTE: Recent versions of macOS no longer ship headers for the system OpenSSL libraries.
NOTE: Either build without the --ssl flag, or describe how to find OpenSSL.
NOTE: Set the include path for the OpenSSL headers with the CPPPATH SCons variable.
NOTE: Set the library path for OpenSSL libraries with the LIBPATH SCons variable.
NOTE: If you are using HomeBrew, and have installed OpenSSL, this might look like:
\tscons CPPPATH=/usr/local/opt/openssl/include LIBPATH=/usr/local/opt/openssl/lib ...
NOTE: Consult the output of 'brew info openssl' for details on the correct paths."""
I'd bet if you did the same but pointed at the proper locations on your system for the openssl libs and header files, you'd be able to build.
(see: https://github.com/mongodb/mongo/blob/r4.2.0/SConstruct#L3015 )

Compiling CUDA with clang - 'No available targets are compatible with triple "nvptx64-nvidia-cuda"'

I am trying to compile the example CUDA code axpy.cu from the llvm docs using:
clang++ axpy.cu -o axpy --cuda-gpu-arch=sm_86 -L/usr/local/cuda-11.2/lib64 -lcudart_static -ldl -lrt -pthread
but I'm getting the following error:
error: unable to create target: 'No available targets are compatible with triple "nvptx64-nvidia-cuda"'
What's going on here? I was able to compile CUDA with clang a day or two ago and now it's not working for some reason. I'm not sure what changed on my system.
I'm using clang 13 which should support CUDA 11.2.
The problem was that I built llvm/clang from source without support for cuda. The solution is to use the -DLLVM_TARGETS_TO_BUILD="X86;NVPTX" when building llvm from source.

Compile hadoop native libraries in Mac OS Catalina. error: unknown type name 'constexpr'. alias declarations are a C++11 extension

I'm trying to compile Hadoop native libraries in Unix, these is what I'm using:
Hadoop: branch-3.2 (here is the Hadoop Repository)
macOS: Catalina Version 10.15.5
Protobuf: libprotoc 2.5.0
OpenSSL 1.0.2t 10 Sep 2019
gcc: Apple clang version 11.0.3 (clang-1103.0.32.62) Target: x86_64-apple-darwin19.5.0 Thread model: posix InstalledDir: /Library/Developer/CommandLineTools/usr/bin
java version "1.8.0_251" (build 1.8.0_251-b08)
I followed all steps here: Compiling Hadoop on MAC
After fixing a couple of problems with openssl and protobuf now it looks like the compilation of Apache Hadoop MapReduce NativeTask is failing due to a dependency with C++11 .
Do I need to specify somehow to maven the CXXFLAGS parameter set to -std=c++11? How do I do it? Or am I missing some configuration in my gcc?
I tried setting an alias to gcc so then it immediately is called with the flags like it's explained here: How to make clang support C++ 11 by default, but still doesn't work.
So far these are one of the many similar errors I have:
[WARNING] /usr/local/include/snappy-stubs-public.h:61:16: warning: alias declarations are a C++11 extension [-Wc++11-extensions]
[WARNING] using uint64 = std::uint64_t;
[WARNING] In file included from /Users/josh/Dev/hadoop/repo/hadoop/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src/main/native/test/TestCompressions.cc:29:
[WARNING] /usr/local/include/snappy.h:197:10: error: unknown type name 'constexpr'
[WARNING] static constexpr int kBlockLog = 16;
[INFO] Apache Hadoop MapReduce NativeTask ................. FAILURE [ 1.995 s]
And after reading the output more carefully, I think this is the command that ends up throwing the error:
[WARNING] /Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/nttest.dir/build.make CMakeFiles/nttest.dir/build
[WARNING] [ 75%] Building CXX object CMakeFiles/nttest.dir/main/native/test/TestCompressions.cc.o
[WARNING] /Library/Developer/CommandLineTools/usr/bin/c++ -I/Users/josh/Dev/hadoop/repo/hadoop/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/target/native/javah -I/Users/josh/Dev/hadoop/repo/hadoop/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src/main/native/src -I/Users/josh/Dev/hadoop/repo/hadoop/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src/main/native/src/util -I/Users/josh/Dev/hadoop/repo/hadoop/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src/main/native/src/lib -I/Users/josh/Dev/hadoop/repo/hadoop/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src/main/native/test -I/Users/josh/Dev/hadoop/repo/hadoop/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src -I/Users/josh/Dev/hadoop/repo/hadoop/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/target/native -I/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/include/darwin -I/usr/local/include -isystem /Users/josh/Dev/hadoop/repo/hadoop/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src/../../../../hadoop-common-project/hadoop-common/src/main/native/gtest/include -g -O2 -Wall -pthread -D_FILE_OFFSET_BITS=64 -DNDEBUG -DSIMPLE_MEMCPY -fno-strict-aliasing -fsigned-char -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -o CMakeFiles/nttest.dir/main/native/test/TestCompressions.cc.o -c /Users/josh/Dev/hadoop/repo/hadoop/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src/main/native/test/TestCompressions.cc
[WARNING] In file included from /Users/josh/Dev/hadoop/repo/hadoop/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-nativetask/src/main/native/test/TestCompressions.cc:29:
[WARNING] In file included from /usr/local/include/snappy.h:45:
[WARNING] /usr/local/include/snappy-stubs-public.h:54:14: warning: alias declarations are a C++11 extension [-Wc++11-extensions]
[WARNING] using int8 = std::int8_t;
THANK YOU!
I also had difficulty building the hadoop-native libs on OSX with clang. I had more success switching to using gcc 10.
First install with homebrew:
brew install gcc
This should put the gcc binaries in the path, but they'll be gcc-10, g++-10 etc. So setting some environment magic should casue CMake to use these rather than the built-in clang binaries:
export CC=$(which gcc-10)
export CXX=$(which g++-10)
export CPP=$(which cpp-10)
export LD=$(which gcc-10)

clang++ installed via homebrew (macOS): compilation errors

After installing clang++ (tried v. 6.0.1 and 7.0) with:
brew install --with-toolchain llvm
very trivial programs result to the following error:
In file included from test.cpp:1:
In file included from /usr/local/Cellar/llvm/7.0.0/include/c++/v1/iostream:38:
In file included from /usr/local/Cellar/llvm/7.0.0/include/c++/v1/ios:215:
In file included from /usr/local/Cellar/llvm/7.0.0/include/c++/v1/iosfwd:90:
/usr/local/Cellar/llvm/7.0.0/include/c++/v1/wchar.h:119:15: fatal error: 'wchar.h' file not found
#include_next <wchar.h>
Command used to compile:
clang++7() {
LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"
CPPFLAGS="-I/usr/local/opt/llvm/include"
/usr/local/opt/llvm/bin/clang++ -std=c++11 $CPPFLAGS $LDFLAGS $1
}
Is it possible to use the official clang instead of Apple's version?
With Apple's version, we do not even know which version of LLVM it really is...
It appears that as of Mojave (10.14), Xcode doesn't install system headers in /usr/include anymore. There is a compatibility package that does, but it's not recommended.
Instead, the official solution is for tools to search for headers in /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk. That path can be obtained from
xcrun --show-sdk-path
The release notes say
The Command Line Tools package installs the macOS system headers inside the macOS SDK. Software that compiles with the installed tools will search for headers within the macOS SDK provided by either Xcode at:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk
or the Command Line Tools at:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
depending on which is selected using xcode-select.
If you built clang yourself, this can be achieved by passing the -isysroot option to clang:
clang++ -isysroot "$(xcrun --show-sdk-path)" …
See also: https://github.com/Homebrew/homebrew-core/issues/32765
It works for me to add a -I (minus eye) option to the clang++ command line, pointing to /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include