ITADN

aarch64-pc-windows-msvc cross-compilation from Linux fails: GAS assembly missing preprocessor defines

#143Openmmastrac 创建于 2026-04-10
M
mmastraccommented
When cross-compiling to `aarch64-pc-windows-msvc` from a Linux host, psm selects the GAS assembly file (`aarch_aapcs64.s`) but skips the preprocessor flag (`-xassembler-with-cpp`) and platform defines (`CFG_TARGET_OS_windows`, etc.) because the compiler is detected as MSVC-like (clang-cl). This causes the assembly to fall into the `#else` (Linux/ELF) path in `aarch_aapcs64.s`, which emits `.type` and `.size` directives that COFF targets reject. ### Root Cause In `build.rs`, line 84: ```rust let masm = msvc && var("HOST").expect("HOST env not set").contains("windows"); ``` This correctly detects that MASM isn't available when cross-compiling from Linux. The GAS `.s` file is selected as the fallback (line 30-36). However, lines 101-106 skip preprocessing for all MSVC compilers: ```rust if !msvc { cfg.flag("-xassembler-with-cpp"); cfg.define(&*format!("CFG_TARGET_OS_{}", os), None); cfg.define(&*format!("CFG_TARGET_ARCH_{}", arch), None); cfg.define(&*format!("CFG_TARGET_ENV_{}", env), None); } ``` When `msvc` is true but `masm` is false (cross-compiling from Linux), the `.s` file is used but doesn't get the preprocessor or `CFG_TARGET_OS_windows` define. The macros in `aarch_aapcs64.s` (lines 13-17) don't match, falling through to the ELF code path which emits directives incompatible with COFF. ### Reproduction ```bash # On a Linux host with clang, lld, and Rust nightly: rustup target add aarch64-pc-windows-msvc cargo install cargo-xwin cargo xwin build --target aarch64-pc-windows-msvc ``` Any crate depending on `stacker` (which depends on `psm`) will fail with: ``` src/arch/aarch_aapcs64.s:32:7: error: expected absolute expression src/arch/aarch_aapcs64.s:38:1: error: unknown directive ``` The `x86_64-pc-windows-msvc` target is not affected because it uses a separate `x86_64_windows_gnu.s` file that doesn't rely on these preprocessor macros. ### Suggested Fix Change line 101 from: ```rust if !msvc { ``` to: ```rust if !msvc || !masm { ```
0 条评论