Programing: GNU Make (gmake) Tutorial

By Xah Lee. Date:

Here's some learning notes and comments about the unix “make” tool (GNU Make, to be exact). If you didn't know make, 10 minutes here will get you started. It's extremely simple.

Ok, after 12 years of unix (4 years as unix admin in data centers starting in 1998s and the rest as backend web app dev on unix), today i learned the “make” tool for the first time. Yeah, i've call it hundreds of times to install programs, but never had to understand it or write it. Here's my take on a tutorial, with my style of focusing on syntax and what exactly it functional do, as opposed to talking about some “engineering” or abstract “purpose” approach. In the following, i'll call it “gmake” to avoid confusion with the english word “make”.

Here's a few points of introduction so you get some idea what it is.

First of all, it is not a standalone tool by itself. It lives in unix shell environment. You need all the shell bags to use “make”.

Secondly, it more of a file format than anything. You could think of it as a shell script with a particular formatting conventions. The name of this text file is typically “Makefile”.

A “Makefile” is pretty much several shell commands. In fact, “gmake” is simply a convenient way of saving you time of needing to repeatedly type the same set of shell commands. “gmake” is simply a naturally evolved form of repeating shell commands.

The whole purpose of gmake, is to create one (or more) new files. In other words, your shell commands creates new files. “gmake” simply execute them. “gmake” is originally and primarly created because of C. When writing C, you need to compile it. So, for example, you do gcc -o myapp myapp.c, which takes the input file “myapp.c” and generates the output file with name “myapp”.

This page is my learning notes on GNU Make.

Make (software) A makefile consists of dependency lines of text which define a target (a rule) followed by a colon and optionally a set of files on which the target depends. The dependency line is arranged so that the target (left hand of : character) depends on components (right hand of : character). After each dependency line, a series of lines of tab-indented text may follow which define how to transform the components (usually source files) into the target (usually the "output"). If any of the components have been modified, the command below are run. The basic structure is:[8] # Comments are started with the hash(#) symbol. target [target ...]: [component ...] [command 1] . . . [command n]