在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
相关产品推荐
相关产品推荐

