| 
 | 1 | +# Jobserver  | 
 | 2 | + | 
 | 3 | +Internally, `rustc` may take advantage of parallelism. `rustc` will coordinate  | 
 | 4 | +with the build system calling it if a [GNU Make jobserver] is passed in the  | 
 | 5 | +`MAKEFLAGS` environment variable. Other flags may have an effect as well, such  | 
 | 6 | +as [`CARGO_MAKEFLAGS`].  | 
 | 7 | + | 
 | 8 | +Starting with Rust 1.76.0, `rustc` will warn if a jobserver appears to be  | 
 | 9 | +available but is not accessible, e.g.:  | 
 | 10 | + | 
 | 11 | +```console  | 
 | 12 | +$ echo 'fn main() {}' | MAKEFLAGS=--jobserver-auth=3,4 rustc -  | 
 | 13 | +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)  | 
 | 14 | +  |  | 
 | 15 | +  = note: the build environment is likely misconfigured  | 
 | 16 | +```  | 
 | 17 | + | 
 | 18 | +## Integration with build systems  | 
 | 19 | + | 
 | 20 | +The following subsections contain recommendations on how to integrate `rustc`  | 
 | 21 | +with build systems so that the jobserver is handled appropriately.  | 
 | 22 | + | 
 | 23 | +### GNU Make  | 
 | 24 | + | 
 | 25 | +When calling `rustc` from GNU Make, it is recommended that all `rustc`  | 
 | 26 | +invocations are marked as recursive in the `Makefile` (by prefixing the command  | 
 | 27 | +line with the `+` indicator), so that GNU Make enables the jobserver for them.  | 
 | 28 | +For instance:  | 
 | 29 | + | 
 | 30 | +<!-- ignore-tidy-tab -->  | 
 | 31 | + | 
 | 32 | +```make  | 
 | 33 | +x:  | 
 | 34 | +	+@echo 'fn main() {}' | rustc -  | 
 | 35 | +```  | 
 | 36 | + | 
 | 37 | +In particular, GNU Make 4.3 (a widely used version as of 2024) passes a simple  | 
 | 38 | +pipe jobserver in `MAKEFLAGS` even when it was not made available for the child  | 
 | 39 | +process, which in turn means `rustc` will warn about it. For instance, if the  | 
 | 40 | +`+` indicator is removed from the example above and GNU Make is called with e.g.  | 
 | 41 | +`make -j2`, then the aforementioned warning will trigger.  | 
 | 42 | + | 
 | 43 | +For calls to `rustc` inside `$(shell ...)` inside a recursive Make, one can  | 
 | 44 | +disable the jobserver manually by clearing the `MAKEFLAGS` variable, e.g.:  | 
 | 45 | + | 
 | 46 | +```make  | 
 | 47 | +S := $(shell MAKEFLAGS= rustc --print sysroot)  | 
 | 48 | + | 
 | 49 | +x:  | 
 | 50 | +	@$(MAKE) y  | 
 | 51 | + | 
 | 52 | +y:  | 
 | 53 | +	@echo $(S)  | 
 | 54 | +```  | 
 | 55 | + | 
 | 56 | +### CMake  | 
 | 57 | + | 
 | 58 | +CMake 3.28 supports the `JOB_SERVER_AWARE` option in its [`add_custom_target`]  | 
 | 59 | +command, e.g.:  | 
 | 60 | + | 
 | 61 | +```cmake  | 
 | 62 | +cmake_minimum_required(VERSION 3.28)  | 
 | 63 | +project(x)  | 
 | 64 | +add_custom_target(x  | 
 | 65 | +    JOB_SERVER_AWARE TRUE  | 
 | 66 | +    COMMAND echo 'fn main() {}' | rustc -  | 
 | 67 | +)  | 
 | 68 | +```  | 
 | 69 | + | 
 | 70 | +For earlier versions, when using CMake with the Makefile generator, one  | 
 | 71 | +workaround is to have [`$(MAKE)`] somewhere in the command so that GNU Make  | 
 | 72 | +treats it as a recursive Make call, e.g.:  | 
 | 73 | + | 
 | 74 | +```cmake  | 
 | 75 | +cmake_minimum_required(VERSION 3.22)  | 
 | 76 | +project(x)  | 
 | 77 | +add_custom_target(x  | 
 | 78 | +    COMMAND DUMMY_VARIABLE=$(MAKE) echo 'fn main() {}' | rustc -  | 
 | 79 | +)  | 
 | 80 | +```  | 
 | 81 | + | 
 | 82 | +[GNU Make jobserver]: https://www.gnu.org/software/make/manual/html_node/POSIX-Jobserver.html  | 
 | 83 | +[`CARGO_MAKEFLAGS`]: https://doc.rust-lang.org/cargo/reference/environment-variables.html  | 
 | 84 | +[`add_custom_target`]: https://cmake.org/cmake/help/latest/command/add_custom_target.html  | 
 | 85 | +[`$(MAKE)`]: https://www.gnu.org/software/make/manual/html_node/MAKE-Variable.html  | 
0 commit comments