Why zig cc

Hello Ziggit!

I’m still a bit of a newbie with Zig (and with system programming in general) and my English is still a bit poor, so don’t judge too hard =).

This morning i’ve been experimenting a bit with the Zig c compiler, something i’ve thinking on is why would you want to replace previous build systems and C compilers with Zig cc, i read on the language page it does help you to cross compile and to be a better alternative than, say, CMake (which i’m not a big fan of), and i’ve about the Uber case too, though i don’t fully understand what exactly was the process. Am i missing something? Are there any other advantages to it? Personally i don’t have much experience with cross compilation, but i’m fascinated with the idea of compiling C code with the Zig compiler.

I’ll split it in two. This is my own personal interpretation, I’m not an official Zig anything, but I am an unofficial Zig proselytizer. :smiley:

Zig wants to support a lot of targets on a lot of hosts and provide a good development experience across all of it. One of the main features of “good development experience” is that selecting a target for building should be as easy as passing a flag to the compiler. Another is that installing zig should be trivial.

Depending on your exact compilation setup, this is very frequently not the case in C/C++-land.

gcc by design is compiled for the target you want it to support as well as the host, so to support N different targets you need N different installations.

I think this influenced how most C build system works as well.

In cmake, for instance, this means writing toolchain files, which is a short header/config-like file that tells the build system where to find your C compiler, environment, and dependencies for the different targets.

Where your compiler lives, how to install it, and how to access it differs by host platform as well, so this ends up with a whole lot of “if on host A find compiler for target B at location C” in your build scripts, and a whole lot of “if on host A install compiler B for target C following guide D” in your onboarding docs, which is super annoying to maintain and keep up to date.

Newer compilers like clang simplify a lot of that by supporting multiple targets, but you still need to make sure the installation you have supports the target you want, which isn’t always a given.

Zig says “this shouldn’t be so hard” and does a lot of things under the hood to make sure every installation has a compiler available with the same interface on every host supporting every target, and that the installed compiler has near-zero dependencies on the host system, which means invoking Zig to build a C program for some platform is the exact same (clang-compatible) command line interface, no matter how Zig was installed, and requires no other programs to be installed.

That’s what zig cc is.

11 Likes

You know, after writing Zig for years, I can argue this all night. It feels soooo good writing C and CXX; I can actually get everything done without annoying people on the internet. Yeah, it’s a bit more challenging. But hey, how is this a _bad_ thing? Robots are hard, just like math. IT IS NOT SUPPOSED TO BE EASY! The harder the task, the stronger the output (there is just no way around this one). You should train that most important muscle in your body daily if you are writing code. If somebody is failing with basic stuff like project setup in C or CXX, they either just need some training, or they need to switch to stuff like cooking (most modern engineers should, the state of the internet screams this into everybody’s faces). I feel like all the issues that Zig accumulated are because it is trying to be many things instead of one and solving problems that do not really exist. Memory safety? Not an issue with proper dedication. Cross-compilation too hot? It is not, although your scripting game might just not be there.

Back in the day, one would have to brute-force jumpers to solve a segfault, the stuff people are complaining about today is just comical.

1 Like

Not having to write CMake is a already a winner for me.

Where zig’s built-in C compiler really comes in handy is for a mixed-codebase of Zig and C. There’s plenty of mature, high-quality C libraries out there, and zig cc lets you use them in a zig project without having to install additional build tools. Many examples here.

This makes installing from source as simple as:

  1. Download Zig.
  2. Run zig build install

P.S. The zig compiler can transpile zig to c: e.g
zig build-obj -ofmt=c -O fast file.zig
I believe zig-bootstrap uses it, during its early stages where it’s not able to output machine code on its own.

4 Likes

I’ll try the transpilation later =).

Now that you mention CMake, what’s the problem people has with it? I wrote a bit of CMake because of a uni project, i didn’t like it that much but i’m not aware of the flaws it has, or why people doesn’t like it.

I wanna keep this positive so I’m gonna focus on what I think Zig improves compared to other build systems. Feel free to liberally insert “unlike cmake” wherever you feel like.

  1. It’s a part of the standard library for the language instead of being a separate language. I still have to learn how to use that part of the standard library, but I don’t have to learn a whole new syntax for the build system or install a new program.

  2. Being a Zig library, it has Zig’s type system, which I find pleasant to work with.

  3. It’s in the standard library and it’s good, so Zig projects use it universally. Anything that’s universal in an ecosystem is great.

  4. The design of the package management system feels appropriately not-evil to me. It’s easy enough to use that I don’t hate configuring new libraries without being so frictionless that it encourages silly things.

  5. The caching system is awesome. I like that cache misses are usually easy to predict and understand, even if it means that I have to be more explicit about inputs and outputs.

  6. Support for “just-in-time-vendoring” libraries via --fork and placing your fetched libraries alongside your own codebase means inspecting and fiddling around with the source code of your dependencies is trivial, which I think is great because it encourages getting familiar with your core libraries and contributing to upstream projects.

4 Likes

It’s less that it’s hard and more that it’s really annoying to need to do this multiple times for each host+target combination.

I just have better things to do than to babysit that.

Can I do that? Yes.
Do I want to? No.
So even if Zig wouldn’t exist, I would write something to automate this for me.
And even then you get a better setup with clang instead of GCC since with GCC you need a separate binary for every host+target combination instead of just a separate one for every host like with clang (or Zig).
And each required binary just increases the setup time, even if you automate it and can walk away from it.

The entirety of mathematics is about finding abstractions and commonalities between things to make stuff easier.

4 Likes

This is exactly why humans have scripts for annoying stuff. Another thing is linux, lol. It is just a collection of sloppy BSD workarounds and nothing more. Imagine if there were a system with only one package manager and so many dep issues would become obsolete in a heartbeat. Just like POSIX dictates. Oh wait, there is actually more than one system like this.

Of course. But what makes you think that the road to easy stuff should be a breeze? The balance of the universe does not work like that.

Considering you are on a forum for the Zig programming language, the default assumption might reasonably be that nobody thinks the road to easy stuff should be a breeze.

Indeed, build.zig is, if you squint at it, exactly the script you argue for :wink:

3 Likes

I recommend reading `zig cc`: a Powerful Drop-In Replacement for GCC/Clang - Andrew Kelley if you haven’t, especially the “under the hood” section near the bottom.
I personally never really understood why cross compilation was so hard until I read what zig does to make it easy.

Regarding CMake, my personal take is it’s a programming language with a config script coat. It’s full of conventions that are opaque, so you need to a) put a huge amount of effort to understand or b) copy paste stuff around.
In both cases it’s frustrating because you typically don’t spend so much time in the “make it compile” part of the project, and by the time you have issues you forgot a lot about it. Except if that’s your full time job, it’s difficult to feel like you are doing progresses.

But there is another big philosophical difference between CMake and the zig build system that I would summarize like this: CMake tries to abstract the host platform differences, whereas zig tries to sandbox the compilation.
You still need to learn the API of the zig build system. But it’s written in the zig language itself so it’s much easier to study how it works by reading the source, and it tries very strongly to add friction to steer you towards genetically reproducible builds. “Use my functions and if it builds on your machine it will build de same on every host for every target” (or that’s the goal at least)

CMake on the other hand is more “Use this function and I will find the relevant header somewhere on your machine but if that thing is missing on somebody’s else computer well too bad, I’ll split out a cryptic message”

Or put another way, CMake makes it easy to write very convoluted and uselessly complex build script, whereas zig tries to makes it obvious if the build script is a mess.

Although to be fair a lot if the mess of CMake is, I suppose, more a consequence of the C Compilation model and CMacros hell than only about CMake being bad.

2 Likes

Squinting eyes like that would be hazardous without even looking at any code :slight_smile:
You want to do the job right, use the right tool. Languages are for writing the code, build systems are for building the code. Yeah, the idea is sound to have both in one package. But it cannot work, not in this universe. The build system should be a simple intuitive tool that would not block your way to a compiled binary. Kinda like bash vs. csh. You don’t need all that speed and power of C in a shell; a shell is just the glue to put together actually powerful tools.

I don’t see how that assertion stands? Why will it not work?

2 Likes

My guess is because the planet is spinning and we don’t have enough knowledge to break quantum barriers? F1 engineers can explain to you in all beauty the importance of the balance and what WILL happen when you refuse to respect it. Big/fast, skilled/smart, cold/hot: team work is a key to success. Language should not dictate how I am supposed to build my software. No one gets to. I should be able to inject any build system in the workflow that I consider most efficient for the task. Like with C, if I am writing a simple CLI app, meson is all I need. If I need some serious guns, GUI, etc, I will go with C/Make. Again, you want to do the job right? Then use the right tool.

If you don’t have anything constructive to contribute to the discussion you can just not participate.

8 Likes

I won’t accept people in this forum who just want to put themselves into a position of some sort of guru spouting mythical garbage to make themselves sound smart.

Sure there might be laws of thermodynamics, but this isn’t a physics or philosophy forum, so keep your overly vague notions to yourself and keep towards the topic at hand: Zig, programming and things that can be actually verified with programming.

Just following your claims with more claims, isn’t how you make an argument.

12 Likes

Disclaimer that I have little C experience and less C via Zig experience…

But in my little experience, using Zig to compile C, and its build system are monumental improvements:

  • it is fully self contained, no need to fiddle with system dependencies
  • Having a proper language for the build system, instead of a DSL where programming is an after thought, is just more cohesive and sensible experience.
    and to the person who suggested otherwise, any sufficiently large or complex project needs a proper language to build said project without an unreasonable amount of effort
  • zig makes cross compilation seamless even with C
2 Likes

And it isn’t a breeze.
It’s just that the Zig team did that work for us instead of everyone to do it over and over again.

1 Like