Non-Recursive Make Considered Harmful [pdf]
research.microsoft.com
research.microsoft.com
Also, I find it amusing that they claim Make's language is horrible, when they admit their replacement isn't shorter, I have to learn Haskell to use their system, and it looks like this (random snippet). No better than Make (in my opinion), and further I have to write unicode arrows?
"∗.o" %> \out → do
let src = out -<.> "c"As a start I'd suggest to read "Shake before building".
Shake should work on Windows, given that Neil wrote a Windows progress bar tool for Shake.
For me, it is a killer feature -- any system where dependencies are maintained manually inevitably gets out of sync with the code. Some systems have special compiler hacks (like gcc's -MM flag), but you still have to find the magic option for each program you use, and link them into your compiler. That's also very hard to do in dynamic languages, where you don't know what libraries you have loaded until you've run the program.
I do use auto-generated/-detected deps for build time dependency graphs, but I didn't like how tup implements it.
And no, you don't have to write Unicode arrows. You write those things as ->. For some reason academic Haskell papers use Unicode symbols where real Haskell uses ASCII.
"Here's a Haskell library, go write your own build system in Haskell" is technically a solution to every build problem, but not a very practical one. Especially because Haskell libraries are themselves so hard to build on a fresh system!
cmake is "pretty good" about exposing policy flags to control compatibility.
Fedora EPEL6 has had to include two new cmake versions so far to be able to build more packages.
The bizarre opeators seem to be an attempt to maintain similarity to make's cryptic oerstorsr
This is why I think everyone should learn programming first and linux second - since many linux tools are terrible.
As expressed in the SICP book - the programming language should allow you to build abstractions. Make doesn't at all allow that.
Abstractions are perfectly possible, you just do it in your own script (Python or whatever) and this way you don't have to learn a new language. Ninja is a better alternative to Make, and it is even less expressive (which is one of the reasons why it is better, IMO).
Or in other words, we build abstractions in Make by composing it with other tools, rather than creating a huge monolithic Makefile syntax which can do anything you want.
It's like saying that "Why use assembly at all? GCC could generate anything." Well, yes. But you're on an x86 machine and there's an assembler right there for GCC to use, and GCC has been using that assembler for decades.
Manipulating files is trivial in any programming language expect maybe in something like C,C++,Java,etc.
Python/js/go make it really easy to deal with complex build systems or even just 1 liners.
So I have no idea why make has any advantage over those - only use-case is if you are writing C where its non-trival to do file-handling.
I moved to npm scripts once I asked the question "how do i make a multi-process build script in make ?"
and all the neck-beards in uni had no answer - so I just write small scripts which grow and shrink based on my needs.
make --jobs=2No idea how you missed the -j option.
This ability to write and compose is a rare feature today. Json is pretty opposite to it and even Yaml is rather bad at it as to compose pieces one have to parse them first.
Here are the recipes, most recent version: https://github.com/marssaxman/ozette/blob/master/srctree.mk
And this is an example of a makefile using those recipes: https://github.com/marssaxman/ozette/blob/master/Makefile
Until they re-implement it again :)
> Unfortunately no cross-platform APIs are available to detect used dependencies, so such tools are all limited in which platforms they support.
How about using libfuse? One could run the build inside a "virtual" folder served by libfuse, and thus detect all dependencies (they will show up as "read" operations in the libfuse API).
As the paper says, every previous implementation started nicely and got horrible towards the end. This time, that hasn't happened, so _hopefully_ it's the final one. But, of course, never say never.
> How about using libfuse?
What about Windows? Certainly you could use something like libfuse, and we're trying other solutions - if we manage to build a cross-platform API Shake will be able to use it easily.
And, besides: a huge impediment to improving the state of build systems is that new build mechanisms won’t be installed on most platforms by default. If you must explore new ways to build, be sure to implement that in terms of what is already there (Perl/Python/whatever) and make sure to ship your new build system WITH your code.
When I download some "neat-project-1.0.tar.gz", the last thing I want is to have to futz with setting up your special build system that Probably Nothing Else uses or will ever use. If it’s not in the tarball, I will already lose a lot of interest; I know most things can "configure, make, make install" in minutes but I don’t know how much time will be wasted installing whizbang-build-0.1 first and I probably won’t even try.
In some cases you do need to re-autoconfiscate, which is why EPEL6 has autoconf268 (from RHEL7). Otherwise there's a software collection with up-to-date autotools, though you might expect them in the devtoolsets.
But I can see the appeal of Ninja files of something that allows one to avoid the GHC requirement in a build environment.
Though I've found Ninja to be more like something that needs to be generated from something else and less something you'd write. So maybe Ninja can be exactly that, kinda like build script assembly.
I use Docker for a similar purpose nowadays. It's inconvenient for development, since rebuilding the containers is slow. But it usually works without much trouble. I think there's a GHC Dockerfile somewhere that hvr maintains.
I haven't used Shake specifically much. The only thing that bugs me is that Haskell isn't nearly as portable as plain Make. If Shake didn't build the program but rather emitted a build-file that a small reference C program could interpret, I would feel much more comfortable about using it for just about everything. Because I'd know that if I was on some ancient CentOS 4 system, I could still build my software.
Used frivolously, it feels like blasphemy.