多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Meson 教程:从零构建 C 项目到集成 GTK+ 图形界面依赖

Meson 教程:从零构建 C 项目到集成 GTK+ 图形界面依赖 构建工具【免费下载链接】mesonThe Meson Build System项目地址https://gitcode.com/gh_mirrors/me/meson点击查看免费下载本教程以 Meson 官方 Tutorial.md 为主体完整演示从零创建第一个 Meson 构建定义、用 Ninja 后端编译可执行程序、再到通过dependency()函数接入 GTK 图形库的完整链路。读完本文你将掌握meson setup/meson compile的核心工作流、源码目录与构建目录分离的设计原则以及 Meson 如何自动检测构建定义变更并触发自身重新生成从而在日常开发中做到只敲一条编译命令。环境准备安装 GTK 开发库本教程以 Linux 为主要运行环境并假设系统上已经具备 GTK 开发库。在 Debian 系发行版如 Ubuntu上可以用下面的命令安装sudo apt install libgtk-3-dev此外建议安装 2.74 或更高版本的 glib 库教程中的示例代码会通过GLIB_CHECK_VERSION(2, 74, 0)宏对不同版本的 GTK 应用创建接口做兼容处理。GUI 应用也可以在 Windows、macOS 等平台构建但需要自行安装对应的依赖。需要强调的是安装 GTK 只是为了让教程第二部分的图形窗口示例能运行教程第一部分Hello World不依赖任何第三方库是纯 C 编译流程的最小演示。第一步最基础的 Hello World编写源代码main.c先创建一个保存源码的文件main.c内容如下#include stdio.h // // main is where all program execution starts // int main(int argc, char **argv) { printf(Hello there.\n); return 0; }编写构建描述meson.build在同一个目录下创建 Meson 构建描述文件meson.build内容只有两行project(tutorial, c) executable(demo, main.c)project(tutorial, c)声明项目名称为tutorial并使用 C 语言。在解释器层面该函数由 func_project 实现负责初始化项目元数据与语言编译器。executable(demo, main.c)声明一个名为demo的可执行目标其源码列表为main.c对应实现为 func_executable。就这些仅此而已。与 Autotools 不同你不需要把任何头文件加入源码列表——具体原因参见 FAQDo I need to add my headers to the sources list like in Autotools。FAQ 中解释得很清楚Autotools 要求把公开/私有头文件写入源码列表是为了让make dist知道打包含哪些文件而 Meson 的dist命令直接打包 git/hg 仓库中已提交的全部内容且 Ninja 会利用编译器的依赖信息自动推导 C 源文件与头文件之间的依赖关系头文件变更后会自动触发正确的重建。即便你把非生成头文件塞进源码列表Meson 也会直接忽略它们。作为对照仓库中的真实测试工程 test cases/frameworks/7 gnome/gir/meson.build 会把.h头文件一并写进sources因为头文件作为 GIR 扫描输入具有实际用途这也印证了头文件是否入列取决于功能需要而非构建必需这一原则。初始化构建目录并编译现在可以构建了。Meson 强制要求源码内构建in-source build不被允许必须先创建独立的构建目录$ meson setup builddir构建目录用于存放全部编译器输出常见约定是把默认构建目录放在顶层源码目录的子目录中。这是 Meson 与其他构建系统的一大差异其背后是源码目录与构建目录的严格分离在 Environment 的初始化逻辑中source_dir与build_dir被作为两个独立实体管理并通过 get_source_dir() / get_build_dir() 分别对外暴露msetup.py 中的 validate_dirs 还会校验构建目录不能是源码目录的父目录这类非法情形同时向构建目录写入CACHEDIR.TAG与版本控制忽略文件避免构建产物被误提交进版本库。运行meson setup后终端会输出类似下面的信息The Meson build system version: 0.13.0-research Source dir: /home/jpakkane/mesontutorial Build dir: /home/jpakkane/mesontutorial/builddir Build type: native build Project name is tutorial. Using native c compiler ccache cc. (gcc 4.8.2) Creating build target demo with 1 files.接着进入构建目录并执行构建。如果你的 Meson 版本较老可以使用 Ninja 直接构建$ cd builddir $ ninja如果 Meson 版本高于 0.55.0则推荐使用**后端无关backend-agnostic**的统一编译命令meson compile——无论后端是 Ninja、Visual Studio 还是 Xcode命令都保持一致$ cd builddir $ meson compile本文后续统一使用后一种形式。meson compile的实现位于 mcompile.py它会校验当前目录是否为合法的 Meson 构建目录检查meson-private/coredata.dat是否存在并读取meson-info/intro-targets.json来解析可编译的目标列表。编译完成后运行程序$ ./demo得到预期输出Hello there.第二步接入 GTK 图形界面依赖仅仅打印文字已经不够时髦了。下面把程序升级为创建一个图形窗口使用 GTK 控件工具包。改写main.c使用 GTK#include gtk/gtk.h // // Should provide the active view for a GTK application // static void activate(GtkApplication* app, gpointer user_data) { GtkWidget *window; GtkWidget *label; window gtk_application_window_new (app); label gtk_label_new(Hello GNOME!); gtk_container_add (GTK_CONTAINER (window), label); gtk_window_set_title(GTK_WINDOW (window), Welcome to GNOME); gtk_window_set_default_size(GTK_WINDOW (window), 400, 200); gtk_widget_show_all(window); } // end of function activate // // main is where all program execution starts // int main(int argc, char **argv) { GtkApplication *app; int status; #if GLIB_CHECK_VERSION(2, 74, 0) app gtk_application_new(NULL, G_APPLICATION_DEFAULT_FLAGS); #else app gtk_application_new(NULL, G_APPLICATION_FLAGS_NONE); #endif g_signal_connect(app, activate, G_CALLBACK(activate), NULL); status g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; } // end of function main注意其中的#if GLIB_CHECK_VERSION(2, 74, 0)当 glib 版本 ≥ 2.74 时使用G_APPLICATION_DEFAULT_FLAGS创建应用否则回退到旧的G_APPLICATION_FLAGS_NONE这正是前面建议安装 glib ≥ 2.74 的原因——新版 API 是后续 GTK 版本中的标准写法。改写meson.build用dependency()查找外部库project(tutorial, c) gtkdep dependency(gtk-3.0) executable(demo, main.c, dependencies : gtkdep)dependency(gtk-3.0)会让 Meson 在系统中查找名为gtk-3.0的库并把查到的编译参数头文件路径、链接库等通过dependencies关键字参数注入demo目标的构建过程。dependency()函数由 func_dependency 实现并在实际查找时通过 dependencies/factory.py 依次尝试多种查找机制。对于 GTK 这类通过 pkg-config 元数据描述的库Meson 会优先走 pkg-config 路径底层由 PkgConfigDependency 负责它调用系统pkg-config解析.pc文件并提取cflags、libs等信息。这也是为什么meson setup输出中会出现Found pkg-config version 0.26一行。若项目无法使用 pkg-config例如交叉编译场景Meson 还支持 CMake、config-tool、系统内置查找等回退方案详见 Dependencies 文档。如果程序需要同时使用多个库必须为每个库单独调用一次dependency()并放进同一个数组中gtkdeps [dependency(gtk-3.0), dependency(gtksourceview-3.0)]本教程的示例只需要一个 GTK无需使用数组形式。无需重建目录Meson 自动重新生成现在再次构建。需要注意的关键点是我们不需要重新创建构建目录也不需要执行任何魔法命令只需敲下与未修改构建定义时完全相同的命令$ meson compile一旦首次执行过meson setup之后就再也不用手动运行meson配置命令了——始终只运行meson compile即可。Meson 会自动检测构建定义文件的变更并自行处理一切用户无需关心。此时会产生如下输出[1/1] Regenerating build files The Meson build system version: 0.13.0-research Source dir: /home/jpakkane/mesontutorial Build dir: /home/jpakkane/mesontutorial/builddir Build type: native build Project name is tutorial. Using native c compiler ccache cc. (gcc 4.8.2) Found pkg-config version 0.26. Dependency gtk-3.0 found: YES Creating build target demo with 1 files. [1/2] Compiling c object demo.dir/main.c.o [2/2] Linking target demo注意输出开头的[1/1] Regenerating build filesMeson 发现构建定义meson.build发生了变化于是自动重新运行了自身随后才增量编译并链接新的目标。这个过程完全透明开发者只需要记得改完构建定义后照常编译即可。程序现在可以运行了$ ./demo运行后会弹出如下 GUI 窗口构建流程背后的源码支撑结合本仓库源码可以把教程中的几个关键行为对应到具体实现上构建目录强制分离meson setup阶段由 msetup.py 的MesonApp驱动先通过validate_dirs()确认源码目录与构建目录的合法性构建目录不能是源码目录的父目录、不能为空目录等再执行配置与生成。构建元数据存放在构建目录下的meson-private/子目录如coredata.dat后续meson compile正是靠检测该文件来判断当前目录是否为合法构建目录见 validate_builddir。meson compile的后端无关性mcompile会读取meson-info/intro-targets.json中的目标清单再根据构建目录实际使用的后端Ninja / VS / Xcode执行对应的编译命令因此一套命令适用于所有后端。dependency()的多机制查找从 dependencies/factory.py 的注释可以看出依赖查找按DependencyMethods的优先级顺序执行pkg-config 只是其中一种候选机制DependencyMethods.PKG_CONFIG且允许在 kwargs 中传入自定义查找器。构建类型与自动编译参数教程未显式指定构建类型时Meson 默认启用调试信息与告警标志如-g与-Wall。若需要优化版本可在meson setup时使用--buildtypedebugoptimized对应-O2且保留调试信息其参数映射逻辑见 coredata.py 的 get_nondefault_buildtype_args。这也是为什么教程从头到尾都没有手动加-g/-Wall的原因——Meson 已代劳。小结与下一步至此你已经走完了 Meson 的完整入门链路用两行meson.build定义最小 C 项目project()executable()通过meson setup builddir创建独立构建目录用meson compile完成编译用dependency(gtk-3.0)一行接入外部库并把依赖注入目标的dependencies关键字理解 Meson 自动检测构建定义变更并重新生成 build 文件的机制日常开发中无需再手动重跑配置。如果想进一步深入仓库中还有大量可参考的一手资料Commands.md 汇总了meson全部子命令Builtin-options.md 介绍了--buildtype等内置选项Dependencies.md 详解dependency()的完整参数与查找流程而 test cases/frameworks 目录下的大量真实工程则展示了 GTK、Qt、pkg-config 等依赖在各种场景下的组合用法是学习 Meson 写法的绝佳样例。赞分享构建工具【免费下载链接】mesonThe Meson Build System项目地址https://gitcode.com/gh_mirrors/me/meson点击查看免费下载相关推荐高效企业级量化交易引擎Lean算法交易平台深度解析与实战指南高效企业级量化交易引擎Lean算法交易平台深度解析与实战指南 Lean算法交易引擎是一个专业的企业级量化投资开发平台支持股票、期货、期权等多资产类别策略开发金融科技后端Syncthing-GTK基于GTK的Syncthing图形界面教程Syncthing GTK基于GTK的Syncthing图形界面教程 项目介绍 Syncthing GTK 是一个面向桌面用户的 Syncthing 图形前端桌面应用Meson Qt6 Module 完全指南从依赖检测到 QML 集成的自动化构建Meson Qt6 Module 完全指南从依赖检测到 QML 集成的自动化构建 导读 本文全面讲解 Meson 构建系统中 Qt6 module 的使用方法构建工具上一篇crosspoint-reader 固件缓存文件格式完全解析book.bin、section.bin 与 CLX1 库索引下一篇构建端到端长文本问答LFQA系统transformers longform-qa 检索增强生成实战解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表