Just, Nix Shell and Podman are a Killer Combo
- A four minute read
- 35 comments
Let’s say, for some unclear reasons, you need to compile the “Hello World” C program using a variety of C compilers.
Let’s also say that your dev machine is a MacBook, and some of these C compilers run only on Linux.
Let’s start with Clang. Clang is the default C compiler on macOS, and you probably have it already
installed. Let that be the case, and you compile hello.c
by running:
clang -o hello-clang hello.c
Well and good. But you don’t want to be typing all that every time you need to compile (your unusual
circumstances compell you to compile the file again and again). So you put it in a justfile
:
Great! Now you use Just, a modern command runner, to run Clang, like so:
just build-clang
Just when you think you troubles are over, you remember that you need to compile the file using GCC as well. macOS does not come with GCC installed, and now you need to figure out how to install it and its dependencies. You can Homebrew that stuff, but you know better.
Enter Nix. Nix is a lot of things, but for the purpose of this post, it is a way to easily create
reproducible development environments. So after installing Nix, you quickly put together the shell.nix
file that
gathers your dependencies, and makes them present your shell’s $PATH
:
Next, you expand the justfile
so that it compiles hello.c
with GCC:
With this setup, you compile hello.c
with GCC by running:
just build-gcc
The _run-in-nix-shell
Just command takes care of automatically starting the nix-shell
if
required. nix-shell
downloads GCC and its dependencies for you, and sets them up correctly,
so that you don’t have to care about a thing in the world.
Except one thing: now you also need to compile hello.c
with TinyCC, and for some bizzare reasons,
it so happens that TinyCC runs only on Linux, and not on macOS. You can spin up a Docker container,
but again, you know better.
You decide to use Podman.
First you alter shell.nix
to set up Podman et al., and TinyCC:
Then you write the Just commands to create and operate a Podman container:
And the helper commands to run Just commands in the Podman container:
And finally, the commands to run TinyCC on hello.c
:
Finally, you compile hello.c
with TinyCC by running1:
just build-tcc
You watch in amazement as Nix downloads Podman and QEMU, Just sets up and runs the container, Nix downloads
TinyCC within the container, and TinyCC finally compiles the file. Everything cleans up afterwards,
and you are left with a hello-tcc
binary file in your directory, which you cannot run because it was
compiled on Linux, and you are on macOS2. But whatever. You job was to compile, not to run. You pack
up your laptop, move to the living room, and open it again to browse Reddit. A day well spent3.
If you have Just installed at the OS level, you can run Just commands from other directories as well, like this:
↩︎just ~/Projects/just-nix-podman-demo/build-tcc
This
justfile
runs fine on a Linux machine as well, except thebuild-clang
command.↩︎The use-case described in this post is a rather trivial and contrived example, but this pattern has served me well in real-world use-cases.↩︎
Got suggestions, corrections, or thoughts? Post a comment!
35 comments
candeira
peterbourgon
dud8
mixedCase_
dud8
andyc
carlana
andyc
sfultong
jakuzureno
Abhinav Sarkar
Abhinav Sarkar
matklad
eterps
matklad
viraptor
matklad
MazeChaZer
ploynog
Abhinav Sarkar
leothrix
shogditontoast
Apprehensive_Sir_243
shogditontoast
Abhinav Sarkar
leothrix
pbsds
Apprehensive_Sir_243
Aidenn0
Abhinav Sarkar
BosonCollider
toastal
Abhinav Sarkar
knl
toastal