【问题标题】:Nix: How a derivation sets up PATH in nix-shell without calling builder?Nix:派生如何在不调用 builder 的情况下在 nix-shell 中设置 PATH?
【发布时间】:2020-10-26 14:26:16
【问题描述】:

派生需要很多参数,但其中只有一个,builder,是可执行的,对吗?

nix-shell 并没有真正执行 builder,这意味着无法运行诸如 export PATH=... 之类的命令。

但我发现其他一些派生提供了他们的虚拟 shell 环境,其中 PATH 是任意设置的,例如 .env haskell 包派生的属性。

我还发现 mkDerivationbuildInput 包的子 /bin 目录添加到 PATH(如果存在)。

他们是怎么做到的?内置 derivation 函数是否有一些特殊参数可以让您在评估时运行自定义命令?

【问题讨论】:

    标签: nix nix-shell


    【解决方案1】:

    另一种方法是在推导阶段导出特定路径 - 尽管我不确定这是否正确。

    假设您需要一个包cowsay 在您构建某些东西时出现在您的路径中,然后您可以通过添加它来使其可用:

    # ... 
    <nixpkgs>.stdenv.mkDerivation{
    # ...
      buildPhase = '' 
        export PATH="${<nixpkgs>.cowsay}/bin:$PATH"
      '';
    # ... 
    }
    

    这将使构建器在 buildPhase 期间执行该命令,并构建包并将其添加到构建阶段的路径中。您可以使用 mkDerivation 对 shell 执行相同操作,方法是使用 shellHook

    # ... 
    <nixpkgs>.stdenv.mkDerivation{
    # ...
      shellHook = '' 
        export PATH="${<nixpkgs>.cowsay}/bin:$PATH"
      '';
    # ... 
    }
    

    然后路径将在您的 shell 环境中可用。

    值得注意的是,默认情况下,如果生成了派生(在buildInputs 或其他任何地方,如果它有一个./bin/ 目录,则它对环境可用。

    【讨论】:

      【解决方案2】:

      我上次检查时,nix-shell 在启动时尝试运行此命令:

      source $stdenv/setup
      

      因此,当您调用derivation 函数时,您应该定义一个名为$stdenv 的环境变量,该变量指向一个包含名为setup 的文件的目录,并且该文件应该是一个有效的Bash 脚本。然后,该脚本可以定义您需要的 shell 函数和环境变量。

      在我的nixcrpkgs project 中,我的setup 脚​​本只有一行:

      export PATH=$_PATH
      

      所以我将_PATH 作为参数传递给derivation,然后我的setup 脚本将其复制到PATH 环境变量中。

      我们不能只在派生中设置 PATH,因为 nix-shell 会使派生的 PATH 覆盖系统 PATH,这意味着我们不能使用主机系统中的“git”或“which”等实用程序。

      这里有一些伪代码显示你需要做什么:

      derivation {
        stdenv = ./my_pretened_stdenv;  # directory that has setup script in it
        _PATH = "/stuff/bin:/more_stuff/bin";
        # other attributes
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-27
        • 2018-08-24
        • 2018-02-20
        • 2016-12-05
        • 2019-11-17
        • 1970-01-01
        • 1970-01-01
        • 2017-11-28
        相关资源
        最近更新 更多