#cargo-build #交叉编译 #交叉 #编译 #操作系统开发 #cargo-toml #std

构建 cargo-xbuild

自动交叉编译 sysroot 库 crate core、compiler_builtins 和 alloc

50 个版本

0.6.6 2022 年 6 月 21 日
0.6.5 2021 年 1 月 25 日
0.6.4 2020 年 12 月 28 日
0.6.3 2020 年 10 月 21 日
0.4.8 2018 年 7 月 3 日

#131构建工具

Download history 338/week @ 2024-03-11 248/week @ 2024-03-18 282/week @ 2024-03-25 215/week @ 2024-04-01 151/week @ 2024-04-08 117/week @ 2024-04-15 219/week @ 2024-04-22 244/week @ 2024-04-29 263/week @ 2024-05-06 258/week @ 2024-05-13 277/week @ 2024-05-20 114/week @ 2024-05-27 192/week @ 2024-06-03 84/week @ 2024-06-10 231/week @ 2024-06-17 74/week @ 2024-06-24

每月 586 次下载

MIT/Apache

67KB
1.5K SLoC

cargo-xbuild

Cargo-xbuild 是 cargo build 的包装器,用于为自定义目标交叉编译 sysroot 库 crate core、compiler_builtins 和 alloc。它是 xargo 的简化分支,目前处于维护模式。

替代方案:cargo 的 build-std 功能

Cargo 现在有自己的功能用于交叉编译 sysroot:[build-std](https://doc.rust-lang.net.cn/nightly/cargo/reference/unstable.html#build-std)。您可以通过将 `--build-std=core,alloc` 传递给 cargo build 来使用它。或者,您可以在 .cargo/config.toml 文件中指定以下内容:

[unstable]
build-std = ["core", "compiler_builtins", "alloc"]

上述配置需要至少 Rust nightly 2020–07–15。配置完成后,正常的 cargo build 命令现在将自动交叉编译指定的 sysroot 库 crate。

编译器可能会产生对memsetmemcpy等引用,这些通常由平台的libc提供,但幸运的是compiler_builtins有一个mem特性,可以提供这些函数的实现。为了启用这个特性,我们可以使用不稳定的cargo标志-Z build-std-features=compiler-builtins-mem,或者在config.toml中指定以下内容。

[unstable]
build-std = ["core", "compiler_builtins", "alloc"]
+build-std-features = ["compiler-builtins-mem"]

请注意,使用compiler-builtins-mem需要至少Rust nightly 2020-09-30版本。对于较旧版本,您需要添加对rlibc crate的依赖,以提供编译器期望的memsetmemcpy等函数的实现。请注意,您需要添加一个extern crate rlibc语句,以便使其正常工作(即使在2018版Rust中)。这是为了使cargo链接上否则未使用的crate所必需的。

cargo-xbuild相比,使用cargo自身特性的优点很多。

  • 可以使用正常的cargo {check, build, run, test}命令
  • 无需安装外部工具
  • 由于总是与rustc/cargo保持更新,因此错误更少且损坏更少
  • 由于编译器可以并行构建sysroot和项目crate,因此编译速度更快
  • 它可能有一天会稳定

因此,强烈建议尝试cargo的build-std特性,而不是使用这个crate。

依赖关系

  • 可以使用rustup component add rust-src安装的rust-src组件。

  • Rust和Cargo。

cargo-xbuild的安装

如果您出于某种原因决定使用cargo-xbuild而不是cargo的build-std特性,可以通过以下方式安装此crate。

$ cargo install cargo-xbuild

注意:最新版本的cargo-xbuild支持2020-07-30之后的所有nightly版本。如果您使用的是较旧的nightly版本,则需要安装版本0.5.35:cargo install cargo-xbuild --version 0.5.35

用法

在为自定义目标进行交叉编译时,只需使用cargo xbuild代替cargo build

cargo xbuild --target your-target-name.json

与使用纯cargo build时可能出现的“找不到crate for core”错误不同,此crate会交叉编译corecompiler_builtinsalloc crate,然后使用修改后的sysroot调用cargo build。sysroot是在crate的target目录中编译的。

所有额外的参数(例如 --release--verbose)都会转发给 cargo build

配置

要配置 cargo-xbuild,请在您的 Cargo.toml 中创建一个 package.metadata.cargo-xbuild 表。以下是一些可用的选项

[package.metadata.cargo-xbuild]
memcpy = true
sysroot_path = "target/sysroot"
panic_immediate_abort = false
  • memcpy 标志定义了是否激活 compiler_builtins crate 的 mem 功能。关闭此标志允许指定自己版本的 memcpymemset 等函数。
  • sysroot_path 标志指定了 sysroot 应放置的目录。
  • panic_immediate_abort 标志指定了是否在 core crate 中定义 panic_immediate_abort 功能。

环境变量

除了上述配置键外,cargo-xbuild 还可以通过以下环境变量进行配置

  • XBUILD_SYSROOT_PATH 变量可以用来指定 cargo-xbuild 应将生成的 sysroot 放置的位置。此变量优先于 package.metadata.cargo-xbuild.sysroot_path 配置键。
  • 当设置 XBUILD_KEEP_TEMP 变量时,用于编译 sysroot 的临时目录不会被删除。这对于调试很有用。为了方便,当设置环境变量时,cargo-xbuild 也会打印目录名。

开发频道

如果您想使用本地的 Rust 源代码而不是 rust-src rustup 组件,您可以设置 XARGO_RUST_SRC 环境变量。

# The source of the `core` crate must be in `$XARGO_RUST_SRC/core`
$ export XARGO_RUST_SRC=/path/to/rust/src

$ cargo xbuild --target msp430-none-elf.json

在 Android 上使用

可以在您的 Android 手机上运行 cargo-xbuild

安装 Termux 和 Nightly Rustc

  • 安装 Termux
  • 安装 fish shell 并将其设置为默认(可选):pkg install fish; chsh -s fish; fish
  • 安装一些基本工具:pkg install wget tar
  • 添加 by its-pointless 的社区仓库:wget https://its-pointless.github.io/setup-pointless-repo.sh; bash setup-pointless-repo.sh
  • 安装 rust nightly:pkg install rustc cargo rustc-nightly
  • 将 nightly rustc 路径添加到您的 $PATH 中,以便使用 nightly(fish 语法):set -U fish_user_paths $PREFIX/opt/rust-nightly/bin/ $fish_user_paths
  • 执行 rustc --version 应返回 nightly 版本

(可选)安装 Git 并克隆您的仓库

  • 安装 git:pkg install git
  • 克隆您选择的仓库:git clone https://github.com/phil-opp/blog_os.git

安装 Xbuild

  • 安装 cargo-xbuild: cargo install cargo-xbuild
  • 将 cargo 的 bin 目录添加到您的 $PATH (fish 语法): set -U fish_user_paths ~/.cargo/bin/ $fish_user_paths
  • 现在 cargo xbuild 应该可用。

目前它还不能正常工作,因为它需要访问 Rust 源代码。默认情况下,它会尝试使用 rustup 来完成此操作,但因为我们没有 rustup 支持,所以我们需要另一种方法。

提供 Rust 源代码

与我们安装的 nightly 版本相对应的 Rust 源代码位于 its-pointless 仓库中

  • 下载它: wget https://github.com/its-pointless/its-pointless.github.io/raw/master/rust-src-nightly.tar.xz
  • 解压它: tar xf rust-src-nightly.tar.xz
  • 设置 XARGO_RUST_SRC 环境变量来告诉 cargo-xbuild 源路径 (fish 语法): set -Ux XARGO_RUST_SRC ~/rust-src-nightly/rust-src/lib/rustlib/src/rust/src

现在 cargo-xbuild 应该不再会抱怨缺少 rust-src 组件。然而,在构建 sysroot 后,它将抛出一个 I/O 错误。问题在于下载的 Rust 源代码的结构与 rustup 提供的源代码不同。我们可以通过添加符号链接来修复这个问题

ln -s ~/../usr/opt/rust-nightly/bin ~/../usr/opt/rust-nightly/lib/rustlib/aarch64-linux-android/bin

现在 cargo xbuild --target your-target.json 应该可以工作了!

许可证

根据您的要求,许可协议为以下之一

由您选择。

贡献

除非您明确声明,否则根据 Apache-2.0 许可证定义的,您有意提交以包含在作品中的任何贡献,将按上述方式双许可,不附加任何额外的条款或条件。

依赖关系

~3–12MB
~153K SLoC