强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

GNU Guix 函数式包管理教程 / 第一章 Guix 概述

第一章:Guix 概述

1.1 什么是 GNU Guix?

GNU Guix(发音同 “geeks”)是一个由 GNU 项目维护的函数式包管理器(Functional Package Manager)。它不仅仅是一个包管理工具,更是一个完整的操作系统框架——Guix System(也称 GuixSD,即 Guix System Distribution)。

Guix 的核心理念来源于函数式编程(Functional Programming):将软件包视为纯函数(Pure Function)的输出。给定相同的输入(源码、依赖、构建脚本),Guix 保证产出完全相同的二进制结果。

输入(源码 + 依赖 + 构建脚本)──► 构建过程 ──► 输出(二进制包,固定路径)

Guix 的核心组成

组成部分说明
GNU Guix包管理器本身,基于 GNU Guile(Scheme 方言)实现
Guix System完整的 GNU/Linux 发行版,系统配置完全声明式
Guix Home用户级环境管理器,声明式管理 dotfiles 和用户服务
Guix Channels通道机制,用于分发和扩展包集合

1.2 函数式包管理

1.2.1 传统包管理的困境

传统包管理器(如 APT、DNF、Pacman)采用**命令式(Imperative)**方式管理软件包:

# 传统方式:逐步操作,状态累积
sudo apt install vim          # 安装
sudo apt upgrade              # 升级(覆盖旧版本)
sudo apt remove vim           # 删除(可能留下残留配置)

传统模式存在以下问题:

问题描述
依赖地狱(Dependency Hell)多个包要求同一依赖的不同版本
不可逆升级升级后难以精确回退到之前的状态
环境污染全局安装的包互相影响
不可重现无法保证两台机器得到相同的环境

1.2.2 函数式包管理的解决方案

Guix 借鉴了 Nix 包管理器的思想,将函数式编程的核心原则应用于包管理:

原则一:不可变性(Immutability)

所有包安装到一个名为 store/gnu/store)的只读目录中。每个包的路径包含其哈希值:

/gnu/store/abc123...-vim-9.0.1
/gnu/store/def456...-vim-9.0.2

两个不同版本的 Vim 可以和平共存,因为它们的路径完全不同。

原则二:声明式配置(Declarative Configuration)

系统状态由配置文件描述,而非逐步操作:

;; 系统配置声明:安装了什么、服务怎么运行、用户如何配置
(operating-system
  (packages (list vim git python))
  (services (list (service openssh-service-type))))

原则三:可重现性(Reproducibility)

同一份配置在任何机器上都会产生相同的结果,因为构建过程被严格沙箱化,排除了一切外部变量。

1.2.3 Guix Store 的工作原理

用户环境(~/.guix-profile)
    │
    ├── /gnu/store/abc...-bash-5.1/bin/bash
    ├── /gnu/store/def...-coreutils-9.1/bin/ls
    └── /gnu/store/ghi...-vim-9.0/bin/vim
         │
         ├── /gnu/store/jkl...-glibc-2.35/lib/libc.so
         └── /gnu/store/mno...-ncurses-6.3/lib/libncurses.so

用户环境中的每个条目都是指向 /gnu/store 中不可变对象的符号链接(Symlink)。升级或回滚只需更改符号链接的指向,旧版本依然保留在 store 中。


1.3 Guix 与 Nix 的对比

Guix 和 Nix 是目前最知名的两个函数式包管理器。Guix 最初受 Nix 启发,但后来走出了独特的发展道路。

1.3.1 核心差异

特性GNU GuixNix
实现语言Guile (Scheme)C++ + Nix 表达式语言
配置语言Scheme(同一种语言)Nix 专用 DSL
包定义风格纯 Scheme S-expressionNix 函数式 DSL
系统配置Guix System(声明式)NixOS(声明式)
用户环境Guix Home(原生支持)Home Manager(社区项目)
GNU 项目
自由软件严格遵循 GNU FSDG包含非自由软件选项
容器支持guix container(原生)nix-container
通道/FlakesChannels(通道)Flakes
社区规模较小但活跃较大,生态更丰富

1.3.2 语法对比

Nix 定义一个包:

{ stdenv, fetchurl, perl }:
stdenv.mkDerivation {
  pname = "hello";
  version = "2.12";
  src = fetchurl {
    url = "mirror://gnu/hello/hello-2.12.tar.gz";
    sha256 = "0ssi1wpaf7plaswqqjwigppsg5f漖qyvr2as4wd1g";
  };
  buildInputs = [ perl ];
}

Guix 定义同一个包:

(define-public hello
  (package
    (name "hello")
    (version "2.12")
    (source (origin
              (method url-fetch)
              (uri (string-append "mirror://gnu/hello/hello-"
                                  version ".tar.gz"))
              (sha256
               (base32 "0ssi1wpaf7plaswqqjwigppsg5f漖qyvr2as4wd1g"))))
    (build-system gnu-build-system)
    (inputs (list perl))
    (home-page "https://www.gnu.org/software/hello/")
    (synopsis "Hello, GNU world")
    (description "GNU Hello prints a greeting.")
    (license license:gpl3+)))

1.3.3 如何选择?

场景推荐
追求纯自由软件生态Guix
已有 Lisp/Scheme 经验Guix
需要更大的包集合和社区Nix
希望统一配置语言(包定义 = 系统配置)Guix
企业生产环境,需要非自由软件Nix

💡 提示:两者可以共存于同一台机器上,但建议初次接触时选择其一深入学习。


1.4 GNU 项目与 Guix

Guix 是 GNU 项目(GNU Project)的一部分,这意味着它严格遵循 GNU 自由系统发行指南(FSDG)。

1.4.1 这意味着什么?

特性说明
仅包含自由软件不包含非自由固件(firmware)、非自由驱动、非自由内核
Linux-libre 内核使用去除所有非自由 blob 的 Linux-libre 内核
无专有软件仓库不像 Ubuntu 有 non-free 仓库
社区驱动由 GNU 社区志愿者维护

⚠️ 注意:由于使用 Linux-libre 内核,某些需要专有固件的硬件(如部分 Wi-Fi 网卡、NVIDIA 显卡)可能无法正常工作。在安装前请确认硬件兼容性。

1.4.2 Guile 的角色

Guix 使用 GNU Guile(“GNU Ubiquitous Intelligent Language for Extensions”)作为实现语言和配置语言。选择 Guile 的原因:

  • 同像性(Homoiconicity):代码即数据,配置文件本身就是可执行的 Scheme 程序
  • 宏系统(Macro System):强大的元编程能力,包定义可以被灵活扩展
  • GNU 生态:与 GNU 项目深度集成

1.5 适用场景

1.5.1 Guix 擅长的场景

场景一:开发环境管理

# 为不同项目创建隔离的开发环境
guix shell --pure python python-numpy python-pandas -- python

# 项目 A:Python 3.11 + 旧版库
guix shell --manifest=project-a.scm

# 项目 B:Python 3.12 + 新版库
guix shell --manifest=project-b.scm

场景二:科学计算与可重现研究

研究人员需要确保实验环境完全可重现:

;; research-env.scm — 科学计算环境清单
(specifications->manifest
  '("python"
    "python-numpy"
    "python-scipy"
    "python-matplotlib"
    "jupyter"))

场景三:服务器部署

;; 服务器系统配置
(operating-system
  (host-name "prod-server")
  (packages (list nginx postgresql redis))
  (services
    (append
      (list (service nginx-service-type
              (nginx-configuration ...)))
      %base-services)))

场景四:系统配置版本控制

整个操作系统配置存储在 Git 仓库中,实现:

  • 配置变更可追踪(Audit Trail)
  • 配置可回滚到任意历史版本
  • 多台机器共享同一份配置

1.5.2 Guix 可能不太适合的场景

场景原因
需要非自由软件(如 NVIDIA 驱动)Guix 严格限制非自由软件
硬件兼容性要求高Linux-libre 内核可能缺少固件支持
团队成员不熟悉 Scheme学习曲线较陡
追求最快的软件更新速度Guix 官方仓库更新可能较慢

💡 提示:如果你的硬件需要非自由固件,可以在安装阶段使用 nonguix 通道安装非自由内核。


1.6 Guix 的历史与发展

时间事件
2012Ludovic Courtès 启动 Guix 项目
2013Guix 成为 GNU 官方项目
2015Guix System Distribution(GuixSD)首次发布
2019GuixSD 更名为 Guix System
2020Guix Home 用户环境管理功能加入
2021通道(Channels)机制成熟,支持版本锁定
2022持续改进容器支持和可重现构建
2023-2024包集合快速增长,社区稳步发展

1.7 核心概念速查表

概念英文说明
Store/gnu/store存放所有包的只读目录
ProfileProfile用户环境,由符号链接组成
ChannelChannel包集合的来源仓库
ManifestManifest声明式包列表
DerivationDerivation包的构建描述(构建计划)
Garbage CollectionGC清理不再被引用的 store 对象
RollbackRollback将 profile 回退到上一状态
GenerationGenerationprofile 的历史版本
ShepherdShepherdGuix 使用的 init 系统(PID 1)
GuileGNU GuileGuix 使用的 Scheme 实现

1.8 总结

本章介绍了 Guix 的核心理念和设计哲学:

  1. 函数式包管理——将包视为纯函数输出,保证可重现性
  2. 不可变 Store——所有包存放在 /gnu/store,通过哈希标识版本
  3. 声明式配置——系统和用户环境由配置文件完全描述
  4. GNU 生态——严格遵循自由软件原则,基于 Guile 实现

下一章我们将动手安装 Guix,开始实际操作。


扩展阅读