[RFC] Amending `runtimes` build system to be able to build all Apple platforms (not only macOS)

Good morning,
I am working on teachin the build system for the Swift compiler to use LLVM_ENABLE_RUNTIMES instead of LLVM_BUILD_EXTERNAL_COMPILER_RT 1 – in doing so I realized that we may need a change in LLVM to avoid silently dropping build products for some Apple platforms, and I seeking your input to assess if the solution 2 I have in mind goes in the right direction.

The issues seems to stem from the fact that the llvm_ExternalProject_Add invocation used to build the default targets for builtins and runtimes always specify a target triple – when building on macOS that’s set to <arch>-apple-macos<version>.
That is subsequently used by in every compiler invocation generated by CMake, including the ones used to detect valid architectures for other platforms like iOS – the detection fails as a result and we silent skip building for such platforms.

My current solution 2 would be to add a flag to decide whether we set TARGET_TRIPLE for those external project invocation (maintaining by default the current behaviour), and then on Swift side we set that appropriately – however I cannot gauge effectively if this will impact other platforms or other runtime products using this infrastructure.

cc @etcwilde @compnerd

cc @petrhosek @beanz

Can you share your CMake invocation for building runtimes with LLVM_ENABLE_RUNTIMES? We have been building runtimes for Apple platforms with LLVM_ENABLE_RUNTIMES as part of our toolchain for years and we never encountered this issue so I’m curious how your build differs from ours.

We do something similar, except we add x86_64-apple-darwin to our LLVM_BUILTIN_TARGETS and LLVM_RUNTIME_TARGETS explicitly. Clang has special logic for overriding darwin triples with the appropriate OS and architecture, and the Apple runtime builds do so. ⚙ D86313 [runtimes] Allow LLVM_BUILTIN_TARGETS to include Darwin has some related discussion.

Answering to aid future searches and troubleshooting: this is the invocation that did not build iOS and iOS Sim – if I drop LLVM_HOST_TRIPLE, those are built

cmake \
 -G Ninja \
 -DLLVM_VERSION_MAJOR:STRING=17 \
 -DLLVM_VERSION_MINOR:STRING=0 \
 -DLLVM_VERSION_PATCH:STRING=0 \
 -DCLANG_VERSION_MAJOR:STRING=17 \
 -DCLANG_VERSION_MINOR:STRING=0 \
 -DCLANG_VERSION_PATCH:STRING=0 \
 -DLLVM_ENABLE_ASSERTIONS:BOOL=TRUE '-DLLVM_TARGETS_TO_BUILD=X86;AArch64' \
 -DCLANG_VENDOR=Apple \
 -DCLANG_VENDOR_UTI=com.apple.compilers.llvm.clang \
 -DPACKAGE_VERSION=17.0.0 \
 -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=13.0 \
 -DCOMPILER_RT_ENABLE_IOS:BOOL=ON \
 -DCOMPILER_RT_ENABLE_WATCHOS:BOOL=FALSE \
 -DCOMPILER_RT_ENABLE_TVOS:BOOL=FALSE \
 -DSANITIZER_MIN_OSX_VERSION=13.0 \
 -DLLVM_ENABLE_MODULES:BOOL=FALSE \
 -DCMAKE_OSX_ARCHITECTURES=arm64 \
 -DLLVM_TARGET_ARCH=AArch64 \
 -DLLVM_HOST_TRIPLE:STRING=arm64-apple-macosx13.0 \
 -DINTERNAL_INSTALL_PREFIX=local \
 '-DCMAKE_C_FLAGS=-Wno-unknown-warning-option -Werror=unguarded-availability-new -arch arm64 -target arm64-apple-macosx13.0 -fno-stack-protector' \
 '-DCMAKE_CXX_FLAGS=-Wno-unknown-warning-option -Werror=unguarded-availability-new -arch arm64 -target arm64-apple-macosx13.0 -fno-stack-protector' \
 -DCMAKE_BUILD_TYPE:STRING=Release \
 -DLLVM_TOOL_SWIFT_BUILD:BOOL=FALSE \
 -DLLVM_TOOL_LLD_BUILD:BOOL=TRUE \
 -DLLVM_INCLUDE_DOCS:BOOL=TRUE \
 -DCOMPILER_RT_INTERCEPT_LIBDISPATCH=ON '-DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra;lld' \
 -DLLVM_ENABLE_RUNTIMES='compiler-rt' \
 -ULLVM_TOOL_COMPILER_RT_BUILD \
 -ULLVM_BUILD_EXTERNAL_COMPILER_RT \
 -DLLVM_APPEND_VC_REV=OFF '-DCMAKE_IGNORE_PATH=/usr/lib;/usr/local/lib;/lib' \
 -DPKG_CONFIG_EXECUTABLE=/usr/bin/false \
 -S llvm-project-llvm-org-main/llvm \
 -B ${build_folder} \

Using the Fuchsia configuration I am able to build runtimes for the iOS simulator, but not for iOS proper – possibly because we set CMAKE_OSX_ARCHITECTURES in RUNTIMES_CMAKE_ARGS, and that seems to interfere with the SDK detection

cmake -G Ninja \
      -DBUILTIN_TARGETS="default" \
  -DRUNTIME_TARGETS="default" \
  -DCOMPILER_RT_ENABLE_TVOS:BOOL=OFF \
  -DCOMPILER_RT_ENABLE_WATCHOS:BOOL=OFF \
  -DCOMPILER_RT_USE_BUILTINS_LIBRARY:BOOL=ON \
  -DLIBUNWIND_ENABLE_SHARED:BOOL=OFF \
  -DLIBUNWIND_USE_COMPILER_RT:BOOL=ON \
  -DLIBCXXABI_ENABLE_SHARED:BOOL=OFF \
  -DLIBCXXABI_ENABLE_STATIC_UNWINDER:BOOL=ON \
  -DLIBCXXABI_INSTALL_LIBRARY:BOOL=OFF \
  -DLIBCXXABI_USE_COMPILER_RT:BOOL=ON \
  -DLIBCXXABI_USE_LLVM_UNWINDER:BOOL=ON \
  -DLIBCXX_ABI_VERSION=2 \
  -DLIBCXX_ENABLE_SHARED:BOOL=OFF \
  -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY:BOOL=ON \
  -DLIBCXX_HARDENING_MODE="none" \
  -DLIBCXX_USE_COMPILER_RT:BOOL=ON \
  -DRUNTIMES_CMAKE_ARGS="-DCMAKE_OSX_DEPLOYMENT_TARGET=10.13;-DCMAKE_OSX_ARCHITECTURES=arm64|x86_64" \
  -DBUILTINS_CMAKE_ARGS="--trace-expand;--debug-trycompile;--trace-redirect=llvm-main-build-fuchsia-reference.builtins.trace.txt" \
  -DCOMPILER_RT_ENABLE_IOS:BOOL=ON \
    -DCMAKE_BUILD_TYPE:STRING=Release \
    -DLLVM_ENABLE_PROJECTS='clang;clang-tools-extra;lld' \
    -DLLVM_TARGETS_TO_BUILD='X86;AArch64' \
    -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.13 \
    -DLLVM_ENABLE_RUNTIMES='compiler-rt' \
    -DLLVM_APPEND_VC_REV=OFF \
    -DCMAKE_IGNORE_PATH='/usr/lib;/usr/local/lib;/lib' \
    -DPKG_CONFIG_EXECUTABLE=/usr/bin/false \
    -S llvm-project-llvm-org-main/llvm -B ${build_folder}

Thanks for the feedback and apologies for my late acknowledgement – the approach described by @smeenai allows us to build all the Apple platforms, so my LLVM change is not needed.

On a slight different note – is there a date for the removal of compiler-rt as a valid value for LLVM_ENABLE_PROJECTS? I cannot see anything when searching in forums and Github (in particular Deprecate the use of `LLVM_ENABLE_PROJECTS` for all runtimes · Issue #124009 · llvm/llvm-project · GitHub)