In part 3 I created a native libc++ so now I can use this to build most of compiler-rt (leaving out libfuzzer which is another build of libc++) This ‘runtime only’ build is reasonably straight forward except for one small gotcha.
linker_flags = '-stdlib=libc++ -rtlib=compiler-rt -fuse-ld=lld'
subprocess.run (
[
'cmake',
'-G',
'Ninja',
'-S',
'runtimes',
'-B',
build,
'--trace-expand',
'--trace-redirect=' + build +'/cmake.log',
'-DCMAKE_BUILD_TYPE=Release',
'-DCMAKE_C_COMPILER=' + STAGING + '/bin/clang',
'-DCMAKE_CXX_COMPILER=' + STAGING + '/bin/clang++',
'-DCMAKE_CXX_FLAGS=-stdlib=libc++',
'-DCMAKE_EXE_LINKER_FLAGS_INIT=' + linker_flags,
'-DCMAKE_INSTALL_PREFIX=' + STAGING,
'-DCMAKE_MODULE_LINKER_FLAGS_INIT=' + linker_flags,
'-DCMAKE_SHARED_LINKER_FLAGS_INIT=' + linker_flags,
'-DCOMPILER_RT_BUILD_LIBFUZZER=OFF',
'-DCOMPILER_RT_USE_BUILTINS_LIBRARY=ON',
'-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON',
'-DLLVM_ENABLE_RUNTIMES=compiler-rt',
'-DLLVM_TARGETS_TO_BUILD=Native'
],
check=True
)
subprocess.run (
[
'ninja',
'-C',
build,
'compiler-rt'
],
check=True
)
subprocess.run (
[
'ninja',
'-C',
build,
'install-compiler-rt'
],
check=True
)
Where
- linker_flags clearly defines that I want to use llvm-project libraries and tools
- build is set to ‘build-native-rt’
- –trace-expand and --trace-redirect are used to debug cmake
- STAGING is still set to ‘/staging’ (it is a constant after all)
- CMAKE_CXX_FLAGS is the gotcha! The XRAY instrumentation code ignores the linker information expects -stdlib=libc++ to be found here instead.
- COMPILER_RT_BUILD_LIBFUZZER is turned off as it kicks off another build of libc++. Its something I will have to finish later.
The CMAKE_CXX_FLAGS highlights the highly inconsistent use of flags thoughout the llvm-project.
I would have thought that the more general cmake flags would serve as the main flags for the llvm-project with perhaps the ability to override these in a consistent way at the llvm and runtimes level and then again for each project or runtime if it is neccessary.
Unfortunately, throughout the cmake code I have seen nearly every flag being overwritten, making it almost impossible to understand. You can see from my builds, that I now aviod any non-cmake flag unless it is absolutely neccessary (and probably a bug)
At this point we are ready to commit the files in STAGING to /usr/local
Now as I am developing on a raspberry Pi, based on Debian, my host triple is not aarch64-unknown-linux-gnu, it is aarch64-linux-gnu. So the libc++.so libc++abi.so libunwind.so libraries are in the wrong place. I could move them into the correct place, but then clang cannot find them. I compromise by copying them:
mkdir /usr/local/lib/aarch64-linux-gnu && \
cp /usr/local/lib/aarch64-unknown-linux-gnu/libunwind.so.1.0 /usr/local/lib/aarch64-linux-gnu/libunwind.so.1.0 && \
ln -s /usr/local/lib/aarch64-linux-gnu/libunwind.so.1.0 /usr/local/lib/aarch64-linux-gnu/libunwind.so.1 && \
ln -s /usr/local/lib/aarch64-linux-gnu/libunwind.so.1 /usr/local/lib/aarch64-linux-gnu/libunwind.so && \
cp /usr/local/lib/aarch64-unknown-linux-gnu/libc++abi.so.1.0 /usr/local/lib/aarch64-linux-gnu/libc++abi.so.1.0 && \
ln -s /usr/local/lib/aarch64-linux-gnu/libc++abi.so.1.0 /usr/local/lib/aarch64-linux-gnu/libc++abi.so.1 && \
ln -s /usr/local/lib/aarch64-linux-gnu/libc++abi.so.1 /usr/local/lib/aarch64-linux-gnu/libc++abi.so && \
cp /usr/local/lib/aarch64-unknown-linux-gnu/libc++.so.1.0 /usr/local/lib/aarch64-linux-gnu/libc++.so.1.0 && \
ln -s /usr/local/lib/aarch64-linux-gnu/libc++.so.1.0 /usr/local/lib/aarch64-linux-gnu/libc++.so.1 && \
cp /usr/local/lib/aarch64-unknown-linux-gnu/libc++.so /usr/local/lib/aarch64-linux-gnu/ && \
ldconfig /usr/local/lib/aarch64-linux-gnu
return to building clang again which is really part1 with the linker flags set to llvm-project
linker_flags = '-stdlib=libc++ -rtlib=compiler-rt -fuse-ld=lld'
subprocess.run (
[
'cmake',
'-G',
'Ninja',
'-S',
'llvm',
'-B',
build,
'-DCMAKE_BUILD_TYPE=Release',
'-DCMAKE_C_COMPILER=clang',
'-DCMAKE_CXX_COMPILER=clang++',
'-DCMAKE_EXE_LINKER_FLAGS_INIT=' + linker_flags,
'-DCMAKE_INSTALL_PREFIX=' + STAGING,
'-DCMAKE_MODULE_LINKER_FLAGS_INIT=' + linker_flags,
'-DCMAKE_SHARED_LINKER_FLAGS_INIT=' + linker_flags,
'-DLIBCLANG_BUILD_STATIC=ON',
'-DLLVM_ENABLE_LIBCXX=ON',
'-DLLVM_ENABLE_PROJECTS=clang;lld',
'-DLLVM_TARGETS_TO_BUILD=Native',
],
check=True
)
Where:
- DLLVM_ENABLE_LIBCXX is used because -stdlib=libc++ is ignored in the linker commands
- LIBCLANG_BUILD_STATIC is a failed attempt at statically linking libc++ into clang - still more work to do!
I have tested that these builds work without any of the (C++) GNU Compiler Collection:
apt-get install -y --no-install-recommends \
bzip2 \
cmake \
git \
libc6-dev \
ninja-build \
python3 \
python3-distutils \
unzip \
zip \
zlib1g \
at least twice (to ensure they are repeatable)