How to compile C++ files under compiler-rt with -stdlib=libc++?

I am using the following commands to build runtimes.

$ cmake \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=<install-path> \
-DLLVM_ENABLE_ASSERTIONS=OFF \
-DCOMPILER_RT_USE_LIBCXX=ON \
-DLLVM_TARGETS_TO_BUILD=X86 \
'-DLLVM_RUNTIME_TARGETS=x86_64-unknown-linux-gnu;i386-unknown-linux-gnu' \
'-DLLVM_ENABLE_PROJECTS=clang;lld'  \
'-DLLVM_ENABLE_RUNTIMES=compiler-rt;libcxx;libcxxabi;libunwind' \
'-DCMAKE_CXX_FLAGS=-stdlib=libc++' \
'-DCMAKE_EXE_LINKER_FLAGS=-rtlib=compiler-rt' \
'-DCMAKE_SHARED_LINKER_FLAGS=-rtlib=compiler-rt' \
'-DCMAKE_MODULE_LINKER_FLAGS=-rtlib=compiler-rt' \
-DCMAKE_CXX_COMPILER=<path-to-clang++> \
-DCMAKE_C_COMPILER=<path-to-clang> \
-S <source-dir> \
-B build
$ ninja -C build runtimes

But the build fails with errors in various C++ files under compiler-rt (e.g. llvm-project/compiler-rt/lib/orc/macho_platform.cpp) because clang++ (which happens to be the clang++ that was just built) uses the system libstdc++ which is very old and does not support C++14.

You may notice that I have added -stdlib=libc++ to CMAKE_CXX_FLAGS and also tried -DCOMPILER_RT_USE_LIBCXX but they don’t help. But when I manually add -stdlib=libc++ to build.ninja, the files failing to compile go through.

What cmake configuration option can I use to make clang use libc++? The clang installation that I used to build LLVM and the new clang also contains libc++ but that is not what ends up getting used when building runtimes.

Or here is a more general question. What are the proper steps for creating a self-contained clang/libc++/libc++abi/compiler-rt/libunwind installation?

I used to be able to do this before (e.g. version 11.0.0) but the recent changes to building libcxx, compiler-rt and libunwind have broken my build scripts. I have tried to follow these instructions but they don’t work because the system libstdc++ is old and the newly built clang picks it up instead of libc++ (that was just built) when building the C++ sources under compiler-rt.

Previously, it used to work because the clang that I provide with -DCMAKE_CXX_COMPILER was used to build everything the first time around.

Can I get some pointers to a solution for this problem? I tried the instructions for building a distribution but run into the same problem. The clang++ built in stage1 is not able to compile compiler-rt because it is using the old system libstdc++ instead of the libc++ that it just built. How can I get -stdlib=libc++ to be passed to this clang? -DCMAKE_CXX_FLAGS=-stdlib=libc++ doesn’t help.

The runtimes builds do their own separate CMake configures, so variables you’ve specified in your initial CMake invocation won’t necessarily get passed down to them. The logic is in https://github.com/llvm/llvm-project/blob/main/llvm/runtimes/CMakeLists.txt, and the relevant bit for your case is https://github.com/llvm/llvm-project/blob/da047445f77bfd74b04c36169e104f35dbfff84e/llvm/runtimes/CMakeLists.txt#L232-L258. Looking at that, it seems like any variables specified in RUNTIMES_CMAKE_ARGS will be passed down to the runtimes configuration, so adding -DRUNTIMES_CMAKE_ARGS='-DCOMPILER_RT_USE_LIBCXX=ON' should do the trick. If you want the clang you’re building to default to libc++, you could pass -DCLANG_DEFAULT_CXX_STDLIB=libc++ to your initial configure instead.

@petrhosek builtin_default_target adds COMPILER_RT to its PASSTHROUGH_PREFIXES, but runtime_default_target doesn’t. Do you know if this is intentional or just an oversight?

Thanks. -DRUNTIMES_CMAKE_ARGS='-DCOMPILER_RT_USE_LIBCXX=ON' did not do the trick :frowning:

I am a little confused how distribution builds are supposed to work if the system C++ compiler and libstdc++ are older (in my case, it is CentOS 7 with gcc 4.8.5) and newer compilers and C++ library are in some non-standard path.

So I am doing the stage 1 build with gcc 9.2.0 which is available in a non-standard path. stage 1 clang builds fine but then when compiler-rt is built using the just built clang, it fails on C++ files like llvm-project/compiler-rt/lib/orc/macho_platform.cpp . It is spewing out errors because clang is picking up old C++ headers from the system path.

Even when I follow the instructions for building a distribution, it fails on macho_platform.cpp.

My case is not atypical (system libraries being old but having an installation of a newer compiler and libraries elsewhere). So what I am missing?

Hmm. There should be a file like llvm/runtimes/runtimes-bins/CMakeCache.txt in your build directory (might not be at that exact path, but searching for files named CMakeCache.txt in your build directory should find the one I’m after). Does that include the COMPILER_RT_USE_LIBCXX entry?

I started looking at this again…

The top-level cmake emits this warning:

CMake Warning:
  Manually-specified variables were not used by the project:

    RUNTIMES_CMAKE_ARGS

COMPILER_RT_USE_LIBCXX is defined CMakeCache.txt though:

$ grep COMPILER_RT_USE_LIBCXX llvm/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/CMakeCache.txt
COMPILER_RT_USE_LIBCXX:BOOL=ON

But compiler-rt still fails to build:

/u/riyaz/src/llvm-project/compiler-rt/lib/orc/error.h:234:12: error: no template named 'enable_if_t' in namespace 'std'; did you mean 'enable_if'?
      std::enable_if_t<!std::is_convertible<OtherT, T>::value> * = nullptr) {
      ~~~~~^~~~~~~~~~~
           enable_if
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/type_traits:1766:12: note: 'enable_if' declared here
    struct enable_if 
           ^
In file included from /u/riyaz/src/llvm-project/compiler-rt/lib/orc/macho_platform.cpp:13:
In file included from /u/riyaz/src/llvm-project/compiler-rt/lib/orc/macho_platform.h:17:
In file included from /u/riyaz/src/llvm-project/compiler-rt/lib/orc/executor_address.h:20:
In file included from /u/riyaz/src/llvm-project/compiler-rt/lib/orc/simple_packed_serialization.h:39:
/u/riyaz/src/llvm-project/compiler-rt/lib/orc/error.h:372:10: error: no template named 'aligned_union_t' in namespace 'std'
    std::aligned_union_t<1, storage_type> TStorage;
    ~~~~~^
/u/riyaz/src/llvm-project/compiler-rt/lib/orc/error.h:373:10: error: no template named 'aligned_union_t' in namespace 'std'
    std::aligned_union_t<1, error_type> ErrorStorage;
    ~~~~~^

Why is it picking up the system libstdc++ from /usr/lib/gcc/..../4.8.5/.... even though COMPILER_RT_USE_LIBCXX=ON is specified and there is libc++.* under build/lib/x86_64-unknown-linux-gnu/?

Are you supposed to use llvm-project/llvm/runtimes as the source dir? When I switched some builds over to “the default build” I used the top-level llvm-project/runtimes and I recall that I got different results if I accidentally used llvm-project/llvm/runtimes.

This might be entirely unrelated to your issues reported here, though.

Hi,
I think I have a related problem. I did not the full picture yet, but so far my best guess is, that is somehow like this:

  • While compiling with gcc the includes of the gcc are taken automatically (by gcc) and therefore everything is properly defined.
  • For runtimes clang is used. Because the include-path of the gcc includes are not given to CFLAGS/CXXFLAGS (or how it has to be defined) the definitions are not available yet and because everything is compiled together clang is not installed so far and the includes for clang does not exist yet. Therefore only the system include files are seen.

At least I assume in my case something like this. One solution could be to provide the gcc includes for clang, but I think that is not clean. Another way could be to first install clang and then compile the runtimes with a proper installed clang. Not sure if that works out.

Maybe I am also totally wrong, but that is so far my best guess.

the system C++ compiler and libstdc++ are older […] and newer compilers and C++ library are in some non-standard path.

This is my situation and I’m running into the same issues (libstdc++ getting picked up, etc).

@RVP Did you ever discover a solution here?