about summary refs log tree commit diff
path: root/third_party/nix/src/nix-build/nix-build.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/nix/src/nix-build/nix-build.cc')
-rw-r--r--third_party/nix/src/nix-build/nix-build.cc581
1 files changed, 0 insertions, 581 deletions
diff --git a/third_party/nix/src/nix-build/nix-build.cc b/third_party/nix/src/nix-build/nix-build.cc
deleted file mode 100644
index 26c3089677..0000000000
--- a/third_party/nix/src/nix-build/nix-build.cc
+++ /dev/null
@@ -1,581 +0,0 @@
-#include <cstring>
-#include <fstream>
-#include <iostream>
-#include <regex>
-#include <sstream>
-#include <vector>
-
-#include <absl/strings/ascii.h>
-#include <absl/strings/str_split.h>
-#include <glog/logging.h>
-
-#include "libexpr/attr-path.hh"
-#include "libexpr/common-eval-args.hh"
-#include "libexpr/eval-inline.hh"
-#include "libexpr/eval.hh"
-#include "libexpr/get-drvs.hh"
-#include "libmain/shared.hh"
-#include "libstore/derivations.hh"
-#include "libstore/globals.hh"
-#include "libstore/store-api.hh"
-#include "libutil/affinity.hh"
-#include "libutil/status.hh"
-#include "libutil/util.hh"
-#include "nix/legacy.hh"
-
-using namespace nix;
-using namespace std::string_literals;
-
-/* Recreate the effect of the perl shellwords function, breaking up a
- * string into arguments like a shell word, including escapes
- */
-std::vector<std::string> shellwords(const std::string& s) {
-  std::regex whitespace("^(\\s+).*");
-  auto begin = s.cbegin();
-  std::vector<std::string> res;
-  std::string cur;
-  enum state { sBegin, sQuote };
-  state st = sBegin;
-  auto it = begin;
-  for (; it != s.cend(); ++it) {
-    if (st == sBegin) {
-      std::smatch match;
-      if (regex_search(it, s.cend(), match, whitespace)) {
-        cur.append(begin, it);
-        res.push_back(cur);
-        cur.clear();
-        it = match[1].second;
-        begin = it;
-      }
-    }
-    switch (*it) {
-      case '"':
-        cur.append(begin, it);
-        begin = it + 1;
-        st = st == sBegin ? sQuote : sBegin;
-        break;
-      case '\\':
-        /* perl shellwords mostly just treats the next char as part of the
-         * string with no special processing */
-        cur.append(begin, it);
-        begin = ++it;
-        break;
-    }
-  }
-  cur.append(begin, it);
-  if (!cur.empty()) {
-    res.push_back(cur);
-  }
-  return res;
-}
-
-static void _main(int argc, char** argv) {
-  auto dryRun = false;
-  auto runEnv = std::regex_search(argv[0], std::regex("nix-shell$"));
-  auto pure = false;
-  auto fromArgs = false;
-  auto packages = false;
-  // Same condition as bash uses for interactive shells
-  auto interactive =
-      (isatty(STDIN_FILENO) != 0) && (isatty(STDERR_FILENO) != 0);
-  Strings attrPaths;
-  Strings left;
-  RepairFlag repair = NoRepair;
-  Path gcRoot;
-  BuildMode buildMode = bmNormal;
-  bool readStdin = false;
-
-  std::string envCommand;  // interactive shell
-  Strings envExclude;
-
-  auto myName = runEnv ? "nix-shell" : "nix-build";
-
-  auto inShebang = false;
-  std::string script;
-  std::vector<std::string> savedArgs;
-
-  AutoDelete tmpDir(createTempDir("", myName));
-
-  std::string outLink = "./result";
-
-  // List of environment variables kept for --pure
-  std::set<std::string> keepVars{
-      "HOME",         "USER", "LOGNAME", "DISPLAY",         "PATH", "TERM",
-      "IN_NIX_SHELL", "TZ",   "PAGER",   "NIX_BUILD_SHELL", "SHLVL"};
-
-  Strings args;
-  for (int i = 1; i < argc; ++i) {
-    args.push_back(argv[i]);
-  }
-
-  // Heuristic to see if we're invoked as a shebang script, namely,
-  // if we have at least one argument, it's the name of an
-  // executable file, and it starts with "#!".
-  if (runEnv && argc > 1 &&
-      !std::regex_search(argv[1], std::regex("nix-shell"))) {
-    script = argv[1];
-    try {
-      Strings lines = absl::StrSplit(readFile(script), absl::ByChar('\n'),
-                                     absl::SkipEmpty());
-      if (std::regex_search(lines.front(), std::regex("^#!"))) {
-        lines.pop_front();
-        inShebang = true;
-        for (int i = 2; i < argc; ++i) {
-          savedArgs.emplace_back(argv[i]);
-        }
-        args.clear();
-        for (auto line : lines) {
-          line = absl::StripTrailingAsciiWhitespace(line);
-          std::smatch match;
-          if (std::regex_match(line, match,
-                               std::regex("^#!\\s*nix-shell (.*)$"))) {
-            for (const auto& word : shellwords(match[1].str())) {
-              args.push_back(word);
-            }
-          }
-        }
-      }
-    } catch (SysError&) {
-    }
-  }
-
-  struct MyArgs : LegacyArgs, MixEvalArgs {
-    using LegacyArgs::LegacyArgs;
-  };
-
-  MyArgs myArgs(
-      myName, [&](Strings::iterator& arg, const Strings::iterator& end) {
-        if (*arg == "--help") {
-          deletePath(Path(tmpDir));
-          showManPage(myName);
-        }
-
-        else if (*arg == "--version") {
-          printVersion(myName);
-
-        } else if (*arg == "--add-drv-link" || *arg == "--indirect") {
-          ;  // obsolete
-
-        } else if (*arg == "--no-out-link" || *arg == "--no-link") {
-          outLink = Path(tmpDir) + "/result";
-
-        } else if (*arg == "--attr" || *arg == "-A") {
-          attrPaths.push_back(getArg(*arg, arg, end));
-
-        } else if (*arg == "--drv-link") {
-          getArg(*arg, arg, end);  // obsolete
-
-        } else if (*arg == "--out-link" || *arg == "-o") {
-          outLink = getArg(*arg, arg, end);
-
-        } else if (*arg == "--add-root") {
-          gcRoot = getArg(*arg, arg, end);
-
-        } else if (*arg == "--dry-run") {
-          dryRun = true;
-
-        } else if (*arg == "--repair") {
-          repair = Repair;
-          buildMode = bmRepair;
-        }
-
-        else if (*arg == "--run-env") {  // obsolete
-          runEnv = true;
-
-        } else if (*arg == "--command" || *arg == "--run") {
-          if (*arg == "--run") {
-            interactive = false;
-          }
-          envCommand = getArg(*arg, arg, end) + "\nexit";
-        }
-
-        else if (*arg == "--check") {
-          buildMode = bmCheck;
-
-        } else if (*arg == "--exclude") {
-          envExclude.push_back(getArg(*arg, arg, end));
-
-        } else if (*arg == "--expr" || *arg == "-E") {
-          fromArgs = true;
-
-        } else if (runEnv && *arg == "--pure") {
-          pure = true;
-        } else if (runEnv && *arg == "--impure") {
-          pure = false;
-
-        } else if (*arg == "--packages" || *arg == "-p") {
-          packages = true;
-
-        } else if (inShebang && *arg == "-i") {
-          auto interpreter = getArg(*arg, arg, end);
-          interactive = false;
-          auto execArgs = "";
-
-          // Überhack to support Perl. Perl examines the shebang and
-          // executes it unless it contains the string "perl" or "indir",
-          // or (undocumented) argv[0] does not contain "perl". Exploit
-          // the latter by doing "exec -a".
-          if (std::regex_search(interpreter, std::regex("perl"))) {
-            execArgs = "-a PERL";
-          }
-
-          std::ostringstream joined;
-          for (const auto& i : savedArgs) {
-            joined << shellEscape(i) << ' ';
-          }
-
-          if (std::regex_search(interpreter, std::regex("ruby"))) {
-            // Hack for Ruby. Ruby also examines the shebang. It tries to
-            // read the shebang to understand which packages to read from. Since
-            // this is handled via nix-shell -p, we wrap our ruby script
-            // execution in ruby -e 'load' which ignores the shebangs.
-            envCommand = (format("exec %1% %2% -e 'load(\"%3%\")' -- %4%") %
-                          execArgs % interpreter % script % joined.str())
-                             .str();
-          } else {
-            envCommand = (format("exec %1% %2% %3% %4%") % execArgs %
-                          interpreter % script % joined.str())
-                             .str();
-          }
-        }
-
-        else if (*arg == "--keep") {
-          keepVars.insert(getArg(*arg, arg, end));
-
-        } else if (*arg == "-") {
-          readStdin = true;
-
-        } else if (*arg != "" && arg->at(0) == '-') {
-          return false;
-
-        } else {
-          left.push_back(*arg);
-        }
-
-        return true;
-      });
-
-  myArgs.parseCmdline(args);
-
-  if (packages && fromArgs) {
-    throw UsageError("'-p' and '-E' are mutually exclusive");
-  }
-
-  auto store = openStore();
-
-  auto state = std::make_unique<EvalState>(myArgs.searchPath, store);
-  state->repair = repair;
-
-  std::unique_ptr<Bindings> autoArgs = myArgs.getAutoArgs(*state);
-
-  if (packages) {
-    std::ostringstream joined;
-    // TODO(grfn): Generate a syntax tree here, not a string
-    joined << "with import <nixpkgs> { }; (pkgs.runCommandCC or "
-              "pkgs.runCommand) \"shell\" { buildInputs = [ ";
-    for (const auto& i : left) {
-      joined << '(' << i << ") ";
-    }
-    joined << "]; } \"\"";
-    fromArgs = true;
-    left = {joined.str()};
-  } else if (!fromArgs) {
-    if (left.empty() && runEnv && pathExists("shell.nix")) {
-      left = {"shell.nix"};
-    }
-    if (left.empty()) {
-      left = {"default.nix"};
-    }
-  }
-
-  if (runEnv) {
-    setenv("IN_NIX_SHELL", pure ? "pure" : "impure", 1);
-  }
-
-  DrvInfos drvs;
-
-  /* Parse the expressions. */
-  std::vector<Expr*> exprs;
-
-  if (readStdin) {
-    exprs = {state->parseStdin()};
-  } else {
-    for (const auto& i : left) {
-      if (fromArgs) {
-        exprs.push_back(state->parseExprFromString(i, absPath(".")));
-      } else {
-        auto absolute = i;
-        try {
-          absolute = canonPath(absPath(i), true);
-        } catch (Error& e) {
-        };
-        if (store->isStorePath(absolute) &&
-            std::regex_match(absolute, std::regex(".*\\.drv(!.*)?"))) {
-          drvs.push_back(DrvInfo(*state, store, absolute));
-        } else {
-          /* If we're in a #! script, interpret filenames
-             relative to the script. */
-          exprs.push_back(
-              state->parseExprFromFile(resolveExprPath(state->checkSourcePath(
-                  lookupFileArg(*state, inShebang && !packages
-                                            ? absPath(i, absPath(dirOf(script)))
-                                            : i)))));
-        }
-      }
-    }
-  }
-
-  /* Evaluate them into derivations. */
-  if (attrPaths.empty()) {
-    attrPaths = {""};
-  }
-
-  for (auto e : exprs) {
-    Value vRoot;
-    state->eval(e, vRoot);
-
-    for (auto& i : attrPaths) {
-      Value& v(*findAlongAttrPath(*state, i, autoArgs.get(), vRoot));
-      state->forceValue(v);
-      getDerivations(*state, v, "", autoArgs.get(), drvs, false);
-    }
-  }
-
-  state->printStats();
-
-  auto buildPaths = [&](const PathSet& paths) {
-    /* Note: we do this even when !printMissing to efficiently
-       fetch binary cache data. */
-    unsigned long long downloadSize;
-    unsigned long long narSize;
-    PathSet willBuild;
-    PathSet willSubstitute;
-    PathSet unknown;
-    store->queryMissing(paths, willBuild, willSubstitute, unknown, downloadSize,
-                        narSize);
-
-    if (settings.printMissing) {
-      printMissing(ref<Store>(store), willBuild, willSubstitute, unknown,
-                   downloadSize, narSize);
-    }
-
-    if (!dryRun) {
-      util::OkOrThrow(store->buildPaths(std::cerr, paths, buildMode));
-    }
-  };
-
-  if (runEnv) {
-    if (drvs.size() != 1) {
-      throw UsageError("nix-shell requires a single derivation");
-    }
-
-    auto& drvInfo = drvs.front();
-    auto drv = store->derivationFromPath(drvInfo.queryDrvPath());
-
-    PathSet pathsToBuild;
-
-    /* Figure out what bash shell to use. If $NIX_BUILD_SHELL
-       is not set, then build bashInteractive from
-       <nixpkgs>. */
-    auto opt_shell = getEnv("NIX_BUILD_SHELL");
-    std::string shell;
-
-    if (opt_shell.has_value()) {
-      shell = opt_shell.value();
-    } else {
-      try {
-        auto expr = state->parseExprFromString(
-            "(import <nixpkgs> {}).bashInteractive", absPath("."));
-
-        Value v;
-        state->eval(expr, v);
-
-        auto drv = getDerivation(*state, v, false);
-        if (!drv) {
-          throw Error(
-              "the 'bashInteractive' attribute in <nixpkgs> did not evaluate "
-              "to a derivation");
-        }
-
-        pathsToBuild.insert(drv->queryDrvPath());
-
-        shell = drv->queryOutPath() + "/bin/bash";
-
-      } catch (Error& e) {
-        LOG(WARNING) << e.what() << "; will use bash from your environment";
-        shell = "bash";
-      }
-    }
-
-    // Build or fetch all dependencies of the derivation.
-    for (const auto& input : drv.inputDrvs) {
-      if (std::all_of(envExclude.cbegin(), envExclude.cend(),
-                      [&](const std::string& exclude) {
-                        return !std::regex_search(input.first,
-                                                  std::regex(exclude));
-                      })) {
-        pathsToBuild.insert(makeDrvPathWithOutputs(input.first, input.second));
-      }
-    }
-    for (const auto& src : drv.inputSrcs) {
-      pathsToBuild.insert(src);
-    }
-
-    buildPaths(pathsToBuild);
-
-    if (dryRun) {
-      return;
-    }
-
-    // Set the environment.
-    auto env = getEnv();
-
-    auto tmp =
-        getEnv("TMPDIR").value_or(getEnv("XDG_RUNTIME_DIR").value_or("/tmp"));
-
-    if (pure) {
-      decltype(env) newEnv;
-      for (auto& i : env) {
-        if (keepVars.count(i.first) != 0u) {
-          newEnv.emplace(i);
-        }
-      }
-      env = newEnv;
-      // NixOS hack: prevent /etc/bashrc from sourcing /etc/profile.
-      env["__ETC_PROFILE_SOURCED"] = "1";
-    }
-
-    env["NIX_BUILD_TOP"] = env["TMPDIR"] = env["TEMPDIR"] = env["TMP"] =
-        env["TEMP"] = tmp;
-    env["NIX_STORE"] = store->storeDir;
-    env["NIX_BUILD_CORES"] = std::to_string(settings.buildCores);
-
-    StringSet passAsFile =
-        absl::StrSplit(get(drv.env, "passAsFile", ""),
-                       absl::ByAnyChar(" \t\n\r"), absl::SkipEmpty());
-
-    bool keepTmp = false;
-    int fileNr = 0;
-
-    for (auto& var : drv.env) {
-      if (passAsFile.count(var.first) != 0u) {
-        keepTmp = true;
-        std::string fn = ".attr-" + std::to_string(fileNr++);
-        Path p = Path(tmpDir) + "/" + fn;
-        writeFile(p, var.second);
-        env[var.first + "Path"] = p;
-      } else {
-        env[var.first] = var.second;
-      }
-    }
-
-    restoreAffinity();
-
-    /* Run a shell using the derivation's environment.  For
-       convenience, source $stdenv/setup to setup additional
-       environment variables and shell functions.  Also don't
-       lose the current $PATH directories. */
-    auto rcfile = Path(tmpDir) + "/rc";
-    writeFile(
-        rcfile,
-        fmt((keepTmp ? "" : "rm -rf '%1%'; "s) +
-                "[ -n \"$PS1\" ] && [ -e ~/.bashrc ] && source ~/.bashrc; "
-                "%2%"
-                "dontAddDisableDepTrack=1; "
-                "[ -e $stdenv/setup ] && source $stdenv/setup; "
-                "%3%"
-                "PATH=\"%4%:$PATH\"; "
-                "SHELL=%5%; "
-                "set +e; "
-                R"s([ -n "$PS1" ] && PS1='\n\[\033[1;32m\][nix-shell:\w]\$\[\033[0m\] '; )s"
-                "if [ \"$(type -t runHook)\" = function ]; then runHook "
-                "shellHook; fi; "
-                "unset NIX_ENFORCE_PURITY; "
-                "shopt -u nullglob; "
-                "unset TZ; %6%"
-                "%7%",
-            Path(tmpDir), (pure ? "" : "p=$PATH; "),
-            (pure ? "" : "PATH=$PATH:$p; unset p; "), dirOf(shell), shell,
-            (getenv("TZ") != nullptr
-                 ? (std::string("export TZ='") + getenv("TZ") + "'; ")
-                 : ""),
-            envCommand));
-
-    Strings envStrs;
-    for (auto& i : env) {
-      envStrs.push_back(i.first + "=" + i.second);
-    }
-
-    auto args = interactive ? Strings{"bash", "--rcfile", rcfile}
-                            : Strings{"bash", rcfile};
-
-    auto envPtrs = stringsToCharPtrs(envStrs);
-
-    environ = envPtrs.data();
-
-    auto argPtrs = stringsToCharPtrs(args);
-
-    restoreSignals();
-
-    execvp(shell.c_str(), argPtrs.data());
-
-    throw SysError("executing shell '%s'", shell);
-  }
-
-  PathSet pathsToBuild;
-
-  std::map<Path, Path> drvPrefixes;
-  std::map<Path, Path> resultSymlinks;
-  std::vector<Path> outPaths;
-
-  for (auto& drvInfo : drvs) {
-    auto drvPath = drvInfo.queryDrvPath();
-    auto outPath = drvInfo.queryOutPath();
-
-    auto outputName = drvInfo.queryOutputName();
-    if (outputName.empty()) {
-      throw Error("derivation '%s' lacks an 'outputName' attribute", drvPath);
-    }
-
-    pathsToBuild.insert(drvPath + "!" + outputName);
-
-    std::string drvPrefix;
-    auto i = drvPrefixes.find(drvPath);
-    if (i != drvPrefixes.end()) {
-      drvPrefix = i->second;
-    } else {
-      drvPrefix = outLink;
-      if (!drvPrefixes.empty() != 0u) {
-        drvPrefix += fmt("-%d", drvPrefixes.size() + 1);
-      }
-      drvPrefixes[drvPath] = drvPrefix;
-    }
-
-    std::string symlink = drvPrefix;
-    if (outputName != "out") {
-      symlink += "-" + outputName;
-    }
-
-    resultSymlinks[symlink] = outPath;
-    outPaths.push_back(outPath);
-  }
-
-  buildPaths(pathsToBuild);
-
-  if (dryRun) {
-    return;
-  }
-
-  for (auto& symlink : resultSymlinks) {
-    if (auto store2 = store.dynamic_pointer_cast<LocalFSStore>()) {
-      store2->addPermRoot(symlink.second, absPath(symlink.first), true);
-    }
-  }
-
-  for (auto& path : outPaths) {
-    std::cout << path << '\n';
-  }
-}
-
-static RegisterLegacyCommand s1("nix-build", _main);
-static RegisterLegacyCommand s2("nix-shell", _main);