Zig self-update

Could zig self-update to enable working with multiple versions of zig?

Lets review the landscape:

rust -> rustup
python -> uv -> uv self-update
python -> pip -> ?
bazel -> bazelisk
zig -> zigup
zig -> anyzig
zig -> zvm

This is annoying, I want to depend on zig. Not a bash script + anyzig + zig (no disrespect to anyzig!). Can we do better than all have tried before?

I guess if I was truly hard-core I would just commit zig into my repo.

Further reading: https://www.youtube.com/watch?v=jVC4DP-8xLM

I don’t understand how this would help, you still would have to get zig initially, why can’t you use whatever method you use to get zig initially to get the version of zig that your project needs?

Can you explain how / why this would be helpful?

3 Likes

When I made anyzig I did consider whether Zig itself should integrate the same functionality (i.e. dynamically detect which version of Zig is required and automatically download and forward the invocation to the correct version of Zig). Ultimately I decided that there are some advantages to keeping this sort of logic outside of Zig itself and keeping it in an external tool like anyzig. It keeps Zig more simple, you know once you actually execute the ā€œreal Zigā€, it’s not going to do anything tricky and try to forward invocation to yet another Zig. So, I’m pretty happy with the status quo now and am unsure whether having Zig do more would be a net benefit?

8 Likes

There is also zi.

PS: zi also has the option to manage your zls installation for you.

Well I think it’s a bit of a departure from ā€œonly one obvious way to do thingsā€. If someone has no experience with zig, they download the tar ball, untar it, and add to PATH.

Once they need two versions, they add two different zigs to PATH, or graduate to anyzig.

But it begs the question of if they should have started with anyzig. I don’t know.

On a somewhat related note, PATH also irritates me. I understand what it is now, but it feels like we should have something better. I hate that I have to modify some bashrc and relogin. There is always the fear that I have broken something that I don’t know how to fix, that I will modify PATH in some way that will screw me later or break some other part of my workflow (the fear comes from inexperience, yes, but it’s annoying). It also comes from the annoyance of having multiple versions of python installed on a system, and shooting yourself in the foot over and over again because of typing python instead of python3.10.

PATH is probably one of the biggest frustrations for a true noob learning programming, and why many people spend years clicking the play button in their IDE to compile and run their code.

Just feels like something is missing.

For just learning programming, there are better tools than Zig or even Python. I’d use something with like Scratch, or even a ZX Spectrum Next, where you can start it and directly type Basic programs.
Once you start programming ā€œfor realā€, I think it is essential to be curious and explore the command line in a terminal window and wonder how the computer knows what you mean when you type ā€œzigā€.
And then you’ll find environment variables and, in particular, PATH, and how to modify them.
On Linux, it’s a bit more complicated than on Windows because there’s LD_LIBRARY_PATH and ldconfig in addition, and the difference between just setting a variable and exporting it.
In this regard, Windows cmd.exe is actually easier for beginners than the various Linux shells.

BTW you don’t have to modify .bashrc if you want to use different Zig versions. You could create different shell scripts which set and export PATH accordingly (one for each Zig version) and use these scripts.

I don’t manually edit PATH for anything. I just type out the path to whatever I execute.

3 Likes

My solution was to just make a compile script that automatically downloads the right zig version.
This has the nice side effect that even people with no programming/command line experience can compile it (which is awesome when making a game).

In many cases, that’s sufficient, but in many cases, it’s not.
From experience, I learned to be cautious.
In particular, when installing software on servers (outside of Docker containers), it’s best to create start scripts which set set the environment variables exactly as needed for your program.

Why don’t you just deliver the compiled program?
Are your users expected to change your program code?

And then you’ll find environment variables and, in particular, PATH, and how to modify them.

Tbh I do this shit for decades now on all sorts of platforms and I still don’t know which of the dozens dot-files in my home directory is the right one to add env variables :wink:

FWIW I’m a happy user of zvm.

1 Like

None of them.

I think this is basically the same mistake that many installers for Windows make: They add entries to the system-wide environment, in particular modify PATH.

I’ve seen and debugged too many issues on production servers which were caused by this.
Thanks to containers, this now happens less frequently at least.

I consider modifying the system (or user) global environment as a configuration error.
If I want to use a specific program that depends on environment variables (most do, just because they depend on DLLs), I create a little start script that sets the variables accordingly, and I maybe I create a link on the desktop to run this script if I need the program frequently.

For me it is the oposite. I dont want development tools having any connection to the internet, especially sending analytics, and then trying to update things under my feet, nightmare.
I dont know if it was zls or codium, but my old dev env would nag me to update zig everytime I started it. I ended up removing zls. I’ll avoid the modules stuff for the same ā€˜offline/local first’ reasons.

No, but it can make debugging faster if I can just tell them to change some code, instead of needing to compile and package a build for them every time.
But the biggest advantage is that it allows our artists (or even players although that happens rarely) to test pull requests before they are merged.

1 Like

To be fair, you can put a binary in a directory that is already in your PATH. I keep different versions of the Zig toolchain in /opt, then put symlinks to the compiler binaries in /usr/local/bin.

If there’s one thing I do find to be a drag here, it’s keeping zig and zls synchronized.

1 Like

I use this webi to install zig in my bootstrap than I use it to compile, Ghostty, Zls, Zigup, uninstall it and use zigup to manage everything

1 Like

Judging by the entirety of Zig, that sounds like something you would do xD

I can see I am not the only one confused by the Linux file structure, and afraid of how packages are managed. Even though I am pretty proficient at Linux imo. It’s ultra magic. In a bad way.

I just use zvm. You can easily install any version of zig with zvm i <version_number> or master for latest nightly. You can easily swap between with zvm u <version_number> or master.

During first install you either source the file it tells you to or close the terminal emulator and start a new one.

Something this also enables is seamless updates for large teams. No spamming the chat with ā€œeverybody upgrade your zigā€.

as a heavy uv user, can’t hold back this one: neither of those commands directly change Python versions. uv self update just updates the uv tool. However, uv does manage Python versions for your projects (as specified in the pyproject.toml for instance; pip never did this btw.).

That said, having zig manage its own versions for zig projects (as specified in build.zig.zon) seems nice to me, although I’m not a particularly heavy zig user to be honest.