A Clean Build of OpenSSL using Zig
openssl-zig is a working compilation of OpenSSL using the Zig build system that I've been working on for the past couple of weeks. There are a few advantages of using Zig to compile:
- Fast compile times
- Zig build scripts are easy to hack/modify
- Integration with Zig projects as a package
While there are other packages that aim to do the same thing, my goal for this project was to build OpenSSL is the cleanest way possible, without hacky workarounds or anything of that sort.
In this blog post, I'll go over what I learned and my thoughts on the Zig build system as a whole. If you just want to read about the project, check out the GitHub repository.
Learning Zig Build
I came into this project knowing nothing about how to write Zig build scripts. It took a while to know what was going on, especially given the lack of up-to-date documentation.
The Zig docs do have a tutorial of sorts, but given how vast the possibilities are, it doesn't cover a lot of ground.1 I ended up learning how to do things in two ways:
- Trial and error
- Reading other build scripts
For the latter, I read the build.zig
file of
a different Zig compilation of OpenSSL.
While that project does a few things that I wanted to avoid in my compilation,
it was a fantastic starting place. I also read the
Ghostty project's
build.zig
. It's
quite complex, but it showed me examples of more advanced things, like using the
Run build
step.
Lazy Paths
The LazyPath is one of the most important concepts in the Zig build system. Getting comfortable with them is the best way to get good at Zig build, in my opinion.
A LazyPath
is the path of a file or directory that may or may not exist
yet. To understand why we need them, it helps to know about the design of Zig
build scripts. Zig builds are declarative, so there are two phases:
- Telling Zig how to build the project, in steps
- Executing the steps in the specified manner
For example, in my project, one step of the build process is generating C files
to be included in the compilation.2 Another step (the C compilation
step) depends on those files being built. This is where LazyPath
comes in. At
the time of specifying the build steps (phase 1), the generated files do not
exist yet. So, in order to properly describe the compilation step, we need to
reference their future locations.
Closing Thoughts
Writing my first Zig build script was an enjoyable experience after I got over the first few hurdles. Until the language stabilizes, I suspect that this will continue to be the case for newcomers.
I think it's a very viable replacement for CMake (and similar meta-build tools), on account of how much more programmatic everything feels.
Make sure to check out openssl-zig if you're at all interested! I also wrote a HOW.md in case you want to learn more about the design of the project. I hope you enjoyed this post!
This is not a complaint about the language! As of this post, Zig is at version 0.13.0 and is still growing. Once the language eventually stabilizes, good documentation will become fair expectation to have. ↩︎
The OpenSSL project generates a lot of files at build time using Perl, so I need to re-create that generation in my build scripts. ↩︎