I’ve managed to turn some of my company’s C++ projects to fully cross-compile by setting zig as the C and C++ compiler. There’s a bit of work involved to create a CmakeToolchain file for each architecture you want to target and always some work to fix the code to be cross compilable but it has been a very nice experience so far and amazingly useful.
However there are some issues I haven’t dared to tackle yet (for example cross-compiling a Qt project).
Has anyone used the zig package manager in conjunction with a cmake project using zigc and zigcc? Is it be possible? (I know that one option is to write a build.zig file for the project instead and dump cmake but I’m trying a gradual approach first as some upstream projects rely on cmake)
I worked on ZigROS a bit last year, and for most projects it wasn’t too bad to create a build.zig for the C/++ project so long as you only cared about a specific build with specific options, but for complex projects targeting multiple OS’s with a lot of build-time options (for example, OpenCV), what I found was easier was to build that project separately and “install” the library / libraries to a local directory for the Zig build system to then reference.
For OpenCV, for example, my approach to cross-compilation was to start from a minimal alpine Docker image, install Zig, clone the OpenCV repo at the commit I needed, then use command-line args to CMake to use zig as the compiler, linker, and archiver for the CMake build. This would generate a fully static library with zero system dependencies for both x86 and aarch64. I would then place the libraries into build_deps/{x86_64,aarch64} directories in my zig-based repo (actually I had the Zig build system fetch the prebuilt libraries over the network from a private package cache), and it was easy to link those libraries from there. This works really well for dependencies you aren’t actively maintaining, but if the CMake-based project is under active development, it might be a bit cumbersome.
Well changing from using Cmake to using Zig is not really an option, for multiple reasons. 3 of them being:
Changing build systems is a political decision, not a technical decision
Time to make the change
Upstream projects are using cmake, so we need to provide a very easy cmake integration
So using a build.zig file is out of the question. However it’s possible to use parts of zig and with that show little by little how zig makes everyone’s life easier. Are there any integrations points between the zig package manager and zigc / zigcc? Can I have a build.zig.zon file with my dependencies and use zig fetch to download by dependencies and then trigger the build with cmake?
Doesn’t really make sense to me, or at least you don’t describe why that wouldn’t be an option.
You could have a build.zig that just contains code to invoke cmake commands, where the build.zig.zon alongside that describes dependencies that use the pristine-tar-ball strategy (basically that those dependencies don’t include their own build.zig or build.zig.zon).
Doesn’t really make sense to me, or at least you don’t describe why that wouldn’t be an option.
I’d rather focus the thread on if it’s possible to use the zig package manager for C++ and use other build systems, this is not a XY problem, I just don’t want to go too into detail on the pitfalls of build.zig for C++ as I know the biggest issues are already in the Zig tracker.
But since you asked, there are 3 dealbreaker issues with build.zig that make it a non-viable option:
Because upstream projects use cmake, many projects, it’s not possible to port all of them to use build.zig;
Because build.zig does not create a correct compile_commands.json file for LSP usage, while zigc and zigcc do. This single issue makes the build.zig approach effectively worthless, since it’s a massive drawback to the local development experience.
You could have a build.zig that just contains code to invoke cmake commands, where the build.zig.zon alongside that describes dependencies that use the pristine-tar-ball strategy (basically that those dependencies don’t include their own build.zig or build.zig.zon).
Ah I see where the confusion comes from. I meant upstream projects use cmake, not downstream, currently they use git submodules / vcpkg / Conan for defining their dependencies and cmake to then build them, I was hoping to use the zig’s way to track dependencies instead of those
In theory, you could use std.Build.Dependency.path to fetch the root directory of the upstream dependency, fetch its CMakeLists file and call cmake with that information, though I’ve never done this myself.
This’d let you fetch and build upstream dependencies fully integrated with a build.zig file, while still using cmake.
There’s also always the option of creating a allyourcodebase-style repo for the upstream dependency, where you create a build.zig file for the upstream dependency and a build.zig.zon file that can fetch the upstream dependency in its unmodified form.
Then, in your final build, you depend on your “allyourcodebase” repositories, and now you can build your entire dependency tree with Zig and only Zig.