I really don’t think that is a good idea - it is extremely standard for git, cmake, and system dependencies to be managed externally to a C/C++ project source. To do otherwise would be invasive and far too opinionated. Tooling should not be running the git command on any user’s behalf. That’s a violation of the relationship between a source project and the user. Each one of these steps - git, cmake, and ninja (or make) - has options that the user might want to manage. For example:
git - you might want to use --shallow, or build instead from a downloaded tarball
cmake - you might want to choose between debug/release or how to find llvm
ninja/make - you might want to choose the other option instead, or configure how many jobs to run in parallel
Just learn the extremely standard process for using git, cmake, and make/ninja to build C/C++ projects. It’s a great skill to have.
In the long term plan, there is no more cmake and no more make/ninja. The only dependency will be a C compiler toolchain:
cc -o bootstrap bootstrap.c
./bootstrap
CMakeLists.txt will be deleted.
And then, yes, there will be a separate repository for building llvm and clang from source, in order to provide a binary package. This package will be officially provided by the Zig project, but maintained on a separate release schedule than the Zig compiler itself (in lockstep with LLVM release schedule). Projects will depend on this package in order to use any of these features:
Use LLVM’s optimization pipeline to convert .bc files into object files.
C translation functionality. @cImport will be removed from the language, moved to the build system, and gain more configuration options.
Compilation of C, C++, Objective C, Objective C++ files into object files.
Aha, I guess that’s the key thing that I am missing, thanks!
From where I stand, I see two properties of the build process as extremely desirable:
a single-command “build & run the tests”, which works the same on any machine and forms the basis of doing anything else with the project
a repeatable build by default — not necessary fully byte-for-byte reproducible, but enough hermiticity to make sure that default-configuration builds on CI, on local maintainer’s machine and on an opportunistic contributor laptop are functionally identical. Notably, this includes pining dependencies to specific versions by default.
But it seems that achieving that for C/C++ project with dependencies is non-trivial, as the traditional answer for dependencies is “they are managed externally, by your OS package manager”, and anything other than that is swimming uphill. I agree that half-assing that with “I know, I’ll just git clone and cmake on behalf of the user” has a tonne of practical and conceptual downsides.
Lol the YouTube algorithm coincidentally gave me your GOTO talk on this subject a couple hours after posting this. Oops
All incredibly fair points, I generally don’t use docker to develop locally because its usually more trouble than it’s worth. I do like it for CI, and occasional sanity checks when I get over my skis and properly bork my local dev environment
I’m certainly not a Docker fanboy by any means so I’m happy to take down the repo if it muddies the waters on the proper way to get going w/ Zig compiler development!
Strange comment from someone who’s just said he can’t control “what shenanigans Linux distributions get up to”. The entire idea behind Docker is motivated by precisely that thought.
If you build LLVM yourself from source you’re not exposed all that much to distribution shenanigans. It’s generally not hard to get your hands on the dependencies required to build LLVM and run the 3 commands required to make it happen.
If you try to use the LLVM shipped by your distro’s package manager then yes your mileage may vary, for example in the past it happened to me a few times that brew would package LLVM in some weird way that caused issues when compiling Zig.
When I discovered the “build.zig” and compiled Zig for the first time using “zig build”, I thought to myself: “This is the easiest large project I have ever compiled”. There was onr time when the most recent binary refused to compile the most recent source code, something about missing targets, I just waited a day and it worked again.
The times when I built from source I was just doing some small pull-requests to the std library, like OP. They were basically one-liners, there was no point in messing with LLVM options, I just needed to make sure that it compiled.
If you have flakes enabled nix installed, you can also run nix develop github:Cloudef/zig2nix#zig.git.src, you are now dropped into a shell that has all the dependencies to do a LLVM build of a recent zig.
The two lines I have in the post you replied to are:
cc -o bootstrap bootstrap.c
./bootstrap
This has two nice properties:
It works
The only system dependency is a C compiler
I don’t understand why you would change my code snippet to this and call it a simplification, because it no longer has either property. It doesn’t work, because there is no Makefile, and it introduces a system dependency on make which wasn’t there before.
Well, paint me red and call me a firetruck! Today I learned that make supports implicit rules even when there is no Makefile.
So, sure, if you have make installed, you can use that feature as a shortcut. I would never use that example in the readme, however, because it would probably lead to confusion that the build process depended on make.
My machine started to sigh when I tried to compile LLVM and my patience ran out after an hour when I realized it would take many more hours to complete.
So I had to find some way to get LLVM already compiled.
I found https://apt.llvm.org/ and the rest is a recipe to build zig in Debian or Ubuntu using LLVM deb packages.
EDIT: updated for LLVM 19
# add the llvm apt repository in /etc/apt/sources.list.d/
# e.g. for Debian Bookworm:
# deb http://apt.llvm.org/bookworm/ llvm-toolchain-bookworm-19 main
# add the llvm key in /etc/apt/trusted.gpg.d/
# wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
sudo apt update
sudo apt install libclang-19-dev liblld-19-dev llvm-19-dev
# add /usr/lib/llvm-19/bin to PATH
git clone https://github.com/ziglang/zig
cd zig
mkdir build
cd build
cmake .. -DCMAKE_PREFIX_PATH=/usr/lib/llvm-19 -DCMAKE_BUILD_TYPE=Release -DZIG_NO_LIB=ON -GNinja
ninja install
stage3/bin/zig version