查看原文:Build Script Support
有些包需要编译第三方的非Rust代码,比如说C库。其他包需要链接到C库,这些C库可能位于系统磁盘上,也有可能需要从源代码中构建。其他人仍然需要一些功能,比如在构建之前的代码生成(考虑解释器生成器)(没明白是什么意思)。
Cargo并不是为了取代这些针对这些任务进行了良好优化的其他工具,但是它确实与构建配置选项集成在一起了:
一、如何使用构建脚本
在Cargo.toml文件中
[package] # ... build = "build.rs"
构建命令(相对于包的根)指定的Rust文件,将在其他任何在包中东西被编译之前被编译和调用,这能允许你的Rust代码依赖于构建或生成的组件。
注意:如果你没有为构建命令指定值,但是你的包根目录下确实存在一个"build.rs"文件,Cargo将会为你编译并调用这个文件。
构建命令的一些用例如下:
- 构建一个绑定的C库
- 在主机系统上查找一个C库
- 从规范中生成一个Rust模块
- 执行Crate需要的任何针对特定平台的配置
下面详细介绍每个用例,以给出构建命令如何工作的示例。
一、构建脚本的输入
当构建脚本运行时,构建脚本有大量的输入,所有的输入都以环境变量的形式传递。而除了环境变量之外,构建脚本的当前目录是构建脚本包的源目录。
二、构建脚本的输出
通过构建脚本输出到stdout的所有行,都会被写到文件中如:target/debug/build/<pkg>/stdout(具体位置可能取决于你的配置)。任何以 "cargo:" 开头的行都会被Cargo直接解释。这一行必须是这种格式:
cargo:key=value
如下所示:
# specially recognized by Cargo cargo:rustc-link-lib=static=foo cargo:rustc-link-search=native=/path/to/foo cargo:rustc-cfg=foo cargo:rustc-env=FOO=bar # arbitrary user-defined metadata cargo:root=/path/to/foo cargo:libdir=/path/to/foo/lib cargo:include=/path/to/foo/include
另外,打印到stderr的行会被写入到一个文件:target/debug/build/<pkg>/stderr,但是不会被Cargo解释。
Cargo会识别一些特殊的关键字,会一定程度上影响crate的构建方式:
- rustc-link-lib=[KIND=]NAME 表示指定的值是一个库名,应该将其作为 -l 标识传递给编译器。可选的KIND可以是static,dylib(默认),或者framework(只适用于苹果系统),可以通过rustc --help查看更多细节。
- rustc-link-search=[KIND=]PATH 表示指定的值是一个库的搜索路径,应该将其作为 -L 标识传递给编译器。可选的KIND可以是dependency,crate,native,framework或者是all(默认),查看rustc --help获取更多细节。
- rustc-flags=FLAGS 是传递给编译器的一组标识,只有 -l 和 -L 标识被支持。
- rustc-cfg=FEATURE 表示指定的特性将会被以一个 --cfg 标识传递给编译器。这通常用于进行各种特性的编译时检测。
- rust-env=VAR=VALUE 表示指定的环境变量将被添加到编译器在其中运行的环境中。然后在编译的crate中,可以通过 env! 宏检索这个环境变量。这对于在crate的代码中嵌入额外的元数据非常有用,比如Git HEAD的hash或者持续集成服务器的唯一标识符。
- rerun-if-changed=PATH 是一个文件或目录的路径,该路径指示构建脚本在更改时应该重新运行(通过文件的最近修改时间戳检测)。通常情况下,如果在crate的根目录下的任何文件发生变化,那么构建脚本就会重新运行,但是这可以用于将更改范围更改为一小部分文件。(如果该路径指向一个目录,那么整个目录将不会被遍历更改--而只更改目录本身的时间戳(对应于目录中的某些类型的更改,这取决于平台),这将触发重新构建。如果要请求对整个目录中的任何更改都进行重新构建,请递归的为该目录打印一行,并且为其内部的所有内容打印另一行)。注意,如果构建脚本本身(或它的一个依赖项)发生了更改,那么它将被无条件的重新构建和重新运行,因此:cargo:rerun-if-changed=build.rs几乎总是冗余的(除非你想忽略除build.rs之外所有其他文件的更改)。
- rurun-if-env-changed=VAR 是一个环境变量的名称,它表示如果环境变量的值发生变换,应该重新运行构建脚本。这基本上工作方式与 rerun-if-changed 相同,只不过它与环境变量一起工作。注意,这里的环境变量是为诸如CC之类的全局环境变量而设计的,因此对于env
时间: 2024-10-13 20:02:20