Once again, our Zig code available at GitHub is functionally the same as the C code.
Setting up the Build System
Zig provides a native build system that uses a build.zig file.
In that file, you basically assemble a directed graph with nodes being build steps and edges being dependencies.
This build system currently does not provide an official package manager.
But Zicross is built upon Nix, which we can use as package manager.
To facilitate this, Zicross provides a function buildZig.
It uses Nix, instead of Zig, to describe the build steps, and generates a build.zig file from them.
Here’s how we use it:
First, we fetch zig-sdl from GitHub.
This shows how Nix can depend on a library even if it is not explicitly set up to be consumed by Nix – other unofficial Zig package managers require some information in the repository.
This SDL2 wrapper does have an SDK which is designed to be consumed by build.zig.
This currently does not play nice with buildZig so we supply a file zig-sdl-build-options.zig that would be generated by the SDK.
Then, we set up the wrapper package named sdl2, depending on the native API in sdl-native and build_options which links to our file.
Our buildInputs will create linkSystemLibrary calls in the build.zig we generate.
linkSystemLibrary calls, you guessed it, call pkg-config.
In zigExecutables, we give our main file and set it up to be installed.
zigTests sets up the tests we want to run.
In preCheck, we change resources.zig to point to the upstream path of the logo, instead of the copy we put into the share directory when installing.
This allows us to run the tests without building the output directory tree.
Let’s build and test our application:
If we want to have a build.zig file so that we can call zig on it directly, we can do
This gives us a build.zig file that can be used with the zig command.
Cross-Compiling for Debian on Raspberry Pi
There is nothing happening here that has not been discussed before:
Test it:
Cross-Compiling for x86_64 Windows
We’re removing -lSDL2main from sdl2.pc because it does not work well with Zig.
Otherwise, it’s just what we have seen before:
Build and test:
Conclusion
With Zig at the heart of Zicross, it is not surprising that cross-compiling boils down to „specify the target system and the dependencies“.
There is no requirement to use Zicross’es buildZig function; you can instead have a build.zig and setup PKG_CONFIG_PATH just like we did for C.
Whether you prefer to write your building steps in Zig or Nix is probably personal preference.
Having the build script written in the implementation language does have its appeal.
On the other hand, Zicross allows you to pin a certain compiler version for your project, which may be helpful since Zig is not stable yet and projects tend to track its master branch.
Also you can depend on any publicly available Zig libraries without worrying about whether they support the package manager you use.