8 ms·
> One of the things that makes make a great tool is how deceptively simple it is. One of the worst things of Make is how deceptively simple it looks. Make doe
by ReleaseCandidat 2y ago
> One of the things that makes make a great tool is how deceptively simple it is.
One of the worst things of Make is how deceptively simple it looks.
Make does exactly one thing: it takes input files, some dependencies and generates _exactly_one_ output file.
To have rules which don't generate output (like `install` or `all` or `clean` or all targets in the article) we need to resort to a hack, a special magic target like `.PHONY` (which hasn't been part of POSIX up to the 2017 version - IEEE Std 1003.1-2017 - https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html https://pubs.opengroup.org/onlinepubs/9699919799/utilities/m..., only the current one - IEEE Std 1003.1-2024 - https://pubs.opengroup.org/onlinepubs/9799919799/utilities/make.html https://pubs.opengroup.org/onlinepubs/9799919799/utilities/m... includes `.PHONY`). If you want to generate more than one file (like an object file and a module or a precompiled header or ...) you are on your own to build some brittle hack to get that working. Don't forget that not every Make is GNU Make, BSD and other nix like Solaris/Illumos still exist.
Don't get me wrong: Make has it's uses for sufficiently complex projects which aren't too complex yet to need some "better" build system. Problem is that such projects may get too complex when more code is added and they inevitably gain some sort of scripts/programs to generate Makefiles or parts of Makefiles (so, an ad hoc meta build system is created).
And the problem isn't that they use it, but that they are proposing it as a solution to "everybody". And that their Makefile stops working as soon as there is a directory (or file) `build` (or `dev` or ...) in the project root.
- jart 2y agoI work on a project with 4.4 million lines of code and using a single Makefile with no generated code works fine. It's really not all that difficult.
- wruza 2y agoProjects of much smaller sizes often have recursive convoluted makefiles.
- chipdart 2y ago> Projects of much smaller sizes often have recursive convoluted makefiles. You name any technology and anyone can enumerate dozens of projects that use it wrong.
- wruza 2y agoI’d walk that before talking. Take any complex makefile system and turn it into a single “not really difficult” makefile without sacrificing anything important. Wins this argument and helps those who “use it wrong”.
- ReleaseCandidat 2y agoAnd I can show you thousands of "Hello World"s that use GNU Autotools or CMake ;) But seriously: can I take a look at it (Soource + Makefile)?
- Drawde 2y agoThis is most likely what is being referenced: https://github.com/jart/cosmopolitan/blob/master/Makefile https://github.com/jart/cosmopolitan/blob/master/Makefile I like how the includes are separated and commented. Also if you weren't already familiar with their work you might be interested in giving this a read: https://justine.lol/ape.html https://justine.lol/ape.html
- homebrewer 2y agoCan % grep '^include' Makefile -c 159 includes with % wc --lines --total=only $(awk '/^include/{ print $2 }' Makefile) Makefile 22547 lines in total really count as having a single makefile? I have no dog in this fight, just wondering.
- rectang 2y agoI don’t object to “it works for me”, but “it’s really not all that difficult” is a bad generalization. * If you need portability, Makefiles are hard. * The whitespace design of Makefiles is bad and has swallowed up countless debugging hours over the years. This design flaw isn’t intrinsic to the way Makefiles work, it’s just a lousy artifact from a superficial decision from decades ago: to change behavior based on distinctions invisible in source code. It’s mitigated by syntax highlighting but still bites people. * Makefiles are dependent on the consistency of the build environment, for example the availability and behavior of command line switches. Even if your project doesn’t need OS platform portability, this is still a pain across time and requires external tooling to manage. * There are certain subtleties to the way Makefiles behave that are addressed by `.PHONY`. I agree that these are manageable in the absence of other complexities, but they contribute towards Makefiles being more difficult than appears at first. I’m sure you’re familiar with those critiques and others. They may not bother you, but you don’t speak for everybody.
- jart 2y agoMy Makefile is portable. It builds binaries that run on six OSes and two architectures. So I used my Makefile to build GNU Make and a GCC toolchain. Now I can run my Makefile on any of those OSes / architectures too, and it'll produce the same deterministic output, bit for bit.
- whartung 2y agoIf part of your build is building your own build tool in order to ensure you have the proper build tool then why not build a different “better” build tool? Part of the premise of Make is its ubiquity, but if you can’t rely on that save as a simple bootstrap (as you seem to be doing) then why not forego it for something else?
- marci 2y agoAre you suggesting this: https://xkcd.com/927/ https://xkcd.com/927/ ?
- 2y ago
- flykespice 2y agoSure buddy anything can be manageable once you invest enough time and sanity. Now show us the Makefile.
- sshine 2y ago> I work on a project with 4.4 million lines of code [...] It's really not all that difficult. You may be biased.
- oblio 2y ago> If you want to generate more than one file (like an object file and a module or a precompiled header or ...) He's not using C, though :-) > And the problem isn't that they use it, but that they are proposing it as a solution to "everybody". He's proposing it for the same reason I'm starting to like it, after many years in the industry: as a simple build wrapper. > And that their Makefile stops working as soon as there is a directory (or file) `build` (or `dev` or ...) in the project root. And they can fix that problem in 5 minutes, big deal :-) > Don't forget that not every Make is GNU Make, BSD and other nix like Solaris/Illumos still exist. This is a very bad reason in this day and age. 99.999999% of *NIX usage these days, probably 99.9999999999999999% for the average person, since most people won't ever get to those environments where BSD and Solaris are still used, is Linux. And even for BSD and Solaris, guess what... you add an extra step in the build instructions asking them to... install GNU Make. Heck, even back in 2005 (I think?) for Solaris one of the first things you'd do was to install the GNU userland wherever allowed because the Solaris one was so forlorn I swear I heard wooden planks creak and dust pouring down every time I had to use their version of ps. And regarding POSIX, meh. If you're a C developer (C++, Rust, I guess), knock yourself out. Most of the stuff devs use are so far removed from POSIX... Actually, not removed, but has so many non-POSIX layers on top (I mean not standardized). Ruby bundler is not standardized like awk. Python pip is not standardized like make. Etc, etc. That's the reality we're in. POSIX is very useful but only as a very low level base most people don't need to chain themselves directly to. I'd definitely not avoid a tool because it's not in the latest POSIX standard (or only in the latest POSIX standard).
- ReleaseCandidat 2y ago> He's not using C, though :-) As said elsewhere, the use-case in the article is too simple to warrant a Makefile. So: if you aren't compiling some static language, you do not need - and certainly don't want to use - Make. > you add an extra step in the build instructions asking them to... install GNU Make. The main reason to use Make is that it is installed everywhere, as stated multiple times in other posts. If you must install something, you can also install a better alternative for your specific use-case to Make. > one of the first things you'd do was to install the GNU userland Yes, and the Unix vendors even shipped them on companion CDs or similar. > is not standardized like awk Same problem with awk (and sed and ...): some weeks ago I had problem with the SDK for some real-time Linux that works with mawk only, and not with GNU awk (most of the time it's the other way round, only working for some GNU program).
- chipdart 2y ago> Make does exactly one thing: it takes input files, some dependencies and generates _exactly_one_ output file. Not true. Your dependency graph might culminate on a single final target, but nothing prevents you from adding as many targets that generate as many output files as you feel like adding and set them as dependencies of your final target. Think about it for a second. If Make was only able to output a single file, how in the world do you think it's used extensively to compile all source files of a project, generate multiple libraries, link all libraries, generate executables, and even output installers and push them to a remote repository? > To have rules which don't generate output (like `install` or `all` or `clean` or all targets in the article) we need to resort to a hack, a special magic target like `.PHONY` I don't understand what point you thought you were making. So a feature that boils down to syntactic sugar was added many years ago. So what? As you showed some gross misconceptions on what the tool does and how to use it, this point seems terribly odd. > And the problem isn't that they use it, but that they are proposing it as a solution to "everybody". I think you're making stuff up. No one wants Make to rule the world. I don't know where you got that from. I think the whole point is that Make excels at a very specific usecase: implement workflows comprised of interdependent steps that can be resumed and incrementally updated. Being oblivious of Make leads many among us to reinvent the wheel poorly, using scripting languages to do much of the same thing but requiring far more work. If you can do this with a dozen lines of code in a Makefile, why on earth would you be churning out hundreds of lines of any random scripting language?
- ReleaseCandidat 2y ago> Not true. Your dependency graph might culminate on a single final target, but nothing prevents you from adding as many targets that generate as many output files as you feel like adding and set them as dependencies of your final target. Sorry, I did phrase that badly. A better version of that sentence would be A single target (a single node in the dependency graph) of Make does exactly one thing: it takes input files, some dependencies and generates _exactly_one_ output file. > I think the whole point is that Make excels at a very specific usecase [..] Excatly what I wanted to express with my post above. But the article isn't about such a case, but for something for which a single shell script (or, better, just adding the commands to the `scripts` stanza of `package.json`, which is the more common, expected way to do it) is actually better suited and way less error prone.
- anymouse123456 2y agoI don't understand this statement, "which hasn't been part of POSIX up to the 2017 version - IEEE Std 1003.1-2017." I've definitely been using .PHONY on various Linux and MacOS computers long before 2017. Maybe it's just me, but I've never much cared for whether or not something is specified if it happens to be present everywhere I go.
- ReleaseCandidat 2y ago> I've definitely been using .PHONY on various Linux and MacOS computers long before 2017. Me too, and I've also used Makes which didn't (on e.g. Irix). What I wanted to express had been that you can't even rely on `.PHONY` existing, much less many other features.
- theamk 2y agoI think it's pretty reasonable to expect GNU make to be available, and rely on its features. IRIX is dead for 18 years now.
- ReleaseCandidat 2y agoIf I may cite myself: Don't forget that not every Make is GNU Make, BSD and other nix like Solaris/Illumos still exist. And I'm not even talking about Windows and Nmake.
- theamk 2y agoBoth BSDs and Solaris provide gmake via official channels. There is "make" for Windows too, but it's not as relevant - the windows commands are so different, it's unlikely you'll have a cross-platform file for Windows and BSD/Linux, unless you require user to install unix tools on Windows, in which case they will likely come with GNU make. I think in most cases, using GNU make is the easiest way to provide compatibility with multiple OSes. There are certainly exception - if your daily driver is FreeBSD, use BSD make. But for Mac OS or Linux users, GNU make is a good default.
- deleted 2y ago[deleted]
- stabbles 2y ago> If you want to generate more than one file A pattern like tgt: generate_many_files touch $@ is pretty common. What's the issue?