rust交叉编译环境搭建流程学习随笔

这篇笔记只是我在搜集阅读各种rust交叉编译学习资料时做的一个概括性笔记,不求甚解,目的在于将各种知识点汇总起来,主要是怕自己日后忘了,后来接触相关工作时或是自己时间充裕时,再做一一实验验证,毕竟我不主攻嵌入式编程,只是顺便收集一下知识点罢了。

1. 构建目标平台设定:rust官方设计: –target构建目标平台的设定推荐两种方式:

(1) 命令行方式:

# 编译(release 模式)
cargo build --target <target-triple> --release
# 或运行程序
cargo run --target <target-triple>

2) 通过: .cargo/config.toml配置文件:

#设定构建目标平台
[build]
target = ["x86_64-unknown-linux-gnu""i686-unknown-linux-gnu"]
#------------------------------
#目标平台的一些特殊配置
[target.thumbv7m-none-eabi]
linker = "arm-none-eabi-gcc"
runner = "my-emulator"
rustflags = ["…""…"]
#---
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
runner = "my-arm-wrapper"
rustflags = ["…""…"]
#-------------------------------
#foo是目标平台下的一个库,一下特殊配置用于找到目标库,
#参数含义:库名、搜索路径,环境变量,链接参数等等。
[target.x86_64-unknown-linux-gnu.foo]
rustc-link-lib = ["foo"]
rustc-link-search = ["/path/to/foo"]
rustc-flags = "-L /some/path"
rustc-cfg = ['key="value"']
rustc-env = {key = "value"}
rustc-cdylib-link-arg = ["…"]
metadata_key1 = "value"
metadata_key2 = "value"
# 全局默认目标平台
[default]
target = "x86_64-unknown-linux-gnu"
# 针对特定目标的编译选项
[target.arm-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"  # 指定交叉编译器
rustflags = ["-C""target-cpu=cortex-a53"]  # 优化CPU指令集

Cargo的编译目标平台配置主要在.cargo/config.toml文件中设置。 用于指定默认的编译目标平台、输出目录等参数。项目级别的配置文件(如项目根目录下的Cargo.toml)一般用于管理项目依赖和元数据,结合feature的条件编译设定,而与目标平台相关的编译参数和工具链集等等编译构建配置主要聚焦在.cargo/config.toml,两者分工明确,项目配置和环境配置解耦,隔离平台差异;简化依赖管理,避免大杂烩;易于配置管理和分级,全局和局部配置分级;更好地适配CI/CD, 多目标构建更高效;总之,Cargo.toml定义项目“是什么” , .cargo/config.toml定制如何构建, 避免了有些编程语言的混合配置模式,降低了配置复杂度。

注意:在Cargo.toml中配置–target是不推荐的,或是不可行的。下面是rust cargo 官方文档给出的: .cargo/config.toml文件的各种可配置项目,以供参考:

paths = ["/path/to/override"# path dependency overrides
[alias]     # command aliases
b = "build"
c = "check"
t = "test"
r = "run"
rr = "run --release"
recursive_example = "rr --example recursions"
space_example = ["run""--release""--"""command list""]
[build]
jobs = 1                      # number of parallel jobs, defaults to # of CPUs
rustc = "rustc"               # the rust compiler tool
rustc-wrapper = "…"           # run this wrapper instead of `rustc`
rustc-workspace-wrapper = "…" # run this wrapper instead of `rustc` for workspace members
rustdoc = "rustdoc"           # the doc generator tool
target = "triple"             # build for the target triple (ignored by `cargo install`)
target-dir = "target"         # path of where to place all generated artifacts
rustflags = ["…""…"]        # custom flags to pass to all compiler invocations
rustdocflags = ["…""…"]     # custom flags to pass to rustdoc
incremental = true            # whether or not to enable incremental compilation
dep-info-basedir = "…"        # path for the base directory for targets in depfiles
[credential-alias]
# Provides a way to define aliases for credential providers.
my-alias = ["/usr/bin/cargo-credential-example""--argument""value""--flag"]
[doc]
browser = "chromium"          # browser to use with `cargo doc --open`,
                              # overrides the `BROWSER` environment variable
[env]
# Set ENV_VAR_NAME=value for any process run by Cargo
ENV_VAR_NAME = "value"
# Set even if already present in environment
ENV_VAR_NAME_2 = { value = "value", force = true }
# `value` is relative to the parent of `.cargo/config.toml`, env var will be the full absolute path
ENV_VAR_NAME_3 = { value = "relative/path", relative = true }
[future-incompat-report]
frequency = 'always' # when to display a notification about a future incompat report
[cache]
auto-clean-frequency = "1 day"   # How often to perform automatic cache cleaning
[cargo-new]
vcs = "none"              # VCS to use ('git', 'hg', 'pijul', 'fossil', 'none')
[http]
debug = false               # HTTP debugging
proxy = "host:port"         # HTTP proxy in libcurl format
ssl-version = "tlsv1.3"     # TLS version to use
ssl-version.max = "tlsv1.3" # maximum TLS version
ssl-version.min = "tlsv1.1" # minimum TLS version
timeout = 30                # timeout for each HTTP request, in seconds
low-speed-limit = 10        # network timeout threshold (bytes/sec)
cainfo = "cert.pem"         # path to Certificate Authority (CA) bundle
check-revoke = true         # check for SSL certificate revocation
multiplexing = true         # HTTP/2 multiplexing
user-agent = "…"            # the user-agent header
[install]
root = "/some/path"         # `cargo install` destination directory
[net]
retry = 3                   # network retries
git-fetch-with-cli = true   # use the `git` executable for git operations
offline = true              # do not access the network
[net.ssh]
known-hosts = ["..."]       # known SSH host keys
[patch.<registry>]
# Same keys as for [patch] in Cargo.toml
[profile.<name>]         # Modify profile settings via config.
inherits = "dev"         # Inherits settings from [profile.dev].
opt-level = 0            # Optimization level.
debug = true             # Include debug info.
split-debuginfo = '...'  # Debug info splitting behavior.
strip = "none"           # Removes symbols or debuginfo.
debug-assertions = true  # Enables debug assertions.
overflow-checks = true   # Enables runtime integer overflow checks.
lto = false              # Sets link-time optimization.
panic = 'unwind'         # The panic strategy.
incremental = true       # Incremental compilation.
codegen-units = 16       # Number of code generation units.
rpath = false            # Sets the rpath linking option.
[profile.<name>.build-override]  # Overrides build-script settings.
# Same keys for a normal profile.
[profile.<name>.package.<name>]  # Override profile for a package.
# Same keys for a normal profile (minus `panic`, `lto`, and `rpath`).
[resolver]
incompatible-rust-versions = "allow"  # Specifies how resolver reacts to these
[registries.<name>]  # registries other than crates.io
index = "…"          # URL of the registry index
token = "…"          # authentication token for the registry
credential-provider = "cargo:token" # The credential provider for this registry.
[registries.crates-io]
protocol = "sparse"  # The protocol to use to access crates.io.
[registry]
default = "…"        # name of the default registry
token = "…"          # authentication token for crates.io
credential-provider = "cargo:token"           # The credential provider for crates.io.
global-credential-providers = ["cargo:token"# The credential providers to use by default.
[source.<name>]      # source definition and replacement
replace-with = "…"   # replace this source with the given named source
directory = "…"      # path to a directory source
registry = "…"       # URL to a registry source
local-registry = "…" # path to a local registry source
git = "…"            # URL of a git repository source
branch = "…"         # branch name for the git repository
tag = "…"            # tag name for the git repository
rev = "…"            # revision for the git repository
[target.<triple>]
linker = "…"              # linker to use
runner = "…"              # wrapper to run executables
rustflags = ["…""…"]    # custom flags for `rustc`
rustdocflags = ["…""…"# custom flags for `rustdoc`
[target.<cfg>]
runner = "…"            # wrapper to run executables
rustflags = ["…""…"]  # custom flags for `rustc`
[target.<triple>.<links>] # `links` build script override
rustc-link-lib = ["foo"]
rustc-link-search = ["/path/to/foo"]
rustc-flags = "-L /some/path"
rustc-cfg = ['key="value"']
rustc-env = {key = "value"}
rustc-cdylib-link-arg = ["…"]
metadata_key1 = "value"
metadata_key2 = "value"
[term]
quiet = false                    # whether cargo output is quiet
verbose = false                  # whether cargo provides verbose output
color = 'auto'                   # whether cargo colorizes output
hyperlinks = true                # whether cargo inserts links into output
unicode = true                   # whether cargo can render output using non-ASCII unicode characters
progress.when = 'auto'           # whether cargo shows progress bar
progress.width = 80              # width of progress bar
progress.term-integration = true # whether cargo reports progress to terminal emulator

rust cargo 官方文档:
https://doc.rust-lang.org/cargo/reference/config.html


2. rust cargo交叉编译环境配置工作流

(1)安装目标平台构建工具链(编译器、链接器)

# 在 Ubuntu 中,可通过包管理器安装目标平台的 C/C++ 工具链。
sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf

注意:rust target命名和具体目标平台构建工具链集的名字可能不太一样,他们之间如何对应,还要参考官方或网上的资料。

(2)rustup 安装目标target

#列出rust支持的目标平台列表:
rustup target list
#安装目标平台:
rustup target add arm-unknown-linux-gnueabihf

注意:例如执行 rustup target add
arm-unknown-linux-gnueabihf 时,Rustup 会下载该目标平台对应的标准库、编译辅助文件(如 libcore、libstd 的目标平台版本),但不涉及 C/C++ 编译器、链接器等目标平台系统工具,无法解决目标平台依赖的外部工具链问题。

(3) 在.cargo/config.toml中enable目标平台和相关参数.

# 全局默认enable目标平台
[default]
target="arm-unknown-linux-gnueabihf"


#或者通过以下形式enable构建目标平台
[build]
target = ["x86_64-unknown-linux-gnu""arm-unknown-linux-gnueabihf"]




# 针对特定目标的编译选项
[target.arm-unknown-linux-gnueabihf]
linker="arm-linux-gnueabihf-gcc"# 指定交叉编译器
rustflags=["-C","target-cpu=cortex-a53"]# 优化CPU指令集

或者命令行指定rust target以及目标平台的c/c++工具集:



RUSTFLAGS="-C linker=arm-linux-gnueabihf-gcc" cargo build --target arm-unknown-linux-gnueabihf

(4) 项目级配置:在 Cargo.toml 中通过 [target.triple] 块设置特定平台的依赖或编译选项,包括代码中的条件编译配置

[package]
name = "my_project"
version = "0.1.0"
edition = "2021"
# 针对特定目标平台的配置
[target.x86_64-pc-windows-gnu]
# 可在此添加该平台特有的依赖或编译选项
dependencies = { winapi = "0.3" }
[target.arm-unknown-linux-gnueabihf]
# 树莓派平台配置
rustflags = ["-C""link-arg=-s"]  # 可选优化参数

(5) 执行构建命令

cargo  build --release


3. .cargo/config.toml优先级

Cargo 支持针对特定包的本地配置以及全局配置。它会从当前目录开始,逐级向上查找所有父目录中的配置文件。例如,如果在 /projects/foo/bar/baz 目录下运行 Cargo,系统会按以下顺序探测并合并配置文件:

  1. /projects/foo/bar/baz/.cargo/config.toml
  2. /projects/foo/bar/.cargo/config.toml
  3. /projects/foo/.cargo/config.toml
  4. /projects/.cargo/config.toml
  5. /.cargo/config.toml
  6. $CARGO_HOME/config.toml
  7. (默认路径为:
  8. Windows: %USERPROFILE%.cargoconfig.toml
  9. Unix: $HOME/.cargo/config.toml)

注意:关于workspace中配置上的差异,请参考cargo官方文档。文档链接:

https://doc.rust-lang.org/cargo/reference/config.html

【配置优先级概略总结】

命令行参数 > 项目本地子目录配置 > 项目根目录配置 > 用户全局配置(家目录)。


后记: 个人学习笔记,仓促行文,加之水平有限,难免谬误,还请海涵,不吝指教,粗鄙之文权当备忘和抛砖引玉。

【代码仓库】
https://gitee.com/yujinliang-pure/rust-learn

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容