Skip to content

Commit 13cb0b1

Browse files
16bit-ykikoclaude
andcommitted
feat: cross-compile support for macOS x64, Linux arm64, Windows arm64
Add CLICE_TARGET_TRIPLE to toolchain.cmake for cross-compilation. Upgrade LLVM from 21.1.4 to 21.1.8 and switch publish workflow from xmake to CMake. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1dd94e5 commit 13cb0b1

File tree

9 files changed

+174
-130
lines changed

9 files changed

+174
-130
lines changed

.github/workflows/build-llvm.yml

Lines changed: 95 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ jobs:
1212
fail-fast: false
1313
matrix:
1414
include:
15+
# ── Native builds ──────────────────────────────────────────────
1516
- os: windows-2025
1617
llvm_mode: Debug
1718
lto: OFF
@@ -39,6 +40,38 @@ jobs:
3940
- os: macos-15
4041
llvm_mode: RelWithDebInfo
4142
lto: ON
43+
44+
# ── Cross-compilation builds ───────────────────────────────────
45+
# macOS x64 (from arm64 macos-15)
46+
- os: macos-15
47+
llvm_mode: RelWithDebInfo
48+
lto: OFF
49+
target_triple: x86_64-apple-darwin
50+
- os: macos-15
51+
llvm_mode: RelWithDebInfo
52+
lto: ON
53+
target_triple: x86_64-apple-darwin
54+
55+
# Linux aarch64 (from x64 ubuntu-24.04)
56+
- os: ubuntu-24.04
57+
llvm_mode: RelWithDebInfo
58+
lto: OFF
59+
target_triple: aarch64-linux-gnu
60+
- os: ubuntu-24.04
61+
llvm_mode: RelWithDebInfo
62+
lto: ON
63+
target_triple: aarch64-linux-gnu
64+
65+
# Windows arm64 (from x64 windows-2025)
66+
- os: windows-2025
67+
llvm_mode: RelWithDebInfo
68+
lto: OFF
69+
target_triple: aarch64-pc-windows-msvc
70+
- os: windows-2025
71+
llvm_mode: RelWithDebInfo
72+
lto: ON
73+
target_triple: aarch64-pc-windows-msvc
74+
4275
runs-on: ${{ matrix.os }}
4376
steps:
4477
- name: Checkout repository
@@ -76,17 +109,27 @@ jobs:
76109
cache: true
77110
locked: true
78111

79-
- name: Clone llvm-project (21.1.4)
112+
- name: Clone llvm-project (21.1.8)
80113
shell: bash
81114
run: |
82-
git clone --branch llvmorg-21.1.4 --depth 1 https://github.com/llvm/llvm-project.git .llvm
115+
git clone --branch llvmorg-21.1.8 --depth 1 https://github.com/llvm/llvm-project.git .llvm
83116
84117
- name: Build LLVM (install-distribution)
85118
shell: bash
86119
run: |
87-
pixi run build-llvm --llvm-src=.llvm --mode="${{ matrix.llvm_mode }}" --lto="${{ matrix.lto }}" --build-dir=build
120+
EXTRA_ARGS=""
121+
if [[ -n "${{ matrix.target_triple }}" ]]; then
122+
EXTRA_ARGS="--target-triple=${{ matrix.target_triple }}"
123+
fi
124+
pixi run build-llvm \
125+
--llvm-src=.llvm \
126+
--mode="${{ matrix.llvm_mode }}" \
127+
--lto="${{ matrix.lto }}" \
128+
--build-dir=build \
129+
${EXTRA_ARGS}
88130
89131
- name: Build clice using installed LLVM
132+
if: ${{ !matrix.target_triple }}
90133
shell: bash
91134
run: |
92135
cmake -B build -G Ninja \
@@ -99,6 +142,7 @@ jobs:
99142
cmake --build build
100143
101144
- name: Run tests
145+
if: ${{ !matrix.target_triple }}
102146
shell: bash
103147
run: |
104148
EXE_EXT=""
@@ -108,8 +152,10 @@ jobs:
108152
./build/bin/unit_tests${EXE_EXT} --test-dir="./tests/data"
109153
uv run --project tests pytest -s --log-cli-level=INFO tests/integration --executable=./build/bin/clice${EXE_EXT}
110154
155+
# Prune is only supported for native builds (requires linking clice to test).
156+
# Cross-compiled targets reuse the native prune manifest of the same OS.
111157
- name: Prune LLVM static libraries (Debug/RelWithDebInfo no LTO)
112-
if: matrix.llvm_mode == 'Debug' || (matrix.llvm_mode == 'RelWithDebInfo' && matrix.lto == 'OFF')
158+
if: (!matrix.target_triple) && (matrix.llvm_mode == 'Debug' || (matrix.llvm_mode == 'RelWithDebInfo' && matrix.lto == 'OFF'))
113159
shell: bash
114160
run: |
115161
MANIFEST="pruned-libs-${{ matrix.os }}.json"
@@ -123,16 +169,36 @@ jobs:
123169
--manifest "${MANIFEST}"
124170
125171
- name: Upload pruned-libs manifest
126-
if: matrix.llvm_mode == 'RelWithDebInfo' && matrix.lto == 'OFF'
172+
if: (!matrix.target_triple) && matrix.llvm_mode == 'RelWithDebInfo' && matrix.lto == 'OFF'
127173
uses: actions/upload-artifact@v4
128174
with:
129175
name: llvm-pruned-libs-${{ matrix.os }}
130176
path: ${{ env.LLVM_PRUNED_MANIFEST }}
131177
if-no-files-found: error
132178
compression-level: 0
133179

134-
- name: Apply pruned-libs manifest (RelWithDebInfo + LTO)
135-
if: matrix.llvm_mode == 'RelWithDebInfo' && matrix.lto == 'ON'
180+
- name: Apply pruned-libs manifest (RelWithDebInfo + LTO, native only)
181+
if: (!matrix.target_triple) && matrix.llvm_mode == 'RelWithDebInfo' && matrix.lto == 'ON'
182+
shell: bash
183+
env:
184+
GH_TOKEN: ${{ github.token }}
185+
run: |
186+
MANIFEST="pruned-libs-${{ matrix.os }}.json"
187+
python3 scripts/prune-llvm-bin.py \
188+
--action apply \
189+
--manifest "${MANIFEST}" \
190+
--install-dir ".llvm/build-install/lib" \
191+
--build-dir "build" \
192+
--gh-run-id "${{ github.run_id }}" \
193+
--gh-artifact "llvm-pruned-libs-${{ matrix.os }}" \
194+
--gh-download-dir "artifacts" \
195+
--max-attempts 60 \
196+
--sleep-seconds 60
197+
198+
# For cross-compiled LTO builds, apply the native prune manifest.
199+
# The unused library set is arch-independent (same API surface).
200+
- name: Apply pruned-libs manifest (cross-compile + LTO)
201+
if: matrix.target_triple && matrix.lto == 'ON'
136202
shell: bash
137203
env:
138204
GH_TOKEN: ${{ github.token }}
@@ -157,16 +223,28 @@ jobs:
157223
MODE_TAG="debug"
158224
fi
159225
160-
ARCH="x64"
161-
PLATFORM="linux"
162-
TOOLCHAIN="gnu"
163-
if [[ "${{ matrix.os }}" == windows-* ]]; then
164-
PLATFORM="windows"
165-
TOOLCHAIN="msvc"
166-
elif [[ "${{ matrix.os }}" == macos-* ]]; then
167-
ARCH="arm64"
168-
PLATFORM="macos"
169-
TOOLCHAIN="clang"
226+
# Determine arch/platform/toolchain from target triple or runner OS
227+
if [[ -n "${{ matrix.target_triple }}" ]]; then
228+
case "${{ matrix.target_triple }}" in
229+
x86_64-apple-darwin)
230+
ARCH="x64"; PLATFORM="macos"; TOOLCHAIN="clang" ;;
231+
aarch64-linux-gnu)
232+
ARCH="aarch64"; PLATFORM="linux"; TOOLCHAIN="gnu" ;;
233+
aarch64-pc-windows-msvc)
234+
ARCH="aarch64"; PLATFORM="windows"; TOOLCHAIN="msvc" ;;
235+
esac
236+
else
237+
ARCH="x64"
238+
PLATFORM="linux"
239+
TOOLCHAIN="gnu"
240+
if [[ "${{ matrix.os }}" == windows-* ]]; then
241+
PLATFORM="windows"
242+
TOOLCHAIN="msvc"
243+
elif [[ "${{ matrix.os }}" == macos-* ]]; then
244+
ARCH="arm64"
245+
PLATFORM="macos"
246+
TOOLCHAIN="clang"
247+
fi
170248
fi
171249
172250
SUFFIX=""

.github/workflows/publish-clice.yml

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,61 +9,65 @@ jobs:
99
fail-fast: false
1010
matrix:
1111
include:
12+
# ── Native builds ──────────────────────────────────────────────
1213
- os: windows-2025
13-
artifact_name: clice.zip
1414
asset_name: clice-x64-windows-msvc.zip
15-
symbol_artifact_name: clice-symbol.zip
1615
symbol_asset_name: clice-x64-windows-msvc-symbol.zip
1716

1817
- os: ubuntu-24.04
19-
artifact_name: clice.tar.gz
2018
asset_name: clice-x86_64-linux-gnu.tar.gz
21-
symbol_artifact_name: clice-symbol.tar.gz
2219
symbol_asset_name: clice-x86_64-linux-gnu-symbol.tar.gz
2320

2421
- os: macos-15
25-
artifact_name: clice.tar.gz
2622
asset_name: clice-arm64-macos-darwin.tar.gz
27-
symbol_artifact_name: clice-symbol.tar.gz
2823
symbol_asset_name: clice-arm64-macos-darwin-symbol.tar.gz
2924

25+
# ── Cross-compilation builds ───────────────────────────────────
26+
- os: macos-15
27+
target_triple: x86_64-apple-darwin
28+
asset_name: clice-x86_64-macos-darwin.tar.gz
29+
symbol_asset_name: clice-x86_64-macos-darwin-symbol.tar.gz
30+
31+
- os: ubuntu-24.04
32+
target_triple: aarch64-linux-gnu
33+
asset_name: clice-aarch64-linux-gnu.tar.gz
34+
symbol_asset_name: clice-aarch64-linux-gnu-symbol.tar.gz
35+
36+
- os: windows-2025
37+
target_triple: aarch64-pc-windows-msvc
38+
asset_name: clice-aarch64-windows-msvc.zip
39+
symbol_asset_name: clice-aarch64-windows-msvc-symbol.zip
40+
3041
runs-on: ${{ matrix.os }}
3142

3243
steps:
3344
- name: Checkout repository
3445
uses: actions/checkout@v4
3546

36-
- name: Setup xmake
37-
uses: xmake-io/github-action-setup-xmake@v1
38-
with:
39-
xmake-version: 3.0.5
40-
actions-cache-folder: ".xmake-cache"
41-
actions-cache-key: ${{ matrix.os }}
42-
package-cache: true
43-
package-cache-key: ${{ matrix.os }}-pkg-release-v1
44-
build-cache: true
45-
build-cache-key: ${{ matrix.os }}-build-release-v1
46-
4747
- uses: ./.github/actions/setup-pixi
4848
with:
4949
environments: package
5050

51-
- name: Remove ci llvm toolchain on Windows
52-
if: runner.os == 'Windows'
51+
- name: Build & Package
52+
shell: bash
5353
run: |
54-
# @see https://github.com/xmake-io/xmake/issues/7158
55-
xmake lua os.rmdir "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm"
56-
xmake lua os.rmdir "C:/Program Files/LLVM"
57-
58-
- name: Package
59-
run: pixi run package
54+
EXTRA_ARGS=""
55+
if [[ -n "${{ matrix.target_triple }}" ]]; then
56+
EXTRA_ARGS="-DCLICE_TARGET_TRIPLE=${{ matrix.target_triple }}"
57+
fi
58+
cmake -B build/release -G Ninja \
59+
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
60+
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain.cmake \
61+
-DCLICE_RELEASE=ON \
62+
${EXTRA_ARGS}
63+
cmake --build build/release
6064
6165
- name: Upload Main Package to Release
6266
if: startsWith(github.ref, 'refs/tags/v')
6367
uses: svenstaro/upload-release-action@v2
6468
with:
6569
repo_token: ${{ secrets.GITHUB_TOKEN }}
66-
file: build/xpack/clice/${{ matrix.artifact_name }}
70+
file: build/release/clice${{ contains(matrix.asset_name, '.zip') && '.zip' || '.tar.gz' }}
6771
asset_name: ${{ matrix.asset_name }}
6872
tag: ${{ github.ref }}
6973
overwrite: true
@@ -73,7 +77,7 @@ jobs:
7377
uses: svenstaro/upload-release-action@v2
7478
with:
7579
repo_token: ${{ secrets.GITHUB_TOKEN }}
76-
file: build/xpack/clice/${{ matrix.symbol_artifact_name }}
80+
file: build/release/clice-symbol${{ contains(matrix.asset_name, '.zip') && '.zip' || '.tar.gz' }}
7781
asset_name: ${{ matrix.symbol_asset_name }}
7882
tag: ${{ github.ref }}
7983
overwrite: true

cmake/llvm.cmake

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ function(setup_llvm LLVM_VERSION)
2525
list(APPEND LLVM_SETUP_ARGS "--offline")
2626
endif()
2727

28+
if(DEFINED CLICE_TARGET_TRIPLE)
29+
if(CLICE_TARGET_TRIPLE MATCHES "linux")
30+
list(APPEND LLVM_SETUP_ARGS "--target-platform" "Linux")
31+
elseif(CLICE_TARGET_TRIPLE MATCHES "darwin")
32+
list(APPEND LLVM_SETUP_ARGS "--target-platform" "macosx")
33+
elseif(CLICE_TARGET_TRIPLE MATCHES "windows")
34+
list(APPEND LLVM_SETUP_ARGS "--target-platform" "Windows")
35+
endif()
36+
endif()
37+
2838
execute_process(
2939
COMMAND "${Python3_EXECUTABLE}" "${LLVM_SETUP_SCRIPT}" ${LLVM_SETUP_ARGS}
3040
RESULT_VARIABLE LLVM_SETUP_RESULT

cmake/package.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
include_guard()
22

33
include(${CMAKE_CURRENT_LIST_DIR}/llvm.cmake)
4-
setup_llvm("21.1.4+r1")
4+
setup_llvm("21.1.8")
55

66
# install dependencies
77
include(FetchContent)

cmake/toolchain.cmake

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,29 @@
11
cmake_minimum_required(VERSION 3.30)
22

3+
# Cross-compilation support via CLICE_TARGET_TRIPLE.
4+
# Examples:
5+
# -DCLICE_TARGET_TRIPLE=x86_64-apple-darwin (macOS x64 from arm64)
6+
# -DCLICE_TARGET_TRIPLE=aarch64-linux-gnu (Linux arm64 from x64)
7+
# -DCLICE_TARGET_TRIPLE=aarch64-pc-windows-msvc (Windows arm64 from x64)
8+
if(DEFINED CLICE_TARGET_TRIPLE)
9+
if(CLICE_TARGET_TRIPLE MATCHES "^x86_64-apple-darwin")
10+
set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "")
11+
elseif(CLICE_TARGET_TRIPLE MATCHES "^aarch64-.*-linux")
12+
set(CMAKE_SYSTEM_NAME Linux)
13+
set(CMAKE_SYSTEM_PROCESSOR aarch64)
14+
set(CMAKE_C_COMPILER_TARGET "aarch64-linux-gnu" CACHE STRING "")
15+
set(CMAKE_CXX_COMPILER_TARGET "aarch64-linux-gnu" CACHE STRING "")
16+
if(DEFINED ENV{CONDA_PREFIX} AND NOT DEFINED CMAKE_SYSROOT)
17+
set(CMAKE_SYSROOT "$ENV{CONDA_PREFIX}/aarch64-conda-linux-gnu/sysroot" CACHE PATH "")
18+
endif()
19+
elseif(CLICE_TARGET_TRIPLE MATCHES "^aarch64-.*-windows")
20+
set(CMAKE_SYSTEM_NAME Windows)
21+
set(CMAKE_SYSTEM_PROCESSOR ARM64)
22+
set(CMAKE_C_COMPILER_TARGET "aarch64-pc-windows-msvc" CACHE STRING "")
23+
set(CMAKE_CXX_COMPILER_TARGET "aarch64-pc-windows-msvc" CACHE STRING "")
24+
endif()
25+
endif()
26+
327
set(CMAKE_C_COMPILER clang CACHE STRING "")
428
set(CMAKE_CXX_COMPILER clang++ CACHE STRING "")
529

0 commit comments

Comments
 (0)