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 在 构建工具
每月 586 次下载
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。
编译器可能会产生对memset
、memcpy
等引用,这些通常由平台的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的依赖,以提供编译器期望的memset
、memcpy
等函数的实现。请注意,您需要添加一个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会交叉编译core
、compiler_builtins
和alloc
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
功能。关闭此标志允许指定自己版本的memcpy
、memset
等函数。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 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
由您选择。
贡献
除非您明确声明,否则根据 Apache-2.0 许可证定义的,您有意提交以包含在作品中的任何贡献,将按上述方式双许可,不附加任何额外的条款或条件。
依赖关系
~3–12MB
~153K SLoC