CMakePkg — link CMake targets from build.zig

I like Zig build system, it is easy to write, extensible and, of course, written in Zig (what makes it enjoyable to work with).

But many libraries I depend on, are too complex to replace their build system with build.zig, for example Qt6. You can always link library by name, but in case with Qt6 there’s so many things, include directories, defines, compiler flags, internal libraries (for example, that’s Qt6 compiler flags on my system: -I/usr/include/qt6/QtCore -I/usr/include/qt6 -DQT_CORE_LIB -DQT_NO_DEBUG -I/usr/lib/qt6/mkspecs/linux-g++).

And this is how CMakePkg started: at first it was a CLI utility (my initial use case was a Makefile), and now it’s a build.zig plugin.
The idea is pretty simple: use CMake to extract include directories, compiler flags, libraries, link options, the whole dependency tree, and turn it into pkgconf-ish output of flags. Solution I come up with is way too hacky, I had to write a simple CMake generator expression engine in CMake language.
I can’t recommend anyone to seriously use it, as I just want to share what I crafted :grin:, there’s no documentation, there could be bugs.

You can find Qt6 example at yataro/cmake-pkg-qt-example - Codeberg.org, assuming you have Qt6 and Zig 0.15.2 installed on your system, just run zig build run to start demo program.

The penalties of CMakePkg is that CMake configuration step is triggered on every zig build run, but it’s only a few seconds. This is fixed, now subsequent configurations will happen much faster (from 1.4s to 0.1s on my system), CMakePkg build plugin now uses deterministic CMake configuration directory, which will leverage CMake configuration cache.

This was my first big Zig project, I started it more than a year ago, after long hiatus I upgraded it to Zig 0.15.2, and added build.zig plugin. I can say that upgrade from Zig 0.13.0 to 0.15.2 was simple and didn’t took long (I used Zig almost every day since then).

11 Likes

Very impressive and useful project, but man I hate how cmake creeps into non-C/C++ ecosystems mainly just because the cmake build scripts are usually so overengineered that they are too hard to replicate in another build system :slight_smile:

3 Likes

It doesn’t help that CMake lets you do a ton of things that many other build systems typically don’t permit without external scripts or a lot of extra work. Which is partially why it is such a lock-in build system. I have a strong suspicion that someone is going to want CMake Zig language/compiler integration one of these days. (Which, really, wouldn’t exactly be the worst idea ever…)

I have a strong suspicion that someone is going to want CMake Zig language/compiler integration one of these days.

I nearly wrote something about a hypotethical ‘translateCMake()’ build step similar to ‘translateC()’ but bit my tongue :wink: