From 8c0b42f857b53993d95c5bc077e8f8a71028c5ac Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 12 May 2004 09:35:51 +0000 Subject: [PATCH] * An quick and dirty hack to support distributed builds. --- src/libmain/shared.cc | 7 ------- src/libstore/normalise.cc | 22 +++++++++++++++++++++- src/libutil/util.cc | 10 ++++++++-- src/libutil/util.hh | 3 +++ src/nix-env/main.cc | 2 +- tests/Makefile.am | 7 +++++-- tests/build-hook.hook.sh | 17 +++++++++++++++++ tests/build-hook.nix.in | 25 +++++++++++++++++++++++++ tests/build-hook.sh | 12 ++++++++++++ 9 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 tests/build-hook.hook.sh create mode 100644 tests/build-hook.nix.in create mode 100644 tests/build-hook.sh diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index d9cc990f9..95552a361 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -52,13 +52,6 @@ void checkStoreNotSymlink(Path path) } -static string getEnv(const string & key, const string & def = "") -{ - char * value = getenv(key.c_str()); - return value ? string(value) : def; -} - - /* Initialize and reorder arguments, then call the actual argument processor. */ static void initAndRun(int argc, char * * argv) diff --git a/src/libstore/normalise.cc b/src/libstore/normalise.cc index 983d7d476..0c8a8057f 100644 --- a/src/libstore/normalise.cc +++ b/src/libstore/normalise.cc @@ -302,6 +302,7 @@ bool Normaliser::startBuild(Path nePath) /* Obtain locks on all output paths. The locks are automatically released when we exit this function or Nix crashes. */ + /* !!! BUG: this could block, which is not allowed. */ goal.outputLocks.lockPaths(goal.expr.derivation.outputs); /* Now check again whether there is a successor. This is because @@ -364,6 +365,25 @@ bool Normaliser::startBuild(Path nePath) return true; } + /* !!! Hack */ + Path buildHook = getEnv("NIX_BUILD_HOOK"); + if (buildHook != "") { + printMsg(lvlChatty, format("using build hook `%1%'") % buildHook); + int status = system((buildHook + " " + goal.nePath + " 1>&2").c_str()); + if (WIFEXITED(status)) { + int code = WEXITSTATUS(status); + if (code == 100) { /* == accepted */ + printMsg(lvlChatty, + format("build hook succesfully realised output paths")); + finishGoal(goal); + return true; + } else if (code != 101) /* != declined */ + throw Error( + format("build hook returned exit code %1%") % code); + } else throw Error( + format("build hook died with status %1%") % status); + } + /* Otherwise, start the build in a child process. */ startBuildChild(goal); @@ -660,7 +680,7 @@ void Normaliser::finishGoal(Goal & goal) { Path path = *i; if (!pathExists(path)) - throw Error(format("path `%1%' does not exist") % path); + throw Error(format("output path `%1%' does not exist") % path); nf.closure.roots.insert(path); makePathReadOnly(path); diff --git a/src/libutil/util.cc b/src/libutil/util.cc index bf2954f53..399233983 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -29,6 +29,13 @@ SysError::SysError(const format & f) } +string getEnv(const string & key, const string & def) +{ + char * value = getenv(key.c_str()); + return value ? string(value) : def; +} + + Path absPath(Path path, Path dir) { if (path[0] != '/') { @@ -206,8 +213,7 @@ void makePathReadOnly(const Path & path) static Path tempName() { static int counter = 0; - char * s = getenv("TMPDIR"); - Path tmpRoot = s ? canonPath(Path(s)) : "/tmp"; + Path tmpRoot = canonPath(getEnv("TMPDIR", "/tmp")); return (format("%1%/nix-%2%-%3%") % tmpRoot % getpid() % counter++).str(); } diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 1b0600006..d9ca1dac2 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -55,6 +55,9 @@ typedef set PathSet; extern string thisSystem; +/* Return an environment variable. */ +string getEnv(const string & key, const string & def = ""); + /* Return an absolutized path, resolving paths relative to the specified directory, or the current directory otherwise. The path is also canonicalised. */ diff --git a/src/nix-env/main.cc b/src/nix-env/main.cc index ed00fc206..8cbc3b703 100644 --- a/src/nix-env/main.cc +++ b/src/nix-env/main.cc @@ -118,7 +118,7 @@ void loadDerivations(EvalState & state, Path nePath, DrvInfos & drvs) static Path getHomeDir() { - Path homeDir(getenv("HOME")); + Path homeDir(getEnv("HOME", "")); if (homeDir == "") throw Error("HOME environment variable not set"); return homeDir; } diff --git a/tests/Makefile.am b/tests/Makefile.am index 14662c20d..608ffec19 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -16,8 +16,10 @@ simple.sh: simple.nix dependencies.sh: dependencies.nix locking.sh: locking.nix parallel.sh: parallel.nix +build-hook.sh: build-hook.nix -TESTS = init.sh simple.sh dependencies.sh locking.sh parallel.sh +TESTS = init.sh simple.sh dependencies.sh locking.sh parallel.sh \ + build-hook.sh XFAIL_TESTS = @@ -27,4 +29,5 @@ EXTRA_DIST = $(TESTS) \ simple.nix.in simple.builder.sh \ dependencies.nix.in dependencies.builder*.sh \ locking.nix.in locking.builder.sh \ - parallel.nix.in parallel.builder.sh + parallel.nix.in parallel.builder.sh \ + build-hook.nix.in diff --git a/tests/build-hook.hook.sh b/tests/build-hook.hook.sh new file mode 100644 index 000000000..7176315d9 --- /dev/null +++ b/tests/build-hook.hook.sh @@ -0,0 +1,17 @@ +set -x + +drv=$1 + +echo "HOOK for $drv" + +outPath=$(sed 's/Derive(\[\"\([^\"]*\)\".*/\1/' $drv) + +echo "output path is $outPath" + +if $(echo $outPath | grep -q input-1); then + mkdir $outPath + echo "BAR" > $outPath/foo + exit 100 +fi + +exit 101 \ No newline at end of file diff --git a/tests/build-hook.nix.in b/tests/build-hook.nix.in new file mode 100644 index 000000000..920564955 --- /dev/null +++ b/tests/build-hook.nix.in @@ -0,0 +1,25 @@ +let { + + input1 = derivation { + name = "dependencies-input-1"; + system = "@system@"; + builder = "@shell@"; + args = ["-e" "-x" ./dependencies.builder1.sh]; + }; + + input2 = derivation { + name = "dependencies-input-2"; + system = "@system@"; + builder = "@shell@"; + args = ["-e" "-x" ./dependencies.builder2.sh]; + }; + + body = derivation { + name = "dependencies"; + system = "@system@"; + builder = "@shell@"; + args = ["-e" "-x" ./dependencies.builder0.sh]; + inherit input1 input2; + }; + +} \ No newline at end of file diff --git a/tests/build-hook.sh b/tests/build-hook.sh new file mode 100644 index 000000000..bd74e42fe --- /dev/null +++ b/tests/build-hook.sh @@ -0,0 +1,12 @@ +export NIX_BUILD_HOOK="sh build-hook.hook.sh" + +storeExpr=$($TOP/src/nix-instantiate/nix-instantiate build-hook.nix) + +echo "store expr is $storeExpr" + +outPath=$($TOP/src/nix-store/nix-store -qnfvvvvv "$storeExpr") + +echo "output path is $outPath" + +text=$(cat "$outPath"/foobar) +if test "$text" != "BARBAR"; then exit 1; fi