如何获取Nix的所有构建时依赖(含引导依赖)?
问题描述
我正尝试搭建一个Nix缓存,其中包含构建一个简单derivation所需的所有存储路径,目标是在空存储环境中运行且无缓存命中,无需访问cache.nixos.org。但遇到问题:Nix会下载大量额外的引导组件用于拉取资源。
例如,以下derivation:
# empty_store_test_simple.nix with { inherit (import <nixpkgs> {}) fetchFromGitHub; }; (fetchFromGitHub { owner = "codedownio"; repo = "templates"; rev = "ba68b83d25d2b74f5475521ac00de3bbb884c983"; sha256 = "sha256-LNTi1ZBEsThmGWK53U9Na1j5DKHljcS42/PRXj97p6s="; })
在空存储中执行nix-build --dry-run构建时,显示将获取48个路径,但使用closureInfo工具仅得到1个路径,与预期不符。请问如何获取dry-run显示的所有构建时依赖?是否Nixpkgs中存在IFD导致此问题?
解决方案
1. 路径数量差异的原因
核心问题在于:
closureInfo默认仅计算运行时依赖,而--dry-run展示的是构建时+运行时的全量依赖。import <nixpkgs>确实会触发隐式IFD(导入时派生)——Nixpkgs在导入过程中会构建大量包集合初始化所需的派生对象,比如工具链组件、配置脚本等,这些都是构建目标派生的前置依赖。
2. 获取全量构建时依赖的方法
方法一:用nix-store追踪完整依赖链
先获取派生的存储路径,再查询其所有依赖(包含构建时):
# 获取派生的存储路径 DRV_PATH=$(nix-instantiate empty_store_test_simple.nix) # 查询该派生的所有依赖 nix-store -q --requisites $DRV_PATH
方法二:用nix derivation show分析依赖结构
该命令能输出派生的完整依赖明细,包括构建阶段的所有输入:
nix derivation show $(nix-instantiate empty_store_test_simple.nix) | jq '.[].inputDrvs'
方法三:精简Nixpkgs导入配置
通过关闭不必要的Nixpkgs特性,减少导入时产生的额外依赖:
import <nixpkgs> { config = { allowUnfree = false; }; overlays = []; system = builtins.currentSystem; # 指定当前系统,避免跨平台冗余 }
3. IFD的验证方法
要确认额外依赖是否来自IFD,可以用Nix内置的builtins.fetchGit替代Nixpkgs封装的fetchFromGitHub:
builtins.fetchGit { url = "https://github.com/codedownio/templates.git"; rev = "ba68b83d25d2b74f5475521ac00de3bbb884c983"; sha256 = "sha256-LNTi1ZBEsThmGWK53U9Na1j5DKHljcS42/PRXj97p6s="; }
此时执行nix-build --dry-run,依赖数量会大幅减少——因为builtins.fetchGit是Nix原生函数,无需依赖Nixpkgs的额外组件,这就能验证原问题中的额外路径确实来自Nixpkgs导入时的IFD。
内容的提问来源于stack exchange,提问作者tom
相关产品推荐
相关产品推荐

