Skip to content

Commit 6860b85

Browse files
Jake-Shadlenagisa
authored andcommitted
Add back Windows cross-compilation support
This adds back support for Windows cross-compilation by using the GAS files if the Microsoft assembler isn't found rather than unconditionally trying to use it targeting the `msvc` environment. This also adds a test job to compile and test a cross compilation scenario. If we take out testing and instead just test building then that would be a much simpler step since we wouldn't need wine nor the Windows SDK, which are only required when building/running the cargo test executables. Resolves: #58
1 parent 8665a9e commit 6860b85

File tree

2 files changed

+72
-6
lines changed

2 files changed

+72
-6
lines changed

.github/workflows/test.yml

+55-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
- '*.mkd'
99
- 'LICENSE'
1010
pull_request:
11-
types: [opened, repoened, synchronize]
11+
types: [opened, reopened, synchronize]
1212

1313
jobs:
1414
native-test:
@@ -257,6 +257,60 @@ jobs:
257257
command: build
258258
args: --target=${{ matrix.rust_target }} --manifest-path=${{ matrix.manifest }}
259259

260+
cross-windows-build:
261+
name: Cross-compile ${{ matrix.manifest }} for ${{ matrix.rust_target }} from x86_64-unknown-linux-gnu
262+
runs-on: ubuntu-20.04
263+
strategy:
264+
fail-fast: true
265+
matrix:
266+
rust_target:
267+
- x86_64-pc-windows-msvc
268+
- i686-pc-windows-msvc
269+
manifest: ['psm/Cargo.toml', 'Cargo.toml']
270+
xwin_version: ["0.1.6"]
271+
timeout-minutes: 10
272+
steps:
273+
- uses: actions/checkout@v2
274+
- name: Install Rust
275+
uses: actions-rs/toolchain@v1
276+
with:
277+
toolchain: stable
278+
profile: minimal
279+
target: ${{ matrix.rust_target }}
280+
- name: Add toolchain shims
281+
run: |
282+
set -eux
283+
sudo ln -s clang-12 /usr/bin/clang-cl
284+
sudo ln -s llvm-ar-12 /usr/bin/llvm-lib
285+
sudo ln -s lld-link-12 /usr/bin/lld-link
286+
- name: Install Windows SDK
287+
run: |
288+
set -eux
289+
xwin_version=${{ matrix.xwin_version }}
290+
xwin_prefix="xwin-$xwin_version-x86_64-unknown-linux-musl"
291+
292+
# Install xwin to cargo/bin via github release. Note you could also just use `cargo install xwin`.
293+
curl --fail -L https://github.com/Jake-Shadle/xwin/releases/download/$xwin_version/$xwin_prefix.tar.gz | tar -xzv -C /home/runner/.cargo/bin --strip-components=1 $xwin_prefix/xwin
294+
295+
# Splat the CRT and SDK files to /tmp/xwin/crt and /tmp/xwin/sdk respectively
296+
xwin --accept-license 1 splat --output /tmp/xwin
297+
- name: Test
298+
env:
299+
CC: "clang-cl"
300+
CXX: "clang-cl"
301+
AR: "llvm-lib"
302+
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER: "lld-link"
303+
CARGO_TARGET_I686_PC_WINDOWS_MSVC_LINKER: "lld-link"
304+
# Note that we only disable unused-command-line-argument here since clang-cl
305+
# doesn't implement all of the options supported by cl, but the ones it doesn't
306+
# are _generally_ not interesting.
307+
CFLAGS: "-Wno-unused-command-line-argument -fuse-ld=lld-link /imsvc/tmp/xwin/crt/include /imsvc/tmp/xwin/sdk/include/ucrt /imsvc/tmp/xwin/sdk/include/um /imsvc/tmp/xwin/sdk/include/shared"
308+
# Inform the linker where to search for libraries
309+
RUSTFLAGS: "-Lnative=/tmp/xwin/crt/lib/x86_64 -Lnative=/tmp/xwin/sdk/lib/um/x86_64 -Lnative=/tmp/xwin/sdk/lib/ucrt/x86_64"
310+
run: |
311+
set -eux
312+
cargo build --target ${{ matrix.rust_target }} --manifest-path ${{ matrix.manifest }}
313+
260314
wasm-test:
261315
name: Test stacker on WASM
262316
runs-on: ubuntu-latest

psm/build.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,26 @@ fn find_assembly(
5656
}
5757

5858
fn main() {
59-
let arch = ::std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
60-
let env = ::std::env::var("CARGO_CFG_TARGET_ENV").unwrap();
61-
let os = ::std::env::var("CARGO_CFG_TARGET_OS").unwrap();
62-
let endian = ::std::env::var("CARGO_CFG_TARGET_ENDIAN").unwrap();
59+
use std::env::var;
60+
61+
let arch = var("CARGO_CFG_TARGET_ARCH").unwrap();
62+
let env = var("CARGO_CFG_TARGET_ENV").unwrap();
63+
let os = var("CARGO_CFG_TARGET_OS").unwrap();
64+
let endian = var("CARGO_CFG_TARGET_ENDIAN").unwrap();
6365

6466
let mut cfg = cc::Build::new();
67+
6568
let msvc = cfg.get_compiler().is_like_msvc();
66-
let asm = if let Some((asm, canswitch)) = find_assembly(&arch, &endian, &os, &env, msvc) {
69+
// If we're targeting msvc, either via regular MS toolchain or clang-cl, we
70+
// will _usually_ want to use the regular Microsoft assembler if it exists,
71+
// which is done for us within cc, however it _probably_ won't exist if
72+
// we're in a cross-compilation context pm a platform that can't natively
73+
// run Windows executables, so in that case we instead use the the equivalent
74+
// GAS assembly file instead. This logic can be removed once LLVM natively
75+
// supports compiling MASM, but that is not stable yet
76+
let masm = msvc && var("HOST").expect("HOST env not set").contains("windows");
77+
78+
let asm = if let Some((asm, canswitch)) = find_assembly(&arch, &endian, &os, &env, masm) {
6779
println!("cargo:rustc-cfg=asm");
6880
if canswitch {
6981
println!("cargo:rustc-cfg=switchable_stack")

0 commit comments

Comments
 (0)