Guile/Scheme 编程教程 / 第2章:安装与环境搭建
第 2 章:安装与环境搭建
2.1 各平台安装方法
2.1.1 Linux 发行版
Linux 是 Guile 最原生的平台,几乎所有发行版都提供官方包。
Debian / Ubuntu
# 安装 Guile 3.0
sudo apt update
sudo apt install guile-3.0
# 验证安装
guile --version
# GNU Guile 3.0.9
# 安装额外的开发库(用于 C 扩展开发)
sudo apt install guile-3.0-dev
# 安装文档
sudo apt install guile-3.0-doc
Fedora / RHEL
# 安装 Guile
sudo dnf install guile30
# 开发库
sudo dnf install guile30-devel
Arch Linux
# 安装 Guile
sudo pacman -S guile
# AUR 中可能有更新的版本
yay -S guile-git
openSUSE
sudo zypper install guile3
2.1.2 macOS
# 使用 Homebrew(推荐)
brew install guile
# 使用 MacPorts
sudo port install guile3
# 验证
guile --version
注意:macOS 上的 Guile 可能需要设置
GUILE_LOAD_PATH环境变量。使用 Homebrew 安装时通常会自动配置。
2.1.3 Windows
Windows 上安装 Guile 相对复杂,推荐以下方案:
方案一:MSYS2(推荐)
# 1. 安装 MSYS2: https://www.msys2.org/
# 2. 在 MSYS2 终端中
pacman -S mingw-w64-x86_64-guile
# 3. 验证
guile --version
方案二:WSL(Windows Subsystem for Linux)
# 在 WSL 中使用 Ubuntu 的包管理器
sudo apt update
sudo apt install guile-3.0
方案三:编译安装
# 需要先安装依赖:libgc, libunistring, libffi
# 下载源码
wget https://ftp.gnu.org/gnu/guile/guile-3.0.9.tar.gz
tar xzf guile-3.0.9.tar.gz
cd guile-3.0.9
# 编译
./configure --prefix=/usr/local
make -j$(nproc)
sudo make install
2.1.4 各平台安装对比
| 平台 | 安装方式 | 难度 | 推荐度 |
|---|---|---|---|
| Debian/Ubuntu | apt | ★☆☆☆☆ | ⭐⭐⭐⭐⭐ |
| Fedora | dnf | ★☆☆☆☆ | ⭐⭐⭐⭐⭐ |
| Arch | pacman | ★☆☆☆☆ | ⭐⭐⭐⭐⭐ |
| macOS (Homebrew) | brew | ★☆☆☆☆ | ⭐⭐⭐⭐ |
| Windows (MSYS2) | pacman | ★★☆☆☆ | ⭐⭐⭐ |
| Windows (WSL) | apt | ★★☆☆☆ | ⭐⭐⭐⭐ |
| 源码编译 | make | ★★★★☆ | ⭐⭐ |
2.2 GNU Guix 系统
GNU Guix 是一个纯函数式的包管理器和操作系统,完全使用 Guile 编写配置。如果你计划长期使用 Guile,强烈推荐了解 Guix。
2.2.1 Guix 包管理器(在任何 Linux 上安装)
# 安装 Guix 包管理器(不影响现有系统)
# 参考: https://guix.gnu.org/manual/en/html_node/Binary-Installation.html
# 1. 下载安装脚本
wget https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh
chmod +x guix-install.sh
# 2. 运行安装
sudo ./guix-install.sh
# 3. 重新加载 profile
source ~/.bashrc
# 4. 安装 Guile
guix install guile
# 5. 安装 Guile 包
guix install guile-srfi-64 ; 测试框架
guix install guile-json ; JSON 支持
guix install guile-lib ; 通用库集合
2.2.2 Guix System(完整操作系统)
Guix System 是一个完整的 GNU/Linux 发行版,系统配置完全用 Guile 编写:
;; /etc/config.scm — Guix 系统配置示例
(use-modules (gnu)
(gnu system)
(gnu system nss)
(gnu packages)
(gnu packages admin)
(gnu packages guile)
(gnu packages version-control))
(operating-system
(host-name "guile-dev")
(timezone "Asia/Shanghai")
(locale "zh_CN.utf8")
;; 引导加载器
(bootloader (bootloader-configuration
(bootloader grub-bootloader)
(targets '("/dev/sda"))
(keyboard-layout (keyboard-layout "cn"))))
;; 文件系统
(file-systems (append
(list (file-system
(device (file-system-label "root"))
(mount-point "/")
(type "ext4")))
%base-file-systems))
;; 用户
(users (cons (user-account
(name "developer")
(comment "Guile Developer")
(group "users")
(supplementary-groups '("wheel" "netdev" "audio" "video")))
%base-user-accounts))
;; 系统级包
(packages (append (list guile-3.0
git
nss-certs)
%base-packages)))
# 应用 Guix 系统配置
sudo guix system reconfigure /etc/config.scm
2.2.3 Guix 开发环境
# 创建项目专属的 Guile 开发环境
# guix.scm 或 manifest.scm
guix shell guile guile-json guile-srfi-64 -- \
guile -c '(display "Guile ready!\n")'
# 或创建 manifest 文件
cat > manifest.scm << 'EOF'
(specifications->manifest
'("guile@3.0"
"guile-json"
"guile-srfi-64"
"guile-lib"))
EOF
guix shell -m manifest.scm
2.3 Emacs 集成
Emacs 是开发 Guile 程序的最佳编辑器,原生支持 Geiser 和多种 Lisp 交互模式。
2.3.1 安装 Geiser
Geiser 是 Emacs 的 Scheme 交互开发环境,提供一流的 Guile 支持。
;; 在 Emacs 配置文件中添加(~/.emacs.d/init.el 或 ~/.emacs)
;; 安装 Geiser(使用 use-package)
(use-package geiser
:ensure t
:config
(setq geiser-active-implementations '(guile))
(setq geiser-guile-binary "guile"))
;; 可选:安装 geiser-guile 包(有些 Emacs 版本需要单独安装)
(use-package geiser-guile
:ensure t)
;; 可选:安装 paredit(结构化编辑,强烈推荐)
(use-package paredit
:ensure t
:hook ((scheme-mode . paredit-mode)
(geiser-repl-mode . paredit-mode)))
2.3.2 Geiser 核心快捷键
| 快捷键 | 功能 | 说明 |
|---|---|---|
C-c C-s | 启动 REPL | 选择 Scheme 实现 |
C-c C-c | 加载当前缓冲区 | 类似 “运行文件” |
C-c C-r | 加载选中区域 | 只执行部分代码 |
C-M-x | 加载当前定义 | 光标所在的顶层定义 |
C-c C-z | 切换到 REPL | 在代码和 REPL 间切换 |
C-c C-d | 查看文档 | 查看当前符号的文档 |
C-c C-a | 添加模块导入 | 自动添加 use-modules |
M-. | 跳转到定义 | 转到函数定义处 |
M-, | 返回 | 从定义处返回 |
C-c C-e | 求值表达式 | 在 minibuffer 中输入表达式 |
2.3.3 Geiser 工作流示例
;; 在 Emacs 中创建 hello.scm
(display "Hello from Geiser!")
(newline)
;; 按 C-c C-c 加载整个文件
;; 或按 C-M-x 加载当前定义
;; 在 REPL 中交互测试
;; 按 C-c C-z 切换到 REPL
;; 直接输入表达式:
(+ 1 2 3) ; => 6
2.3.4 其他编辑器支持
| 编辑器 | 插件 | 支持程度 |
|---|---|---|
| VS Code | vscode-scheme | 基础语法高亮 |
| Vim/Neovim | vim-sexp, conjure | 中等,需配置 |
| Sublime Text | Scheme 语法包 | 基础 |
| DrRacket | 原生支持 | 完整 IDE(Racket 方言) |
| IntelliJ | 插件有限 | 基础 |
2.4 Guile REPL 使用
2.4.1 启动 REPL
# 最简单的启动方式
guile
# 启动并加载文件
guile -l script.scm
# 启动并执行表达式
guile -c '(display "Hello!\n")'
# 从标准输入读取
echo '(+ 1 2)' | guile
# 启动并进入交互模式(即使有 -l 或 -c)
guile -l script.scm --interactive
2.4.2 REPL 基本操作
;; Guile REPL 启动后显示:
;; GNU Guile 3.0.9
;; Copyright (C) 1995-2024 Free Software Foundation, Inc.
;; Guile comes with ABSOLUTELY NO WARRANTY.
;; ...
;; scheme@(guile-user)>
;; 基本算术
scheme@(guile-user)> (+ 1 2 3)
$1 = 6
;; 定义变量
scheme@(guile-user)> (define name "Guile")
scheme@(guile-user)> name
$2 = "Guile"
;; 定义函数
scheme@(guile-user)> (define (square x) (* x x))
scheme@(guile-user)> (square 5)
$3 = 25
;; 查看历史结果
scheme@(guile-user)> ,apropos display
;; 搜索所有包含 "display" 的绑定
;; REPL 命令(以逗号开头)
scheme@(guile-user)> ,help ; 显示帮助
scheme@(guile-user)> ,quit ; 退出 REPL
scheme@(guile-user)> ,use (srfi srfi-1) ; 加载模块
scheme@(guile-user)> ,pp '(1 2 3) ; 美化打印
scheme@(guile-user)> ,trace (factorial 5) ; 追踪调用
2.4.3 REPL 命令参考
| 命令 | 功能 | 示例 |
|---|---|---|
,help | 显示帮助 | ,help |
,quit | 退出 | ,quit |
,use MODULE | 加载模块 | ,use (srfi srfi-1) |
,pp EXPR | 美化打印 | ,pp '((a 1) (b 2)) |
,trace EXPR | 追踪求值 | ,trace (fib 10) |
,time EXPR | 计时 | ,time (fib 30) |
,apropos STR | 搜索符号 | ,apropos "map" |
,bindings | 列出绑定 | ,bindings |
,option | 查看选项 | ,option |
,clear | 清屏 | ,clear |
,backtrace | 显示回溯 | ,backtrace |
2.4.4 REPL 技巧
;; 1. 多行输入 —— 用分号或直接续行
scheme@(guile-user)> (define (long-function x y z)
.... (+ x
.... y
.... z))
;; 2. 使用 #; 注释掉一个表达式
scheme@(guile-user)> (+ 1 #;(+ 2 3) 4)
$1 = 5
;; 3. 使用 ,option 查看和修改选项
scheme@(guile-user)> ,option print-width 80
;; 4. 调试:使用 ,bt 查看回溯
scheme@(guile-user)> (define (buggy n) (/ n 0))
scheme@(guile-user)> (buggy 5)
;; ERROR: In procedure /: Numerical overflow
scheme@(guile-user)> ,bt
;; 显示调用栈
;; 5. 从错误中恢复
scheme@(guile-user)> ,c ; 继续(如果可能)
scheme@(guile-user)> ,r ; 重试
2.5 项目结构约定
2.5.1 推荐的项目布局
my-guile-project/
├── README.md
├── guix.scm # Guix 环境定义(可选)
├── manifest.scm # Guix manifest(可选)
├── Makefile # 构建脚本
├── src/
│ ├── main.scm # 入口文件
│ ├── core.scm # 核心逻辑
│ └── utils.scm # 工具函数
├── tests/
│ ├── test-core.scm # 核心测试
│ └── test-utils.scm # 工具测试
├── doc/
│ └── manual.md # 文档
└── examples/
└── demo.scm # 示例
2.5.2 简单的 Makefile
# Makefile for Guile project
GUILE = guile
GUILE_FLAGS = -L src
# 运行主程序
run:
$(GUILE) $(GUILE_FLAGS) src/main.scm
# 运行测试
test:
$(GUILE) $(GUILE_FLAGS) tests/test-core.scm
# 语法检查
check:
$(GUILE) $(GUILE_FLAGS) -e main -c '(use-modules (src core))'
.PHONY: run test check
2.5.3 脚本文件头约定
#!/usr/bin/env guile
!#
;; -*- mode: scheme; -*-
;; my-script.scm — 脚本说明
;; 模块声明(如果是独立脚本可省略)
(use-modules (ice-9 format)
(srfi srfi-1))
;; 主逻辑
(define (main args)
(format #t "Hello, ~a!~%" (if (null? args) "World" (car args)))
0)
;; 脚本入口
(main (command-line))
2.6 版本管理
2.6.1 并行安装多版本
# 使用 Guix 管理多版本
guix install guile@2.2.7
guix install guile@3.0.9
# 指定版本运行
guix shell guile@3.0.9 -- guile --version
# 查看已安装的版本
guix package -I guile
2.6.2 版本检测脚本
;; check-version.scm — 检查 Guile 版本兼容性
(define (check-guile-version major minor)
"检查当前 Guile 版本是否 >= 指定版本"
(let ((current-major (string->number
(car (string-split (version) #\.))))
(current-minor (string->number
(cadr (string-split (version) #\.)))))
(or (> current-major major)
(and (= current-major major)
(>= current-minor minor)))))
;; 使用示例
(unless (check-guile-version 3 0)
(display "警告: 需要 Guile 3.0 或更高版本\n")
(exit 1))
2.7 第一个完整程序
#!/usr/bin/env guile
!#
;; hello-guile.scm — 一个完整的 Guile 入门程序
(use-modules (ice-9 format)
(srfi srfi-19)) ; 日期时间库
;; 定义问候函数
(define (greet name)
"生成个性化问候语"
(let* ((now (current-date))
(hour (date-hour now))
(time-greeting (cond
((< hour 6) "夜深了")
((< hour 12) "早上好")
((< hour 18) "下午好")
(else "晚上好"))))
(format #f "~a,~a!当前时间是 ~a"
time-greeting
name
(date->string now "~Y-~m-~d ~H:~M:~S"))))
;; 主函数
(define (main args)
(let ((name (if (> (length args) 1)
(cadr args)
"Guile 学习者")))
(display (greet name))
(newline)
(format #t "Guile 版本: ~a~%" (version))
(format #t "运行平台: ~a~%" (utsname:sysname (uname)))
0))
;; 执行
(main (command-line))
# 运行程序
chmod +x hello-guile.scm
./hello-guile.scm "开发者"
# 早上好,开发者!当前时间是 2026-05-10 09:30:15
# Guile 版本: 3.0.9
# 运行平台: Linux
2.8 常见问题排查
2.8.1 安装问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
guile: command not found | 未安装或不在 PATH 中 | 检查安装和 PATH 设置 |
ERROR: no code for module | 模块路径错误 | 检查 GUILE_LOAD_PATH |
libguile-3.0.so: cannot open | 共享库路径缺失 | 设置 LD_LIBRARY_PATH |
Unbound variable: use-modules | 版本太旧(< 2.0) | 升级到 3.0 |
编译时找不到 libgc | 依赖未安装 | 安装 libgc-dev |
2.8.2 环境变量
# GUILE_LOAD_PATH —— 模块搜索路径
export GUILE_LOAD_PATH="/my/modules:$GUILE_LOAD_PATH"
# GUILE_COMPILED_PATH —— 编译后的 .go 文件路径
export GUILE_COMPILED_PATH="/my/compiled:$GUILE_COMPILED_PATH"
# GUILE_AUTO_COMPILE —— 自动编译 (0=关闭, 1=开启)
export GUILE_AUTO_COMPILE=1
# GUILE_WARN_DEPRECATED —— 弃用警告
export GUILE_WARN_DEPRECATED=detailed
2.9 本章小结
| 主题 | 要点 |
|---|---|
| Linux 安装 | 使用包管理器,最简单 |
| macOS | 推荐 Homebrew |
| Windows | 推荐 MSYS2 或 WSL |
| Guix | Guile 生态的核心,推荐学习 |
| Emacs | Geiser 是最佳开发工具 |
| REPL | 交互式开发的核心工具 |
扩展阅读
上一章:第 1 章:Guile 概述 下一章:第 3 章:基本语法