Living on the edge of Zig

I like programming computers and I also like the Zig programming language. It is a great systems programming language that is not trying to do everything but it doing a few things very well. This is not the blog post to describe how great comptime is, but I will describe the fun I had when the compiler broke my code.

To clarify, my code is still working. In fact, for the Zig compiler at the 0.11 going 0.12 level of maturity, the compiler is remarkably mature. The code is generates is great and faster than a lot of other languages can manage. The problem is that I’m living on the edge. Everyday, I get a new compiler, and therefore everyday something could have been renamed, redesigned, or something more dramatic. Yesterday that was addModule.

In a build.zig file, that describes how to build a zig project, I had a module and I was trying to create the unit tests around that.

const module = b.addModule ("foo", .{
    .root_source_file = .{ .path = "src/foo.zig" },
});

const foo_unit_tests = b.addTest (.{
    .root_source_file = .{ .path = "src/test_foo.zig" },
});

We could then just use addModule on the unit tests to allow the importing of foo into the unit tests.

foo_unit_tests.addModule ("ecs", ecs_module);

This broke.

I started looking at the git history, and yes there was a complete re-organization of the Build directory in the standard library where the Module stuff was taken out of one file and placed into its own. At the same time, the addModule function was deleted. Yeah, that explained how it broke, but not how to fix it.

There are no release notes to look at, and the notes on the pull request didn’t suggest any particular changes necessary. All highly understandable, I’m just following the edge of development and at this stage, thing like this will happen. What did I do?

I started with a search for addModule over the whole of the standard library. Nope, only the function on Build remained. I then searched for any functions took in a module? There was an addImport that worked on a Module. However, the result of calling addTest was a Step.Compile and not a Module.

I then went and looked at the commit that made the change. I did find the deletion of addModule from line 1181. I didn’t find any function to replace it. What I did find was a change to the addExecutable and addTest functions that had a root_module instead of just a root_source_file. The intention is to allow different modules to have different compilation targets or optimization levels. This would be lovely if for example you have a high performance application that would really benefit from AVX-512 support but would also like to run it on old architecture CPUs. Just compile the code twice, with different target architectures and include them both into the project. This is now possible. It didn’t fix my issue directly.

Then I thought,is a module this is a root_module, that becomes a Module, and Module has an addImport function. Bingo.

foo_unit_tests.root_module.addImport ("foo", foo_module);

I compiled, and it worked.

Living on the edge is both frustrating and exciting. I wouldn’t have it any other way.