Build.zig plugins

Zig build system is undoubtedly amazing, the fact that build config is a Zig source code implies no limitations, but one thing I really want to see is distributable plugins.

At the moment I haven’t found a clean way to use 3rd party libraries in build.zig. While it is possible to hack around like in how to use your fav pkg in `build.zig` - Zig NEWS, I don’t think it looks very good.

I wrote a cmake-pkg (still in beta, but works really well for me) - basically a pkg-config clone but for CMake (exported targets/FindXXX.cmake), which I can call like pkg-config to link complex CMake-exported libraries (Qt6 and etc.) from trivial build systems (Makefiles or GYP in my case).

Later I realized that I can use it with addLibraryPath+linkSystemLibrary and addIncludePath (or maybe with theoretical build plugin API one can export something like CMake’s interface flags?). Though to use it from theoretical build plugin it requires trivial refactoring (I coded it only with CLI interface in mind), but I believe such tool can be very useful to build wrappers for libraries like Qt.
The only problem as mentioned before is that I can’t see any clean/idiomatic way to call 3rd party package from build.zig. I’m really sorry if I missed something, I only started my zig journey two months ago or so.

Any thoughts on this?

2 Likes

In your build.zig file, you can directly @import your dependencies listed in build.zig.zon. This imports the build.zig file from the dependency, so you can expose things at build time by putting pub declarations inside that file.

5 Likes

Thanks, that’s very slick!
I’m happy with it, but is any support for plugins/extensions planned?

First of all cmake-pkg looks cool, nice job.

I’m happy with it, but is any support for plugins/extensions planned?

I’m curious what more you would need than build.zig.zon and ability to @import?

2 Likes

I just thought it would be cool to have something you could integrate into the build process, like a custom code generator, library manager, etc. It can all be done right now with the current build.zig capabilities, but I’m wondering if there will be something like Bazel’s Rules Tutorial  |  Bazel .
Now I kinda understand that there’s no practical need for such stuff if you can use what you already have (which in this case is not really complicated). Then I remembered Zig’s “Only one obvious way to do things,” which completely answers my question (there will be no such thing).
Thank you for helping me understand this.

Also, I realized that the post I linked is exactly the same thing andrewrk said (for some reason, it was easier to understand his reply), but it’s good to see that this is not an abuse, but an intended use.

2 Likes

Generally, “plugins” for the Zig build system take the form of either utility types/functions that can be imported via direct @import of the build.zig of the dependency, or as CLI programs that consuming packages can invoke via b.addRunArtifact(). If the CLI program takes files as inputs, you can pass them via run_step.addFileArg(), and if it generates output files, you can obtain LazyPaths representing the generated files via run_step.addOutputFileArg().

See the Running the Project’s Tools for an example of code generation. The only difference between building and running your own artifact and running a dependency’s artifact is that for the latter you would obtain the artifact via dependency.artifact("generator"). But the argument passing code is the same.

If you want to go slightly more advanced, you could of course also combine both @import and artifacts and expose a utility function that resolves the artifact representing the CLI program, sets up all arguments and returns the generated result. I do this in my OpenGL binding generator if you want an example (generator build.zig, consuming build.zig).

2 Likes