自动化与脚本
使用 Nix flake/overlay/shell.nix…
适用于编写或维护 Nix flake、overlay、shell.nix、flake.nix,以及排查 nix develop、unfree 包、hash 和 overlay 问题。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
使用 Nix flake/overlay特定
解决思路
- 按标准 flake.nix 结构编写:顶层 description;inputs 中声明 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable" 和 flake-utils.url = "github:numtide/flake-utils";outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { inherit system; }; in { devShells.default = pkgs.mkShell { buildInputs = with pkgs; [ ... ]; }; });
- 添加 overlay 类 input 时,用 follows 共享父级 nixpkgs,避免下载多个 nixpkgs 版本:some-overlay.inputs.nixpkgs.follows = "nixpkgs"。
- 链式 follows 到中间 input:another-overlay.inputs.nixpkgs.follows = "some-overlay"。
- 即使 input 不直接使用,也必须在 outputs 函数参数中列出所有 inputs:outputs = { self, nixpkgs, some-overlay, another-overlay, ... }: ...
- 应用 overlay 时,在导入 nixpkgs 的 overlays 列表中放入 overlay 的 default 输出:pkgs = import nixpkgs { inherit system; overlays = [ overlay1.overlays.default overlay2.overlays.default (final: prev: { myPackage = prev.myPackage.override { ... }; }) ]; };
- 处理 unfree 包(团队推荐):添加 nixpkgs-unfree input,并让其 follows 父 nixpkgs:nixpkgs-unfree.url = "github:numtide/nixpkgs-unfree/nixos-unstable"; nixpkgs-unfree.inputs.nixpkgs.follows = "nixpkgs";
- 让专有包 overlay 跟随 nixpkgs-unfree:proprietary-tool.url = "github:owner/proprietary-tool-overlay"; proprietary-tool.inputs.nixpkgs.follows = "nixpkgs-unfree";形成 proprietary-tool → nixpkgs-unfree → nixpkgs 链。
- 处理 unfree 包(用户配置):在 ~/.config/nixpkgs/config.nix 写入 { allowUnfree = true; }。
- 处理 unfree 包(仅特定包):在导入 nixpkgs 时设置 config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ "specific-package" ];。
- 注意:flake.nix 中的 config.allowUnfree 对 nix develop 不生效;改用 nixpkgs-unfree 或用户配置。
- 为缺少功能的 open-core/社区版工具创建二进制 overlay:在 flake 中从官方 URL 获取二进制。
- 参考 0xBigBoss/atlas-overlay、0xBigBoss/bun-overlay 的二进制 overlay 模式。
- 二进制 overlay 的 flake 结构:inputs 声明 nixpkgs 和 flake-utils;outputs 用 flake-utils.lib.eachDefaultSystem;取 pkgs = nixpkgs.legacyPackages.${system};定义 version。
- 为各平台定义 sources 属性集,例如 x86_64-linux、aarch64-linux、x86_64-darwin、aarch64-darwin,每项包含 url 和 sha256。
- 用 source = sources.${system} or (throw "Unsupported system: ${system}"); 选择当前平台源,不支持时抛错。
- 用 pkgs.stdenv.mkDerivation 打包二进制:设置 pname、version、src = pkgs.fetchurl { inherit (source) url sha256; }; sourceRoot = "."; dontUnpack = true; installPhase 中 mkdir -p $out/bin、cp $src $out/bin/tool、chmod +x $out/bin/tool。
- 为二进制包补充 meta:description、homepage、license = licenses.unfree(或合适许可证)、platforms = builtins.attrNames sources。
- 导出 packages 和 overlays:packages.default = toolPackage; packages.tool = toolPackage; overlays.default = final: prev: { tool = toolPackage; }; 并在末尾用 // { overlays.default = final: prev: { tool = self.packages.${prev.system}.tool; }; } 覆盖为跨系统版本。
- 获取 SHA256:运行 nix-prefetch-url https://example.com/tool-linux-amd64-v1.0.0。
- 把 base32 hash 转成 SRI:运行 nix hash to-sri --type sha256 <base32-hash>。
- 或直接用 SRI 获取:运行 nix-prefetch-url --type sha256 https://example.com/tool-linux-amd64-v1.0.0。
- 基础 devShell:devShells.default = pkgs.mkShell { buildInputs = with pkgs; [ nodejs python3 ]; shellHook = ''echo "Dev environment ready"''; };
- 在 devShell 中设置静态环境变量:DATABASE_URL = "postgres://localhost/dev";。
- 在 devShell 中动态设置环境变量:在 shellHook 中写 export PROJECT_ROOT="$(pwd)"。
- 在 devShell 中处理 C 库等原生依赖:buildInputs 加入 openssl、postgresql;shellHook 中导出 C_INCLUDE_PATH="${pkgs.openssl.dev}/include:$C_INCLUDE_PATH"、LIBRARY_PATH="${pkgs.openssl.out}/lib:$LIBRARY_PATH"、PKG_CONFIG_PATH="${pkgs.openssl.dev}/lib/pkgconfig:$PKG_CONFIG_PATH"。
- 为 flake 项目集成 direnv:在 .envrc 写 use flake。
- 没有 nixpkgs-unfree 但需要 unfree 包时,在 .envrc 写 export NIXPKGS_ALLOW_UNFREE=1 和 use flake --impure。
- 更新全部 flake inputs:nix flake update。
- 更新指定 input:nix flake update some-input。
- 检查 flake 有效性:nix flake check。
- 查看 flake 元数据:nix flake metadata。
- 进入开发 shell:nix develop。
- 在开发 shell 中执行命令:nix develop -c <command>。
- 构建包:nix build .#packageName。
- 运行包:nix run .#packageName。
- 排查 "unexpected argument":确保所有 inputs 都列在 outputs 函数参数中,例如 outputs = { self, nixpkgs, other-input, ... }: ...。
- 排查 nix develop 的 unfree 包错误:优先使用 nixpkgs-unfree input;或配置用户 ~/.config/nixpkgs/config.nix;或运行 NIXPKGS_ALLOW_UNFREE=1 nix develop --impure。
- 排查重复下载 nixpkgs:用 follows 把各 input 链到同一个 nixpkgs 源。
- 排查 overlay 未生效:确认导入 nixpkgs 时把 overlay 放进 overlays 列表:pkgs = import nixpkgs { inherit system; overlays = [ my-overlay.overlays.default ]; }。
- 排查 hash mismatch:重新运行 nix-prefetch-url 获取 hash 并更新;上游更新同一 URL 的二进制时 hash 会变化。
适用边界 · 注意事项
- 不适用于未使用 Nix/flake 的项目,或仍在用非 flake 的旧 Nix 表达式工作流。
- 不需要官方二进制或必须从源码构建时,不采用二进制 overlay 模式。
- 若组织已通过系统级 nixpkgs config 统一管理 unfree 许可,则无需 nixpkgs-unfree 或 --impure。