diff --git a/src/libstore/builtins/buildenv.cc b/src/libstore/builtins/buildenv.cc index eeaccb24c..204912278 100644 --- a/src/libstore/builtins/buildenv.cc +++ b/src/libstore/builtins/buildenv.cc @@ -1,4 +1,5 @@ #include "nix/store/builtins/buildenv.hh" +#include "nix/store/builtins.hh" #include "nix/store/derivations.hh" #include "nix/util/signals.hh" @@ -166,7 +167,7 @@ void buildProfile(const Path & out, Packages && pkgs) debug("created %d symlinks in user environment", state.symlinks); } -void builtinBuildenv( +static void builtinBuildenv( const BasicDerivation & drv, const std::map & outputs) { @@ -203,4 +204,6 @@ void builtinBuildenv( createSymlink(getAttr("manifest"), out + "/manifest.nix"); } +static RegisterBuiltinBuilder registerBuildenv("buildenv", builtinBuildenv); + } diff --git a/src/libstore/builtins/unpack-channel.cc b/src/libstore/builtins/unpack-channel.cc index e03f3076b..47bf25fbf 100644 --- a/src/libstore/builtins/unpack-channel.cc +++ b/src/libstore/builtins/unpack-channel.cc @@ -3,7 +3,7 @@ namespace nix { -void builtinUnpackChannel( +static void builtinUnpackChannel( const BasicDerivation & drv, const std::map & outputs) { @@ -42,4 +42,6 @@ void builtinUnpackChannel( } } +static RegisterBuiltinBuilder registerUnpackChannel("unpack-channel", builtinUnpackChannel); + } diff --git a/src/libstore/include/nix/store/builtins.hh b/src/libstore/include/nix/store/builtins.hh index 004e9ef64..6d54c2a22 100644 --- a/src/libstore/include/nix/store/builtins.hh +++ b/src/libstore/include/nix/store/builtins.hh @@ -12,8 +12,19 @@ void builtinFetchurl( const std::string & netrcData, const std::string & caFileData); -void builtinUnpackChannel( - const BasicDerivation & drv, - const std::map & outputs); +using BuiltinBuilder = + std::function & outputs)>; + +struct RegisterBuiltinBuilder +{ + typedef std::map BuiltinBuilders; + static BuiltinBuilders * builtinBuilders; + + RegisterBuiltinBuilder(const std::string & name, BuiltinBuilder && fun) + { + if (!builtinBuilders) builtinBuilders = new BuiltinBuilders; + builtinBuilders->insert_or_assign(name, std::move(fun)); + } +}; } diff --git a/src/libstore/include/nix/store/builtins/buildenv.hh b/src/libstore/include/nix/store/builtins/buildenv.hh index a0a262037..163666c0b 100644 --- a/src/libstore/include/nix/store/builtins/buildenv.hh +++ b/src/libstore/include/nix/store/builtins/buildenv.hh @@ -45,8 +45,4 @@ typedef std::vector Packages; void buildProfile(const Path & out, Packages && pkgs); -void builtinBuildenv( - const BasicDerivation & drv, - const std::map & outputs); - } diff --git a/src/libstore/unix/build/derivation-builder.cc b/src/libstore/unix/build/derivation-builder.cc index 4bde9750d..c40d5251b 100644 --- a/src/libstore/unix/build/derivation-builder.cc +++ b/src/libstore/unix/build/derivation-builder.cc @@ -1835,6 +1835,9 @@ void setupSeccomp() } +RegisterBuiltinBuilder::BuiltinBuilders * RegisterBuiltinBuilder::builtinBuilders = nullptr; + + void DerivationBuilderImpl::runChild() { /* Warning: in the child we should absolutely not make any SQLite @@ -2293,12 +2296,14 @@ void DerivationBuilderImpl::runChild() if (drv.builder == "builtin:fetchurl") builtinFetchurl(drv, outputs, netrcData, caFileData); - else if (drv.builder == "builtin:buildenv") - builtinBuildenv(drv, outputs); - else if (drv.builder == "builtin:unpack-channel") - builtinUnpackChannel(drv, outputs); - else - throw Error("unsupported builtin builder '%1%'", drv.builder.substr(8)); + else { + std::string builtinName = drv.builder.substr(8); + assert(RegisterBuiltinBuilder::builtinBuilders); + if (auto builtin = get(*RegisterBuiltinBuilder::builtinBuilders, builtinName)) + (*builtin)(drv, outputs); + else + throw Error("unsupported builtin builder '%1%'", builtinName); + } _exit(0); } catch (std::exception & e) { writeFull(STDERR_FILENO, e.what() + std::string("\n"));