Skip to content

Commit 67bdece

Browse files
committed
build-cores: detect cores automatically if set to 0
This changes makes nix detect a machines available cores automatically whenever build-cores is set to 0. So far, nix simply passed NIX_BUILD_CORES=0 whenever build-cores is set to 0. (only when build-cores is unset it was detecting cores automatically) The behavior of passing NIX_BUILD_CORES=0 leads to a performance penalty when sourcing nixpkgs' generic builder's `setup.sh`, as setup.sh has to execute `nproc`. This significantly slows down sourcing of setup.sh
1 parent df2d5f2 commit 67bdece

File tree

8 files changed

+57
-10
lines changed

8 files changed

+57
-10
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
synopsis: "`build-cores = 0` now auto-detects CPU cores"
3+
---
4+
5+
When `build-cores` is set to `0`, nix now automatically detects the number of available CPU cores and passes this value via `NIX_BUILD_CORES`, instead of passing `0` directly. This matches the behavior when `build-cores` is unset. This prevents the builder from having to detect the number of cores.

src/libstore/globals.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ std::vector<Path> getUserConfigFiles()
140140
return files;
141141
}
142142

143-
unsigned int Settings::getDefaultCores()
143+
unsigned int Settings::getDefaultCores() const
144144
{
145145
const unsigned int concurrency = std::max(1U, std::thread::hardware_concurrency());
146146
const unsigned int maxCPU = getMaxCPU();

src/libstore/include/nix/store/globals.hh

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ const uint32_t maxIdsPerBuild =
4343

4444
class Settings : public Config {
4545

46-
unsigned int getDefaultCores();
47-
4846
StringSet getDefaultSystemFeatures();
4947

5048
StringSet getDefaultExtraPlatforms();
@@ -57,6 +55,8 @@ public:
5755

5856
Settings();
5957

58+
unsigned int getDefaultCores() const;
59+
6060
Path nixPrefix;
6161

6262
/**
@@ -153,7 +153,7 @@ public:
153153

154154
Setting<unsigned int> buildCores{
155155
this,
156-
getDefaultCores(),
156+
0,
157157
"cores",
158158
R"(
159159
Sets the value of the `NIX_BUILD_CORES` environment variable in the [invocation of the `builder` executable](@docroot@/language/derivations.md#builder-execution) of a derivation.
@@ -166,15 +166,13 @@ public:
166166
-->
167167
For instance, in Nixpkgs, if the attribute `enableParallelBuilding` for the `mkDerivation` build helper is set to `true`, it passes the `-j${NIX_BUILD_CORES}` flag to GNU Make.
168168
169-
The value `0` means that the `builder` should use all available CPU cores in the system.
169+
If set to `0`, nix will detect the number of CPU cores and pass this number via NIX_BUILD_CORES.
170170
171171
> **Note**
172172
>
173173
> The number of parallel local Nix build jobs is independently controlled with the [`max-jobs`](#conf-max-jobs) setting.
174174
)",
175-
{"build-cores"},
176-
// Don't document the machine-specific default value
177-
false};
175+
{"build-cores"}};
178176

179177
/**
180178
* Read-only mode. Don't copy stuff to the store, don't change

src/libstore/unix/build/derivation-builder.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1083,7 +1083,7 @@ void DerivationBuilderImpl::initEnv()
10831083
env["NIX_STORE"] = store.storeDir;
10841084

10851085
/* The maximum number of cores to utilize for parallel building. */
1086-
env["NIX_BUILD_CORES"] = fmt("%d", settings.buildCores);
1086+
env["NIX_BUILD_CORES"] = fmt("%d", settings.buildCores ? settings.buildCores : settings.getDefaultCores());
10871087

10881088
/* In non-structured mode, set all bindings either directory in the
10891089
environment or via a file, as specified by

src/nix-build/nix-build.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ static void main_nix_build(int argc, char * * argv)
542542

543543
env["NIX_BUILD_TOP"] = env["TMPDIR"] = env["TEMPDIR"] = env["TMP"] = env["TEMP"] = tmpDir.path().string();
544544
env["NIX_STORE"] = store->storeDir;
545-
env["NIX_BUILD_CORES"] = std::to_string(settings.buildCores);
545+
env["NIX_BUILD_CORES"] = fmt("%d", settings.buildCores ? settings.buildCores : settings.getDefaultCores());
546546

547547
auto parsedDrv = StructuredAttrs::tryParse(drv.env);
548548
DerivationOptions drvOptions;

tests/functional/build-cores.nix

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
with import ./config.nix;
2+
3+
{
4+
# Test derivation that checks the NIX_BUILD_CORES environment variable
5+
testCores = mkDerivation {
6+
name = "test-build-cores";
7+
buildCommand = ''
8+
echo "$NIX_BUILD_CORES" > $out
9+
'';
10+
};
11+
}

tests/functional/build-cores.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env bash
2+
3+
source common.sh
4+
5+
clearStoreIfPossible
6+
7+
echo "Testing build-cores configuration behavior..."
8+
9+
# Test 1: When build-cores is set to a non-zero value, NIX_BUILD_CORES should have that value
10+
echo "Testing build-cores=4..."
11+
rm -f "$TEST_ROOT"/build-cores-output
12+
nix-build --cores 4 build-cores.nix -A testCores -o "$TEST_ROOT"/build-cores-output
13+
result=$(cat "$(readlink "$TEST_ROOT"/build-cores-output)")
14+
if [[ "$result" != "4" ]]; then
15+
echo "FAIL: Expected NIX_BUILD_CORES=4, got $result"
16+
exit 1
17+
fi
18+
echo "PASS: build-cores=4 correctly sets NIX_BUILD_CORES=4"
19+
rm -f "$TEST_ROOT"/build-cores-output
20+
21+
# Test 2: When build-cores is set to 0, NIX_BUILD_CORES should be resolved to getDefaultCores()
22+
echo "Testing build-cores=0..."
23+
nix-build --cores 0 build-cores.nix -A testCores -o "$TEST_ROOT"/build-cores-output
24+
result=$(cat "$(readlink "$TEST_ROOT"/build-cores-output)")
25+
if [[ "$result" == "0" ]]; then
26+
echo "FAIL: NIX_BUILD_CORES should not be 0 when build-cores=0"
27+
exit 1
28+
fi
29+
echo "PASS: build-cores=0 resolves to NIX_BUILD_CORES=$result (should be > 0)"
30+
rm -f "$TEST_ROOT"/build-cores-output
31+
32+
echo "All build-cores tests passed!"

tests/functional/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ suites = [
145145
'placeholders.sh',
146146
'ssh-relay.sh',
147147
'build.sh',
148+
'build-cores.sh',
148149
'build-delete.sh',
149150
'output-normalization.sh',
150151
'selfref-gc.sh',

0 commit comments

Comments
 (0)