rust-lang / rust-lang/stacker

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

Open Beginner friendly
#143 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
360
Forks
78
PR merge metrics
No merged PRs in 30d

Description

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 {

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in build.rs around the MASM detection and assembler flag setup, then inspect src/arch/aarch_aapcs64.s lines 13-17 and its target-specific branches. Reproduce with cargo xwin build --target aarch64-pc-windows-msvc on Linux and verify the assembly receives preprocessing and Windows defines without the COFF errors; a successful build is done.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
build-system, operating-systems
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.