12 ms·
Absolutely do not use make for any new project. If you love make, it's a big, red, burning flag that you're not demanding enough of your tools and that you're n
by mseebach 14y ago
Absolutely do not use make for any new project. If you love make, it's a big, red, burning flag that you're not demanding enough of your tools and that you're not keeping up with changes in your ecosystem.
There are many, many way better alternatives to make. Which one is better depends on the platform you're on. The majority of them throws in automatic dependency management for free.
Yes, I know that the essence of the post is "use a build system". I agree completely. In fact, script everything. Then script your scripts. Then refactor your scripts because they are getting messy. But don't give impressionable souls the idea that "make" is anywhere near an acceptable (generalised, default) choice today.
- falcolas 14y agoLots of "Don't do this" without suggesting alternatives doesn't do anyone much good. If you're on a *nix system, building C/C++ programs (or automating one-off builds like the example), what would you recommend in make's place?
- lmm 14y agoCMake
- craftkiller 14y agoPersonally I'd suggest Premake because it uses Lua instead of rolling its own scripting language. The world would be a better place if we could all agree on one scripting language for stuff like this so no one has to look up the syntax for things like creating arrays for every individual tool. Feature-wise premake isn't entirely caught up to CMake but it has everything important. Also the premake files look a lot cleaner and more readable compared to cmake files.
- leif 14y agohttp://xkcd.com/927 http://xkcd.com/927
- quotemstr 14y ago> The world would be a better place if we could all agree on one scripting language for stuff like this It's called bloody "make". If Prolog is a language, so is make. Make is still a scripting language even if it's not boneheadedly sequential and imperative the way, say, Python is.
- deleted 14y ago[deleted]
- Peaker 14y agoMake is simply not up to the job. It make writing correct build systems very difficult (hard to not under-specify dependencies). It does not support auto-generating code and then scanning it for extra build dependencies. It is a crappy tool and we should standardize on something better.
- lmm 14y agoIf what you want is a standardized language Scons has that and is a bit more established.
- swift 14y agoCMake is pretty ugly in its own right, though I will grant it's hard to be worse than GNU make.
- jahewson 14y agoCMake is an abomination
- xymostech 14y agoMind pointing out any constructive arguments against it? I recently switched over from hand-built makefiles to cmake for one of my projects, and it's been a breeze.
- wtracy 14y agoI have never been able to figure out how to cross-compile a project that uses CMake. GNU Make lets you just set some environment flags and drop in a different compiler.
- cmccabe 14y agoCMake honors the same environment variables as Make. Just set them before running CMake. CMake also supports cross-compiling. www.vtk.org/Wiki/CMake_Cross_Compiling
- quotemstr 14y agoI prefer autotools to CMake. Maybe I didn't really give CMake a fair shot, but in a few hours of trying, I couldn't out figure out the CMake equivalent to a bit of custom glue code in configure.ac that checked for a Lisp compiler. I get the feeling CMake works fine as long as you color within the lines, but that it's much harder to extend than autotools is.
- McUsr 14y agoYes, this is something I have thought through, though I may have been lucky/unlucky with my pick of projects. But generally speaking, installs I have installed based on GNU autotools, seems to install with less fuzz than those with C-Make. So, that, and the fact that there is full free documentation of GNU Autotools, even books out there, have made my personal choice easy. For me the overall factor is the ease for any of my users, installing something I have written.
- mseebach 14y agoI debated whether to start namedropping build systems, but I decided it was going to be counter productive and devolve into a debate of the relative merits of the systems I'd picked out. In the end it depends heavily on the environment you're in what makes sense for your project.
- NelsonMinar 14y agoIn other words: if you're not sure, use make.
- lmm 14y agoNo, really not. If you pick a build system at random it's probably better than make. If it's a big project it's worth taking 30 minutes to actually look at what's available and pick one.
- lflux 14y agoNinja.
- vinkelhake 14y agoYou probably don't want to write ninja files yourself. CMake + Ninja is a nice combo.
- Peaker 14y agoI'd suggest tup[1] and Shake[2]. [1]: http://gittup.org/tup/ http://gittup.org/tup/ [2]: http://community.haskell.org/~ndm/shake/ http://community.haskell.org/~ndm/shake/
- payload 14y agoThanks for the links! I will definitely use tup for some next project. I try from time to time different make-like systems but I always come back to GNU Make. I also don't fear the GNU Make Reference. But tup looks, again, quite promising. It even has those little context sensitive one-special-char one-letter variables :) But they do something better by design, I see http://gittup.org/tup/make_vs_tup.html http://gittup.org/tup/make_vs_tup.html
- quotemstr 14y ago> This page compares make to tup. This page is a little biased because tup is so fast. How fast? This one time a beam of light was flying through the vacuum of space at the speed of light and then tup went by and was like "Yo beam of light, you need a lift?" cuz tup was going so fast it thought the beam of light had a flat tire and was stuck. True story. Anyway, feel free to run your own comparisons if you don't believe me and my (true) story. The completely unprofessional tone here really turns me off to the entire system. If you write like a typical teenager, you probably code like a typical teenager, and I don't want a typical teenager writing my goddamn build system. Besides: who the hell is bottlenecked on the build system? The compiler and linker (or the equivalent for your favorite language) do all the work. Anyone who believes this article makes a different is completely ignorant of Amdahl's Law.
- plorkyeran 14y agoFor very large projects the build system can quite easily become the bottleneck when just changing a single file, which also happens to be the most important use-case for developers. In extreme cases a no-op build with make can easily get to 15+ seconds.
- rachelbythebay 14y agoAssuming you're building your own code and are willing to arrange things in a compatible manner, then I have a solution to offer. It figures out the dependencies by reading the source code. You can create objects and binaries just by asking it to build a certain target. I recorded an example of installing and using it here: http://rachelbythebay.com/jvt/view?bb_install http://rachelbythebay.com/jvt/view?bb_install You can get a copy for experimentation here: http://rachelbythebay.com/bb/ http://rachelbythebay.com/bb/ It isn't for everyone, but only you can know if it'll meet your needs. Hopefully this helps.
- quotemstr 14y ago> willing to arrange things in a compatible manner, then I have a solution to offer. So you're proposing that people give up screwdrivers because figuring out what bit to use is hard, and that they should instead use your potato peeler, never mind that it doesn't actually drive screws?
- rachelbythebay 14y agoNope. Not at all. But I like that you think that.
- _phred 14y agoWhoa, your terminal playback thing is pretty neat. Did you use GNU Screen to record the session?
- rachelbythebay 14y agoThank you! I used script. Certain implementations have an option to emit timing and byte count data on stderr. Then it's just a matter of saving it and building something to honor those delays during playback.
- kragen 14y agoThat's awesome! I had no idea about `script -t`; I'd written my own a few years back. Thank you!
- jhasse 14y agoScons: http://scons.org/ http://scons.org/
- niggler 14y ago"There are many, many way better alternatives to make" Can you give an example with the ubiquity of make and better expressiveness?
- mseebach 14y agoNo, probably not. But I think the metrics you've chosen are irrelevant. Make was not only the best, it was the only player in the game until quite recently, so of course it's ubiquitous. As for expressiveness, yes, it certainly is expressive. It's also very hard to learn and very difficult to maintain. But build systems such as Gradle or SBT, are also incredibly expressive, by virtue of being configurable in actual programming languages - with the added benefit of not having to learn a new language.
- niggler 14y ago"But I think the metrics you've chosen are irrelevant." Nothing is more frustrating than discovering that you need to install a new component or build system just to build a specific component. It gets worse when dealing with multiple external components in different build systems. "It's also very hard to learn and very difficult to maintain" I agree insofar as most people go into make without trying to learn it properly. There's a manpage and pretty good documentation for the GNU extensions. But in my experience, with custom build setups using stuff like Maven, a lot of time is spent fighting the build system when a simple Makefile would suffice. "with the added benefit of not having to learn a new language." You've shifted the burden from "learning a new but very simple language" to "learning a framework atop your language", which (based on my reading of gradle's docs) is not very concise.
- imissmyjuno 14y agoIndeed, mseebach's answer is really saying that those metrics are irrelevant to him.
- mseebach 14y agoNo, what I'm really saying is that if you get to cherry-pick the metrics, you can win any debate. Of course there are tradeoffs in anything, and if the expressiveness of your build script is the deal-breaker for your project, by all means use make. On the whole, I will still argue that more modern alternatives provide a better total experience. Also, note that the OP is directed at beginners.
- w3pm 14y agoUse the best tool for the job. Your advice is probably correct for whichever apps you've written in the past, but it's definitely not correct in the general case. Appropriate tools are highly dependent on what you're building. In my area of experience make has been more than adequate (crossplatform games and Erlang servers with rebar + make). Yes the syntax is arcane and ugly but it does a fine job.
- mseebach 14y agoWhile my advice might not be directly applicable in the general sense, I maintain that the headline advice of the article is wrong in the general sense. Also, I quite specifically didn't claim that make is never the right choice.
- gatherknwldg 14y ago"Which one is better depends on the platform you're on" That works against a portable build. That still matters to some of us.
- mseebach 14y agoBy 'platform' I meant programming language and execution environment (JVM/Ruby/Python), not OS.
- gatherknwldg 14y agoI'm fond of not having the number of build systems I'm responsible for maintaining grow in step with the number of programming languages I use in a project.
- mseebach 14y agoAll build systems I've come across are quite happy to build code in other languages - just like make. The reason I'd recommend the dominant system in each ecosystem is, well, that: It's dominant, thus likely to be better supported for the issue you're likely to face.
- gatherknwldg 14y agoI've gone back and re-read your comments in this post and tried to find something concrete in them. You use strong, imperative language, yet I have no idea what you are recommending.
- mmphosis 14y agoWhich one is better depends on the platform you're on. We are not stuck on any particular platform, we target numerous platforms new and old. Using make, the target may determine which of those wonderful tools in our ever changing (improving, failing and obsoleting) ecosystem does the actual build. build: xcodebuild -target MyApp -configuration Release clean xcodebuild -target MyApp-universal -configuration Release-universal clean But all I need to do is type make
- beagle3 14y agoIf you are on a unix system, "redo" (designed by djb and implemented by apenwarr) is excellent. It's refreshingly simple and robust. And, there's a minimalist version called "do" which is a hundred-or-so lines of shell, that does a complete rebuild (no dependency tracking) - so you can package that with your project, and not have to worry about your users having to install yet another build system. Other alternatives I'd recommend, with some degree of success: SCons - cross platform, but slow (every big enough project eventually abandons it) waf - a unix-only (AFAIK) SCons derivative that's a bit more limited, but much faster CMake - cross platform, very complete, on par with Make on every level (including ugliness and complexity) Premake - cross platform, makes IDE file but can also write makefiles for you.
- jhasse 14y agowaf is cross-platform (Python) https://code.google.com/p/waf/ https://code.google.com/p/waf/
- lifthrasiir 14y agoI don't know if waf is really faster than other alternatives, but having used waf in production, I can safely say that deploying waf is at best hellish. A single-file script with zipimported package that extracts itself to a world-writable hidden directory? Crazy.
- eckzow 14y agoFor Unix-only and smaller projects another great option is fabricate.py
- Game_Ender 14y agoThanks for the tip on fabricate, it appears to be just the tool I was looking for. A light weight dependency based "build" system in python that is not focused on distutils or making python packages. We shall see how well it works for data processing.
- 14y ago
- dap 14y agoI agree that make's syntax is hard to pick up and often unintuitive, but in my experience, if you reject make, it's a big, red burning flag that you don't fully understand the problems that it solves. The ability to define arbitrary dependencies and actions (including overriding built-in ones) is the defining aspect of a build system. All of the build systems I've used besides "make" (mostly scons, waf, ant, and gyp) have attempted to first-class certain types of dependencies, and the better ones allow you to define some of your own, but they all make assumptions about what one might want to do that make things I do all the time impossible (or at best, way off the beaten path). Examples include post-processing object files before linking, post-processing a binary after linking, or generating object files from something other than the compiler.
- SomeCallMeTim 14y agoSyntax is hard? Somewhat, but that's not the problem. Syntax is not intuitive? It's not bad once you've read the docs. Complex Makefiles with huge included boilerplate libraries (e.g., the Android build system) are completely impossible to debug in any reasonable way? THAT is the problem. As soon as you do anything non-trivial in your Makefile, you've created something that, when it fails, the reason will be COMPLETELY opaque to anyone who isn't intimately familiar with the ENTIRE program. The implicit connections that a Makefile makes for building are great for JUST that part. As soon as you try to use them to write a program, you have to commit all manner of write-only-code abominations. I know because I've both DONE this and tried to debug OTHER people's code. There is NO good way to debug Makefiles. And that alone means that they should be consigned to historic projects only, to be replaced by SOME kind of a better system.
- Jare 14y ago> There are many, many way better alternatives to make. Which one is better depends on the platform you're on. There's your answer: there are many alternatives, but only one make. Ok maybe 2 o 4. :) But a build system should for the most part be platform agnostic. I have such a hard time understanding why so many programming languages seem to need their own Make alternative (Rake, Cake, Fake, ...?)
- shadowmint 14y agoSure, make is a generic tool, and you can do anything with it; from parsing json files, to compiling C code, to formatting documents. ...but so are bash scripts. I wouldn't advocate actually using either of these though, unless the situation is appropriate. Every system and platform has different requirements, and its a bit of a big ask to want make to be 'the right tool' for all of them. Certainly, I'd never use make to look after a ruby project, or a c project. That doesn't mean I think make is horrible and I'd never use it for anything, but you can see, perhaps, how something as low level as make might not provide all the tools (dependency management, downloading resources from git hub, automatically tracking system information, a templating system for generating system-dependent headers) you might need for some things. You could think about it this way: If make did all of these things and was easy to use, there wouldnt be all of these other clones and different attempts at the same thing. ...but there are. So there's certainly something about it isn't making people happy.
- McUsr 14y agoI just want to inform you that GNU make indeed is very good for c projects as it can read the dependency files made by gcc (and clang), so you get very small very readable makefiles, that takes care of tracking the dependencies for you. http://wiki.osdev.org/Makefile http://wiki.osdev.org/Makefile
- shadowmint 14y agoReally? There are a lot of people who use makefiles for C projects, but most of those people don't write them by hand. They use a frontend that generates a vastly complex and arcane makefile using either automake, cmake, qmake, etc. These makefiles are utterly unmaintainable and deserve a place next to 'goto' in the section labeled 'considered harmful'... but they serve a purpose; correctly collecting build settings, templates and metadata and using those to construct the correct makefile. That doesn't count as 'using make'. There are a vanishingly few projects that actually use make; google for it's NDK builds (and a few other things; but these are massive recursive makefile monsters that you have a tiny safe api to work with), LUA with its 15 makefiles, one for each platform. There are a couple of other examples, but not many. I can't think of any big ones off the top of my head. I think we can safely say that writing a Makefile to build your C code is a bad idea.
- quotemstr 14y agoI could not disagree with you more strongly. Make is powerful, ubiquitous, and extensible. There's a reason it's stood the test of time. If you must, use something that will generate makefiles for you, like CMake or GNU autotools, but even with these tools, you'll still be using make, and if you understand how make works, you'll be far better equipped to understand the actual operation of your build system. To me, blatant avoidance of make is a big, red, burning flag that whoever made that decision values novelty over value and that he's likely to be a bandwagon-jumper or a NIHer in other aspects of his professional life too, and such people are best avoided.
- watmough 14y agoCan't mod this up enough. Microsoft's crazy-ass xml build mechanism is a giant pain in the ass, even compared to their old nmake (I think) tool. The new system is a great example of a system where someone presumably said "Make is garbage, a big red flag, let's build something better."
- quotemstr 14y agoYep: the parts of the Windows tree still built with nmake are much more pleasant to hack on than the parts that use msbuild.
- SomeCallMeTim 14y ago>GNU autotools Autoconf is similarly an abomination that should be put out of our misery. The syntax is so opaque that 99% of people copy-and-paste the configuration file into their project, leading to 10 minute ./configure runs that check for 200 things the project doesn't use in addition to the one that it does. Not to mention that 99% of what it's checking for is OBE: A simple check for whether you're trying to build on a modern Linux, one of 2-3 Windows build flavors, or OS X, is sufficient to set the 5-10 typical flags most projects need. Look at LuaJIT's build process, for example. It builds practically everywhere and digs into OS internals, and yet doesn't need anything complicated to build. I agree that Make should be retired, and yet I'm typically the "Makefile expert" where ever I work. I've worked with a lot of smart people, and most don't know anything other than the basics of Make. I have to suspect that most people who are defending Make haven't had to REALLY use it to do anything complex, because when you do, it sucks.
- acdha 14y agoSuch a broad statement needs support and you offer only vague assertions. I would be the first to suggest alternatives for make on a large, complex project but for a simple project make is quite useful, particularly since it's so broadly available. I have a few websites with very short makefiles to package static files. That's 5 simple lines of mostly patterns, very easy to understand and there's no tooling related overhead on any system we use. I wouldn't say that make is better than all of the alternatives but you're in serious diminishing returns territory trying to make further improvements. The real advice I would offer is the bottom line observation that your build system is supposed to save you time. Don't start looking for a cool-kid approved new one until you're spending time on the tool rather than the complexity specific to your project.
- jburnat 14y agoThis is akin to saying that you should not be using libc, on account of there being many newer, more suitable libraries for string manipulation, I/O, and so on. There's a clear downside to having dependencies on relatively obscure, cutting-edge technologies that may not necessarily work or be available elsewhere. And since build systems usually don't really need to be fancy, as much as they need to work, being conservative in this area usually doesn't hurt.
- ycombobreaker 14y ago> If you love make, it's a big, red, burning flag that you're not demanding enough of your tools and that you're not keeping up with changes in your ecosystem. I wouldn't say that I love make, but it is my tool of choice. I have tried out SCons and CMake, and both seemed to require more hoop-jumping for customizations. That is, Makefiles are very close to being raw shell scripts. That, and SCons had performance issues (IIRC due to the md5sum it was doing on every input file). I have casually perused bjam files and even _building_ boost seemed awkward to me, with the weirdo string-parsing within individual flags. I am happy with autoconf as a package user, but I've never developed any software packages of my own with it. I typically work with C and C++ on Linux server environments. I'm quite happy with non-recursive Makefiles, timestamp-based change detection, and GCC-generated dependency graphs. This setup does incremental builds correctly for me, and parallizes linearly (and occasionally superlinearly due to I/O). I'd genuinely like to know what magic sauce you would recommend for build automation on this sort of a platform.