02 - 环境搭建与工具链
第 2 章:环境搭建与工具链
工欲善其事,必先利其器。本章将带你从零搭建 Vala 开发环境。
2.1 安装 Vala 编译器
Vala 的编译器叫做 valac。它将 .vala 源代码编译为 C 代码,再调用系统的 C 编译器(gcc 或 clang)生成可执行文件。
2.1.1 各发行版安装方法
| 发行版 | 安装命令 | 包名 |
|---|---|---|
| Ubuntu / Debian | sudo apt install valac | valac |
| Fedora | sudo dnf install vala | vala |
| Arch Linux | sudo pacman -S vala | vala |
| openSUSE | sudo zypper install vala | vala |
| Void Linux | sudo xbps-install -S vala | vala |
| Alpine | sudo apk add vala | vala |
| macOS (Homebrew) | brew install vala | vala |
2.1.2 安装开发依赖
仅安装 valac 是不够的,你还需要 GObject 和 GTK 的开发文件:
# Ubuntu / Debian
sudo apt install \
valac \
libglib2.0-dev \
libgtk-4-dev \
libadwaita-1-dev \
meson \
ninja-build \
pkg-config
# Fedora
sudo dnf install \
vala \
glib2-devel \
gtk4-devel \
libadwaita-devel \
meson \
ninja-build \
pkgconfig
# Arch Linux
sudo pacman -S \
vala \
glib2 \
gtk4 \
libadwaita \
meson \
ninja \
pkgconf
2.1.3 验证安装
# 检查 valac 版本
valac --version
# 输出示例:Vala 0.56.17
# 检查 pkg-config 是否能找到 GTK4
pkg-config --modversion gtk4
# 输出示例:4.14.5
# 检查 Meson 版本
meson --version
# 输出示例:1.4.0
2.2 编译选项详解
2.2.1 基本编译
# 最简单的编译
valac hello.vala -o hello
# 编译多个文件
valac main.vala utils.vala -o myapp
2.2.2 常用编译选项
| 选项 | 说明 | 示例 |
|---|---|---|
-o FILE | 指定输出文件名 | valac hello.vala -o hello |
--pkg PKG | 链接 VAPI 包 | --pkg gtk4 |
--vapidir DIR | 添加 VAPI 搜索路径 | --vapidir ./vapi |
-g | 生成调试信息 | -g |
--save-temps | 保留中间 C 文件 | 用于调试编译结果 |
--thread | 启用多线程支持 | 自动链接 pthread |
--enable-experimental | 启用实验性特性 | 泛型等 |
-D DEFINE | 定义条件编译符号 | -D DEBUG |
-X FLAG | 传递选项给 C 编译器 | -X -O2 |
--target-glib VER | 指定目标 GLib 版本 | --target-glib 2.74 |
--ccode | 只生成 C 代码,不编译 | 用于检查生成代码 |
--library NAME | 编译为共享库 | --library mylib |
--gir NAME | 生成 GIR 文件 | --gir MyLib-1.0.gir |
--fast-vapi | 快速生成 VAPI(无实现) | 用于依赖检查 |
-C / --ccode | 仅生成 C 源代码 | 不调用 gcc |
2.2.3 编译 GTK 应用
# 编译 GTK 4 应用
valac \
--pkg gtk4 \
--pkg libadwaita \
-o myapp \
main.vala
# 编译为共享库
valac \
--library mylib \
--gir MyLib-1.0.gir \
--pkg glib-2.0 \
mylib.vala
2.2.4 调试编译过程
# 保留生成的 C 代码(调试利器)
valac --save-temps hello.vala -o hello
# 会生成 hello.c 等文件
# 只生成 C 代码
valac --ccode hello.vala
# 查看 hello.c 了解 Vala 的编译原理
💡 查看生成的 C 代码 是理解 Vala 工作原理的最佳方式。你会看到 Vala 如何将简洁的类定义展开为完整的 GObject 样板代码。
2.3 第一个编译实例
让我们从最简单的程序开始:
2.3.1 Hello World
// hello.vala
void main () {
print ("Hello, World!\n");
}
# 编译
valac hello.vala -o hello
# 运行
./hello
# 输出:Hello, World!
2.3.2 使用 GLib 功能
// glib_hello.vala
void main () {
// 获取 GLib 版本
print ("GLib 版本: %d.%d.%d\n",
GLib.Version.MAJOR,
GLib.Version.MINOR,
GLib.Version.MICRO);
// 获取当前时间
var now = new GLib.DateTime.now_local ();
print ("当前时间: %s\n", now.format ("%Y-%m-%d %H:%M:%S"));
// 使用 GLib 的命令行参数解析
print ("程序名: %s\n", GLib.Environment.get_prgname ());
print ("用户目录: %s\n", GLib.Environment.get_home_dir ());
print ("临时目录: %s\n", GLib.Environment.get_tmp_dir ());
}
valac glib_hello.vala -o glib_hello --pkg glib-2.0
./glib_hello
2.4 IDE 支持
2.4.1 GNOME Builder(推荐)
GNOME Builder 是 GNOME 官方推荐的 IDE,对 Vala 有原生支持:
# 安装 GNOME Builder
sudo apt install gnome-builder # Ubuntu
sudo dnf install gnome-builder # Fedora
sudo pacman -S gnome-builder # Arch
GNOME Builder 特性:
- ✅ Vala 语法高亮和自动补全
- ✅ 集成 Meson 构建
- ✅ 一键运行和调试
- ✅ Flatpak 打包支持
- ✅ Git 集成
- ✅ 代码模板
2.4.2 Visual Studio Code
安装以下扩展:
| 扩展名 | 说明 |
|---|---|
| Vala | 语法高亮 |
| Vala Language Server | 代码补全(基于 vala-language-server) |
| Meson | Meson 构建系统支持 |
# 安装 Vala 语言服务器
# 从源码构建:
git clone https://github.com/nickvdp/vala-language-server.git
cd vala-language-server
meson setup build
ninja -C build
sudo ninja -C build install
VS Code settings.json 配置:
{
"mesonbuild.buildFolder": "build",
"vala.languageServer.path": "vala-language-server"
}
2.4.3 其他 IDE / 编辑器
| 编辑器 | 支持方式 |
|---|---|
| GNOME Builder | 原生支持(最佳体验) |
| VS Code | 通过扩展 |
| Vim / Neovim | 通过 vala.vim 插件 + LSP |
| Emacs | 通过 vala-mode |
| Sublime Text | 通过语法包 |
| Geany | 内置支持 |
2.4.4 Vim / Neovim 配置
" ~/.vimrc 或 init.vim
" 安装 vala.vim 语法文件
Plug 'nickvdp/vim-vala'
" 如果使用 Neovim + LSP
Plug 'neovim/nvim-lspconfig'
" 配置 vala-language-server
lua << EOF
require'lspconfig'.vala_ls.setup{}
EOF
2.5 项目结构
2.5.1 简单项目结构
my-vala-project/
├── src/
│ ├── main.vala # 程序入口
│ ├── app.vala # 应用逻辑
│ └── utils.vala # 工具函数
├── data/
│ ├── app.desktop # 桌面文件
│ ├── app.svg # 图标
│ └── app.appdata.xml # 应用元数据
├── po/
│ └── POTFILES # 国际化文件列表
├── meson.build # 构建配置
└── README.md
2.5.2 GNOME 应用标准结构
my-gnome-app/
├── src/
│ ├── main.vala
│ ├── application.vala
│ ├── window.vala
│ └── window.ui # GTK Builder UI 文件
├── data/
│ ├── icons/
│ │ └── hicolor/
│ │ └── scalable/
│ │ └── apps/
│ │ └── com.example.MyApp.svg
│ ├── com.example.MyApp.desktop.in.in
│ ├── com.example.MyApp.appdata.xml.in
│ ├── com.example.MyApp.gschema.xml
│ └── meson.build
├── po/
│ ├── POTFILES
│ ├── LINGUAS
│ └── zh_CN.po
├── tests/
│ ├── test_utils.vala
│ └── meson.build
├── meson.build
├── meson_options.txt
├── LICENSE
└── README.md
2.6 Meson 构建系统
2.6.1 为什么用 Meson?
| 特性 | Meson | Autotools | CMake |
|---|---|---|---|
| 配置速度 | ⚡ 极快 | 🐢 慢 | 🚶 中等 |
| 语法 | Python-like | M4 宏 | 自有语法 |
| Vala 支持 | 原生 | 有限 | 需要额外模块 |
| GNOME 生态 | 标准构建系统 | 旧标准 | 非主流 |
| 学习曲线 | 低 | 高 | 中 |
2.6.2 基本 meson.build
# meson.build —— 最简单的 Vala 项目
project('hello', 'vala', 'c',
version: '0.1.0',
meson_version: '>= 0.62.0'
)
# 依赖项
glib_dep = dependency('glib-2.0')
gobject_dep = dependency('gobject-2.0')
# 可执行文件
executable('hello',
'src/main.vala',
dependencies: [glib_dep, gobject_dep],
install: true
)
2.6.3 GTK 4 应用的 meson.build
# meson.build —— GTK 4 应用
project('myapp', 'vala', 'c',
version: '1.0.0',
meson_version: '>= 0.62.0'
)
# 依赖项
gtk4_dep = dependency('gtk4', version: '>= 4.10.0')
libadwaita_dep = dependency('libadwaita-1', version: '>= 1.4.0')
# 源文件
sources = files(
'src/main.vala',
'src/application.vala',
'src/window.vala',
)
# 编译资源
resources = gnome.compile_resources(
'resources',
'data/resources.gresource.xml',
source_dir: 'data'
)
# 可执行文件
executable('myapp',
sources,
resources,
dependencies: [gtk4_dep, libadwaita_dep],
install: true
)
# 子目录
subdir('data')
subdir('po')
2.6.4 编译共享库
# 编译共享库
mylib_sources = files(
'lib/utils.vala',
'lib/config.vala',
)
mylib = shared_library('mylib',
mylib_sources,
dependencies: [glib_dep, gobject_dep],
install: true,
vala_header: 'mylib.h',
vala_vapi: 'mylib-1.0.vapi',
version: '1.0.0',
)
# 导出依赖,供其他项目使用
mylib_dep = declare_dependency(
link_with: mylib,
include_directories: include_directories('.')
)
2.6.5 Meson 构建流程
# 1. 配置构建目录
meson setup build
# 2. 编译
ninja -C build
# 3. 运行(测试)
./build/src/myapp
# 4. 安装(可选)
sudo ninja -C build install
# 5. 重新配置(修改选项后)
meson setup build --reconfigure -Doption=value
# 6. 清理重建
rm -rf build && meson setup build
2.6.6 常用 Meson 命令
| 命令 | 说明 |
|---|---|
meson setup build | 创建构建目录并配置 |
ninja -C build | 编译项目 |
ninja -C build test | 运行测试 |
ninja -C build install | 安装到系统 |
meson configure build | 查看当前配置 |
meson setup build -Dprefix=/opt | 自定义安装路径 |
meson setup build --buildtype=debug | 调试模式构建 |
meson setup build --buildtype=release | 发布模式构建 |
2.7 使用 valac 直接编译(无构建系统)
对于学习和快速原型开发,可以直接用 valac 编译:
2.7.1 单文件编译
valac hello.vala -o hello
2.7.2 多文件编译
valac src/main.vala src/app.vala src/utils.vala -o myapp
2.7.3 使用 Makefile
如果不想用 Meson 但需要自动化,可以用简单的 Makefile:
# Makefile
VALAC = valac
PKG = --pkg gtk4 --pkg libadwaita
SOURCES = src/main.vala src/application.vala src/window.vala
OUTPUT = myapp
all: $(OUTPUT)
$(OUTPUT): $(SOURCES)
$(VALAC) $(PKG) $(SOURCES) -o $(OUTPUT)
clean:
rm -f $(OUTPUT)
run: $(OUTPUT)
./$(OUTPUT)
.PHONY: all clean run
make # 编译
make run # 编译并运行
make clean # 清理
2.8 VAPI 文件
2.8.1 VAPI 是什么?
VAPI(Vala API)文件是 Vala 的接口描述文件。它告诉 valac 如何调用 C 库函数:
// mylib.vapi —— 一个简单的 VAPI 文件示例
[CCode (cheader_filename = "mylib.h")]
namespace MyLib {
[CCode (cname = "mylib_greet")]
public void greet (string name);
[CCode (cname = "MyLibConfig")]
public struct Config {
public string name;
public int version;
}
}
2.8.2 VAPI 查找路径
# 系统 VAPI 目录
ls /usr/share/vala/vapi/
# 或
ls /usr/share/vala-0.56/vapi/
# 查看某个包的 VAPI
cat /usr/share/vala/vapi/gtk4.vapi | head -50
2.8.3 生成 VAPI
# 从头文件生成 VAPI(使用 vapigen)
vapigen --library mylib mylib.h mylib-1.0.gir
# 或从 GIR 文件
vapigen --pkg glib-2.0 MyLib-1.0.gir
2.9 条件编译
2.9.1 使用 #if 预处理指令
void main () {
#if DEBUG
print ("调试模式已启用\n");
#endif
#if VALA_0_56
print ("使用 Vala 0.56+ 特性\n");
#endif
// 版本比较
#if GLIB_2_74
print ("GLib 2.74+ 功能可用\n");
#else
print ("GLib 版本较低\n");
#endif
}
# 编译时定义符号
valac -D DEBUG hello.vala -o hello
2.10 注意事项
⚠️ 常见问题排查
Package XXX not found解决:安装对应的 -dev 包 sudo apt install libgtk-4-devvalac: error: Package XXX not found解决:检查 pkg-config 能否找到该包 pkg-config --modversion gtk4vala: symbol not found解决:缺少 VAPI 文件,检查 --pkg 参数Meson 找不到 Vala 支持
解决:确保 meson >= 0.62,且安装了 valacGNOME Builder 无法识别项目
解决:确保项目根目录有 meson.build 文件
2.11 扩展阅读
| 资源 | 链接 |
|---|---|
| valac 手册页 | man valac |
| Meson 官方文档 | https://mesonbuild.com/ |
| Meson Vala 参考 | https://mesonbuild.com/Vala.html |
| GNOME Builder | https://apps.gnome.org/Builder/ |
| VAPI 文档 | https://wiki.gnome.org/Projects/Vala/VAPI |
| vala-language-server | https://github.com/nickvdp/vala-language-server |
| Meson Best Practices | https://mesonbuild.com/FAQ.html |
2.12 总结
| 要点 | 说明 |
|---|---|
| 编译器 | valac |
| 构建系统 | Meson(GNOME 标准) |
| 推荐 IDE | GNOME Builder |
| VAPI 文件 | C 库的 Vala 绑定描述 |
| 编译流程 | .vala → .c → 可执行文件 |
现在你已经有了可运行的环境,下一章我们将学习 Vala 的基本语法。→ 第 3 章:基本语法