There are a couple of reasons you should use
make utility and write Makefiles
for your projects, even if it is 2013 now and you use modern programming
languages and platforms.
Your build process usually can be described in terms of sequences of commands
with some dependencies between.
make captures this naturally as a set of build
targets (with dependencies) and associated snippets of shell script (usually
lib/app.js: coffee -cp src/app.coffee > lib/app.js app.min.js: lib/app.js uglify-js lib/app.js > app.min.js
This reads as: to build
app.min.js you would need to build
coffee ... to build the former and
uglify-js ... for the latter. To run
% make app.min.js
Shell was designed exactly to perform command line tasks so it is the most efficient and boilerplate-free way to execute a bunch of commands sequentially and even compose pipelines of them.
if you want to execute some commands in order it's really hard to do any better than bash— James Halliday (@substack) May 22, 2013
You write recipes using shell scripting language,
make only organizes recipes
into dependency graph and rebuilds incrementally only needed parts of it (by
comparing timestamps of targets and their dependencies).
But shell scripting is hard
You might say that but in fact it’s not.
If you still think so then you probably didn’t even try it. I think, if you use command line as a part of your development process you should at least give it a shot.
Yes, shell scripting has some quirks but so does any programming language and I wouldn’t say that using shell is more or less painful than using any other language.
Again, give it at least a try — shell scripting documentation fits in one or two man pages.
Makefiles are good for encapsulation
The second reason to use
make is encapsulation. Let me describe what this
Nowadays most platforms have their own build tools. So does Python (distutils, setuptools, pip), Ruby (gem, bundle), Node.js (npm) and a bunch of others and that’s completely fine. Such build tools usually perform much better for their own platforms because they were designed exactly for these.
But even if I work on Python or Node.js project I would still consider using
Makefiles and writing targets to wrap those build tools’ commands into
install link publish: npm $@
Why? Just for the sake of encapsulation — if in a future some of the actions
will require some additional commands to execute I’ll just change this action’s
recipe to be something more than a call to
publish: git tag `node -pe 'require("./package.json").version'` npm publish
and I will not be required to change how I run such action — Makefile allows me to define an interface to running build processes.
If you want to know more how I use
make for npm projects you can read one of
my previous posts on the subject — Makefile recipies for Node.js packages.
What about Windows OS?
make is an alien in a Windows environment but so is command line.
But if a window developer is going to be serious with a command line then they
usually get cygwin installed and there along comes