I ran into the Zig programming language recently. It is a general purpose programming language that claims to compete with C, but also is a C compiler. It comes with a build system that can build both zig projects as well as C projects. I usually work with Go, Python or C++ and decided to look into Zig.
I was particularly fascinated with Zig’s build system and support for crosscompilation. I watched a live stream by Zig’s creator in which they transitioned the build system of the redis project to zig and cross compiled it for macos from linux.
I wanted to try something similar: to see if I could build flite, a pure C project, using Zig. It went very smoothly indeed!
Step 1: Install zig
Download Zig from their release page. At the time of writing, the latest stable release was 0.7.1, but the crosscompilation from linux to macos worked with the latest nightly release. A release newer than 0.8.0-dev.1544+867ae506e
should be good.
Unzip the package and add the zig-*/zig
binary to $PATH
Step 2: Download flite
git clone https://github.com/festvox/flite
Step 3: Download the build.zig file
Flite’s build system uses autoconf and make. I translated portions of the build into zig and published the build.zig as a gist on github. Note that this is not a full translation; but this should be enough for bulding flite with default languages and voices.
Download the gist in the flite directory:
cd flite
wget "https://gist.githubusercontent.com/happyalu/f1b5ecd4736e06f9fcdef710f292b6d3/raw/e23dcbfa73b0b1ce8836fe2924acd6ffac8e0418/build.zig"
Step 4: Build flite
Assuming the zig
binary is in $PATH, the following will compile and build the flite executable:
zig build
The executable will be saved as zig-cache/bin/flite
.
To test that it works, you can generate a test wav file and play it:
./zig-cache/bin/flite "hello world" hello.wav
As of writing this article, flite has a small bug that may cause the systhesis to fail with “Illegal Instruction”. If this bug hasn’t been fixed yet, try disabling the checks for undefined behavior:
zig build -Drelease-fast
./zig-cache/bin/flite "hello world" hello.wav
Step 5: Cross compilation
I was able to cross compile flite for several architectures:
for host in \
x86_64-linux-gnu \
x86_64-macos \
x86_64-windows-gnu \
aarch64-linux-gnu \
aarch64-macos;
do
zig build -Drelease-fast -Dtarget=$host;
mv zig-cache/bin/flite zig-cache/bin/flite-$host;
done
I wasn’t able to compile this for the arm architecture, ran into this issue.
Remarks
The Zig build system is amazing! Flite is written to be highly portable, so I was sure that there won’t be source changes required to get these builds going, but still, in the past, getting cross compilation to work properly has had been a hassle. It took me about an hour to translate flite’s build. Zig simplifies everything, makes cross compilation work with just a 37MB download, and even for the case to build for macos from linux! Go Zig!
This experiment mostly involved playing with Zig’s build system, and even if a project doesn’t use zig, it’s worth looking into using zig for the build. However, I do plan to take a deeper dive into Zig, the language, soon.