Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

使用nix的一些注意事项

Posted on 2023-03-01

最近我第一次开始使用 Mac。到目前为止我注意到的最大缺点是包管理比 Linux 差得多。有时我对 homebrew 感到沮丧,因为我觉得在安装新包时它花了太多时间升级,所以我想——也许我会试试nix包管理器!

nix 以令人困惑着称(它有自己的编程语言!),所以我一直在尝试找出如何以尽可能简单的方式使用 nix,并且不涉及管理任何配置文件或学习新的编程语言。到目前为止,这就是我的想法!我们将讨论如何:

  1. 使用 nix 安装软件包
  2. 为名为paperjam的 C++ 程序构建自定义 nix 包
  3. 使用 nix 安装 5 年前的hugo版本

像往常一样,我可能在这篇文章中弄错了一些东西,因为我对 nix 还是很陌生。我也仍然不确定我有多喜欢 nix——它非常令人困惑!但它帮助我编译了一些我以前很难编译的软件,而且总的来说,它的安装速度似乎比自制软件快。

nix有什么有趣的地方?

人们经常将 nix 描述为“声明式包管理”。我不太关心声明式包管理,所以这里有两点我很欣赏 nix:

  1. 它提供二进制包(托管在https://cache.nixos.org/ ),您可以快速下载和安装
  2. 对于没有二进制包的包,编译它们更容易

我认为 nix 擅长编译软件的原因是:

  • 您可以同时安装同一个库或程序的多个版本(例如,您可以安装 2 个不同版本的 libc)。例如,我的计算机上现在有两个版本的节点,一个在/nix/store/4ykq0lpvmskdlhrvz1j3kwslgc6c7pnv-nodejs-16.17.1和一个在/nix/store/5y4bd2r99zhdbir95w5pf51bwfg37bwa-nodejs-18.9.1 。
  • 当 nix 构建一个包时,它会单独构建它,仅使用您明确声明的特定版本的依赖项。因此,该包不存在秘密依赖于您系统上您不知道的另一个包的风险。不再与LD_LIBRARY_PATH战斗!

我将在这篇文章的后面给出几个例子,两次 nix 让我更容易编译软件。

我是如何开始使用 nix 的

这是我开始使用 nix 的方式:

  1. 安装尼克斯。我完全忘记了我是怎么做到的,但看起来有一个来自 zero-to-nix.com 的官方安装程序和一个非官方安装程序
  2. 将~/.nix-profile/bin放在我的路径上
  3. 使用nix-env -iA nixpkgs.NAME安装软件包
  4. 就是这样。

基本上这个想法是像对待brew install或apt-get install一样对待nix-env -iA 。

例如,如果我想安装fish ,我可以这样做:

 nix-env -iA nixpkgs.fish

这似乎只是从https://cache.nixos.org下载一些二进制文件——非常简单。

有些人使用 nix 来安装他们的 Node、Python 和 Ruby 包,但我没有这样做——我只是像往常一样使用npm install和pip install 。

我没有使用的一些 nix 功能

有很多我没有使用的 nix 功能/工具,但我会提到。我最初认为您必须使用这些功能才能使用 nix,因为我读过的大多数 nix 教程都在谈论它们。但你不必使用它们。

  • NixOS(Linux 发行版)
  • nix-shell
  • 尼克斯片
  • 家庭经理
  • devenv.sh

我不会深入讨论这些,因为我还没有真正使用过它们,而且那里有很多解释。

nix包在哪里定义的?

我认为主 nix 包存储库中的包在https://github.com/NixOS/nixpkgs/中定义

看起来您可以在https://search.nixos.org/packages上搜索包。我还没有想出如何像使用apt-cache search一样在命令行上搜索包。

一切都安装了符号链接

nix 的主要设计选择之一是,所有包都没有一个单独的bin ,而是使用符号链接。例如,我机器上的~/.nix-profile/bin/fish是/nix/store/afkwn6k8p8g97jiqgx9nd26503s35mgi-fish-3.5.1/bin/fish的符号链接

我认为这意味着如果我安装了新版本的fish但我不喜欢它,我可以通过更新符号链接轻松返回。 Nix 有很多管理这些符号链接的工具,我还没有完全理解它们。

卸载软件包不会删除它们

如果我像这样卸载一个 nix 包,它实际上并没有释放任何硬盘空间,它只是删除了符号链接。

 $ nix-env --uninstall oil

我仍然不确定如何真正删除包——我运行了这样的垃圾收集,它似乎删除了一些东西:

 $ nix-collect-garbage ... 85 store paths deleted, 74.90 MiB freed

但是我的系统上仍然有oil /nix/store/8pjnk6jr54z77jiq5g2dbx8887dnxbda-oil-0.14.0 。

升级

看起来你可以像这样升级 nix 包:

 nix-channel --update nix-env --upgrade

(类似于apt-get update && apt-get upgrade )

我还没有真正升级任何东西。我认为如果升级出现问题,您可以回滚(因为在 nix 中一切都是不可变的!)

 nix-env --rollback

下一个目标:定制paperjam包装

安装现有软件包几个月后,我想使用 nix 为一个名为paperjam的程序制作一个自定义软件包,该程序尚未打包。

实际上,即使没有 nix,我也很难编译paperjam ,因为我系统上的libiconv版本是错误的。我认为用 nix 编译它可能更容易,尽管我还不知道如何制作 nix 包。它实际上是!

但是弄清楚如何到达那里非常令人困惑,所以这里有一些关于我是如何做到的笔记。

如何构建示例包

在开始处理 mG paperjam包之前,我想构建一个现有包示例,以确保我了解构建包的过程。我真的很难弄清楚如何做到这一点,但我在 Discord 中询问,有人向我解释了如何从https://github.com/NixOS/nixpkgs/获取工作包并构建它。所以这是这些说明:

第 1 步:从 github 上的nixpkgs下载一些任意包,例如dash包:

 wget https://raw.githubusercontent.com/NixOS/nixpkgs/47993510dcb7713a29591517cb6ce682cc40f0ca/pkgs/shells/dash/default.nix -O dash.nix

第 2 步:替换第一条语句 ( { lib , stdenv , buildPackages , autoreconfHook , pkg-config , fetchurl , fetchpatch , libedit , runCommand , dash }: with with import <nixpkgs> {};我不知道你为什么要这样做,但它有效。

第 3 步:运行nix-build dash.nix

这编译包

第 4 步:运行nix-env -i -f dash.nix

这会将包安装到我的~/.nix-profile

就这样!一旦我这样做了,我觉得我可以修改dash包并制作我自己的包。

我是如何制作自己的包裹的

paperjam有一个依赖项 ( libpaper ) 也没有打包,所以我需要先构建libpaper 。

这是libpaper.nix 。我基本上只是通过从ni​​xpkgs存储库中的其他包复制和粘贴来编写这个。我的猜测是这里发生的事情是 nix 有一些默认的编译 C 包的规则(比如“运行make install ”),所以make install是默认发生的,我不需要明确地配置它。

 with import <nixpkgs> {}; stdenv.mkDerivation rec { pname = "libpaper"; version = "0.1"; src = fetchFromGitHub { owner = "naota"; repo = "libpaper"; rev = "51ca11ec543f2828672d15e4e77b92619b497ccd"; hash = "sha256-S1pzVQ/ceNsx0vGmzdDWw2TjPVLiRgzR4edFblWsekY="; }; buildInputs = [ ]; meta = with lib; { homepage = "https://github.com/naota/libpaper"; description = "libpaper"; platforms = platforms.unix; license = with licenses; [ bsd3 gpl2 ]; }; }

基本上这只是告诉 nix 如何从 GitHub 下载源代码。

我通过运行nix-build libpaper.nix构建了它

接下来,我需要编译paperjam 。这是我写的 nix 包的链接。除了告诉它在哪里下载源代码之外,我需要做的主要事情是:

  1. 添加一些额外的构建依赖项(如asciidoc )
  2. 为安装设置一些环境变量 ( installFlags = [ "PREFIX=$(out)" ]; ) 以便它安装在正确的目录中而不是/usr/local/bin中。

我想出了如何通过在 nixpkgs 存储库中运行rg PREFIX来设置installFlags我认为需要设置PREFIX是很常见的,之前可能有人做过,我是对的。所以我只是从另一个包中复制并粘贴了该行。

然后我跑了:

 nix-build paperjam.nix nix-env -i -f paperjam.nix

然后一切正常,我安装了paperjam !万岁!

下一个目标:安装 5 年前的hugo版本

现在我使用 Hugo 0.40 构建这个博客,从 2018 年开始。我不需要任何新功能,所以我觉得不需要升级。在 Linux 上这很简单:Hugo 的发布是一个静态二进制文件,所以我可以从发布页面下载 5 年前的二进制文件并运行它。简单的!

但是在这台 Mac 上我遇到了一些问题。 Mac 硬件在过去 5 年发生了变化,所以我下载的 Mac Hugo 二进制文件崩溃了。当我尝试使用go build从源代码构建它时,这也不起作用,因为 Go 构建规范在过去 5 年中也发生了变化。

我通过在 Linux docker 容器中运行 Hugo 来解决这个问题,但我不喜欢这样:它有点慢而且感觉很傻。编译一个 Go 程序应该不难!

尼克斯来救援!这是我用 nix 安装旧版本的 hugo 所做的。

使用 nix 安装 hugo 0.40

我想安装 hugo 0.40 并将其作为hugo-0.40放入我的 PATH 中。我是这样做的。我以一种奇怪的方式做到了这一点( Searching and installing old versions of Nix packages描述了一种可能更正常的方法),但它奏效了。

第 1 步:搜索 nixpkgs 存储库以找到 Hugo 0.40

我在这里找到了.nix文件https://github.com/NixOS/nixpkgs/blob/17b2ef2/pkgs/applications/misc/hugo/default.nix

第 2 步:下载该文件并构建它

我下载了那个文件(以及同一目录中另一个名为deps.nix的文件),将第一行替换为with import <nixpkgs> {}; ,并使用nix-build hugo.nix构建它。

这几乎无需任何更改即可工作,但我必须进行两项更改:

  • 出于某种原因with stdenv.lib替换为with lib 。
  • 将包重命名为hugo040这样它就不会与我安装的其他版本的hugo冲突

第 3 步:将hugo重命名为hugo-0.40

我写了一个小的安装后脚本来重命名 hugo 二进制文件。

 postInstall = '' mv $out/bin/hugo $out/bin/hugo-0.40 '';

我想出了如何通过在 nixpkgs 存储库中运行rg 'mv '并复制和修改看起来相关的内容来运行它。

第 4 步:安装它

我通过运行nix-env -i -f hugo.nix安装到我的~/.nix-profile/bin中。

这一切都有效!我将最终的.nix文件放入我自己的个人nixpkgs 存储库中,以便以后可以根据需要再次使用它。

可复制的构建并不神奇

我认为这里值得注意的是这个hugo.nix文件并不神奇——我今天可以轻松安装 Hugo 的原因是 5 年前有人致力于以可重现的方式打包那个版本的 Hugo。

就这样!

安装paperjam和这个已有 5 年历史的 Hugo 版本出奇地轻松,实际上比没有 nix 的情况下编译它要容易得多,因为 nix 使我更容易使用正确版本的libiconv编译paperjam包,而且因为有人 5几年前就已经麻烦地列出了 Hugo 的确切依赖项。

我没有任何计划让 nix 变得更复杂(而且我仍然很可能会对它感到沮丧并回到自制软件!),但我们会看到会发生什么!我发现以简单的方式开始,然后在我觉得需要时开始使用更多功能,而不是一下子采用一大堆复杂的东西要容易得多。

我可能不会在 Linux 上使用 nix——我一直对apt (在基于 Debian 的发行版上)和pacman (在基于 Arch 的发行版上)很满意,而且它们不会那么令人困惑。但在 Mac 上,这似乎是值得的。我们拭目以待!

原文: https://jvns.ca/blog/2023/02/28/some-notes-on-using-nix/

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Bits about Money
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • Elad Gil
  • Ellie Huxtable
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • Henrique Dias
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mostly metrics
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme