| Issue |
180298
|
| Summary |
[Compiler-rt][Sanitizers] compiler-rt ignores CMAKE_*_LINKER_FLAGS_INIT and add_link_options() when building sanitizers for Android
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
mccakit
|
**Title:** compiler-rt ignores CMAKE_*_LINKER_FLAGS_INIT and add_link_options() when building sanitizers for Android
**Description:**
When cross-compiling compiler-rt sanitizers for Android with a custom libc++ and compiler-rt builtins, the build system ignores standard CMake linker flags (`CMAKE_SHARED_LINKER_FLAGS_INIT`, `add_link_options()`) and instead hardcodes `-lstdc++` and `-latomic`, causing link failures.
**Environment:**
- LLVM version: 20 (main branch)
- Target: aarch64-linux-android30
- Host: Linux x86_64
- Build system: CMake + Ninja
**Problem:**
The compiler-rt build system does not respect `CMAKE_SHARED_LINKER_FLAGS_INIT` or `add_link_options()` when linking sanitizer shared libraries. Instead, it uses its own internal `SANITIZER_COMMON_LINK_LIBS` variable which defaults to libstdc++ and libatomic, causing link failures when using a custom-built libc++ and compiler-rt builtins.
**Expected behavior:**
Standard CMake linker flags should be respected, or at minimum, the build should use `-rtlib=compiler-rt` when specified in compiler flags.
**Actual behavior:**
Link command shows:
```
-lstdc++ -lc -ldl -llog -static-libstdc++ -latomic -lm
```
Instead of the configured flags:
```
-nostdlib++ -L/path/to/custom/libcxx/lib -lc++_static -lc++abi -lclang_rt.builtins-aarch64-android
```
This results in linker errors for missing symbols from compiler-rt builtins:
```
ld.lld: error: undefined symbol: __aarch64_swp1_acq
ld.lld: error: undefined symbol: __extenddftf2
ld.lld: error: undefined symbol: typeinfo for __cxxabiv1::__si_class_type_info
```
**Workaround:**
Manually override `SANITIZER_COMMON_LINK_LIBS` in the toolchain file:
```cmake
list(APPEND SANITIZER_COMMON_LINK_LIBS
-L/home/user/dev/libcxx/aarch64-linux-android/lib
-Wl,-Bstatic
-lc++_static
-lc++abi
-Wl,-Bdynamic
-L/home/user/dev/compiler-rt/aarch64-linux-android/lib/linux
-lclang_rt.builtins-aarch64-android
)
```
**Steps to Reproduce:**
1. Build compiler-rt builtins (stage 0):
```bash
cmake -S llvm-project/compiler-rt -B build-builtins -G Ninja \
-DCOMPILER_RT_BUILD_BUILTINS=ON \
-DCOMPILER_RT_BUILD_SANITIZERS=OFF \
-DCOMPILER_RT_BUILD_PROFILE=OFF \
-DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
-DCMAKE_INSTALL_PREFIX=$HOME/dev/compiler-rt/aarch64-linux-android \
-DCMAKE_TOOLCHAIN_FILE=toolchain-stage0.cmake
cmake --build build-builtins
cmake --install build-builtins
```
2. Build libc++ and libc++abi:
```bash
cmake -S llvm-project/runtimes -B build-libcxx -G Ninja \
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
-DCMAKE_INSTALL_PREFIX=$HOME/dev/libcxx/aarch64-linux-android \
-DCMAKE_TOOLCHAIN_FILE=toolchain-libcxx.cmake
cmake --build build-libcxx
cmake --install build-libcxx
```
3. Build compiler-rt sanitizers (stage 1) - **this fails**:
```bash
cmake -S llvm-project/compiler-rt -B build-sanitizers -G Ninja \
-DCOMPILER_RT_BUILD_SANITIZERS=ON \
-DCOMPILER_RT_USE_LIBCXX=OFF \
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
-DCMAKE_INSTALL_PREFIX=$HOME/dev/compiler-rt/aarch64-linux-android \
-DCMAKE_TOOLCHAIN_FILE=toolchain-stage1.cmake
cmake --build build-sanitizers # Link failures here
```
**Toolchain Files:**
<details>
<summary>Stage 0 toolchain (compiler-rt builtins only)</summary>
```cmake
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_SYSTEM_VERSION 30)
set(CMAKE_ANDROID_NDK /home/mccakit/dev/android-clt/ndk/29.0.13599879)
set(ANDROID_NDK /home/mccakit/dev/android-clt/ndk/29.0.13599879)
set(ANDROID_ABI arm64-v8a)
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_C_COMPILER /home/mccakit/dev/llvm/bin/clang)
set(CMAKE_CXX_COMPILER /home/mccakit/dev/llvm/bin/clang++)
set(CMAKE_ASM_COMPILER /home/mccakit/dev/llvm/bin/clang)
set(CMAKE_RC_COMPILER /home/mccakit/dev/llvm/bin/llvm-rc)
set(CMAKE_AR /home/mccakit/dev/llvm/bin/llvm-ar)
set(CMAKE_RANLIB /home/mccakit/dev/llvm/bin/llvm-ranlib)
set(CMAKE_MT /home/mccakit/dev/llvm/bin/llvm-mt)
set(PKG_CONFIG_EXECUTABLE "/home/mccakit/dev/pkgconf/bin/pkgconf.py" CACHE FILEPATH "" FORCE)
set(CMAKE_FIND_ROOT_PATH /home/mccakit/dev /home/.conan)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_EXTENSIONS ON)
set(CMAKE_CXX_FLAGS "--target=aarch64-linux-android30 --sysroot=/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/sysroot -std=c++26 -nostdinc++ -nostdlib++ -isystem /home/mccakit/dev/libcxx/android-arm64/include/c++/v1 -O3 -DNDEBUG")
set(CMAKE_C_FLAGS "--target=aarch64-linux-android30 --sysroot=/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/sysroot -std=gnu23 -O3 -DNDEBUG")
add_link_options(
-fuse-ld=lld
--target=aarch64-linux-android30
--sysroot=/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/sysroot
-L/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/20/lib/linux/aarch64
)
set(CMAKE_BUILD_TYPE RELEASE)
set(BUILD_SHARED_LIBS OFF)
```
</details>
<details>
<summary>libc++ toolchain</summary>
```cmake
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_SYSTEM_VERSION 30)
set(CMAKE_ANDROID_NDK /home/mccakit/dev/android-clt/ndk/29.0.13599879)
set(ANDROID_NDK /home/mccakit/dev/android-clt/ndk/29.0.13599879)
set(ANDROID_ABI arm64-v8a)
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_C_COMPILER /home/mccakit/dev/llvm/bin/clang)
set(CMAKE_CXX_COMPILER /home/mccakit/dev/llvm/bin/clang++)
set(CMAKE_ASM_COMPILER /home/mccakit/dev/llvm/bin/clang)
set(CMAKE_RC_COMPILER /home/mccakit/dev/llvm/bin/llvm-rc)
set(CMAKE_AR /home/mccakit/dev/llvm/bin/llvm-ar)
set(CMAKE_RANLIB /home/mccakit/dev/llvm/bin/llvm-ranlib)
set(CMAKE_MT /home/mccakit/dev/llvm/bin/llvm-mt)
set(PKG_CONFIG_EXECUTABLE "/home/mccakit/dev/pkgconf/bin/pkgconf.py" CACHE FILEPATH "" FORCE)
set(CMAKE_FIND_ROOT_PATH /home/mccakit/dev /home/.conan)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_EXTENSIONS ON)
set(CMAKE_CXX_FLAGS "--target=aarch64-linux-android30 --sysroot=/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/sysroot -std=c++26 -O3 -DNDEBUG")
set(CMAKE_C_FLAGS "--target=aarch64-linux-android30 --sysroot=/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/sysroot -std=gnu23 -O3 -DNDEBUG")
add_link_options(
-fuse-ld=lld
-rtlib=compiler-rt
--target=aarch64-linux-android30
--sysroot=/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/sysroot
-L/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/20/lib/linux/aarch64
)
set(CMAKE_BUILD_TYPE RELEASE)
set(BUILD_SHARED_LIBS OFF)
set(LIBCXX_SHARED_OUTPUT_NAME c++_shared CACHE STRING "")
set(LIBCXX_STATIC_OUTPUT_NAME c++_static CACHE STRING "")
set(LIBCXX_ABI_VERSION 1 CACHE STRING "")
set(LIBCXX_ABI_NAMESPACE __ndk1 CACHE STRING "")
set(LIBCXX_ENABLE_ABI_LINKER_SCRIPT OFF CACHE BOOL "")
set(LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY ON CACHE BOOL "")
set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "")
set(LIBCXXABI_USE_LLVM_UNWINDER OFF CACHE BOOL "")
set(CMAKE_C_COMPILER_WORKS ON CACHE BOOL "")
set(CMAKE_CXX_COMPILER_WORKS ON CACHE BOOL "")
```
</details>
<details>
<summary>Stage 1 toolchain (compiler-rt with sanitizers) - **FAILS WITHOUT WORKAROUND**</summary>
```cmake
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_SYSTEM_VERSION 30)
set(CMAKE_ANDROID_NDK /home/mccakit/dev/android-clt/ndk/29.0.13599879)
set(ANDROID_NDK /home/mccakit/dev/android-clt/ndk/29.0.13599879)
set(ANDROID_ABI arm64-v8a)
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_C_COMPILER /home/mccakit/dev/llvm/bin/clang)
set(CMAKE_CXX_COMPILER /home/mccakit/dev/llvm/bin/clang++)
set(CMAKE_ASM_COMPILER /home/mccakit/dev/llvm/bin/clang)
set(CMAKE_RC_COMPILER /home/mccakit/dev/llvm/bin/llvm-rc)
set(CMAKE_AR /home/mccakit/dev/llvm/bin/llvm-ar)
set(CMAKE_RANLIB /home/mccakit/dev/llvm/bin/llvm-ranlib)
set(CMAKE_MT /home/mccakit/dev/llvm/bin/llvm-mt)
set(PKG_CONFIG_EXECUTABLE "/home/mccakit/dev/pkgconf/bin/pkgconf.py" CACHE FILEPATH "" FORCE)
set(CMAKE_FIND_ROOT_PATH /home/mccakit/dev /home/.conan)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 23)
set(CMAKE_C_EXTENSIONS ON)
set(CMAKE_CXX_FLAGS "--target=aarch64-linux-android30 --sysroot=/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/sysroot -std=c++26 -nostdinc++ -nostdlib++ -isystem /home/mccakit/dev/libcxx/aarch64-linux-android/include/c++/v1 -O3 -DNDEBUG")
set(CMAKE_C_FLAGS "--target=aarch64-linux-android30 --sysroot=/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/sysroot -std=gnu23 -O3 -DNDEBUG")
set(CMAKE_CXX_STDLIB_MODULES_JSON "/home/mccakit/dev/libcxx/aarch64-linux-android/lib/libc++.modules.json")
set(CMAKE_EXE_LINKER_FLAGS_INIT "--target=aarch64-linux-android30 --sysroot=/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fuse-ld=lld -rtlib=compiler-rt -L/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/20/lib/linux/aarch64")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "--target=aarch64-linux-android30 --sysroot=/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fuse-ld=lld -rtlib=compiler-rt -L/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/20/lib/linux/aarch64")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "--target=aarch64-linux-android30 --sysroot=/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/sysroot -fuse-ld=lld -rtlib=compiler-rt -L/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/20/lib/linux/aarch64")
add_link_options(
-fuse-ld=lld
-rtlib=compiler-rt
--target=aarch64-linux-android30
--sysroot=/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/sysroot
-L/home/mccakit/dev/android-clt/ndk/29.0.13599879/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/20/lib/linux/aarch64
-nostdlib++
-L/home/mccakit/dev/libcxx/aarch64-linux-android/lib
-Wl,-Bstatic
-lc++_static
-lc++abi
-Wl,-Bdynamic
)
set(CMAKE_BUILD_TYPE RELEASE)
set(BUILD_SHARED_LIBS OFF)
# WORKAROUND - Without this, the build fails
list(APPEND SANITIZER_COMMON_LINK_LIBS
-L/home/mccakit/dev/libcxx/aarch64-linux-android/lib
-Wl,-Bstatic
-lc++_static
-lc++abi
-Wl,-Bdynamic
-L/home/mccakit/dev/compiler-rt/aarch64-linux-android/lib/linux
-lclang_rt.builtins-aarch64-android
)
```
</details>
**Proposed Solution:**
The compiler-rt build system should respect standard CMake linker flags, or alternatively:
1. When `-rtlib=compiler-rt` is specified in `CMAKE_CXX_FLAGS` or `CMAKE_C_FLAGS`, automatically link against `libclang_rt.builtins-<arch>-android.a`
2. When `-nostdlib++` is specified, do not add `-lstdc++` or `-lc++` to `SANITIZER_COMMON_LINK_LIBS`
3. Respect `CMAKE_SHARED_LINKER_FLAGS_INIT` and `add_link_options()` when building sanitizer libraries
4. Document the `SANITIZER_COMMON_LINK_LIBS` variable as the official way to override default link libraries if the above are not feasible
**Related Code:**
The issue appears to be in `compiler-rt/cmake/base-config-ix.cmake` around lines 280-310 where `SANITIZER_COMMON_LINK_LIBS` is populated based on hardcoded assumptions about libstdc++ and libatomic availability.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs