据我了解,我可以使用该标志来使用给定版本的 Nix 软件包-I
。但我想知道在一个shell.nix
conf中是否可以有类似的东西:
git
v2.1.2htop
v1.2.3- ...
能够确保给定的工具版本。
答案1
是的,有多种方法可以做到这一点,但没有一种方法像这样直接和简单,git v2.1.2; htop v1.2.3
并且有很多注意事项。
在旁边
指定编程语言包的版本也是可能的,但这个主题似乎更混乱。迄今为止最有前途的标准化工作是dream2nix
。
0. 方法
也就是说,在撰写本文时可用:
0.1“版本化”属性路径(如果可用)
单版本政策
仅当有充分理由时,我们才会在 nixpkgs 中保留多个版本。 Nix 能够处理任意数量的版本/配置,但另一方面,当所有(或大多数)仅使用一个版本/配置时,它会更方便。它可以在许多方面更好地共享工作:简化维护、测试、共享二进制文件等。这是大多数发行版所做的。 (只有 gentoo 与我所知道的那些大的有所不同,并且他们为此付出了代价。)
当我们创建更多变体时,我们只需命名它们(属性路径),例如
gcc48
andgcc49
或ffmpeg
andffmpeg-full
。
引用jtojnar 的话语回答更具体的例子:
$ nix-env -qP --available nodejs
nixos.nodejs nodejs-10.18.1
nixos.nodejs-10_x nodejs-10.18.1
nixos.nodejs-12_x nodejs-12.14.1
nixos.nodejs-13_x nodejs-13.6.0
$ nix-env -iA nixos.nodejs-13_x
0.2固定
显式或隐式地与
- Nix 推导表达式(参见示例 2.2)
- Nix 命令行工具(参见示例 2.1)
- 覆盖层
- 覆盖(参见示例 2.3)
- 薄片(默认为固定)
- 第三方、“非官方”和/或专有方法(例如,
niv
,niv
+ 家庭管家,弗洛克斯)
1. 条款
1.1 固定
我能找到的最好的描述是这条评论由CMCD龙凯;解释一下:
固定在一个尼克斯表达意味着使用一个尼克斯套装(通常尼克斯包装或其分叉)在其历史的特定点(即某种状态)。
使用 Git (内容寻址)提交哈希值尼克斯包装repo 类似于“分离头状态”:从 Nix 表达式的角度来看,每个包定义都是发布提交时的最新版本。
例如,当引用固定到的 Nixpkgs 软件包集时39cd40f
(2017 年 9 月 29 日),“最新”版本为:
git
:2.14.2(当前为 2.39.1)htop
:2.0.2(当前为 3.2.2)
警告
Nixpkgs 存储库跟踪官方 Nix 软件包集和Nix 表达式中使用的便捷工具!请参阅下面的示例 2.1,了解这如何打破假设。
据我所知,任何官方文档中仍然没有定义术语“固定”。 (这Nixpkgs 手册曾经用一个例子提到过它,但没有解释。)
1.2 Nix表达
使用以下代码编写的一段代码Nix 表达语言。
1.3 Nix推导表达式
A尼克斯表达这将评估为尼克斯推导(通常通过最终调用derivation
(来源)普里莫普,最常见的是通过mkShell
(来源) 或者mkDerivation
(来源))。
笔记:Nix 推导与 Nix 推导表达式
当我明确区分 Nix 和 Nix 时,我更容易对 Nix 进行推理。尼克斯推导以及计算结果为尼克斯推导(即,Nix 推导表达式)。是否尝试使其更清楚这个答案,但它需要更新,所以要持保留态度。
1.4 普里莫普
原始操作,或普里莫普斯,是语言中内置的函数。它们不需要定义或导入;默认情况下它们在范围内。但由于它们是正常的标识符,因此它们能被本地定义覆盖。
--Eelco Dolstra,纯功能软件部署模型(博士论文)(2006 年 1 月 18 日)
这些实施于NixOS/nix回购。
1.5 Nix推导
(占位符)
1.6 套餐设置
看什么是套装?关于 NixOS 的讨论,但是解释一下ryantm 的回答:
套餐套装是一个集合尼克斯表达s 评估为属性集(也称为“attrset”)其中名称是包的名称(或递归的名称)套装) 的值是尼克斯推导。
例子:
- 尼克斯包装
- Nix 用户存储库 (NUR)
- 以太坊nix
- 来自 nixos.wiki 的替代套餐页:
- 尼克斯帕克斯- 专注于交叉编译
- 海卫一- 看Nixpkgs 和 Triton 之间的区别
- 尼克斯WRT- 基于 nixpkgs 使用 nix 构建路由器镜像
- 来自
awesome-nix-hpc
列表:- 熨斗研究所:https://github.com/flatironinstitute/nix-modules
- 网格化:https://github.com/Gricad/nix-ciment-channel
- 蓝脑计划:https://github.com/BlueBrain/bbp-nixpkgs
- 加拿大计算:https://github.com/ComputeCanada/nixpkgs/tree/computecanada-16.09
- 加拿大计算:https://git.computecanada.ca/nix/ccpkgs
- 数据移动:https://github.com/oar-team/nur-kapack
- 量子化学包:https://github.com/markuskowa/NixOS-QChem
2. 示例
2.1 将 Nixpkg 固定在nix-shell
调用上
压缩常用的 Nix-shell 表达式,
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = [
pkgs.git
pkgs.htop
];
shellHook = ''
echo "git: $(git --version)"
echo "htop: $(htop --version)"
'';
}
变成单行,然后
nix-shell \
-I nixpkgs=https://github.com/NixOS/nixpkgs/archive/39cd40f7bea40116ecb756d46a687bfd0d2e550e.tar.gz \
-E '{ pkgs ? import <nixpkgs> {} }: pkgs.mkShell { buildInputs = [ pkgs.git pkgs.htop ]; shellHook = "echo \"git: $(git --version)\"; echo \"htop: $(htop --version)\";"; }'
不会工作,因为mkShell
尚未实施,因此:
nix-shell \
-I nixpkgs=https://github.com/NixOS/nixpkgs/archive/39cd40f7bea40116ecb756d46a687bfd0d2e550e.tar.gz \
-E '{ pkgs ? import <nixpkgs> {} }: pkgs.stdenv.mkDerivation { name = "shell"; buildInputs = [ pkgs.git pkgs.htop ]; shellHook = "echo \"git: $(git --version)\"; echo \"htop: $(htop --version)\";"; }'
笔记:
两个片段之间的唯一区别是该部分
pkgs.mkShell { buildInputs
已替换为pkgs.stdenv.mkDerivation { name = "shell"; buildInputs
.在 Ubuntu 22.04 上运行这两个命令 (
aarch64
);另外,第二个不会在 上运行aarch64-darwin
。
2.2 在 Nix 表达式中固定 Nixpkg
使用杰夫·海金的评论作为模板:
步骤 0. 找到您想要的版本
使用查找(几乎)包的所有版本lazamar 绝对令人惊叹的在线工具。
第 1 步:使用哈希值安装该版本
单击您需要的版本所在行中的哈希值(例如,git
2.23.0和htop
2.2.0),然后一一使用列出的nix-env
/命令,或者将 Nix 表达式片段复制到文件中(并重命名为变量以避免冲突):nix-shell
# git_htop.nixshell
let
pkgs_for_git = import (builtins.fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/bca9437d1eae9519b61a58f2593f25f65494f8e9.tar.gz";
}) {};
pkgs_for_htop = import (builtins.fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/b5e903cedb331f9ee268ceebffb58069f1dae9fb.tar.gz";
}) {};
# Copied lines above from lazamar's tool,
# but the shortened form works too:
#
# pkgs = import (builtins.fetchTarball "<url>") {};
in
# Chose `pkgs_for_htop` arbitrarily; what matters
# is that the derivation function exists in the
# pinned Nixpkgs.
pkgs_for_htop.mkShell {
buildInputs = [
pkgs_for_htop.htop
pkgs_for_git.git
];
shellHook = ''
echo "git: $(git --version)"
echo "htop: $(htop --version)"
'';
}
然后调用它:
nix-shell -v git_htop.nixshell
2.3 指定带有覆盖层的包(存根)
简单链接nix-config
来自 jwiegley仓库的文件;虽然我还不明白,但还是想把它包括进去。
3. 进一步阅读
围绕这个仍在发展的话题的在线讨论:
github
Nixpkgs 问题 #9682 (关闭): 无法安装/使用特定的软件包版本?2015年开的,虽然现在关了,但问题一直没有得到解决,话题又转到了下一期:
reddit
如何在 Nix 中安装特定版本的软件包?discourse
固定单个包版本的最佳实践discourse
shell.nix
在?中指定包版本
(希望通过更多示例来扩展这一点。)
答案2
您可以导入包含特定软件包版本的散列的 nixpkgs 存档。例如,您可以找到哈希值这里
{ pkgs ? import <nixpkgs> { } }:
let
gitPkgsHash = "0c159930e7534aa803d5cf03b27d5c86ad6050b7"; #git 2.16.2
htopPkgsHash = "5ed9176c52e4ceed2755a19b3e8357a0772de8ff"; #htop 2.0.0
gitPkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/${gitPkgsHash}.tar.gz") { };
htopPkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/${htopPkgsHash}.tar.gz") { };
in
pkgs.mkShell {
buildInputs = [
gitPkgs.gitAndTools.gitFull
htopPkgs.htop
];
}
附言。在此配置中,我使用了较新的版本,因为您的版本非常旧并导致了一些错误