从 Fedora Linux 主机到 Windows 目标的交叉编译 Rust 找不到依赖项

Crosscompiling Rust from Fedora Linux host to Windows target does not find dependencies

我 运行 x86_64 Fedora Linux 31 主机,想编译一些最简单的 rust 代码:

fn main() {
    println!("Hello, world!");
}

它从主机编译到这个主机本身很好,但是当我尝试将它交叉编译为 i686 或 x86_64 windows 时,它编译失败。

我阅读了 Whosebug(例如 )并在互联网上进行了搜索,试图找出类似的问题以及如何解决它,但没有任何收益。

我已经安装了所有必要的目标:

[pfemidi@pfemidi hello_cargo]$ rustup show
Default host: x86_64-unknown-linux-gnu
rustup home:  /home/pfemidi/.rustup

installed targets for active toolchain
--------------------------------------

i686-pc-windows-gnu
i686-unknown-linux-gnu
i686-unknown-linux-musl
x86_64-pc-windows-gnu
x86_64-unknown-linux-gnu
x86_64-unknown-linux-musl

active toolchain
----------------

stable-x86_64-unknown-linux-gnu (default)
rustc 1.39.0 (4560ea788 2019-11-04)

[pfemidi@pfemidi hello_cargo]$

我已经安装了 mingw32 as mingw64,这个小的测试 C++ 代码已经被 mingw32 as mingw64 编译得很好并且没有错误:

#include <iomanip>
#include <iostream>

int main() {
    std::cout << "Hello, world!" << std::endl;
    return 0;
}

我已将 windows 特定的 mingw 链接器和 ar 添加到我的 .cargo/config:

[target.i686-pc-windows-gnu]
linker = "i686-w64-mingw32-gcc"
ar = "i686-w64-mingw32-ar"

[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
ar = "x86_64-w64-mingw32-ar"

但是当我运行要么

cargo build --release --target i686-pc-windows-gnu --verbose

cargo build --release --target x86_64-pc-windows-gnu --verbose

都抱怨 "cannot find -lpthread":

[pfemidi@pfemidi hello_cargo]$ cargo build --release --target i686-pc-windows-gnu --verbose
   Compiling hello_cargo v0.1.0 (/home/pfemidi/mywork/rust/hello_cargo)
     Running `rustc --edition=2018 --crate-name hello_cargo src/main.rs --color always --crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C metadata=3801b83c24480675 -C extra-filename=-3801b83c24480675 --out-dir /home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps --target i686-pc-windows-gnu -C ar=i686-w64-mingw32-ar -C linker=i686-w64-mingw32-gcc -L dependency=/home/r/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps -L dependency=/home/r/mywork/rust/hello_cargo/target/release/deps`
error: linking with `i686-w64-mingw32-gcc` failed: exit code: 1
  |
  = note: "i686-w64-mingw32-gcc" "-Wl,--enable-long-section-names" "-fno-use-linker-plugin" "-Wl,--nxcompat" "-nostdlib" "-Wl,--large-address-aware" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/crt2.o" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/rsbegin.o" "-L" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.0.rcgu.o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.1.rcgu.o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.10.rcgu.o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.11.rcgu.o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.12.rcgu.o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.2.rcgu.o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.3.rcgu.o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.4.rcgu.o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.5.rcgu.o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.6.rcgu.o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.7.rcgu.o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.8.rcgu.o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.hello_cargo.ejabbyqy-cgu.9.rcgu.o" "-o" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.exe" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps/hello_cargo-3801b83c24480675.3miif37looiovbes.rcgu.o" "-Wl,--gc-sections" "-nodefaultlibs" "-L" "/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps" "-L" "/home/pfemidi/mywork/rust/hello_cargo/target/release/deps" "-L" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib" "-Wl,--start-group" "-Wl,-Bstatic" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libstd-78187cf09a9bef6f.rlib" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libpanic_abort-699459bd9d6c1638.rlib" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libhashbrown-397a481a32803af5.rlib" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/librustc_std_workspace_alloc-27eb482dce24475f.rlib" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libbacktrace-046a61f77fc212c5.rlib" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libbacktrace_sys-8c6fe5218eaa7203.rlib" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/librustc_demangle-4d4d47417516248c.rlib" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libunwind-ef8ccbbd42d1b53f.rlib" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libcfg_if-bbe68dc13352b6cc.rlib" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/liblibc-b6447d8e4c58855b.rlib" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/liballoc-3890c13f15229667.rlib" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/librustc_std_workspace_core-ceab434c37c7417c.rlib" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libcore-3b2fced4ccf446c5.rlib" "-Wl,--end-group" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libcompiler_builtins-7e358676639674ac.rlib" "-Wl,-Bdynamic" "-ladvapi32" "-lws2_32" "-luserenv" "-Wl,-Bstatic" "-lgcc_eh" "-lpthread" "-Wl,-Bdynamic" "-lmingwex" "-lmingw32" "-lgcc" "-lmsvcrt" "-lmsvcrt" "-luser32" "-lkernel32" "/home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/rsend.o"
  = note: /usr/lib/gcc/i686-w64-mingw32/9.2.1/../../../../i686-w64-mingw32/bin/ld: cannot find -lpthread
          collect2: error: ld returned 1 exit status


error: aborting due to previous error

error: could not compile `hello_cargo`.

Caused by:
  process didn't exit successfully: `rustc --edition=2018 --crate-name hello_cargo src/main.rs --color always --crate-type bin --emit=dep-info,link -C opt-level=3 -C panic=abort -C metadata=3801b83c24480675 -C extra-filename=-3801b83c24480675 --out-dir /home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps --target i686-pc-windows-gnu -C ar=i686-w64-mingw32-ar -C linker=i686-w64-mingw32-gcc -L dependency=/home/pfemidi/mywork/rust/hello_cargo/target/i686-pc-windows-gnu/release/deps -L dependency=/home/pfemidi/mywork/rust/hello_cargo/target/release/deps` (exit code: 1)
[pfemidi@pfemidi hello_cargo]$

为什么?还要做什么才能满足一切?

交叉编译并不像听起来那么容易。我建议不要发明自己的轮子并使用已经测试过的解决方案。

目前 "standard" 进行交叉编译的方法是使用 cross,这是一种货物包装器,可以让您摆脱交叉编译的细节。

在安装 cross 之前,您应该先安装它 dependencies。如何做到这一点完全取决于您的发行版。

依赖项准备就绪后,您应该像这样安装 cross(假设您有 cargo)。

$ cargo install cross

在那之后构建工作半神奇

cross build --target x86_64-pc-windows-gnu

经过深思熟虑,我能够解决从 Linux 主机到 Windows 目标的 Rust 交叉编译项目的问题,而无需使用 cross 和类似工具,而只是简单地通过在货物中指定特定目标。当然,测试和 运行 项目会失败(如果你没有安装像 wine 这样的模拟器),但是创建 Windows 目标会很顺利。顺便说一句,Rust 最初被开发为交叉编译器,因此拥有完整的工作项目并通过了 Linux 中的所有测试,几乎可以肯定 Windows 中该项目的简单交叉编译不会破坏它无论如何。

因为我 运行 Fedora Linux 31 以下所有内容都适用于此发行版。但我认为其他 Linux 发行版之间没有显着差异。而且我只考虑 pc-windows-gnu Rust 目标,pc-windows-msvc 目标不是我的兴趣。

首先,确保安装了交叉编译所需的所有 MinGW 包:

[pfemidi@pfemidi ~]$ rpm -qa | grep mingw | sort
mingw32-binutils-2.32-6.fc31.x86_64
mingw32-cpp-9.2.1-1.fc31.x86_64
mingw32-crt-6.0.0-2.fc31.noarch
mingw32-filesystem-110-1.fc31.noarch
mingw32-gcc-9.2.1-1.fc31.x86_64
mingw32-headers-6.0.0-2.fc31.noarch
mingw32-winpthreads-6.0.0-2.fc31.noarch
mingw32-winpthreads-static-6.0.0-2.fc31.noarch
mingw64-binutils-2.32-6.fc31.x86_64
mingw64-cpp-9.2.1-1.fc31.x86_64
mingw64-crt-6.0.0-2.fc31.noarch
mingw64-filesystem-110-1.fc31.noarch
mingw64-gcc-9.2.1-1.fc31.x86_64
mingw64-headers-6.0.0-2.fc31.noarch
mingw64-winpthreads-6.0.0-2.fc31.noarch
mingw64-winpthreads-static-6.0.0-2.fc31.noarch
mingw-binutils-generic-2.32-6.fc31.x86_64
mingw-filesystem-base-110-1.fc31.noarch
[pfemidi@pfemidi ~]$

让我们用 Rust 语言创建最简单的项目:

[pfemidi@pfemidi rust]$ cargo new foobar
     Created binary (application) `foobar` package
[pfemidi@pfemidi rust]$ cat foobar/src/main.rs 
fn main() {
    println!("Hello, world!");
}
[pfemidi@pfemidi rust]$

在项目目录下用config文件创建.cargo目录,内容如下:

[pfemidi@pfemidi rust]$ cd foobar
[pfemidi@pfemidi foobar]$ mkdir .cargo
[pfemidi@pfemidi foobar]$ cat > .cargo/config
[target.i686-pc-windows-gnu]
linker = "i686-w64-mingw32-gcc"
ar = "i686-w64-mingw32-ar"

[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
ar = "x86_64-w64-mingw32-ar"
[pfemidi@pfemidi foobar]$

此步骤是必要的,以便在构建 Windows 目标时,Rust 不使用默认安装的 gcc 中的链接器,而是使用 MinGW 链接器。

现在尝试将项目构建为 i686-pc-windows-gnu 目标:

[pfemidi@pfemidi foobar]$ cargo build --target i686-pc-windows-gnu
   Compiling foobar v0.1.0 (/home/pfemidi/mywork/rust/foobar)
error: linking with `i686-w64-mingw32-gcc` failed: exit code: 1
  |
  = note: "i686-w64-mingw32-gcc" "-Wl,--enable-long-section-names" "-fno-use-linker-plugin" "-Wl,--nxcompat" "-nostdlib"

...

  = note: /usr/lib/gcc/i686-w64-mingw32/9.2.1/../../../../i686-w64-mingw32/bin/ld: /home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/crt2.o:crtexe.c:(.text+0x75): undefined reference to `__onexitend'
          /usr/lib/gcc/i686-w64-mingw32/9.2.1/../../../../i686-w64-mingw32/bin/ld: /home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/crt2.o:crtexe.c:(.text+0x7a): undefined reference to `__onexitbegin'
          collect2: error: ld returned 1 exit status


error: aborting due to previous error

error: could not compile `foobar`.

To learn more, run the command again with --verbose.
[pfemidi@pfemidi foobar]$

错误!在 crt2.o 文件中得到 "undefined reference to __onexitend" 和 "undefined reference to __onexitbegin"。事实上,pc-windows-gnu 目标的 Rust 组件是用 MinGW 6.3.0 构建的,但 Fedora Linux 31 中有 MinGW 版本 9.2.1。因此 CRT 有所不同由于编译器版本不匹配。好的,让我们将 crt2.o 从 Fedora Linux MinGW 存储库复制到 i686-pc-windows-gnu 组件的 Rust 目录。与 crt2.o 一起,我们还复制了 dllcrt2.o,它是动态库的入口点,因为 crt2.o 是独立可执行文件的入口点。为了以防万一,我们保存原始文件:

[pfemidi@pfemidi foobar]$ cd ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/
[pfemidi@pfemidi lib]$ mv crt2.o crt2.o.ori
[pfemidi@pfemidi lib]$ mv dllcrt2.o dllcrt2.o.ori
[pfemidi@pfemidi lib]$ cp /usr/i686-w64-mingw32/sys-root/mingw/lib/crt2.o .
[pfemidi@pfemidi lib]$ cp /usr/i686-w64-mingw32/sys-root/mingw/lib/dllcrt2.o .
[pfemidi@pfemidi lib]$ cd -
/home/pfemidi/mywork/rust/foobar
[pfemidi@pfemidi foobar]$ 

现在再次尝试将项目构建为 i686-pc-windows-gnu 目标:

[pfemidi@pfemidi foobar]$ cargo build --target i686-pc-windows-gnu
   Compiling foobar v0.1.0 (/home/pfemidi/mywork/rust/foobar)
    Finished dev [unoptimized + debuginfo] target(s) in 0.19s
[pfemidi@pfemidi foobar]$ 

成功了!

现在尝试对 x86_64-pc-windows-gnu 目标执行相同的操作:

[pfemidi@pfemidi foobar]$ cargo build --target x86_64-pc-windows-gnu
   Compiling foobar v0.1.0 (/home/pfemidi/mywork/rust/foobar)
error: linking with `x86_64-w64-mingw32-gcc` failed: exit code: 1
  |
  = note: "x86_64-w64-mingw32-gcc" "-Wl,--enable-long-section-names" "-fno-use-linker-plugin" "-Wl,--nxcompat" "-nostdlib" "-m64"

...

  = note: /usr/lib/gcc/x86_64-w64-mingw32/9.2.1/../../../../x86_64-w64-mingw32/bin/ld: /home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/crt2.o:crtexe.c:(.rdata$.refptr.__onexitbegin[.refptr.__onexitbegin]+0x0): undefined reference to `__onexitbegin'
          /usr/lib/gcc/x86_64-w64-mingw32/9.2.1/../../../../x86_64-w64-mingw32/bin/ld: /home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/crt2.o:crtexe.c:(.rdata$.refptr.__onexitend[.refptr.__onexitend]+0x0): undefined reference to `__onexitend'
          collect2: error: ld returned 1 exit status


error: aborting due to previous error

error: could not compile `foobar`.

To learn more, run the command again with --verbose.
[pfemidi@pfemidi foobar]$ 

该错误与之前提到的 i686-pc-windows-gnu 目标完全相同。让我们通过类比上面的 32 位目标来复制文件 crt2.o 和 dllcrt2.o:

[pfemidi@pfemidi foobar]$ cd ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/
[pfemidi@pfemidi lib]$ mv crt2.o crt2.o.ori
[pfemidi@pfemidi lib]$ mv dllcrt2.o dllcrt2.o.ori
[pfemidi@pfemidi lib]$ cp /usr/x86_64-w64-mingw32/sys-root/mingw/lib/crt2.o .
[pfemidi@pfemidi lib]$ cp /usr/x86_64-w64-mingw32/sys-root/mingw/lib/dllcrt2.o .
[pfemidi@pfemidi lib]$ cd -
/home/pfemidi/mywork/rust/foobar
[pfemidi@pfemidi foobar]$ 

并再次尝试将项目构建为 x86_64-pc-windows-gnu 目标:

[pfemidi@pfemidi foobar]$ cargo build --target x86_64-pc-windows-gnu
   Compiling foobar v0.1.0 (/home/pfemidi/mywork/rust/foobar)
    Finished dev [unoptimized + debuginfo] target(s) in 0.20s
[pfemidi@pfemidi foobar]$ 

是的!它也有效!所以现在我们可以使用 Rust 发行版中包含的标准货物轻松地为 Windows 构建目标!对于 x86_64 目标,这是完全正确的。但是对于 x86 目标,一切都会好起来,直到我们在我们的项目中使用任何恐慌的函数(f.e。宏恐慌!,期望函数等)。

让我们为我们的简单项目添加恐慌:

[pfemidi@pfemidi foobar]$ cat src/main.rs 
fn main() {
    println!("Hello, world!");
    panic!("I'm panicked!");    // <-- here it is
}
[pfemidi@pfemidi foobar]$

将其构建为 x86_64 目标:

[pfemidi@pfemidi foobar]$ cargo build --target x86_64-pc-windows-gnu
   Compiling foobar v0.1.0 (/home/pfemidi/mywork/rust/foobar)
    Finished dev [unoptimized + debuginfo] target(s) in 0.16s
[pfemidi@pfemidi foobar]$ 

一切顺利(我检查过,效果也很好)。现在尝试对 x86 目标执行相同的操作:

[pfemidi@pfemidi foobar]$ cargo build --target i686-pc-windows-gnu
   Compiling foobar v0.1.0 (/home/pfemidi/mywork/rust/foobar)
error: linking with `i686-w64-mingw32-gcc` failed: exit code: 1
  |
  = note: "i686-w64-mingw32-gcc" "-Wl,--enable-long-section-names" "-fno-use-linker-plugin" "-Wl,--nxcompat" "-nostdlib"

...

  = note: /usr/lib/gcc/i686-w64-mingw32/9.2.1/../../../../i686-w64-mingw32/bin/ld: /home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libpanic_unwind-0c029c00da54fbf5.rlib(panic_unwind-0c029c00da54fbf5.panic_unwind.2hgzd7yq-cgu.0.rcgu.o): in function `ZN12panic_unwind3imp5panic17h03027a0e504502cdE':
          /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14\/src\libpanic_unwind/gcc.rs:73: undefined reference to `_Unwind_RaiseException'
          /usr/lib/gcc/i686-w64-mingw32/9.2.1/../../../../i686-w64-mingw32/bin/ld: /home/pfemidi/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libpanic_unwind-0c029c00da54fbf5.rlib(panic_unwind-0c029c00da54fbf5.panic_unwind.2hgzd7yq-cgu.0.rcgu.o): in function `rust_eh_unwind_resume':
          /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14\/src\libpanic_unwind/gcc.rs:327: undefined reference to `_Unwind_Resume'
          collect2: error: ld returned 1 exit status


error: aborting due to previous error

error: could not compile `foobar`.

To learn more, run the command again with --verbose.
[pfemidi@pfemidi foobar]$

糟糕!我们在 Rust 标准库的 libpanic_unwind 模块中得到 "undefined reference to _Unwind_RaiseException" 和 "undefined reference to _Unwind_Resume"。不过这个问题也解决了,虽然没有上一个简单,只是替换CRTcrt2.o和dllcrt2.o文件

对于堆栈展开,Rust 对 32 位 Windows 目标使用 dwarf 方法,对 64 位 Windows 目标使用 seh 方法,而来自标准 Fedora Linux 发行版的 MinGW 使用 sjlj 方法进行32 位 Windows 目标和 64 位 Windows 目标的 seh 方法(了解差异 here)。因此,64 位目标由 MinGW 链接器链接没有任何问题,但对于 32 位目标,没有必要的符号和目标文件才能正确链接。要获得这些文件和符号,有必要为 32 位 Windows 目标重建具有 dwarf 支持的 MinGW 而不是默认的 sjlj 支持。

我不会在这里详细介绍如何重建 MinGW,我只说一件事:用 dwarf stack unwinding 而不是 sjlj 方法重建 MinGW 后,你只需要选择一个名为 libgcc_eh.a 来自刚刚构建的 MinGW,并将其放入 Rust i686-pc-windows-gnu 目标的库目录中。这样做之后,带有任何 panic 函数的项目不仅对于 64 位 Windows 目标,而且对于 32 位目标都将无错误地构建:

[pfemidi@pfemidi foobar]$ cd ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/
[pfemidi@pfemidi lib]$ cp ~/rpmbuild/BUILD/gcc-9.2.1-20190827/build_win32/i686-w64-mingw32/libgcc/libgcc_eh.a .
[pfemidi@pfemidi lib]$ cd -
/home/pfemidi/mywork/rust/foobar
[pfemidi@pfemidi foobar]$ cargo build --target i686-pc-windows-gnu
   Compiling foobar v0.1.0 (/home/pfemidi/mywork/rust/foobar)
    Finished dev [unoptimized + debuginfo] target(s) in 0.30s
[pfemidi@pfemidi foobar]$ 

RUSTing 快乐! :-)