Skip to content

Commit 6fcf719

Browse files
committed
Improve x64 to x32 cross compilation
1 parent c3f701c commit 6fcf719

File tree

3 files changed

+68
-27
lines changed

3 files changed

+68
-27
lines changed

.cargo/config

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[target.aarch64-unknown-linux-gnu]
2+
linker = "aarch64-linux-gnu-gcc"
3+
4+
[target.mips64-unknown-linux-gnuabi64]
5+
linker = "mips64-linux-gnuabi64-gcc"

.github/workflows/main.yml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@ jobs:
99
matrix:
1010
target:
1111
- x86_64-unknown-linux-gnu
12+
- i686-unknown-linux-gnu
1213
- aarch64-unknown-linux-gnu
1314
- mips64-unknown-linux-gnuabi64
1415
- x86_64-apple-darwin
1516
- aarch64-apple-darwin
1617
- x86_64-pc-windows-gnu
18+
- i686-pc-windows-gnu
1719
- x86_64-pc-windows-msvc
1820
include:
1921
- target: x86_64-unknown-linux-gnu
2022
os: ubuntu-22.04
23+
- target: i686-unknown-linux-gnu
24+
os: ubuntu-22.04
2125
- target: aarch64-unknown-linux-gnu
2226
os: ubuntu-22.04
2327
- target: mips64-unknown-linux-gnuabi64
@@ -28,6 +32,8 @@ jobs:
2832
os: macos-latest
2933
- target: x86_64-pc-windows-gnu
3034
os: ubuntu-22.04
35+
- target: i686-pc-windows-gnu
36+
os: ubuntu-22.04
3137
- target: x86_64-pc-windows-msvc
3238
os: windows-latest
3339
steps:
@@ -37,6 +43,12 @@ jobs:
3743
- uses: dtolnay/rust-toolchain@stable
3844
with:
3945
target: ${{ matrix.target }}
46+
- name: Install GCC (i686-unknown-linux-gnu)
47+
if: ${{ matrix.target == 'i686-unknown-linux-gnu' }}
48+
run: |
49+
sudo apt-get update -y
50+
sudo apt-get install -y --no-install-recommends gcc-multilib
51+
shell: bash
4052
- name: Install GCC (aarch64-unknown-linux-gnu)
4153
if: ${{ matrix.target == 'aarch64-unknown-linux-gnu' }}
4254
run: |
@@ -55,9 +67,15 @@ jobs:
5567
sudo apt-get update -y
5668
sudo apt-get install -y --no-install-recommends gcc-mingw-w64-x86-64
5769
shell: bash
70+
- name: Install GCC (i686-pc-windows-gnu)
71+
if: ${{ matrix.target == 'i686-pc-windows-gnu' }}
72+
run: |
73+
sudo apt-get update -y
74+
sudo apt-get install -y --no-install-recommends gcc-mingw-w64-i686 gcc-multilib
75+
shell: bash
5876
- name: Build for ${{ matrix.target }}
5977
run: |
60-
cargo build --manifest-path testcrate/Cargo.toml --target ${{ matrix.target }} --release
78+
cargo build --tests --manifest-path testcrate/Cargo.toml --target ${{ matrix.target }} --release
6179
shell: bash
6280

6381
test:

src/lib.rs

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ impl Build {
115115
_ => {}
116116
}
117117

118+
let target_pointer_width = env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap();
119+
if target_pointer_width == "32" && env::var_os("HOST_CC").is_none() {
120+
// 32-bit cross-compilation?
121+
let host_cc = cc::Build::new().target(host).get_compiler();
122+
make.env("HOST_CC", format!("{} -m32", host_cc.path().display()));
123+
}
124+
118125
// Infer ar/ranlib tools from cross compilers if the it looks like
119126
// we're doing something like `foo-gcc` route that to `foo-ranlib`
120127
// as well.
@@ -129,43 +136,54 @@ impl Build {
129136
let compiler_path =
130137
which::which(compiler_path).expect(&format!("cannot find {compiler_path}"));
131138
let bindir = compiler_path.parent().unwrap();
132-
make.env("STATIC_CC", &compiler_path);
133-
make.env("TARGET_LD", &compiler_path);
139+
let compiler_path = compiler_path.to_string_lossy();
140+
let compiler_args = compiler.cflags_env();
141+
let compiler_args = compiler_args.to_string_lossy();
142+
if env::var_os("STATIC_CC").is_none() {
143+
make.env("STATIC_CC", format!("{compiler_path} {compiler_args}"));
144+
}
145+
if env::var_os("TARGET_LD").is_none() {
146+
make.env("TARGET_LD", format!("{compiler_path} {compiler_args}"));
147+
}
134148

135149
// Find ar
136-
if bindir.join(format!("{prefix}ar")).is_file() {
137-
let mut ar = bindir.join(format!("{prefix}ar")).into_os_string();
138-
ar.push(" rcus");
139-
make.env("TARGET_AR", ar);
140-
} else if compiler.is_like_clang() {
141-
if bindir.join("llvm-ar").is_file() {
142-
let mut ar = bindir.join("llvm-ar").into_os_string();
150+
if env::var_os("TARGET_AR").is_none() {
151+
if bindir.join(format!("{prefix}ar")).is_file() {
152+
let mut ar = bindir.join(format!("{prefix}ar")).into_os_string();
153+
ar.push(" rcus");
154+
make.env("TARGET_AR", ar);
155+
} else if compiler.is_like_clang() {
156+
if bindir.join("llvm-ar").is_file() {
157+
let mut ar = bindir.join("llvm-ar").into_os_string();
158+
ar.push(" rcus");
159+
make.env("TARGET_AR", ar);
160+
} else {
161+
panic!("cannot find {prefix}ar or llvm-ar");
162+
}
163+
} else if compiler.is_like_gnu() && bindir.join("ar").is_file() {
164+
let mut ar = bindir.join("ar").into_os_string();
143165
ar.push(" rcus");
144166
make.env("TARGET_AR", ar);
145167
} else {
146-
panic!("cannot find {prefix}ar or llvm-ar");
168+
panic!("cannot find {prefix}ar");
147169
}
148-
} else if compiler.is_like_gnu() && bindir.join("ar").is_file() {
149-
let mut ar = bindir.join("ar").into_os_string();
150-
ar.push(" rcus");
151-
make.env("TARGET_AR", ar);
152-
} else {
153-
panic!("cannot find {prefix}ar");
154170
}
155171

156172
// Find strip
157-
if bindir.join(format!("{prefix}strip")).is_file() {
158-
make.env("TARGET_STRIP", bindir.join(format!("{prefix}strip")));
159-
} else if compiler.is_like_clang() {
160-
if bindir.join("llvm-strip").is_file() {
161-
make.env("TARGET_STRIP", bindir.join("llvm-strip"));
173+
if env::var_os("TARGET_STRIP").is_none() {
174+
if bindir.join(format!("{prefix}strip")).is_file() {
175+
make.env("TARGET_STRIP", bindir.join(format!("{prefix}strip")));
176+
} else if compiler.is_like_clang() {
177+
if bindir.join("llvm-strip").is_file() {
178+
make.env("TARGET_STRIP", bindir.join("llvm-strip"));
179+
} else {
180+
panic!("cannot find {prefix}strip or llvm-strip");
181+
}
182+
} else if compiler.is_like_gnu() && bindir.join("strip").is_file() {
183+
make.env("TARGET_STRIP", bindir.join("strip"));
162184
} else {
163-
panic!("cannot find {prefix}strip or llvm-strip");
185+
panic!("cannot find {prefix}strip");
164186
}
165-
} else if compiler.is_like_gnu() && bindir.join("strip").is_file() {
166-
make.env("TARGET_STRIP", bindir.join("strip"));
167-
} else {
168-
panic!("cannot find {prefix}strip");
169187
}
170188

171189
let mut xcflags = vec!["-fPIC"];

0 commit comments

Comments
 (0)