While Guix eventually runs a builder script, the script is 1) a Guile script and 2) not directly provided by the user but the result of compilation.
Guix does not stitch shell scripts together. Builds in Guix are split into build phases, which are Guile procedures. Build system abstractions are collections of these procedures. A packager can inject additional build phases or delete existing build phases from these build systems on a package by package basis.
The `trivial-build-system` is used for packages where none of the existing build systems are applicable, not even with build phases removed or added. This works but is not used very often as it is often more convenient to start with something like the `gnu-build-system` and to replace phases by providing new procedures; this is done to benefit from build phases that the `gnu-build-system` provides, such as those that unpack the sources, patch shebangs, or validate the binaries.
Guix provides build system abstractions like `gnu-build-system` for traditional build systems, but you can easily override or extend the build phases. You can run scripts with `(invoke "my-script.sh")`.
The bigger problem, in my opinion, is that packages that use custom build systems often have strange ideas about what is desirable in a build system. Sometimes they prefer to download things during the build (that's not permitted in Guix) or they will make assumptions about the layout of directories or the discovery of dependencies.
Patching away all of these invalid assumptions can be annoying, but it is possible as is demonstrated in many package definitions in the `(gnu packages bioinformatics)` module.
Gexps are not a build system implementation. They are a means to generate code.
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.
Guix may not manage software compilation, but it is passing parameters to the compilers used to handle compilation. So whilst its not a build system per se, it can be seen as part of the overall build infrastructure.
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.
If the build method has not changed then all you need is five tarballs and use `guix build foo --with-source=foo-0.0.n.tar.gz`.
> build system pulls in a big GUI toolkit binary
This is less likely to work, but it depends on how the big binary is linked.
> just something quick and dirty
You can use "guix build foo --with-source=..." for quick and dirty things. For something slightly less quick and slightly less dirty you can define a local package expression using the Guix DSL, dump that in a file, and build it from there.
The build farm is set up to build substitutes for a selection of x86_64 micro-architectures, as the article mentions. If you tune for one of them, you'll get substitutes and won't have to build locally; otherwise, Guix will transparently fall back to building the tunable package locally.
> That's a rather dated view of what a build system should be
The author mentions JavaScript, which has npm as the package manager, which isn't a build system. It can _invoke_ a build system, but the build output produced is separately published to npm, or the build is triggered by e.g. a post-install hook.
I use GNU Make with npm. Some use e.g. Grunt. Etc.
> More importantly, there's also been a push towards wherever possible installing dependencies into sandboxes to try to prevent things like DLL hell, which isn't possible if you install dependencies at the OS level.
Make has been used this way for quite some time. Debian has its reproducible builds project. GNU Guix builds everything in an isolated environment, and even handles multiple versions of multiple packages---if you have five different packages that each depend on five different versions of the same library, then it'll install five different versions of the library and work just fine.
> I much rather just check out a project and run its build system to fetch all the dependencies instead of what we used to have to do with C projects
Make is just _part_ of a build system---it isn't necessarily one in itself. Some projects might use it exclusively in their build system, but others use a suite of tools. I use Autoconf (which generates configure) and Automake, which in turn generates a Makefile with all standard targets. If you check out a git repository for one of my JS projects, you run `npm install` to get the dependencies before building. Usually they're runtime dependencies, though, so they're not needed for the build. Other dependencies are detected via the configure script (e.g. I use graphviz for certain project, and the script makes sure it's installed and supports the feature I need).
My entire build can run in less time than a ./configure script.
It doesn't require developers to run ./autogen.sh, or to have autotools installed (in their correct versions).
It doesn't contain obscene amounts of indirection, where the actual libraries live in a hidden directory called .libs (looking at you, libtool).
It doesn't make you write m4, or Makefile.am files with all these magic incantations. It doesn't make you delve into the guts of these crufty systems when things don't work the way you expect.
If you want build systems to satisfy your use cases, publish some doc of best practices and capabilities that all build system interfaces should provide. If I'm convinced I'll be happy to conform to the interface you need. But there is no way you're going to convince me that everyone needs to just keep using autotools (a specific implementation) forever. I hate them.
I mean, by that logic, why are you doing something new like GNU Guix when everybody already knows/uses APT, RPM, BSD ports, etc? "Just learn [them], get over the fact that they contain backwards-compatibility crud (that you can just ignore, or how does it hurt you?), and stop the FUD."
Or maybe it is worth breaking with the past sometimes, when you think you can do better.
I've come to think that build systems are a very personal utility. Everyone has their favourite. Mine's fabricate.py, for example. Over time I've built up a library of script snippets and shortcuts and so on which I'm familiar with, comfortable with, and exactly fulfil all my use cases. It's all very clever. :)
Yet when I download some random project's source code, I groan at any sophistry in the build process at all. I'm not interested in your build system - I'm interested in the application itself. Maybe I want to try and fix a bug, or have a half-baked idea for a new feature. I don't need dependency checking, incremental rebuilding, parallel building, and all that stuff you get from a fully operational build system at this point. I only need to build the project - once - as I decide whether to stick around. Sure, if I start working on it for serious, rebuilding over and over - then I'll bother to learn the native build system, and read any complicated scripts. Build systems are an optimization for active developers. They're a utility that is supposed to save time.
Of course, you're never going to get everyone in the world to agree on the same build system. We all have different desires and needs for what machines it should run on, how automated, how much general system administration it should wrap up, how abstractly the build should be described, etc. It's a bit like one's dot files or choice of text editor - my ideal build is tailored just for me but I wouldn't expect it to satisfy anyone else.
So now I wish that everyone who distributes software as source code would do this: include a shell script that builds the project. Just the list of commands, in the order that they are executed, that carries out a full build on the author's system. That's what it comes down to, in the end, isn't it? Your fancy build system should be able to log this out automatically. (Of course then you still include all the fancy build stuff as well, for those interested.)
Of course it's extremely unlikely that your shell script will work on my system without modification. There's probably machine-specific pathnames in there for a start. We might not even use the same shell! It's basically pseudocode. But if I'm faced with a straight list of imperative shell commands that doesn't work, and a program of some sort with its own idiosyncratic syntax and logic and a hundred-page manual and the requirement for me to install something - which also doesn't "just work" - well, as long as you know how to call your compilers and linkers and so on - which you should - the former is going to be easier to tweak into submission, to get that first successful build. After all, if I need much more than that I'll probably just recreate the build in my favourite system anyway.
What's cumbersome about copying a couple of files and adding them to your build scripts? At least that way you have complete control over the entire update and build process, you can use the build system of your choice, and you know exactly that there are no 'surprises' lurking in your dependency tree. It also nudges you to avoid libraries that come with complex build requirements (which will always pay off long term).
I write scheme not for a living. My build script is a scheme file or a makefile, depending on the project.
The build complexity is one of the reasons I stay away from Java: If these people think they need XML for builds, what other needlessly complex horrors have they perpetrated? And that sort of thing.
If you're interested in this sort of thing, this is an excellent paper on build system design, although it focuses more on the properties of the build graph than on how the graph is constructed:
>which don't have any benefit of being a part of a "build" system anyways
Building a package doesn't imply compilation of the binaries the package is composed from. Packages are meant to provide easier distribution and maintenance.
A lot of the time I see these build systems try to solve a few issues:
1. Dependency handling
2. Single script for multiple platforms
3. Easy for a new user to just "run"
But I have yet to find a build system (for C/C++) that solves all these issues better than simply having a few scripts.
I use just a build.batch, linux_build.sh and osx_build.sh usually and I have never had problems.
A new user can just download those scripts, and as long as they haven't tampered with file/library locations it just works.
If people like their build systems - fine by me - but I just think they are unnecessarily complex a lot of the time. Granted I don't have a huge project with 100's of dependencies, but even then, those dependencies don't come all at once.
Guix does not stitch shell scripts together. Builds in Guix are split into build phases, which are Guile procedures. Build system abstractions are collections of these procedures. A packager can inject additional build phases or delete existing build phases from these build systems on a package by package basis.
The `trivial-build-system` is used for packages where none of the existing build systems are applicable, not even with build phases removed or added. This works but is not used very often as it is often more convenient to start with something like the `gnu-build-system` and to replace phases by providing new procedures; this is done to benefit from build phases that the `gnu-build-system` provides, such as those that unpack the sources, patch shebangs, or validate the binaries.
reply