【问题标题】:Crosscompiling Rust from Fedora Linux host to Windows target does not find dependencies从 Fedora Linux 主机到 Windows 目标的交叉编译 Rust 找不到依赖项
【发布时间】:2020-04-10 14:40:47
【问题描述】:

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

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

它可以在本机上从主机编译到该主机,但是当我尝试将它交叉编译到 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]$

我已经安装了 mingw32 和 mingw64,这个小测试 C++ 代码已经被 mingw32 编译为 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

两者都抱怨“找不到 -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]$

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

【问题讨论】:

    标签: linux windows rust cross-compiling


    【解决方案1】:

    经过一番思考,我能够解决问题,将 Rust 中的项目从 Linux 主机交叉编译到 Windows 目标,而无需使用 cross 和类似工具,而只需在货物中指定特定目标。当然,测试和运行项目会失败(如果你没有安装任何模拟器,比如 wine),但是创建 Windows 目标会很顺利。 BTW 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 文件中得到“对__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]$ 
    

    现在尝试再次将项目构建为 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 目标完全相同。让我们复制文件 crt2.o 和 dllcrt2.o 与上面的 32 位目标类比:

    [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 目标,只有在我们在项目中使用任何恐慌的函数(例如宏恐慌!、期望函数等)之前,一切都会好起来的。

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

    [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 模块中获得了“对_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 方法(阅读有关差异here)。因此 64 位目标由 MinGW 链接器链接没有任何问题,但对于 32 位目标,没有必要的符号和目标文件来正确链接。要获取这些文件和符号,必须使用 dwarf 支持而不是 32 位 Windows 目标的默认 sjlj 支持来重建 MinGW。

    我不会在这里详细介绍如何重建 MinGW,我只会说一件事:在使用 dwarf 堆栈展开而不是 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]$ 
    

    RUST 快乐! :-)

    【讨论】:

      【解决方案2】:

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

      目前进行交叉编译的“标准”方式是使用cross,这是一种货物包装器,可让您远离交叉编译的细节。

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

      依赖关系准备好后,你应该像这样安装cross(假设你有cargo)。

      $ cargo install cross

      在那之后构建工作半神奇

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

      【讨论】:

      • 我刚试过这个。是的,它可以工作,但遗憾的是只支持 x86_64 windows 平台。除了 x86,还有什么方法可以做同样的事情吗?
      猜你喜欢
      • 2017-02-03
      • 1970-01-01
      • 2020-01-28
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      相关资源
      最近更新 更多