From a20a7fa1eae3d65cbf3e1fca866028bedf6e17e0 Mon Sep 17 00:00:00 2001 From: Cole Helbling Date: Tue, 17 Jun 2025 12:59:48 -0700 Subject: [PATCH] Allow specifying args to external builder program --- src/libstore/globals.cc | 2 +- src/libstore/include/nix/store/globals.hh | 63 +++++++++++++++++++ .../unix/build/external-derivation-builder.cc | 10 ++- 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index 89f2ee7d0..997d72b99 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -309,7 +309,7 @@ unsigned int MaxBuildJobsSetting::parse(const std::string & str) const } } -NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Settings::ExternalBuilder, systems, program); +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Settings::ExternalBuilder, systems, program, args); template<> Settings::ExternalBuilders BaseSetting::parse(const std::string & str) const { diff --git a/src/libstore/include/nix/store/globals.hh b/src/libstore/include/nix/store/globals.hh index 7f3c9f388..2976ee57a 100644 --- a/src/libstore/include/nix/store/globals.hh +++ b/src/libstore/include/nix/store/globals.hh @@ -1241,6 +1241,7 @@ public: { std::vector systems; Path program; + std::optional> args; }; using ExternalBuilders = std::vector; @@ -1251,6 +1252,68 @@ public: "external-builders", R"( Helper programs that execute derivations. + + The program is passed a JSON document that describes the build environment as the final argument. + The JSON document looks like this: + + { + "args": [ + "-e", + "/nix/store/vj1c3wf9c11a0qs6p3ymfvrnsdgsdcbq-source-stdenv.sh", + "/nix/store/shkw4qm9qcw5sc5n1k5jznc83ny02r39-default-builder.sh" + ], + "builder": "/nix/store/s1qkj0ph0ma64a6743mvkwnabrbw1hsc-bash-5.2p37/bin/bash", + "env": { + "HOME": "/homeless-shelter", + "NIX_BUILD_CORES": "14", + "NIX_BUILD_TOP": "/build", + "NIX_LOG_FD": "2", + "NIX_STORE": "/nix/store", + "PATH": "/path-not-set", + "PWD": "/build", + "TEMP": "/build", + "TEMPDIR": "/build", + "TERM": "xterm-256color", + "TMP": "/build", + "TMPDIR": "/build", + "__structuredAttrs": "", + "buildInputs": "", + "builder": "/nix/store/s1qkj0ph0ma64a6743mvkwnabrbw1hsc-bash-5.2p37/bin/bash", + "cmakeFlags": "", + "configureFlags": "", + "depsBuildBuild": "", + "depsBuildBuildPropagated": "", + "depsBuildTarget": "", + "depsBuildTargetPropagated": "", + "depsHostHost": "", + "depsHostHostPropagated": "", + "depsTargetTarget": "", + "depsTargetTargetPropagated": "", + "doCheck": "1", + "doInstallCheck": "1", + "mesonFlags": "", + "name": "hello-2.12.2", + "nativeBuildInputs": "/nix/store/l31j72f1h33hsa4nq4iyhsmsqjyndq9f-version-check-hook", + "out": "/nix/store/2yx2prgxmzbkrnbb4liy6n4zkzb1cqai-hello-2.12.2", + "outputs": "out", + "patches": "", + "pname": "hello", + "postInstallCheck": "stat \"${!outputBin}/bin/hello\"\n", + "propagatedBuildInputs": "", + "propagatedNativeBuildInputs": "", + "src": "/nix/store/dw402azxjrgrzrk6j0p66wkqrab5mwgw-hello-2.12.2.tar.gz", + "stdenv": "/nix/store/i8bw5nqg1225m281zr6lgsz42bw04z7g-stdenv-linux", + "strictDeps": "", + "system": "aarch64-linux", + "version": "2.12.2" + }, + "realStoreDir": "/nix/store", + "storeDir": "/nix/store", + "system": "aarch64-linux", + "tmpDir": "/private/tmp/nix-build-hello-2.12.2.drv-0/build", + "tmpDirInSandbox": "/build", + "topTmpDir": "/private/tmp/nix-build-hello-2.12.2.drv-0" + } )" }; }; diff --git a/src/libstore/unix/build/external-derivation-builder.cc b/src/libstore/unix/build/external-derivation-builder.cc index 8efdf8ff9..0757ed51f 100644 --- a/src/libstore/unix/build/external-derivation-builder.cc +++ b/src/libstore/unix/build/external-derivation-builder.cc @@ -83,6 +83,7 @@ struct ExternalDerivationBuilder : DerivationBuilderImpl json.emplace("realStoreDir", getLocalStore(store).config->realStoreDir.get()); json.emplace("system", drv.platform); + // FIXME: maybe write this JSON into the builder's stdin instead....? auto jsonFile = topTmpDir + "/build.json"; writeFile(jsonFile, json.dump()); @@ -91,8 +92,15 @@ struct ExternalDerivationBuilder : DerivationBuilderImpl try { commonChildInit(); - Strings args = {externalBuilder.program, jsonFile}; + Strings args = {externalBuilder.program}; + if (externalBuilder.args) { + args.insert(args.end(), externalBuilder.args->begin(), externalBuilder.args->end()); + } + + args.insert(args.end(), jsonFile); + + debug("executing external builder: %s", concatStringsSep(" ", args)); execv(externalBuilder.program.c_str(), stringsToCharPtrs(args).data()); throw SysError("executing '%s'", externalBuilder.program);