Make is the original UNIX build tool. It existed a long time before gulp, or grunt. Loved by some, loathed by others it is at least worth being aware of how
make works, what the strengths are and where it falls short.
Make is available on UNIX-like systems. That means OSX, BSD and Linux. It exposes any system command meaning that you can run system commands and execute arbitrary scripts. There is no doubt that tools like gulp and grunt are inpsired by or at least a reaction to
make you create a Makefile and then run
make [what to run] from the terminal. In the following examples it is assumed
make build will be run from the terminal.
A common build task is to concatenate various files into a single file. In the tradition of UNIX single line commands this is easy.
build: mkdirs concat-css mkdirs: @mkdir -p ./build/css concat-css: @cat ./src/stylesheets/*\.css > ./build/css/application.css
That’s it - five lines of code.
UNIX tools already exist to make directories and combine files and they are fast because more often than not the underlying tools are C based.
We can extend the previous example to minify the CSS using the cssmin node module to minify the css too.
build: mkdirs concat-css min-css mkdirs: @mkdir -p ./build/css concat-css: @cat ./src/stylesheets/*\.css > ./build/css/application.css.tmp min-css: @./node_modules/cssmin/bin/cssmin ./src/css/application.css.tmp > ./build/css/application.css && rm ./build/css/application.css.tmp
UNIX has many tools for copying files around the filesystem. One of those tools is rsync. It lets you synchronise folders on your own filesystem or even over the network.
build: copy-files copy-files: @rsync -aq ./src/ ./build
If you want to exclude files or folders you can do it like this
build: copy-files copy-files: @rsync -aq --exclude='_*' ./src/ ./build
This will exclude any folder names prefixed with _.
build: uglifyjs uglifyjs: @./node_modules/uglify-js/bin/uglifyjs ./build/js/main.js.tmp > ./build/js/main.js && rm ./build/js/main.js.tmp
It is fast. In all tests I’ve run locally using system commands via a Makefile is always faster than using a build framework.
It is simple. If you can complete a task in five lines of code there is less to go wrong and it is easier to understand.
Probably the biggest weakness is that Make is not cross platform. So if you have a windows developer in your team they will have to jump through some hoops to get it working. Make can also become unmaintainable as it is just one big file. Of course you can break tasks down to individual bash scripts that get called in the Makefile.
Managing dependencies is a manual process. For node modules you can use npm to make sure a particular version is available but for UNIX tools you are on your own. Some UNIX tools vary between platforms both in terms of where they are located and what they allow you to do. GNU sed is different from BSD sed for example.
For a super lightweight build system you can also just craft your own bash scripts and ignore Make altogether.
There is a tendency within any programming community to want to do everything in the community’s language. But sometimes the problem has already been solved by men with beards in the 1970’s. If you can park the hipster hacker mentality there are tools that have been around for a long time that are stable and fast that already solve your problem. The main thing is to keep it small and distinct. If you know a little UNIX maybe you should try
make or a small bash script as your build tool.
Have an update or suggestion for this article? You can edit it here and send me a pull request.
Linux and Unix watch command tutorial with examples
Tutorial on using watch, a UNIX and Linux command for executing a program periodically and showing a fullscreen output. Examples of watching a file download, a network interface come up, and showing the five most CPU intensive processes.
Build your own Vim statusline
Statuslines in Vim are not hard to create. Making your own means one less dependency in your life.
Custom Vim Bindings in tmux 2.4
tmux 2.4 made a significant change to key bindings. Here is how to support custom keybindings for versions before and after tmux 2.4