fix(keystore): build macOS helper for target arch, not build host#370
fix(keystore): build macOS helper for target arch, not build host#370hibari-tech wants to merge 1 commit into
Conversation
The Swift helper was compiled with no `-target`, so swiftc defaulted to the
build host's architecture. On Apple Silicon CI hosts this produced an arm64
helper even when cross-compiling the crate for `x86_64-apple-darwin`, leaving
the released x86_64 pay binary with an arm64 helper embedded.
At first run the helper is extracted to `~/.cache/pay/pay.sh` and
`posix_spawn`ed, which returns `EBADARCH (86)` ("Bad CPU type in executable")
on Intel Macs, making `pay setup` unusable.
Pass `-target {CARGO_CFG_TARGET_ARCH}-apple-macos11` so the helper always
matches the crate's target arch.
Verified locally on Intel macOS 15.7.7: helper is now `Mach-O 64-bit
executable x86_64` and `pay setup --backend keychain --force` completes
("Account secured in Apple Keychain").
Fixes solana-foundation#369
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@hibari-tech is attempting to deploy a commit to the Solana Foundation Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryThis PR fixes a cross-compilation bug where the Swift keychain helper was built for the build host's architecture instead of the crate's target architecture, causing an
Confidence Score: 3/5Safe to merge for the x86_64 fix, but introduces a regression for arm64 targets due to the aarch64/arm64 naming mismatch in Apple target triples. The fix correctly solves the cross-compilation bug for x86_64, but the constructed Swift target triple uses rust/crates/keystore/build.rs — the arch name mapping needs to translate Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[build.rs starts on macOS host] --> B[Read CARGO_CFG_TARGET_ARCH]
B --> C{arch value}
C -->|x86_64| D["swift_target = x86_64-apple-macos11 ✅"]
C -->|aarch64| E["swift_target = aarch64-apple-macos11 ⚠️\nApple expects arm64, not aarch64"]
D --> F["swiftc -O -target x86_64-apple-macos11 -o pay-helper"]
E --> G["swiftc -O -target aarch64-apple-macos11 -o pay-helper"]
F --> H{swiftc success?}
G --> I{swiftc success?}
H -->|yes| J[codesign helper → embed in binary]
H -->|no| K[write empty sentinel → compiled at runtime]
I -->|yes| J
I -->|no| K
Reviews (1): Last reviewed commit: "fix(keystore): build macOS helper for ta..." | Re-trigger Greptile |
| let target_arch = | ||
| std::env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_else(|_| "x86_64".to_string()); | ||
| let swift_target = format!("{target_arch}-apple-macos11"); |
There was a problem hiding this comment.
The
CARGO_CFG_TARGET_ARCH value for 64-bit ARM is aarch64, but Apple/LLVM target triples use arm64 — they are not the same string. Passing -target aarch64-apple-macos11 to swiftc is invalid; the correct triple is arm64-apple-macos11. On a native Apple Silicon build or when cross-compiling to arm64, swiftc will reject the target string and fall back to an empty sentinel, regressing the very scenario this PR intended to fix for arm64 users.
| let target_arch = | |
| std::env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_else(|_| "x86_64".to_string()); | |
| let swift_target = format!("{target_arch}-apple-macos11"); | |
| let target_arch = | |
| std::env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_else(|_| "x86_64".to_string()); | |
| // Swift/Apple target triples use "arm64", not "aarch64" (Rust/LLVM name). | |
| let swift_arch = match target_arch.as_str() { | |
| "aarch64" => "arm64", | |
| other => other, | |
| }; | |
| let swift_target = format!("{swift_arch}-apple-macos11"); |
Summary
Fixes #369. The Swift keychain helper was compiled with no
-target, soswiftcdefaulted to the build host's architecture. On Apple Silicon CI runners this produced anarm64helper even when cross-compiling the crate forx86_64-apple-darwin— leaving the released x86_64paybinary with an arm64 helper embedded viainclude_bytes!.At first run that helper is extracted to
~/.cache/pay/pay.shandposix_spawned, which returnsEBADARCH (86)("Bad CPU type in executable") on Intel Macs, breakingpay setup.This passes
-target {CARGO_CFG_TARGET_ARCH}-apple-macos11toswiftcso the helper always matches the crate's target arch (option 1 from #369; happy to switch to a universal helper if preferred).Test plan (verified locally on Intel macOS 15.7.7)
just lint(Prettier + ESLint +cargo clippy --workspace --all-targets -- -D warnings) — cleancargo fmt --check— cleancargo build --release --bin pay— succeedstarget/release/build/pay-keystore-*/out/pay-helperisMach-O 64-bit executable x86_64(wasarm64before the fix)pay-keystoreunit tests: 47/47 passrm ~/.cache/pay/pay.sh && pay setup --backend keychain --force→ "Account secured in Apple Keychain" (wasKeystore error: pay.sh: Bad CPU type in executable (os error 86))Note on
just ci/just testcargo test --workspaceis flaky onmainindependently of this PR:pay-core::server::proxy::tests::forward_request_injects_hmac_authand at least one neighbouring test bothset_var/remove_varthe same_TEST_ALIBABA_ACCESS_KEY_SECRETenv var, andstd::envis process-global, so they race undercargo test's default thread pool and intermittently fail withHMAC secret env var not set. The failing test passes deterministically in isolation:The flake is in a different crate from this change (
pay-corevspay-keystore) and is not introduced by this PR. Happy to file a follow-up if a maintainer confirms the diagnosis.🤖 Generated with Claude Code