iOS cross-compilation fails because `--gc-sections` is passed to Apple's linker
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Hello LLVM maintainers,
I've been experimenting with cross-compiling LLVM for an iOS target on macOS, mainly for learning and potential future use. I'm able to get most of the build to complete, but the build eventually fails when linking `llvm-ar`:
```cmake
[3722/4279] Linking CXX executable bin/llvm-ar
FAILED: [code=1] bin/llvm-ar
: && /usr/bin/c++ -w -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -O3 -DNDEBUG -arch arm64 -isysroot /Applications/Xcode_26.6.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS26.5.sdk -miphoneos-version-min=15.0 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -Wl,--gc-sections tools/llvm-ar/CMakeFiles/llvm-ar.dir/llvm-ar.cpp.o tools/llvm-ar/CMakeFiles/llvm-ar.dir/llvm-ar-driver.cpp.o -o bin/llvm-ar lib/libLLVMAArch64AsmParser.a lib/libLLVMAArch64Desc.a lib/libLLVMAArch64Info.a lib/libLLVMBina
ld: unknown options: --gc-sections
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
```
The relevant part of the generated link command is:
```
-arch arm64
-isysroot .../iPhoneOS26.5.sdk
-miphoneos-version-min=15.0
...
-Wl,--gc-sections
```
Since the iOS build is using Apple's `ld`/`ld64`, `--gc-sections` is rejected. The Darwin linker instead provides `-dead_strip` for dead-code stripping.
I noticed that LLVM's CMake logic uses `-dead_strip` for Darwin targets, while `--gc-sections` is used for other platforms. Since iOS is also an Apple/Darwin platform, I'm wondering whether iOS is expected to take the same linker path.
In particular:
1. Is it expected that an iOS CMake configuration (`CMAKE_SYSTEM_NAME=iOS`) uses `--gc-sections` here?
2. If so, is there a recommended way to configure the LLVM build so that `-dead_strip` is used instead?
3. If this is unintended, would a change to LLVM's CMake platform detection be appropriate?
For reference, this is the script I'm using to reproduce the issue:
```sh
#!/bin/bash
set -e
LLVM_VERSION="22.1.8"
WORKSPACE_DIR=$(pwd)
LLVM_ARCHIVE="llvm-project-${LLVM_VERSION}.src.tar.xz"
LLVM_SRC="${WORKSPACE_DIR}/llvm-src"
curl -L "https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/${LLVM_ARCHIVE}" -o "${LLVM_ARCHIVE}"
tar -xf "${LLVM_ARCHIVE}"
mv "llvm-project-${LLVM_VERSION}.src" "${LLVM_SRC}"
rm "${LLVM_ARCHIVE}"
HOST_BUILD="${WORKSPACE_DIR}/build-host"
cmake -S "${LLVM_SRC}/llvm" -B "${HOST_BUILD}" -G Ninja \
-Wno-author \
-Wno-deprecated \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="clang" \
-DLLVM_TARGETS_TO_BUILD="AArch64"
cmake --build "${HOST_BUILD}" --target llvm-tblgen clang-tblgen --parallel "$(sysctl -n hw.ncpu)"
IOS_BUILD="${WORKSPACE_DIR}/build-ios"
cmake -S "${LLVM_SRC}/llvm" -B "${IOS_BUILD}" -G Ninja \
-Wno-author \
-Wno-deprecated \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_SYSTEM_NAME=iOS \
-DCMAKE_C_FLAGS="-w" \
-DCMAKE_CXX_FLAGS="-w" \
-DCMAKE_MACOSX_BUNDLE=OFF \
-DCMAKE_OSX_SYSROOT="$(xcrun --sdk iphoneos --show-sdk-path)" \
-DCMAKE_OSX_ARCHITECTURES="arm64" \
-DCMAKE_OSX_DEPLOYMENT_TARGET="15.0" \
-DLLVM_ENABLE_PROJECTS="clang" \
-DLLVM_TARGETS_TO_BUILD="AArch64" \
-DLLVM_DEFAULT_TARGET_TRIPLE="arm64-apple-ios15.0" \
-DLLVM_NATIVE_TOOL_DIR="${HOST_BUILD}/bin"
cmake --build "${IOS_BUILD}" --parallel "$(sysctl -n hw.ncpu)"
```
Any guidance on whether this is a configuration issue, an LLVM CMake issue, or if there is an existing recommended approach for building LLVM for iOS would be greatly appreciated.
Contributor guide
Research direction
Run the reproduction script from the issue body and inspect the generated iOS link command, especially the platform logic that adds --gc-sections. Compare the existing Darwin handling with the CMAKE_SYSTEM_NAME=iOS configuration; done means the iOS build uses Apple's supported dead-code-stripping flag and llvm-ar links successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bash, cmake, cpp, ios
- Domain
- build-system, compilers, mobile-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100