ci: de-nix macOS binary libiconv via install_name_tool + re-sign
libiconv is the only /nix/store dep the darwin stdenv bakes in (everything else is system frameworks + libSystem/libobjc). The smoke-test now rewrites that load path to /usr/lib/libiconv.2.dylib (ABI-compatible, present on every Mac), re-signs ad-hoc (install_name_tool breaks the sig; arm64 requires a valid one), then verifies no /nix/store paths remain, the signature is valid, and the native binary launches. Flake comment updated to reflect the propagated-libiconv reality.
This commit is contained in:
@@ -25,21 +25,36 @@ jobs:
|
|||||||
NIX_CONFIG: "experimental-features = nix-command flakes"
|
NIX_CONFIG: "experimental-features = nix-command flakes"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: build both darwin targets through the flake
|
- name: build, de-nix, sign, verify both darwin targets
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
for t in aarch64-apple-darwin x86_64-apple-darwin; do
|
for t in aarch64-apple-darwin x86_64-apple-darwin; do
|
||||||
echo "==================== $t ===================="
|
echo "==================== $t ===================="
|
||||||
nix develop -c cargo build --release --target "$t"
|
nix develop -c cargo build --release --target "$t"
|
||||||
f="target/$t/release/rdbms-playground"
|
f="target/$t/release/rdbms-playground"
|
||||||
file "$f"
|
|
||||||
echo "--- linked libs (otool -L) ---"
|
# The darwin stdenv bakes a /nix/store libiconv load path into the
|
||||||
otool -L "$f"
|
# binary. Rewrite it to the system libiconv (every Mac has it, ABI-
|
||||||
# Portability guard: a distributable macOS binary must link only
|
# compatible), then re-sign ad-hoc — install_name_tool invalidates
|
||||||
# system libs (/usr/lib, /System/Library) — never a /nix/store path.
|
# the signature and arm64 won't run an unsigned/broken-sig binary.
|
||||||
|
for l in $(otool -L "$f" | awk '/\/nix\/store.*libiconv.*dylib/ {print $1}'); do
|
||||||
|
echo "rewrite $l -> /usr/lib/libiconv.2.dylib"
|
||||||
|
install_name_tool -change "$l" /usr/lib/libiconv.2.dylib "$f"
|
||||||
|
done
|
||||||
|
codesign --force --sign - "$f"
|
||||||
|
|
||||||
|
echo "--- linked libs ---"; otool -L "$f"
|
||||||
if otool -L "$f" | grep -q /nix/store; then
|
if otool -L "$f" | grep -q /nix/store; then
|
||||||
echo "ERROR: $t binary links a /nix/store dylib — not portable"; exit 1
|
echo "ERROR: $t still links a /nix/store dylib"; exit 1
|
||||||
fi
|
fi
|
||||||
echo "OK: $t links only system libraries"
|
codesign --verify --verbose=2 "$f" && echo "signature OK"
|
||||||
|
|
||||||
|
# Smoke-run the natively-runnable target (this VM is arm64).
|
||||||
|
if [ "$t" = "aarch64-apple-darwin" ]; then
|
||||||
|
echo "--- run --help ---"; "$f" --help | head -1
|
||||||
|
else
|
||||||
|
echo "(skip run: $t needs Rosetta)"
|
||||||
|
fi
|
||||||
|
echo "OK: $t portable"
|
||||||
done
|
done
|
||||||
echo "=== both darwin targets built + portable ==="
|
echo "=== both darwin targets built, de-nixed, signed, verified ==="
|
||||||
|
|||||||
@@ -63,11 +63,12 @@
|
|||||||
buildInputs = buildInputs ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
|
buildInputs = buildInputs ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
|
||||||
# macOS release builds (aarch64/x86_64-apple-darwin) link AppKit
|
# macOS release builds (aarch64/x86_64-apple-darwin) link AppKit
|
||||||
# (arboard) + libSystem; the Apple SDK provides those framework/
|
# (arboard) + libSystem; the Apple SDK provides those framework/
|
||||||
# system-lib stubs as *system* paths (/usr/lib, /System/Library), so
|
# system-lib stubs as *system* paths (/usr/lib, /System/Library).
|
||||||
# the resulting binary is portable. NOTE: do NOT add `pkgs.libiconv`
|
# NOTE: the darwin stdenv still propagates a *nix-store* libiconv and
|
||||||
# — it makes the linker prefer the nix-store libiconv.dylib, baking a
|
# links it regardless of inputs, so the release workflow rewrites that
|
||||||
# /nix/store path into the binary (non-portable). The SDK's own
|
# one load path to /usr/lib/libiconv.2.dylib (install_name_tool) and
|
||||||
# libiconv stub resolves `-liconv` to /usr/lib/libiconv instead.
|
# re-signs — see release-macos / the macOS smoke-test. Adding
|
||||||
|
# `pkgs.libiconv` here would only reinforce the wrong path, so don't.
|
||||||
pkgs.apple-sdk
|
pkgs.apple-sdk
|
||||||
];
|
];
|
||||||
nativeBuildInputs = nativeBuildInputs ++ [
|
nativeBuildInputs = nativeBuildInputs ++ [
|
||||||
|
|||||||
Reference in New Issue
Block a user