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

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 Guix Nix
实现语言 Guile (Scheme) C++ + Nix 表达式语言
配置语言 Scheme(同一种语言) Nix 专用 DSL
包定义风格 纯 Scheme S-expression Nix 函数式 DSL
系统配置 Guix System(声明式) NixOS(声明式)
用户环境 Guix Home(原生支持) Home Manager(社区项目)
GNU 项目
自由软件 严格遵循 GNU FSDG 包含非自由软件选项
容器支持 guix container(原生) nix-container
通道/Flakes Channels(通道) 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 的历史与发展

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

1.7 核心概念速查表

概念 英文 说明
Store /gnu/store 存放所有包的只读目录
Profile Profile 用户环境,由符号链接组成
Channel Channel 包集合的来源仓库
Manifest Manifest 声明式包列表
Derivation Derivation 包的构建描述(构建计划)
Garbage Collection GC 清理不再被引用的 store 对象
Rollback Rollback 将 profile 回退到上一状态
Generation Generation profile 的历史版本
Shepherd Shepherd Guix 使用的 init 系统(PID 1)
Guile GNU Guile Guix 使用的 Scheme 实现

1.8 总结

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

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

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


扩展阅读