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

Per*_*idi 2 linux windows cross-compiling rust

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

fn main() {
    println!("Hello, world!");
}
Run Code Online (Sandbox Code Playgroud)

它从主机编译到这个主机本机很好,但是当我尝试将它交叉编译到 i686 或 x86_64 窗口时,它无法编译。

我阅读了stackoverflow(例如here)并在互联网上搜索了类似的问题以及如何解决它,但没有任何收益。

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

[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]$
Run Code Online (Sandbox Code Playgroud)

我已经将 mingw32 安装为 mingw64,这个小测试 C++ 代码已经被 mingw32 编译为 mingw64 就好了,没有错误:

#include <iomanip>
#include <iostream>

int main() {
    std::cout << "Hello, world!" << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我已将 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"
Run Code Online (Sandbox Code Playgroud)

但是当我跑

cargo build --release --target i686-pc-windows-gnu --verbose
Run Code Online (Sandbox Code Playgroud)

或者

cargo build --release --target x86_64-pc-windows-gnu --verbose
Run Code Online (Sandbox Code Playgroud)

都抱怨“找不到-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]$
Run Code Online (Sandbox Code Playgroud)

为什么?我还应该做些什么来满足一切?

Per*_*idi 6

经过一番思考,我能够解决问题,将 Rust 中的项目从 Linux 主机交叉编译到 Windows 目标,而无需使用交叉和类似工具,而只需在货物中指定特定目标。当然,测试和运行项目会失败(如果你没有安装任何像 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 ~]$
Run Code Online (Sandbox Code Playgroud)

让我们用 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]$
Run Code Online (Sandbox Code Playgroud)

使用项目目录中的配置文件创建 .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]$
Run Code Online (Sandbox Code Playgroud)

这一步是必要的,以便在构建 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]$
Run Code Online (Sandbox Code Playgroud)

错误!在 crt2.o 文件中得到“未定义的引用__onexitend”和“未定义的引用__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]$ 
Run Code Online (Sandbox Code Playgroud)

现在尝试再次将项目构建为 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]$ 
Run Code Online (Sandbox Code Playgroud)

有效!

现在尝试对 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]$ 
Run Code Online (Sandbox Code Playgroud)

该错误与之前提到的 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]$ 
Run Code Online (Sandbox Code Playgroud)

并再次尝试将项目构建为 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]$ 
Run Code Online (Sandbox Code Playgroud)

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

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

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

将其构建为 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]$ 
Run Code Online (Sandbox Code Playgroud)

它运行得很完美(我检查过也一样有效)。现在尝试对 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]$
Run Code Online (Sandbox Code Playgroud)

哎呀!我们在 Rust 标准库的 libpanic_unwind 模块中得到了“未定义引用_Unwind_RaiseException”和“未定义引用_Unwind_Resume”。但是这个问题也解决了,虽然不像上一个只是替换了CRT crt2.o和dllcrt2.o文件那么简单。

对于堆栈展开,Rust 对 32 位 Windows 目标使用 dwarf 方法,对 64 位 Windows 目标使用 seh 方法,而标准 Fedora Linux 发行版中的 MinGW 对 32 位 Windows 目标使用 sjlj 方法,对 64 位 Windows 目标使用 seh 方法(在此处阅读差异) . 因此,64 位目标由 MinGW 链接器链接没有任何问题,但对于 32 位目标,没有必要正确链接符号和目标文件。要获得这些文件和符号,有必要使用 dwarf 支持而不是 sjlj 支持来重建 MinGW,默认情况下 32 位 Windows 目标。

我不会在这里详细介绍如何重建 MinGW,我只会说一件事:在使用 dwarf stack unwinding 而不是 sjlj 方法重建 MinGW 之后,您只需要从刚刚构建的 MinGW 中选择一个名为 libgcc_eh.a 的文件,然后将它放在 Rust i686-pc-windows-gnu 目标的库目录中。使用任何恐慌功能完成该项目后,不仅对于 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]$ 
Run Code Online (Sandbox Code Playgroud)

快乐生锈!:-)