Jobserver

在内部,rustc 可能会利用并行性。如果通过 MAKEFLAGS 环境变量传递了 GNU Make jobserverrustc 将与其调用的构建系统进行协调。其他标志也可能产生影响,例如 CARGO_MAKEFLAGS。如果没有传递 jobserver,那么 rustc 将自行选择要使用的作业数量。

从 Rust 1.76.0 开始,如果 jobserver 看起来可用但无法访问,例如,rustc 会发出警告。

$ echo 'fn main() {}' | MAKEFLAGS=--jobserver-auth=3,4 rustc -
warning: failed to connect to jobserver from environment variable `MAKEFLAGS="--jobserver-auth=3,4"`: cannot open file descriptor 3 from the jobserver environment variable value: Bad file descriptor (os error 9)
  |
  = note: the build environment is likely misconfigured

与构建系统的集成

以下小节包含关于如何将 rustc 与构建系统集成以便 jobserver 得到妥善处理的建议。

GNU Make

当从 GNU Make 调用 rustc 时,建议在 Makefile 中将所有 rustc 调用标记为递归的 (通过在命令行前加上 + 指示符),以便 GNU Make 为它们启用 jobserver。例如

x:
	+@echo 'fn main() {}' | rustc -

特别是,GNU Make 4.3(截至 2024 年广泛使用的版本)即使子进程没有使其可用,也会在 MAKEFLAGS 中传递一个简单的管道 jobserver,这反过来意味着 rustc 会对此发出警告。例如,如果从上面的示例中移除 + 指示符,并使用例如 make -j2 调用 GNU Make,那么前面提到的警告就会触发。

对于在递归 Make 中位于 $(shell ...) 内部对 rustc 的调用,可以通过清除 MAKEFLAGS 变量来手动禁用 jobserver,例如:

S := $(shell MAKEFLAGS= rustc --print sysroot)

x:
	@$(MAKE) y

y:
	@echo $(S)

CMake

CMake 3.28 在其 add_custom_target 命令中支持 JOB_SERVER_AWARE 选项,例如:

cmake_minimum_required(VERSION 3.28)
project(x)
add_custom_target(x
    JOB_SERVER_AWARE TRUE
    COMMAND echo 'fn main() {}' | rustc -
)

对于更早的版本,当使用 Makefile 生成器与 CMake 一起使用时,一个变通方法是在命令中包含 $(MAKE),以便 GNU Make 将其视为递归的 Make 调用,例如:

cmake_minimum_required(VERSION 3.22)
project(x)
add_custom_target(x
    COMMAND DUMMY_VARIABLE=$(MAKE) echo 'fn main() {}' | rustc -
)