Makefiles

References:

A well written makefile describes all the files and settings used to compile a project and link it with the appropriate libraries

Managing a build with a makefile is less error-prone and far simpler after a one-time setup cost. A makefile with a proper dependency graph will only rebuild a target when one or more of the components it depends on has changed. This allows seperating the components of a project whcih can be built independently.

Syntax

It is common practice to copy and modify old makefules rather than generating new ones from scratch.

#
# A simple makefile for managing build of project composed of C source files.
#


# It is likely that default C compiler is already gcc, but explicitly
# set, just to be sure
CC = gcc

# The CFLAGS variable sets compile flags for gcc:
#  -g        compile with debug information
#  -Wall     give verbose compiler warnings
#  -O0       do not optimize generated code
#  -std=c99  use the C99 standard language definition
CFLAGS = -g -Wall -O0 -std=c99

# The LDFLAGS variable sets flags for linker
#  -lm   says to link in libm (the math library)
LDFLAGS = -lm

# In this section, you list the files that are part of the project.
# If you add/change names of source files, here is where you
# edit the Makefile.
SOURCES = demo.c vector.c map.c
OBJECTS = $(SOURCES:.c=.o)
TARGET = demo


# The first target defined in the makefile is the one
# used when make is invoked with no argument. Given the definitions
# above, this Makefile file will build the one named TARGET and
# assume that it depends on all the named OBJECTS files.

$(TARGET) : $(OBJECTS)
    $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

# Phony means not a "real" target, it doesn't build anything
# The phony target "clean" is used to remove all compiled object files.

.PHONY: clean

clean:
    @rm -f $(TARGET) $(OBJECTS) core

Macros

Subsitutions defined toward top of the file, e.g. (CFLAGS = -g -Wall), and are similar to #define in C . It can be referenced later with $(CFLAGS).

Example macros: - OBJECTS = $(SOURCES:.c=o) - Defines the OBJECTS macro to be the same as the SOURCES macro except that every instance of .c is replaced with .o. - $@: - built-in, name of the current target - $^: - built-in, current targets list of dependencies

Targets

Written in the following form

target-name : dependencies
    action

where the target name is the name of the file that will be produced when this target is built. The first target listed in a make file is the default target, meaning it is invoked by make with no args.

  • Phony targets

    The clean target in the example does not fit the pattern which is previously described of targets. It does not create a file named clean, rather it is a shortcut for running a command whcih cclears out the projects build files. These commands are listed as dependencies of .PHONY which allows Make to run the target without any dependency checks.



Links to this note