Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/manual/rl-next/build-cores-auto-detect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
synopsis: "`build-cores = 0` now auto-detects CPU cores"
prs: [13402]
---

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.
2 changes: 1 addition & 1 deletion src/libstore/globals.cc
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ std::vector<Path> getUserConfigFiles()
return files;
}

unsigned int Settings::getDefaultCores()
unsigned int Settings::getDefaultCores() const
{
const unsigned int concurrency = std::max(1U, std::thread::hardware_concurrency());
const unsigned int maxCPU = getMaxCPU();
Expand Down
12 changes: 5 additions & 7 deletions src/libstore/include/nix/store/globals.hh
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ const uint32_t maxIdsPerBuild =

class Settings : public Config {

unsigned int getDefaultCores();

StringSet getDefaultSystemFeatures();

StringSet getDefaultExtraPlatforms();
Expand All @@ -57,6 +55,8 @@ public:

Settings();

unsigned int getDefaultCores() const;

Path nixPrefix;

/**
Expand Down Expand Up @@ -153,7 +153,7 @@ public:

Setting<unsigned int> buildCores{
this,
getDefaultCores(),
0,
"cores",
R"(
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.
Expand All @@ -166,15 +166,13 @@ public:
-->
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.

The value `0` means that the `builder` should use all available CPU cores in the system.
If set to `0`, nix will detect the number of CPU cores and pass this number via NIX_BUILD_CORES.

> **Note**
>
> The number of parallel local Nix build jobs is independently controlled with the [`max-jobs`](#conf-max-jobs) setting.
)",
{"build-cores"},
// Don't document the machine-specific default value
false};
{"build-cores"}};

/**
* Read-only mode. Don't copy stuff to the store, don't change
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/unix/build/derivation-builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1083,7 +1083,7 @@ void DerivationBuilderImpl::initEnv()
env["NIX_STORE"] = store.storeDir;

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

/* In non-structured mode, set all bindings either directory in the
environment or via a file, as specified by
Expand Down
2 changes: 1 addition & 1 deletion src/nix-build/nix-build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ static void main_nix_build(int argc, char * * argv)

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

auto parsedDrv = StructuredAttrs::tryParse(drv.env);
DerivationOptions drvOptions;
Expand Down
11 changes: 11 additions & 0 deletions tests/functional/build-cores.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
with import ./config.nix;

{
# Test derivation that checks the NIX_BUILD_CORES environment variable
testCores = mkDerivation {
name = "test-build-cores";
buildCommand = ''
echo "$NIX_BUILD_CORES" > $out
'';
};
}
32 changes: 32 additions & 0 deletions tests/functional/build-cores.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash

source common.sh

clearStoreIfPossible

echo "Testing build-cores configuration behavior..."

# Test 1: When build-cores is set to a non-zero value, NIX_BUILD_CORES should have that value
echo "Testing build-cores=4..."
rm -f "$TEST_ROOT"/build-cores-output
nix-build --cores 4 build-cores.nix -A testCores -o "$TEST_ROOT"/build-cores-output
result=$(cat "$(readlink "$TEST_ROOT"/build-cores-output)")
if [[ "$result" != "4" ]]; then
echo "FAIL: Expected NIX_BUILD_CORES=4, got $result"
exit 1
fi
echo "PASS: build-cores=4 correctly sets NIX_BUILD_CORES=4"
rm -f "$TEST_ROOT"/build-cores-output

# Test 2: When build-cores is set to 0, NIX_BUILD_CORES should be resolved to getDefaultCores()
echo "Testing build-cores=0..."
nix-build --cores 0 build-cores.nix -A testCores -o "$TEST_ROOT"/build-cores-output
result=$(cat "$(readlink "$TEST_ROOT"/build-cores-output)")
if [[ "$result" == "0" ]]; then
echo "FAIL: NIX_BUILD_CORES should not be 0 when build-cores=0"
exit 1
fi
echo "PASS: build-cores=0 resolves to NIX_BUILD_CORES=$result (should be > 0)"
rm -f "$TEST_ROOT"/build-cores-output

echo "All build-cores tests passed!"
1 change: 1 addition & 0 deletions tests/functional/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ suites = [
'placeholders.sh',
'ssh-relay.sh',
'build.sh',
'build-cores.sh',
'build-delete.sh',
'output-normalization.sh',
'selfref-gc.sh',
Expand Down
Loading