Code Staging in GNU Guix
hal.inria.fr
hal.inria.fr
https://www.gnu.org/software/guix/manual/html_node/G_002dExp...
I don't know if it's just me, but a lot of build systems just seem unnecessarily complicated. I don't understand why it's necessary to have any more features than a templating language would provide. So for example, set up a template for each compiler with default values, allow the user to override the default values, and throw an exception if builds fail.
Guix continues to use whatever build system a package requires, such as the GNU build system, the CMake build system, the R build system, the Python build system, etc. Gexps are not an attempt to replace these build systems. They are a way to stage code on the host side that is meant to run on the build side; this could be done with mere S-expressions through quoting, but would require more boilerplate. Gexps provide additional context, which allows for simpler code.
Offhand, in this case in particular, it is probably to provide dependency isolation of things that you are building. Some things work as global to the computer dependencies. Some do not.
As for why give the flexibility allowed with a full language? In large, so that users are not constrained by the single vendor of the templates. You could have multiple vendors of the templates, of course, but I suspect you will find that immediately everyone is encouraged to self vend their own. In which case, few would ever actually talk about the templates, but the language the templates are written in.
At its core, what is a build system meant to do? Build packages based on set configurations, right? In other words:
1. Set compiler flags.
2. Define/include/build dependencies.
3. Set build paths.
4. Build and test packages.
All of the required steps can be managed manually via the command line, and at its core a build system is just a way to automate this work. Why are other command-line tasks so much simpler to automate than package compilation? That's what I want to know.
Also how do you clean behind yourself ?
Same thing for testing with even more setup.
Each dependency has its own build configuration file. You build a tree of dependencies and start compilation from the lowest level (i.e. the build objects without any non-compiled dependencies).
With such an approach, why would you have a hidden dependency?
> "How do you handle time ?"
What do you mean by this?
> "How do you ensure that it can be reproduce ?"
Semantic version control on the dependencies.
> "How do you define the dependencies ?"
Is this a hard problem?
> "How do you make sure that nothing change the build paths ? The deps paths ? That your environment is exactly the one you want ?"
By testing during the build process. In the case of the environment, it's just a question of checking against a list of expected environment settings (e.g. OS version, processor architecture, processor features, etc...).
> "That you dynamicly link to the correct lib ?"
This comes down to version control.
> "Also how do you clean behind yourself ?"
Again, is this a hard problem? Even the simplest of makefiles can describe how to handle this.
Perhaps it's best to give a concrete example of a task which is hard for a build system to manage, because I'm still not seeing the complexity here.
Scheme has good abstraction facilities if you wanted to simplify package definitions somehow.
That said, my complaints about the complexity of build systems extend to package managers also, in that I don't see why they need to be as complex as they are. Part of me thinks it's because the tools lack sufficiently rich metadata to make their jobs easier, but otherwise I don't know what's causing it.
I have no issues with the use of Scheme in Guix (I'm learning Racket at the moment, no major complaints), and perhaps the abstractions will become simpler over time. I don't know enough about Guix to comment further on it. My comments were not aimed at Guix in particular anyway, but were general observations.
This means that you can just use package resources and they are available. This avoids having a seperate list of dependencies which is constantly becoming out of date.
I agree that Guix overcomplicates it, but they didn't have to. It's a natural consequence of using an incredibly powerful host language to embed their build language.
G-expressions are used to generate build-side code without having to resort to ad-hoc string interpolation in a target language like Bash. Ideally, this could be done simply with quoted S-expressions, but the paper explains why S-expressions are a little too primitive to use them conveniently in this case.
The gain here is that there is only one language and one set of rules for everything, namely Scheme. In Nix there is the Nix language and a mix of build-side languages (e.g. shell), where host-side values are embedded in build scripts through string interpolation.
There's work underway to extend the reach of Scheme to the daemon itself.
The wimpiness of the Nix language is a virtue. There is no call/cc. There's no ports, and indeed networking is tamed. The language is just barely powerful enough to do its job, and community members have found it somewhere between intractable and impossible to build compilers, text processors, etc. in Nix itself.
String interpolation is a fitting punishment for our decision to continue to use Unix-styled systems; our systems think in bytes and communicate in bytes, and I see no reason why we should walk away from our highly-developed long-standing relationship with bytestrings as long as we are still on Unix. (You will say something beautiful about Scheme. I am busy looking ahead to capability-aware languages; Nix is a scaffold and nothing else.)
These are not incompatible statements. Guix uses an older version of the Nix daemon that has diverged from Nix mainline. As Schemers we prefer to hack on Scheme things, so we're halfway through writing the missing glue to use existing Scheme tools in place of the C++ daemon.
> Patches aren't flowing from Guix to Nix
They cannot because Guix is not a fork of Nix. Guix is an implementation of functional package management as pioneered by Nix.
(As to your claims about Nix and Scheme: I'm not going to bite.)
Why does there need to be a language? Why can't there just be something like a manifest in JSON?