You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Nix中使用mkDerivation时,能否指定buildPhase所用的Shell?

替换mkDerivation构建阶段默认Shell的方法

问题背景

假设你的flake.nix中有如下代码:

foo = pkgs.stdenv.mkDerivation {
  name = "foo";
  buildPhase = ''
    #some shell script
  '';
  installPhase = ''
    #some shell script
  '';
};

需要指定自定义Shell(比如用mkShell定义的环境或指定Shell路径)替代默认bash执行buildPhase、installPhase等阶段,避免在每个脚本块重复复现Shell环境。


可行方案

1. 直接指定特定Shell包

在mkDerivation中通过shell参数直接指定要使用的Shell包(如zsh、fish等),所有构建阶段的脚本会自动改用该Shell执行:

foo = pkgs.stdenv.mkDerivation {
  name = "foo";
  shell = pkgs.zsh; # 指定zsh作为执行Shell
  buildPhase = ''
    echo "当前Shell: $SHELL" # 输出会是zsh的路径
    # 你的构建脚本
  '';
  installPhase = ''
    # 你的安装脚本
  '';
};

2. 复用mkShell定义的环境

如果已经用mkShell定义了包含特定依赖、环境变量的开发环境,可以直接复用其配置到mkDerivation中:

# 先定义你的mkShell环境
myDevShell = pkgs.mkShell {
  buildInputs = [ pkgs.nodejs pkgs.yarn ];
  shellHook = ''
    export NODE_ENV=production
  '';
};

# 在mkDerivation中复用该环境
foo = pkgs.stdenv.mkDerivation {
  name = "foo";
  buildInputs = myDevShell.buildInputs; # 继承依赖
  shell = myDevShell.shell; # 使用mkShell指定的Shell
  preBuild = myDevShell.shellHook; # 加载mkShell的环境变量配置
  buildPhase = ''
    yarn install
    yarn build
  '';
  installPhase = ''
    cp -r dist $out/
  '';
};

3. 自定义全局stdenv

如果多个派生包都需要使用同一个自定义Shell,可以通过override修改默认stdenv,后续所有基于该stdenv的派生都会自动使用指定Shell:

# 自定义stdenv,替换默认bash为fish
myStdenv = pkgs.stdenv.override {
  shell = pkgs.fish;
};

# 使用自定义stdenv创建派生
foo = myStdenv.mkDerivation {
  name = "foo";
  buildPhase = ''
    echo "当前Shell: $SHELL" # 输出会是fish的路径
  '';
  installPhase = ''
    # 你的安装脚本
  '';
};

内容的提问来源于stack exchange,提问作者Lattice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:16:19