Zig NEWS

loading...
Cover image for Compile a C/C++ Project with Zig

Compile a C/C++ Project with Zig

Loris Cro
I swear I didn't put that bug there
・3 min read

Zig is not just a programming language but also a toolchain that can help you maintain and gradually modernize existing C/C++ projects, based on your needs. In this series we're using Redis, a popular in-memory key value store written in C, as an example of a real project that can be maintained with Zig. You can read more in "Maintain it with Zig".

What is Zig?

Zig is a programming language with no runtime, a focus on simplicity, and great C interoperability. Zig bundles LLVM to create optimized release builds and so it's also a full-fledged C/C++ compiler.

Zig has zig cc and zig c++, two commands that expose an interface flag-compatible with clang, allowing you to use the Zig compiler as a drop-in replacement for your existing C/C++ compiler.

For a more complete overview you can check out https://ziglang.org.

Why not just stick with gcc/clang/msvc?

As we'll see in the next posts in this series, there are a few different reasons to consider making Zig your default C/C++ compiler, but for now let's just focus on some basic advantages that you can get without any extra effort.

Ease of setup

Zig is distributed as a ~40MB archive (by comparison LLVM is about 200MB). Unzip it and you're good to go. No extra dependencies needed. The only (optional) extra step is to include zig to your PATH, to be able to invoke compilation from any directory.

This is great for creating build pipelines, for example: no complex Chef scripts, Docker containers or VM images. Just download, unzip and run.

Caching system

Making a change to a single compilation unit should not trigger a full recompilation of the entire project. If you're using a build system like Make, then you're good, but if you're just using a simple build script that invokes the compiler directly, you're out of luck... unless you use Zig.

Zig keeps track of all dependencies for each compilation unit and can compile your project incrementally without requiring any configuration or external build system.

Better defaults

By default Zig enables all the features present in your CPU (e.g. SSE, AVX), producing more efficient binaries out of the box than other compilers. In debug builds Zig also enables UBSAN by default.

Finally, all of this is especially relevant when it comes to common libraries like libc, libcxx, compiler-rt, tsan, libunwind. All these libraries are bundled in Zig in source form and gain native improvements when being built for your native target.

Compiling Redis with Zig

Let's see how hard it is to compile Redis with Zig. Note that Redis doesn't support Windows so you will need a Linux/macOS/BSD host to reproduce the following steps.

Download Zig

Read the getting started guide to learn how to get a copy of Zig. You can choose between downloading a tarball directly and using a package manager.

⚠️ VERY IMPORTANT NOTE ⚠️

To be able to follow along and reproduce this blog post, you will need to use Zig 0.8.1 and commit be6ce8a of Redis. Both Zig and Redis are being actively developed and over time things will change, potentially breaking the code in this series. Of course the same general approach will keep working over time but this is the only way of guaranteeing that you can follow along and have everything work first try.

Get Redis

You can get a copy of Redis by cloning the official repository.

git clone https://github.com/redis/redis.git

# Don't forget to checkout the right commit
git checkout be6ce8a
Enter fullscreen mode Exit fullscreen mode

Compile!

If you read Redis' README you can see that to build it all you need to do is call make. To make make use Zig, all you have to do is specify a couple of variables when invoking the command.

make CC="zig cc" CXX="zig c++"
Enter fullscreen mode Exit fullscreen mode

If you're wondering why we are also specifying a C++ compiler, it's because jemalloc, one of Redis' optional dependencies, is a C++ project.

If everything went well, you should see a message inviting you to run the tests and freshly build executables inside src.

If you got something wrong, make sure to run make distclean before trying again.

What's next?

That's all you need to do to use Zig as a C/C++ compiler. It's almost funny how minimal is the how-to part of this post, but that's kinda the point.

The next part of this series will introduce a much more interesting concept: cross-compilation, which will allow you to create a Linux executable from Windows and/or from x86_64 to ARM, etc.

Discussion (0)