Use Makefiles for more than handling source code

The make command is not just for programmers. Vincent Danen shows you other handy tasks that you can perform with this versatile command.

The make command is generally given little thought by anyone other than programmers. Traditionally, this command and its associated Makefile are found in source code bundles to ease the compilation and linking of source code into executable files. It can, however, be used for much more than just handling source code.

A Makefile is nothing more than a series of commands to execute, working on the idea of dependencies for file targets. For instance, you can execute "make install" and it will check to see that any required targets are up to date first, such as a "compile" target and any dependencies it may have. This makes "make" a very versatile command. This also means you can use it with files other than just source code files; you can make it do things like copy files (locally or remotely), do version control, delete files, or any other command you like that is useful when dealing with files.

For instance, you can have a Makefile written to copy local Web files to a remote server, taking them from a version control repository. Such a Makefile might look like this:

REMOTEHOST = user@host:~/public_html/
ifdef REV
all: dist
       rm -rf website
       rm -f website.tar.gz
       svn co $(SVNURL) $(REVISION) website
dist: clean checkout
       tar czf website.tar.gz website
       rsync -avP -e ssh website/* $(REMOTEHOST)

Note that a proper Makefile must use tab characters to indent command structures that belong to targets. Using spaces will cause "make" to complain. The above Makefile will, in one step (using "make", which uses the default target "all"), clean the current directory (removing the website/ directory, as well as an archived copy of the Web site); check out the code from subversion, the URI of which is defined in the $(SVNURL) variable; and then make a tarball of the Web site and synchronize it to the remote server via rsync.

With the ifdef definition, you can use make REV=600 to check out the subversion repository as it was at revision 600 (passing -r600 to the subversion command); this allows you to quickly and easily revert changes or use specific point-in-time snapshots. One thing to note is that "make" will trap on non-zero exit codes, meaning it exits and returns the return code of the command in question. If you want "make" to proceed despite non-zero return codes, you can easily do so by using something like:

       ps xyz || echo ""
       cat foo

In the above, ps xyz will always exit non-zero because xyz is not a valid command. We trap it with the "||" construct (which indicates to the shell to execute the command following if the preceding command fails). The output of the failed command will still be echoed to the screen, but the error will not cause "make" to abort, and the next command will proceed.

The "make" command and Makefiles are useful for much more than just compiling source code. While it may have been designed for it, it can be used for so much more. Is it better than writing a shell script? That largely depends on your needs, but the fact that "make" does strict exit code checking, when a shell script does not (unless you do it yourself), can make it very compelling in certain situations.

Here is the PDF version of this tip.

Delivered each Tuesday, TechRepublic's free Linux and Open Source newsletter provides tips, articles, and other resources to help you hone your Linux skills. Automatically sign up today!


Vincent Danen works on the Red Hat Security Response Team and lives in Canada. He has been writing about and developing on Linux for over 10 years and is a veteran Mac user.

Editor's Picks