将Rust应用程序从Linux交叉编译到Windows

时间:2015-07-18 15:40:44

标签: linux windows rust cross-compiling

基本上,当我在Linux上开发时,我试图将最简单的代码编译到Windows。

fn main() {
    println!("Hello, and bye.")
}

我通过搜索互联网找到了这些命令:

rustc --target=i686-w64-mingw32-gcc  main.rs
rustc --target=i686_pc_windows_gnu -C linker=i686-w64-mingw32-gcc  main.rs
可悲的是,他们都没有工作。它给我一个关于std crate missing

的错误
$ rustc --target=i686_pc_windows_gnu -C linker=i686-w64-mingw32-gcc  main.rs 

main.rs:1:1: 1:1 error: can't find crate for `std`
main.rs:1 fn main() {
          ^
error: aborting due to previous error

有没有办法在Linux上运行可在Windows上运行的代码?

6 个答案:

答案 0 :(得分:38)

其他答案虽然在技术上是正确的,但比所需的难度更大。不需要使用rustc(实际上,不建议使用cargo),只需要使用rustupcargo

添加目标(您也可以针对交叉编译的目标更改此目标):

rustup target add x86_64-pc-windows-gnu
rustup toolchain install stable-x86_64-pc-windows-gnu

您可以使用以下方法轻松构建箱子:

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

无需弄乱~/.cargo/config或其他任何东西。

编辑:只是想补充一点,尽管您可以使用上面的内容,但有时也令人头疼。我想补充一下,防锈工具团队还维护了一个名为cross的项目:https://github.com/rust-embedded/cross 这可能是您要研究的另一种解决方案

答案 1 :(得分:25)

Rust发行版仅为主机系统提供编译库。但是,根据Arch Linux's wiki page on Rust,您可以在download directory中的Windows软件包中复制已编译的库(请注意,有i686和x86-64软件包)位于系统的适当位置(在{{ 1}}或/usr/lib/rustlib,取决于安装Rust的位置),安装mingw-w64-gcc和Wine,你应该能够交叉编译。

如果您正在使用Cargo,您可以将货物添加到/usr/local/lib/rustlib(其中ar是您使用的架构),告诉Cargo在哪里查找~/.cargo/config和链接器:< / p>

$ARCH

注意:确切的路径可能因您的分布而异。检查您的发行版中mingw-w64软件包(GCC和binutils)的文件列表。

然后你可以像这样使用Cargo:

[target.$ARCH-pc-windows-gnu]
linker = "/usr/bin/$ARCH-w64-mingw32-gcc"
ar = "/usr/$ARCH-w64-mingw32/bin/ar"

答案 2 :(得分:14)

让我们从Ubuntu的Rust-sdl2项目到Windows x86_64的交叉编译示例

~/.cargo/config

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

然后运行:

sudo apt-get install gcc-mingw-w64-x86-64 -y
# use rustup to add target https://github.com/rust-lang-nursery/rustup.rs
rustup target add x86_64-pc-windows-gnu

# Based on instructions from https://github.com/AngryLawyer/rust-sdl2/

# First we need sdl2 libs
# links to packages https://www.libsdl.org/download-2.0.php

sudo apt-get install libsdl2-dev -y
wget https://www.libsdl.org/release/SDL2-devel-2.0.4-mingw.tar.gz -P /tmp
tar xf /tmp/SDL2-devel-2.0.4-mingw.tar.gz -C /tmp

# Prepare files for building

mkdir -p ~/projects
cd ~/projects
git clone https://github.com/AngryLawyer/rust-sdl2
cp -r /tmp/SDL2-2.0.4/x86_64-w64-mingw32/lib/* ~/.multirust/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib/
cp /tmp/SDL2-2.0.4/x86_64-w64-mingw32/bin/SDL2.dll ~/rust-sdl2/

# Build examples

# we use loop for...in because there is no such feature in cargo to build all examples at once
for i in examples/*; do cargo build --target=x86_64-pc-windows-gnu --verbose --example $(basename $i .rs); done

运行

cargo build会将二进制文件放入target/x86_64-pc-windows-gnu/debug/examples/

复制所需文件:

cp /tmp/SDL2-2.0.4/x86_64-w64-mingw32/bin/SDL2.dll ~/rust-sdl/target/x86_64-pc-windows-gnu/debug/examples/
cp ~/rust-sdl/tests/sine.wav ~/rust-sdl/target/x86_64-pc-windows-gnu/debug/examples/

然后将目录~/rust-sdl/target/x86_64-pc-windows-gnu/debug/examples/复制到Windows计算机并运行exe文件。

在cmd.exe中运行

如果要在运行exe文件时查看控制台输出,可以从cmd.exe运行它们。

要在文件资源管理器中的当前目录中打开cmd.exe,请右键单击窗口中空白处的shift并选择Open command window here

mingw没有回溯 - 使用msvc

  

与此同时,如果您确实想要回溯并且不介意安装   VC ++你总是可以使用Rust的x86_64-pc-windows-msvc版本。

https://github.com/rust-lang/rust/issues/33985#issuecomment-222826116

答案 3 :(得分:6)

有一个基于Docker的解决方案,称为cross。所有必需的工具都在虚拟环境中,因此您无需为计算机安装其他软件包。参见Supported targets list

从项目的自述文件:

功能

  • cross将提供交叉编译所需的所有要素,而无需涉及系统安装。
  • cross提供了一个环境,跨工具链和跨编译库,这些环境可生成最可移植的二进制文件。
  • “交叉测试”,cross可以为i686和x86_64以外的体系结构测试包装箱。
  • 支持稳定,测试版和夜间频道。

依赖项

  • rustup
  • 交叉测试需要具有binfmt_misc支持的Linux内核。

这些容器引擎之一是必需的。如果两个都安装,则cross将默认为docker。

  • Docker。请注意,在Linux上,非sudo用户需要位于docker组中。阅读官方的安装后步骤。需要版本1.24或更高版本。
  • Podman。需要版本1.6.3或更高版本。

安装

$ cargo install cross

用法

cross具有与Cargo完全相同的CLI,但是由于它依赖于Docker,因此必须先启动守护程序,然后才能使用它。

# (ONCE PER BOOT)
# Start the Docker daemon, if it's not already running
$ sudo systemctl start docker

# MAGIC! This Just Works
$ cross build --target aarch64-unknown-linux-gnu

# EVEN MORE MAGICAL! This also Just Works
$ cross test --target mips64-unknown-linux-gnuabi64

# Obviously, this also Just Works
$ cross rustc --target powerpc-unknown-linux-gnu --release -- -C lto

答案 4 :(得分:2)

对我有用的解决方案是。它类似于接受的答案之一,但我不需要添加工具链。

rustup target add x86_64-pc-windows-gnu
cargo build --target x86_64-pc-windows-gnu

有关详细信息,请参阅 documentation

答案 5 :(得分:0)

official instructions之后,我没有使用Mingw和Wine 就在Debian(测试)上取得了成功。他们看上去很吓人,但最终并没有那么严重。

官方说明中的几点要点:

  1. Debian:<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script> <script src="//code.jquery.com/jquery-1.11.1.min.js"></script> <div class="row"> <div class="col-sm-12 col-md-12 col-lg-12"> <div style="display: inline-block; width: 100%; overflow-y: auto;"> <ul class="timeline timeline-horizontal"> <li class="timeline-item"> <div class="timeline-badge success"> <i class="glyphicon glyphicon-check"></i> </div> <div class="timeline-panel"> <div class="timeline-heading"> <h4 class="timeline-title"> 0</h4> <p> </div> <div class="timeline-body"> <p>---</p> </div> </div> </li> <li class="timeline-item"> <div class="timeline-badge success"> <i class="glyphicon glyphicon-check"></i> </div> <div class="timeline-panel"> <div class="timeline-heading"> <h4 class="timeline-title">1</h4> <p> </div> <div class="timeline-body"> <p>26039 </p> </div> </div> </li> <li class="timeline-item"> <div class="timeline-badge success"> <i class="glyphicon glyphicon-check"></i> </div> <div class="timeline-panel"> <div class="timeline-heading"> <h4 class="timeline-title"> 2</h4> <p> </div> <div class="timeline-body"> <p>26037 </p> </div> </div> </li> <li class="timeline-item"> <div class="timeline-badge success"> <i class="glyphicon glyphicon-check"></i> </div> <div class="timeline-panel"> <div class="timeline-heading"> <h4 class="timeline-title">3</h4> <p> </div> <div class="timeline-body"> <p>26016 </p> </div> </div> </li> <li class="timeline-item"> <div class="timeline-badge warning"> <i class="glyphicon glyphicon-check"></i> </div> <div class="timeline-panel"> <div class="timeline-heading"> <h4 class="timeline-title">4</h4> <p> </div> <div class="timeline-body"> <p>---</p> </div> </div> </li> <li class="timeline-item"> <div class="timeline-badge warning"> <i class="glyphicon glyphicon-check"></i> </div> <div class="timeline-panel"> <div class="timeline-heading"> <h4 class="timeline-title">5</h4> <p> </div> <div class="timeline-body"> <p>---</p> </div> </div> </li> </ul> </div> </div> </div>
  2. 在$ PATH中的某个位置建立一个名为sudo apt-get install lldlld-link的符号链接。示例:lld
  3. 我不需要交叉编译C / C ++,没有经验。
  4. 这可能是最烦人的部分。我通过rustup在Windows盒子上安装了Rust,并将库从官方文档中命名的目录复制到Linux盒子。请注意,有时库文件名有时是大写的,但lld希望它们全部使用小写(Windows不区分大小写,Linux区分大小写)。我使用以下命令将当前目录中的所有文件重命名为小写:
ln -s /usr/bin/lld local_bin/lld-link

我个人需要两个 Kit 目录和一个 VC 目录。

  1. 我不需要交叉编译C / C ++,没有经验。
  2. 只需在本文末尾的脚本中将for f in `find`; do mv -v "$f" "`echo $f | tr '[A-Z]' '[a-z]'`"; done 指向第4点的lib目录即可。
  3. 必填
  4. 我不需要交叉编译C / C ++,没有经验。
  5. 取决于目标体系结构,以下任一项:
    • $LIB_ROOT
    • rustup target add i686-pc-windows-msvc

对于交叉构建本身,我使用以下简单脚本(32位版本):

rustup target add x86_64-pc-windows-msvc

我使用脚本的方式与使用#!/bin/sh # "cargo build" for the 32-bit Windows MSVC architecture. # Set this to proper directory LIB_ROOT=~/opt/rust-msvc # The rest shouldn't need modifications VS_LIBS="$LIB_ROOT/Microsoft Visual Studio 14.0/VC/lib/" KIT_8_1_LIBS="$LIB_ROOT/Windows Kits/8.1/Lib/winv6.3/um/x86/" KIT_10_LIBS="$LIB_ROOT/Windows Kits/10/Lib/10.0.10240.0/ucrt/x86/" export LIB="$VS_LIBS;$KIT_8_1_LIBS;$KIT_10_LIBS" cargo build --target=i686-pc-windows-msvc "$@"

的方式相同

希望对别人有帮助!