Do not pass -jN to make, use cargo jobserver instead
When compiling a crate that has jemallocator-sys as a dependency with cargo build -j4, I see a short spike where the number of cpu cores used is 8 instead of 4. The cause is this crate using the NUM_JOBS env var to call make, which ignores that cargo already has other running jobs, thus bringing the total number of running jobs to be higher than NUM_JOBS. This doesn't happen in any of the other *-sys crates, I guess because they use the cc crate with the parallel feature enabled instead of manually calling make.
The fix is to remove the -jN arg to make if the CARGO_MAKEFLAGS env var exists, and set MAKEFLAGS to CARGO_MAKEFLAGS instead.
I expect the implementation to be similar to this:
https://github.com/rust-lang/cmake-rs/blob/c4a60dd154dd90e469dffc41a1faa717704f90b3/src/lib.rs#L830
I guess using a crate to call make instead of doing it manually would handle this and other issues automatically, but I don't know what's the standard so I can't recommend any crates.
The fix is to remove the -jN arg to make if the CARGO_MAKEFLAGS env var exists, and set MAKEFLAGS to CARGO_MAKEFLAGS instead.
Make sense. Would you like to send a PR?
I tried to run cargo build but it gave me a strange error "configure: error: cannot find sources (Makefile.in)", and I didn't find any documentation on what should I do to fix it, so I will let some other contributor implement it.
Likely the same problem as https://github.com/tikv/jemallocator/issues/32.
@tmpolaczyk Were you able to clone the submodules, do you still want to contribute a PR? 🙂
Hi, I gave up, and in general this doesn't sound like an easy issue so anyone else feel free to take it
No problem, thank you for reporting!
I created a pull request.
Old logic:
- CARGO_MAKEFLAGS is empty -> make -jN
- CARGO_MAKEFLAGS is set -> concatenate or set MAKEFLAGS
New logic:
- CARGO_MAKEFLAGS is set -> concatenate or set MAKEFLAGS
- MAKEFLAGS is set -> use MAKEFLAGS unchanged
- Otherwise -> make -jN
I believe this was fixed by #120.
I saw something like this in conda-forge/staged-recipes#31488:
│ │ running: cd "$SRC_DIR/src/rust/target/x86_64-unknown-linux-gnu/release/build/tikv-jemalloc-sys-cde55cd13423d9e3/out/build" && MAKEFLAGS=" -- OBJECTS=init.o SHLIB=polars.so -j --jobserver-fds=8,9 --jobserver-auth=8,9" "make"
│ │ make[1]: Entering directory '$SRC_DIR/src/rust/target/x86_64-unknown-linux-gnu/release/build/tikv-jemalloc-sys-cde55cd13423d9e3/out/build'
│ │ make[1]: Leaving directory '$SRC_DIR/src/rust/target/x86_64-unknown-linux-gnu/release/build/tikv-jemalloc-sys-cde55cd13423d9e3/out/build'
│ │ --- stderr
│ │ make[1]: *** No rule to make target '-j'. Stop.
│ │ thread 'main' (6599) panicked at $BUILD_PREFIX/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tikv-jemalloc-sys-0.6.1+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7/build.rs:411:9:
│ │ command did not execute successfully: cd "$SRC_DIR/src/rust/target/x86_64-unknown-linux-gnu/release/build/tikv-jemalloc-sys-cde55cd13423d9e3/out/build" && MAKEFLAGS=" -- OBJECTS=init.o SHLIB=polars.so -j --jobserver-fds=8,9 --jobserver-auth=8,9" "make"
It seems like there might be something wrong with the current state.
Hi, could you please clarify what sort of make you are using? Cargo normally passes -j --jobserver-fds= --jobserver-auth=, and it seems to work for GNU Make for me. I also looked online and it seems that it is the expected usage.
Hi, could you please clarify what sort of make you are using?
This was confirmed on conda-forge CI, the logs are here. https://dev.azure.com/conda-forge/feedstock-builds/_build/results?buildId=1392965&view=logs&j=4cabe686-70ae-553a-7fd0-310379f2cbac&t=6a4fc7c9-c31a-5115-eff9-6479d72b69ff
It says:
│ │ │ make ┆ 4.4.1 ┆ hb9d3cd8_2 ┆ conda-forge ┆ 501.06 KiB │
https://dev.azure.com/conda-forge/feedstock-builds/_build/results?buildId=1392965&view=logs&j=4cabe686-70ae-553a-7fd0-310379f2cbac&t=6a4fc7c9-c31a-5115-eff9-6479d72b69ff&l=783
Seems from: https://github.com/conda-forge/make-feedstock
MAKEFLAGS=" -- OBJECTS=init.o SHLIB=polars.so -j --jobserver-fds=8,9 --jobserver-auth=8,9" "make"
The problem may come from --, which requires argument for flags, and -j has no aurgument, so it will be parsed as a target instead of flags.
Hmm, for my make 4.3, it works even with -- for me. Maybe we could reverse the order here and add the Cargo makeflags at the beginning (not the end) of any existing makeflags?
LGTM, in worse case, job sever is overridden by user provided flags, which seems OK.
Ok, https://github.com/tikv/jemallocator/pull/152.