Skip to content

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

@mmastrac

Description

@mmastrac

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:

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:

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

# 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:

  if !msvc {

to:

  if !msvc || !masm {

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions