强曰为道

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

02 - 环境搭建与工具链

第 2 章:环境搭建与工具链

工欲善其事,必先利其器。本章将带你从零搭建 Vala 开发环境。


2.1 安装 Vala 编译器

Vala 的编译器叫做 valac。它将 .vala 源代码编译为 C 代码,再调用系统的 C 编译器(gcc 或 clang)生成可执行文件。

2.1.1 各发行版安装方法

发行版安装命令包名
Ubuntu / Debiansudo apt install valacvalac
Fedorasudo dnf install valavala
Arch Linuxsudo pacman -S valavala
openSUSEsudo zypper install valavala
Void Linuxsudo xbps-install -S valavala
Alpinesudo apk add valavala
macOS (Homebrew)brew install valavala

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
MesonMeson 构建系统支持
# 安装 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?

特性MesonAutotoolsCMake
配置速度⚡ 极快🐢 慢🚶 中等
语法Python-likeM4 宏自有语法
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 注意事项

⚠️ 常见问题排查

  1. Package XXX not found

    解决:安装对应的 -dev 包
    sudo apt install libgtk-4-dev
    
  2. valac: error: Package XXX not found

    解决:检查 pkg-config 能否找到该包
    pkg-config --modversion gtk4
    
  3. vala: symbol not found

    解决:缺少 VAPI 文件,检查 --pkg 参数
    
  4. Meson 找不到 Vala 支持

    解决:确保 meson >= 0.62,且安装了 valac
    
  5. GNOME Builder 无法识别项目

    解决:确保项目根目录有 meson.build 文件
    

2.11 扩展阅读

资源链接
valac 手册页man valac
Meson 官方文档https://mesonbuild.com/
Meson Vala 参考https://mesonbuild.com/Vala.html
GNOME Builderhttps://apps.gnome.org/Builder/
VAPI 文档https://wiki.gnome.org/Projects/Vala/VAPI
vala-language-serverhttps://github.com/nickvdp/vala-language-server
Meson Best Practiceshttps://mesonbuild.com/FAQ.html

2.12 总结

要点说明
编译器valac
构建系统Meson(GNOME 标准)
推荐 IDEGNOME Builder
VAPI 文件C 库的 Vala 绑定描述
编译流程.vala.c → 可执行文件

现在你已经有了可运行的环境,下一章我们将学习 Vala 的基本语法。→ 第 3 章:基本语法