Crosscompiling Flite TTS with Zig!

21 March 2021
tts programming

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.