@@ -118,27 +118,47 @@ jobs:
118118 target : x86_64-pc-windows-msvc
119119 artifact : cortex-cli-windows-x64
120120 ext : .exe
121+ static : false
121122 # Temporarily disabled: Windows ARM64 build has LLVM/clang issues
122123 # - runner: blacksmith-32vcpu-windows-2025
123124 # target: aarch64-pc-windows-msvc
124125 # artifact: cortex-cli-windows-arm64
125126 # ext: .exe
127+ # static: false
126128 - runner : macos-latest
127129 target : x86_64-apple-darwin
128130 artifact : cortex-cli-macos-x64
129131 ext : " "
132+ static : false
130133 - runner : macos-latest
131134 target : aarch64-apple-darwin
132135 artifact : cortex-cli-macos-arm64
133136 ext : " "
137+ static : false
134138 - runner : blacksmith-32vcpu-ubuntu-2404
135139 target : x86_64-unknown-linux-gnu
136140 artifact : cortex-cli-linux-x64
137141 ext : " "
142+ static : false
138143 - runner : blacksmith-32vcpu-ubuntu-2404-arm
139144 target : aarch64-unknown-linux-gnu
140145 artifact : cortex-cli-linux-arm64
141146 ext : " "
147+ static : false
148+ # =================================================================
149+ # Static musl builds - portable across Linux distributions
150+ # These binaries have no GLIBC dependency and work on older systems
151+ # =================================================================
152+ - runner : blacksmith-32vcpu-ubuntu-2404
153+ target : x86_64-unknown-linux-musl
154+ artifact : cortex-cli-linux-x64-static
155+ ext : " "
156+ static : true
157+ - runner : blacksmith-32vcpu-ubuntu-2404-arm
158+ target : aarch64-unknown-linux-musl
159+ artifact : cortex-cli-linux-arm64-static
160+ ext : " "
161+ static : true
142162
143163 steps :
144164 - uses : actions/checkout@v4
@@ -162,6 +182,30 @@ jobs:
162182 prefix-key : " rust-release-cli-${{ matrix.target }}"
163183 shared-key : ${{ needs.prepare.outputs.cache_key }}
164184
185+ # =========================================================================
186+ # Static musl build setup (for portable Linux binaries)
187+ # =========================================================================
188+ - name : Install musl toolchain (x86_64 static)
189+ if : matrix.target == 'x86_64-unknown-linux-musl'
190+ run : |
191+ sudo apt-get update
192+ sudo apt-get install -y musl-tools musl-dev
193+ # Verify musl-gcc is available
194+ which musl-gcc
195+ musl-gcc --version
196+
197+ - name : Install musl toolchain (aarch64 static)
198+ if : matrix.target == 'aarch64-unknown-linux-musl'
199+ run : |
200+ sudo apt-get update
201+ # For cross-compiling to aarch64-musl, we need the cross toolchain
202+ sudo apt-get install -y musl-tools musl-dev gcc-aarch64-linux-gnu
203+ # Install aarch64-linux-musl-gcc cross compiler
204+ wget -q https://musl.cc/aarch64-linux-musl-cross.tgz
205+ tar xzf aarch64-linux-musl-cross.tgz
206+ sudo mv aarch64-linux-musl-cross /opt/
207+ echo "/opt/aarch64-linux-musl-cross/bin" >> $GITHUB_PATH
208+
165209 # Windows ARM64 requires clang from Visual Studio for building the ring crate
166210 # See: https://github.com/briansmith/ring/blob/main/BUILDING.md
167211 - name : Setup MSVC environment for Windows ARM64
@@ -215,12 +259,61 @@ jobs:
215259 echo "C:\Program Files\LLVM\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
216260 }
217261
218- - name : Build release binary
262+ # =========================================================================
263+ # Build commands
264+ # =========================================================================
265+ - name : Build release binary (dynamic)
266+ if : matrix.static == false
219267 run : cargo +nightly build --release --target ${{ matrix.target }} -p cortex-cli
220268 env :
221269 RUSTFLAGS : " -Zthreads=32"
222270 CARGO_PROFILE_RELEASE_LTO : thin
223271
272+ - name : Build release binary (static musl x86_64)
273+ if : matrix.target == 'x86_64-unknown-linux-musl'
274+ run : |
275+ cargo +nightly build --release --target ${{ matrix.target }} -p cortex-cli
276+ env :
277+ RUSTFLAGS : " -Zthreads=32 -C target-feature=+crt-static"
278+ CARGO_PROFILE_RELEASE_LTO : thin
279+ CC_x86_64_unknown_linux_musl : musl-gcc
280+ AR_x86_64_unknown_linux_musl : ar
281+ CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER : musl-gcc
282+
283+ - name : Build release binary (static musl aarch64)
284+ if : matrix.target == 'aarch64-unknown-linux-musl'
285+ run : |
286+ cargo +nightly build --release --target ${{ matrix.target }} -p cortex-cli
287+ env :
288+ RUSTFLAGS : " -Zthreads=32 -C target-feature=+crt-static"
289+ CARGO_PROFILE_RELEASE_LTO : thin
290+ CC_aarch64_unknown_linux_musl : aarch64-linux-musl-gcc
291+ AR_aarch64_unknown_linux_musl : aarch64-linux-musl-ar
292+ CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER : aarch64-linux-musl-gcc
293+
294+ # =========================================================================
295+ # Verify static binary (for musl builds)
296+ # =========================================================================
297+ - name : Verify static binary
298+ if : matrix.static == true
299+ run : |
300+ echo "=== Verifying static binary ==="
301+ BINARY="target/${{ matrix.target }}/release/${{ env.BINARY_NAME }}"
302+ file "$BINARY"
303+ echo ""
304+ echo "=== Checking dynamic dependencies ==="
305+ # For a truly static binary, ldd should report "not a dynamic executable"
306+ # or show no dynamic dependencies
307+ if ldd "$BINARY" 2>&1 | grep -q "not a dynamic executable\|statically linked"; then
308+ echo "✅ Binary is statically linked"
309+ else
310+ echo "⚠️ Binary has some dynamic dependencies (expected for musl with linux-keyutils):"
311+ ldd "$BINARY" 2>&1 || true
312+ fi
313+ echo ""
314+ echo "=== Binary size ==="
315+ ls -lh "$BINARY"
316+
224317 - name : Prepare artifact (Unix)
225318 if : runner.os != 'Windows'
226319 run : |
0 commit comments