buildGoModule中vendorSha256的计算方法解析及自定义Nix表达式中该值的生成问询
我完全理解你在搞懂buildGoModule里vendorSha256计算方式时的困惑——nixpkgs手册里的描述确实太抽象了,根本没法直接落地。其实有两种实用的方法能算出这个哈希值,我就用你给的oapi-codegen示例一步步讲清楚:
方法1:让Nix自动计算(最省心的方式)
这是日常使用中最常用的方法,不需要手动折腾依赖:
- 先把你的Nix表达式里的
vendorSha256字段替换成vendorSha256 = lib.fakeSha256;(lib是你表达式里传入的参数,直接用就行) - 尝试构建这个包,比如如果你的表达式在
default.nix里,运行命令:nix-build -A oapi-codegen - Nix会自动拉取源码、执行
go mod vendor生成依赖目录,但因为你填了假的哈希,它会失败并输出正确的哈希值。你只需要把输出里的got:后面的字符串复制粘贴回vendorSha256字段就完成了。
比如针对你的示例,替换后运行构建命令,Nix会输出类似这样的错误:
error: hash mismatch in fixed-output derivation '/nix/store/xxxxxx-oapi-codegen-vendor.drv':
specified: sha256-0000000000000000000000000000000000000000000000000000
got: sha256-Y4WM+o+5jiwj8/99UyNHLpBNbtJkKteIGW2P1Jd9L6M=
把got:后面的哈希值填回去,再运行构建就没问题了。
方法2:手动生成并计算(适合理解原理)
如果你想搞明白这个哈希背后的逻辑,可以手动模拟buildGoModule的过程:
- 先拉取对应版本的源码:根据你表达式里的fetchFromGitHub参数,运行命令:
git clone https://github.com/deepmap/oapi-codegen.git cd oapi-codegen git checkout v1.6.0 - 生成vendor目录:在源码目录下运行Go的依赖打包命令:
go mod vendor,这会把所有项目依赖下载到本地的vendor文件夹里。 - 计算
vendor目录的哈希:用Nix自带的nix-hash工具计算,命令是:
运行后得到的结果就是你需要的nix-hash --type sha256 --base32 --flat vendor/vendorSha256值,针对这个示例,结果就是sha256-Y4WM+o+5jiwj8/99UyNHLpBNbtJkKteIGW2P1Jd9L6M=,和你表达式里的完全一致。
为什么是“中间获取器派生的输出哈希”?
其实手册里的描述就是在说buildGoModule的工作流程:它会先创建一个中间派生(derivation),这个派生的工作就是拉取Go依赖并生成vendor目录,然后把这个目录作为固定输出的产物,vendorSha256就是这个产物的sha256哈希。我们上面的两种方法,本质上都是在获取这个产物的哈希——第一种是让Nix帮你执行这个过程然后报错给出正确值,第二种是手动模拟这个过程计算。
内容的提问来源于stack exchange,提问作者zuzuleinen

