Basics of Makefile

From Notes_Wiki

Home > CentOS > CentOS 6.x > Programming tools > Makefile > Basics of Makefile

Makefiles can be used to automate compilation of programs or documents. Example use cases are creating a executable file from a C program, or a pdf file from a tex file or a image file from dot file, etc. In order for 'make' to produce the desired target file (executable, pdf or image) it requires user to specify rules (or recipe) using which it can convert pre-requisites (or source files) into target files (or output files).

The most important thing to note about make is that all the recipe lines must start with a 'Tab'. They cannot start with four or eight spaces. Also they cannot start with a Tab and a space or Tab and two spaces etc. All lines must start with exactly one tab and no other white-space character.

Example makefile is:

hello: hello.c
	gcc -Wall -o hello hello.c

This make file can be used with command 'make' or 'make hello' to generate 'hello' executable from 'hello.c' file. Note that make is intelligent and checks the timestamps on hello executable and compares then with timestamps on hello.c file. If hello executable is newer than hello.c file then make will report nothing to do rather than compiling hello.c unnecessarily again. If recompilation is desired in such cases then one can use 'touch hello.c' to update timestamps of hello.c file and then run make again.

Note that if name of makefile is 'makefile' or 'Makefile' then make automatically uses that makefile for make commands. For other makefiles one must specify the file with '-f' command line option as:

make -f <make_file_name> [target]


Default target

The first target in a Makefile is also the default target. Hence if one runs 'make' command with any explicit target name, then first target in makefile is made. Due to this first target in Makefile is often special target 'all' which is used to create all files as shown is below example:

.PHONY: all clean
all: add math

add: add.c add.h
	gcc -Wall -o add add.c

math: subtract.o multiply.o
	gcc -Wall -o math subtract.o multiply.o

clean: 
	rm -f add math

Note following important things about above Makefile:

  • Rules for creating subtract.o and multiply.o are not specified. In this case make will use its implicit rules and create these object files from a C source file or a pascal source file whichever it can find in the current folder. Further if there is a yacc source file .yy then it can even generate a .c file from yacc file and then compile .c file to get object file. Thus make can infer chained rules to generate desired target. Also make has predefined rules for creating few files such .o from .c files.
  • '.PHONY: clean' is used to indicate that all and clean are phony targets. Thus if there is a file with named all or clean in current folder it wont cause any problems during make.
  • Both add and math targets have more than one pre-requisites. If any of these pre-requisites has update time-stamps greater than target or if target is missing only then make will run the recipe commands to generate a newer or updated target. In case a target exists and is more up-to-date in comparison with pre-requisites then make will not create that target again.
  • Few targets such as clean do not have any pre-requisites. This is normal
  • add has pre-requisite add.h but it is not used in the recipe directly. This could be due to add.h being included in add.c file using #include directive. Thus makefile does not forces use of any or all or some pre-requisites in the recipe.


Variables

In the previous example of 'add' and 'math' targets the string 'add math' has been specified twice. We can save the effort of typing it twice by storing the string in a variable and using variable instead. A variable can be declared in shell variable format as '<variable>=<value>' and then substituted using '$(<variable>)' as shown below:

EXECUTABLES=add math
.PHONY: all clean
all: $(EXECUTABLES)

add: add.c add.h
	gcc -Wall -o add add.c

math: subtract.o multiply.o
	gcc -Wall -o math subtract.o multiply.o

clean: 
	rm -f $(EXECUTABLES)


Make is extensively documented at http://www.gnu.org/software/make/manual/make.html One can refer to the given documentation to learn make in considerably more detail than presented here.


Special variables

Two special variables $@ and $< can be used in recipe of all targets. $@ refers to the current target being generated and $< refers to the pre-requisites of the current target. Hence the makefile can also be written as:

EXECUTABLES=add math
.PHONY: all clean
all: $(EXECUTABLES)

add: add.c add.h
	gcc -Wall -o $@ $@.c

math: subtract.o multiply.o
	gcc -Wall -o $@ $<

clean: 
	rm -f $(EXECUTABLES)


Home > CentOS > CentOS 6.x > Programming tools > Makefile > Basics of Makefile