On Wed, Dec 31, 2014 at 10:17:26PM +0200, ketmar via Digitalmars-d wrote: > On Wed, 31 Dec 2014 10:59:32 -0800 > Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote: > > > On 12/31/2014 4:17 AM, Jacob Carlborg wrote: > > > On 2014-12-30 02:51, Walter Bright wrote: > > > > > >> (And actually, the Ddoc macro system very closely resembles the > > >> one used by make, as that is a simple and effective one, well > > >> known by programmers.) > > > > > > "make" has to be the worst tool ever created. I not just me that > > > has that opinion [1]. That you even consider this as a positive > > > argument is baffling me. Or rather not, if you like "make" I can > > > see why you like Ddoc. > > > > You can not like a car's suspension but still like its engine. > > but 'make' is a failure in every aspect, especially GNU make. bwah, > build tool that can't do autoimatic dependency tracking? you must be > joking.
Yeah no kidding. How do I hate make? Let me count the ways: 1) Recursive make considered harmful. (Google it.) 2) Non-reproducible builds -- you have to make clean; make, just to be absolutely sure your build is correct (defeats the purpose of a build tool, really -- might as well use a shell script of compiler commands). 3) Changing compile flags in a makefile does not trigger rebuilding of all affected targets. You're on your own to kick make into rebuilding what's needed. Usually, this means yet another `make clean; make`. Which doesn't always work -- see (6). A great source of heisenbugs. 4) Unnecessary rebuilds -- if you edit a comment in a header file, it causes a waterfall effect in rebuilding everything that #include's it, and even though all of the .o files produced are identical to those from the previous run, make is oblivious to this fact, and wastes time linking them all and cascading even more rebuilds that depend on the link products, etc., etc.. 5) Timestamps are unreliable -- accidentally touching the timestamp of a header file included by everything (without changing its contents) will cause the entire tree to be rebuilt. Timestamps over NFS may be inconsistent, causing make to randomly rebuild files that don't need to be rebuilt and skip files that do. 6) Dependency scanning is O(n). Not scalable. 7) No built-in cleanup function -- everybody writes their own `make clean` rules, which are inevitably wrong (`rm -rf *.o *.so`, but what if you have an .so that isn't generated by the build?) or incomplete (oops, forgot to delete the .c file generated by bison). This, coupled with (2) and (3), leads to heisenbugs where stale libraries from previous builds get linked into the executable, causing runtime bugs that don't exist in the source code. The solution? `make clean; make` and have another coffee break. Very productive. (Except when your make clean rules failed to delete said stale library, then it's time to \rm -rf and git clone a new repo.) 8) Implicit dependencies between source files require external tooling support (gcc -MF, which leaves stray .dep files all over the place, which `make clean` inevitably forgets to clean up, and which cause mistakes in the dependency tree when dependencies change and the .dep files aren't updated before make reads them). 9) Build parameters (e.g. compiler flags) are not well-encapsulated -- the global CFLAGS has to be tweaked, or you have to invent your own convoluted set of macros that are combined into the final compiler flags, which leads to a maintenance nightmare. 10) No support for out-of-tree builds (which are increasingly becoming clear that it's the superior way to go -- littering generated files in the same directories as source files inevitably leads to a gigantic mess). 11) No support for simultaneous variant builds such as cross-compiling for multiple architectures in the same run (unless you manually write this, which is a royal pain and extremely error-prone for something the build system *should* have taken care of for you) -- because of (7): all build variables are global and there's no way to reuse the same build rules with different target parameters. 12) Many common build tasks are not supported by the core make system, and require the user to reinvent the wheel, which results in large, convoluted, and fragile makefiles that stop working as soon as you try to do something that wasn't anticipated by the makefile authors. 13) Anachronistic syntax requirements, like distinguishing between spaces and tabs. Make is like C... it offers you raw functionality to shoot yourself in the foot and drown in dependency bugs, just like C offers you countless ways to have buffer overruns and dangling pointers. Yet people glory in their scars acquired over decades of pain, and build entire ecosystems around it, such that mention of any alternatives is resisted at best, and ridiculed and summarily dismissed at worst. What's baffling is that such a reaction is observed even in the D community, which, ostensibly, exists exactly because people are finally fed up with the problems of C and want a less painful language. T -- It only takes one twig to burn down a forest.