4 ms·
Makefiles are terrible tech. The problem is that they're slightly less bad than most other build system we've come up with, which makes them "useful" in a masoc
by kstenerud 2y ago
Makefiles are terrible tech. The problem is that they're slightly less bad than most other build system we've come up with, which makes them "useful" in a masochistic way.
Build systems tend to commit one or more of the following sins:
* Too basic: Once you try to build anything beyond a toy, it quickly becomes chaos.
* Too complicated: The upfront required knowledge, bureaucracy, synchronization and boilerplate is ridiculous. The build system itself takes an order of magnitude more data and memory than the build target.
* No standard library (or a substandard one that does things poorly or not at all): You must define everything yourself, leading to 10000 different incompatible implementations of the same build patterns. So now no one can just dive in and know what they're doing.
* Too constricting: The interface wasn't built as a simple layer upon an expert layer. So now as soon as your needs evolve, you have to migrate away.
* Too much magic: The hallmark of a poorly designed system. It doesn't have to be turtles all the way down, but it should be relatively close with few exceptions.
* Cryptic or inconsistent syntax.
- sixthDot 2y ago> Once you try to build anything beyond a toy, it quickly becomes chaos. Of course the chaos is not caused by, "very hypotheticaly" let's say, a compiler or maybe a language without modules. How would you estimate that ? 20%, 40%, or 70%, true ?
- tomjen3 2y agoNot OP, but its not just that C/C++ lacks modules. I think that is missing the real issue. Any complicated program probably needs a custom developed tool to build it. As a simple example, imagine a program that uses a database - you want to keep the sources as SQL and generate classes from them. Thats a custom build step. Its just that in some languages and build systems (Node, Maven), we have abstracted this away by calling them plugins and they probably come from the same group that made the library you need. No such pluginsystem exists, as far as I am aware, for makefiles.
- ReleaseCandidat 2y agoGood luck writing Makefiles for Fortran, OCaml or (whenever they will really, actually work) C++ modules. There aren't many widely used build systems that can handle such dynamic dependencies without some special "magic" for these, the only one that I know of (with a significant number of users, so not Shake) is Buck 2 (Bazel and all C++ build systems use "special magic", you can't write in user rules).
- instig007 2y ago> Good luck writing Makefiles for OCaml So what's the problem exactly? https://mmottl.github.io/ocaml-makefile/ https://mmottl.github.io/ocaml-makefile/ Oh look, it even builds a project faster than Dune: https://discuss.ocaml.org/t/dune-build-vs-makefile/11394 https://discuss.ocaml.org/t/dune-build-vs-makefile/11394
- ReleaseCandidat 2y ago> So what's the problem exactly? They all have the samé problem: that you don't know the name (or even the number) of modules (module files) being generated without reading the source. And as a bonus every compiler uses a sligthly different naming scheme for the generated module file (this is of course no problem for OCaml ;). As an example (using Fortran). File `test.f90`: module first contains subroutine hello () end subroutine hello end module first module second contains subroutine world () end subroutine world end module second `gfortran -c test.f90` yields the following files (2 of them are modules): -rw-r--r-- 1 roland staff 221 Sep 21 19:07 first.mod -rw-r--r-- 1 roland staff 225 Sep 21 19:07 second.mod -rw-r--r-- 1 roland staff 185 Sep 21 19:07 test.f90 -rw-r--r-- 1 roland staff 672 Sep 21 19:08 test.o
- overanalytcl 2y ago> Good luck writing Makefiles for Fortran, OCaml or (whenever they will really, actually work) C++ modules. I've successfully written Makefiles for Fortran and they worked with ifort/ifx and gfort. In my experiments I've also made GNU Cobol, GNU Modula-2 and Vishap Oberon fit within the Makefile paradigm without much trouble. You have failed to provide reasons as to why those languages in particular (or more likely any language that's not of C heritage) can't be used with Makefiles. For instance, you can definitely couple OCaml with Makefiles, just use ocamlopt and treat .cmx files as object files, generated beforehand by ocamlopt -c (like you'd do with GCC). I am not familiar with C++ modules and as such I didn't experiment with them.
- kaba0 2y agoThere are projects that generate files, depend on multiple languages, etc. If you push the job of a build tool to the compiler infrastructure, then why even have a “build tool” in the first place? Make is simply anemic for anything remotely complex, and there are countless better tools that actually solve the problem.
- imtringued 2y agoYeah my biggest problem with make is that the compiler has to generate the header file dependencies. This means starting a C or C++ project with make from scratch is a hard problem and there is no default solution or default file for this other than to just use CMake.
- ristos 2y agoMy 2c: Makefiles are excellent tech, just that a lot of people haven't learned to use it properly and use it as it was intended. I'm sure I'll get pushback, that's ok. - Too basic: At least half of the software I use just uses plain makefiles and maybe a configure script. No autotools. I optionally run ./configure, and then make and make install, and it just works. I definitely wouldn't consider my setup to be a toy by any stretch of the imagination. It's built out of smaller programs that do one thing and one thing well. - Too complicated: I don't know, I think make and how it works is really easy to understand to me at least. I guess everyone's had different experiences. Not necessarily your case, but I think usually it's because they had bad experiences that they probably blamed make for, when they were trying to build some complex project that either had a bad build setup itself (not make's fault), or without the requisite knowledge. - No standard library: It's supposed to be tooling agnostic, which is what makes it universally applicable for a very wide range of tools, languages, and use cases. It's viewed as a feature, not a bug. - Too constricting: I'm not sure what you mean here, it's designed to do one thing and one thing well. The simple layer is the dependency tracking. - Too much magic: Cryptic or inconsistent syntax: See 'Too complicated'
- IshKebab 2y agoI agree. Also a lot of the replacements are focused on one language rather than being a generic "do stuff" tool like Make. The fact that Make can't even do subdirectories sanely is kind of ridiculous. Does anyone know of anything better than Make? There's Ninja but it's not designed to be written by hand.
- ReleaseCandidat 2y ago> Does anyone know of anything better than Make? Xmake https://xmake.io/ https://xmake.io/ for C and C++ (I haven't use that for anything serious yet) and Buck 2 https://buck2.build/ https://buck2.build/ if you need a really complex build system. Both of these do caching of build artifacts and can do distributed builds (with less and more complex setup).
- IshKebab 2y agoYeah I've been following Buck2. Definitely interesting. Xmake looks interesting too (even though I hate Lua). I wonder why it isn't more popular - I don't think I've seen a single project use it.
- feelamee 2y agoI think just[1] is a good generic "do stuff" tool [1] https://github.com/casey/just https://github.com/casey/just
- IshKebab 2y agoIt's not a build system though. I mean a generic build system like Make, but without some of the terrible design decisions.
- feelamee 2y agothere is also gn[1]. It doesn't seem to be very popular, but feels good in my experience. [1] https://gn.googlesource.com/gn https://gn.googlesource.com/gn
- cryptonector 2y agoThe worst build systems are the ones centered on a particular programming language. Since there's N>>1 programming languages that's N>>1 build systems -- this does not scale, as the cognitive load is prohibitive. The only general-purpose build system that spans all these languages is `make` or systems that target `make` (e.g., CMake). And this sucks because `make` sucks. And `make` sucks because: - it's really difficult to use right (think recursive vs. non-recursive make) - so many incompatible variations: - Unix/POSIX make - BSD make - GNU make - `nmake` (Windows) - it's rather ugly But `make` used right is quite good. We're really lucky to have `make` for the lowest common denominator.
- instig007 2y agoNix is a general-purpose build system that spans all these languages.
- yencabulator 2y agoI've never seen anyone use Nix to actually build software; it's a glorified launcher for shell scripts in a sandbox, and typically is used to start the actual build system, such as make/cargo/go build/npm/etc, with known inputs.
- zokier 2y agoMake is very much centered around C. For example, make has built-in default rules for building C code https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html#tag_20_76_13_09 https://pubs.opengroup.org/onlinepubs/9699919799/utilities/m...
- kaba0 2y agoGradle and Bazel are absolutely general purpose build tools that are very widely used in industry. As a smaller contender, my personal favorite is the Mill build tool (written in Scala), that is basically what a build tool should be, it’s as close to a theoretical perfect as possible. I really advise reading the blog post by its author Li Haoyi: https://www.lihaoyi.com/post/SoWhatsSoSpecialAboutTheMillScalaBuildTool.html https://www.lihaoyi.com/post/SoWhatsSoSpecialAboutTheMillSca...
- deleted 2y ago[deleted]
- zelphirkalt 2y agoOne or more, OK that leaves of course lots of room. I would estimate: (too basic) Makefiles are not. (too complicated) They can be, depends on what you make them to be. (standard library) Well, there is one, there are some builtin functions you can use in the makefile. (too constricting) Haven't noticed that, so I would say no. (too much magic) Hmmm I don't see it. It is very clear what is a target and a dependency and so on. Not so magical. (syntax) Yeah definitely could be better. Even a plain JSON file would be better here.
- ratboy666 2y agoYep, terrible: I will show how Make hits every one of your complaints: (sarcasm on) in file hello.c: #include <stdio.h> int main(int ac, char **av) { printf("hello\n"); return 0; } How to compile and run this? We need a build system! Download and install GNU Make. When that step is complete: Type in make hello and its done. Now, run via ./hello See, Too much magic (didn't even have a makefile or Makefile), no standard library, Too constricting, cryptic, too basic. And, because you had to install Make, too complicated. Hits every one of your objections. (sarcasm off)