Best way to combine Zig and CMake projects

I have a repository of my own which is written in C, built using CMake, and depends on a number of third party subprojects which are built by CMake into C libraries. I’d like to convert this repository to use Zig instead of C for my own code, but I’m not sure of the best way to do this. As far as I can see, I have the following options:

  1. Re-write all the CMake build scripts to be Zig files instead. This would be alright for my application, but could potentially get complicated if I had to do it for all the third party dependencies as well, as some of them are quite large.
  2. Keep the CMake scripts, but get CMake to use the Zig compiler to build the code. I have got this to work successfully to build C code, but CMake does not seem to have support for compiling Zig. I have looked into creating CMake configuration files to support the Zig compiler, but this also looks to be very complicated.
  3. Re-write only my application’s CMake scripts in Zig, and call the CMake executable for the third party projects (as described in https://www.reddit.com/r/Zig/comments/kf8wgq/cmake_based_library/). This seems like it could be an OK compromise, but then I have to depend on two separate build systems instead of just one.

Is there a preferred way of accomplishing something like this? Personally I rather like CMake, so would quite like to get the Zig compiler working within that framework, but even if I were to set up Cmake support for the compiler, I’m not sure whether or not it would work well, since Zig would probably expect to use its own build scripts for this kind of thing.

The ziggiest way to accomplish this is to get your third-party dependencies into aycb, and then you can switch to exclusively using zig build. The benefits of this vs cmake include fewer dependencies, cross compilation, file system watching, simpler and unified build instructions on all platforms, and ability to enable LTO across your entire dependency tree.

4 Likes

The benefits of this vs cmake include fewer dependencies, cross compilation, file system watching, simpler and unified build instructions on all platforms, and ability to enable LTO across your entire dependency tree.

Ability to build against a specific glibc version without dusting off an old laptop/docker container with ancient Debian is also seriously :zap:, and I think pretty unique to Zig ecosystem.

3 Likes

Ah, aycb seems like a very good one for me to bookmark :grin: Thank you! I can already see some dependencies in there that would be useful to me.

More generally, I can see how this would serve as a good “bridge” solution to allow zig build to work, but it also seems to me like it would potentially create a lot of work for the downstream maintainers if the original CMake scripts changed. It also means that if I wanted to use some esoteric dependency, either I would need to write a Zig script to do what the other build script already does, or I’d need to submit it to aycb who would then need to do the same thing. Perhaps maintaining things this way is standard practice for languages that inter-operate like Zig does, and I’m just not familiar with it, but it seems like a lot of boilerplate work.

If I wanted to just pull in an existing C library reo and invoke whatever build system it uses (CMake, make, or whatever), would this be feasible in Zig? How would I go about importing the produced library as a dependency - would it be similar to importing any other system library?

here’s how i compile cuda (similar to gcc)

I’m not an expert and frankly I’m quite new to this, so I’m not sure if this is the best way to do it. It’s been quite handy for me though and I think it would work well for cpp projects too. This wouldn’t use cmake though so if you’re very cmake dependent then I guess this isn’t for you