Using make
Writing a Makefile
Example simple Java makefile
Example simple C (or C++) makefile
Example more advanced C Makefile
(using makedepend and more advanced make syntax)
GNU make Manual. A complete reference for writing makefiles from simple to
advanced features.
Also, CMake, is a cross platform make
that is useful for very large software projects. It automatically generates
(often hard to read and debug) makefiles for different platforms. It is,
however, overkill for CS projects.
The following is the generic target entry form:
Using make
% make
A specific target in the Makefile can be executed by typing:
% make target_label
For example, to execute the rm commands in the example makefile below, type:
% make clean
Creating a Makefile
A Makefile typically starts with some variable definitions which are
then followed by a set of target entries for building specific targets
(typically .o & executable files in C and C++, and .class files in Java)
or executing a set of command associated with a target label.
# comment
# (note: the <tab> in the command line is necessary for make to work)
target: dependency1 dependency2 ...
<tab> command
for example:
#
# target entry to build program executable from program and mylib
# object files
#
program: program.o mylib.o
gccx -o program program.o mylib.o
An example simple Makefile for a Java
#
# A simple makefile for compiling three java classes
#
# define a makefile variable for the java compiler
#
JCC = javac
# define a makefile variable for compilation flags
# the -g flag compiles with debugging information
#
JFLAGS = -g
# typing 'make' will invoke the first target entry in the makefile
# (the default one in this case)
#
default: Average.class Convert.class Volume.class
# this target entry builds the Average class
# the Average.class file is dependent on the Average.java file
# and the rule associated with this entry gives the command to create it
#
Average.class: Average.java
$(JCC) $(JFLAGS) Average.java
Convert.class: Convert.java
$(JCC) $(JFLAGS) Convert.java
Volume.class: Volume.java
$(JCC) $(JFLAGS) Volume.java
# To start over from scratch, type 'make clean'.
# Removes all .class files, so that the next make rebuilds them
#
clean:
$(RM) *.class
Here is an example of a Java makefile
that uses more advanced makefile syntax.
An example simple Makefile for a C (or C++)
#
# This is an example Makefile for a countwords program. This
# program uses both the scanner module and a counter module.
# Typing 'make' or 'make count' will create the executable file.
#
# define some Makefile variables for the compiler and compiler flags
# to use Makefile variables later in the Makefile: $(
Another makefile (using makedepend and more advanced make syntax)
This is an easier to use and modify makefile, but it is slightly more
difficult to read than the simple one:
#
# 'make depend' uses makedepend to automatically generate dependencies
# (dependencies are added to end of Makefile)
# 'make' build executable file 'mycc'
# 'make clean' removes all .o and executable files
#
# define the C compiler to use
CC = gcc
# define any compile-time flags
CFLAGS = -Wall -g
# define any directories containing header files other than /usr/include
#
INCLUDES = -I/home/newhall/include -I../include
# define library paths in addition to /usr/lib
# if I wanted to include libraries not in /usr/lib I'd specify
# their path using -Lpath, something like:
LFLAGS = -L/home/newhall/lib -L../lib
# define any libraries to link into executable:
# if I want to link in libraries (libx.so or libx.a) I use the -llibname
# option, something like (this will link in libmylib.so and libm.so:
LIBS = -lmylib -lm
# define the C source files
SRCS = emitter.c error.c init.c lexer.c main.c symbol.c parser.c
# define the C object files
#
# This uses Suffix Replacement within a macro:
# $(name:string1=string2)
# For each word in 'name' replace 'string1' with 'string2'
# Below we are replacing the suffix .c of all words in the macro SRCS
# with the .o suffix
#
OBJS = $(SRCS:.c=.o)
# define the executable file
MAIN = mycc
#
# The following part of the makefile is generic; it can be used to
# build any executable just by changing the definitions above and by
# deleting dependencies appended to the file from 'make depend'
#
.PHONY: depend clean
all: $(MAIN)
@echo Simple compiler named mycc has been compiled
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
.c.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $<
clean:
$(RM) *.o *~ $(MAIN)
depend: $(SRCS)
makedepend $(INCLUDES) $^
# DO NOT DELETE THIS LINE -- make depend needs it