cc-rs icon indicating copy to clipboard operation
cc-rs copied to clipboard

Parallel cc-rs builds break parallel cmake-rs builds trying to share the same jobserver in the same build script

Open Notgnoshi opened this issue 1 year ago • 1 comments

When you have a build script that uses both cc-rs and cmake-rs (as is the case when writing bindings with https://github.com/dtolnay/cxx), the jobserver isn't shared between the two correctly.

fn main() {
    cc::Build::new()
        .cpp(true)
        .file("foo.cc")
        .compile("libfoo");

    let install_dir = cmake::Config::new("./spdlog/")
        .cxxflag("-w")
        .build();
}

I filed https://github.com/rust-lang/cmake-rs/issues/172 but am not sure where the bug actually is.

See https://github.com/Notgnoshi/cmake-jobserver-bug for a small example project that reproduces this behavior. The linked issue also has lots more details.

The TL;DR is that after the cc-rs build finishes, the cmake-rs build can't use the jobserver:

$ export MAKEFLAGS=-j16
$ cargo build -vv
...
[cmake-jobserver-bug 0.1.0] -- Build files have been written to: /home/nots/workspace/cmake-jobserver-bug/target/debug/build/cmake-jobserver-bug-b047a90afcff9857/out/build
[cmake-jobserver-bug 0.1.0] running: "cmake" "--build" "." "--target" "install" "--config" "Debug"
[cmake-jobserver-bug 0.1.0] gmake: warning: jobserver unavailable: using -j1.  Add '+' to parent make rule.
...

Using binary search, I was able to tell that the issue was introduced in the 1.0.42 release, which was the one that first introduced jobserver support: https://github.com/rust-lang/cc-rs/commit/4fda8db89e666f402392366501505a4fbd14b23f

A workaround is to pin cmake-rs to 0.1.48, which doesn't use the jobserver, and instead just invokes cmake with --parallel 16

Notgnoshi avatar Dec 01 '22 15:12 Notgnoshi