makefiles what you wanted to know but were afraid to ask
DESCRIPTION
Makefiles What you wanted to know but were afraid to ask. Presentation for ACM By James Haiston Rias Graduate student At South Dakota School of mines and Technology. Shakespeare on Makefiles . To make, or not to make, that is the question: Whether ‘tis nobler in the mind to suffer - PowerPoint PPT PresentationTRANSCRIPT
PRESENTATION FOR ACM
BY JAMES HAISTONRIAS GRADUATE STUDENT
AT SOUTH DAKOTA SCHOOL OF MINES AND TECHNOLOGY
MakefilesWhat you wanted to know
but were afraid to ask.
Shakespeare on Makefiles.
To make, or not to make, that is the question:Whether ‘tis nobler in the mind to sufferThe slings and arrows of Visual Studio,
Or to take arms against a sea of compiler issues,
And by opposing end them; to make, and compile.
What is a Makefile?
Make is a utility that automatically builds executable programs and libraries from source code by reading files called makefiles which specify how to derive a target program.
The makefile is a set of instructions that determine the compilation of a program or instruction set.
How to Write a Simple Makefile
Suppose that you were writing a program that consists of: Three C language source files
main.c iodat.c dorun.c
Assembly language code in li.s, called by one of the C sources.
A set of library routines in /usr/fred/lib/crtn.a.
How to Write a Simple Makefile
If you built the program by hand, the complete set of commands would be: $ cc –c main.c $ cc –c iodat.c $ cc –c dorun.c $ as –o l0.0 lo.s $ cc –o program main.o iodat.o dorun.o lo.o /usr/fred/lib/crtn.a
How to Write a Simple Makefile
The equivalent makefile would be;1 program : main.o oidat.o dorun.o lo.o /usr/fred/lib/crtn.a2 cc –o program main.o iodat.o dorun.o lo.o /usr/fred/lib/crtn.a3 main.o : main.c4 cc –c main.c5 iodat.o : iodat.c6 cc –c iodat.c7 dorun.o : dorun.c8 cc –c dorun.c9 lo.o : lo.s10 as –o lo.o lo.s
Dependency Line
Command line
How to Write a Simple Makefile
Suppose you have multiple versions of a program to compile, one as a terminal and one as a window.
Description of a file that handles both
1 plot_prompt : basic.o prompt.o2 cc –o plot_prompt basic.o prompt.o3 plot_win : basic.o window.o4 cc –o plot_win basic.o window.o5 basic.o : basic.c6 cc –c basic.c7 prompt.o : prompt.c8 cc –c prompt.c9 window.o : window.c10 cc –c window.c
How to Write a Simple Makefile
The previous examples assume that: The project files, as well as the description files,
reside in the same directory. The description files are named makefile or Makefile. The directory containing these files is the current
directory when you enter the make command.Given these conditions, you can build any
target in the description file by entering the command
$ make target
How to Write a Simple Makefile
If some intermediate files are up to date, make skips their commands. The description file executes only the minimal set of commands rebuild the program. If no prerequisite files were modified or removed since the
last time target was created, make issues the message.‘target’ is up to date
If you attempt to make a target that is not contained in the description file make will respond like this:
make: Don’t know how to make nontarget. Stop. Or like this:
‘nontarget’ is up to date.
Some Basic Rules of Syntax
The most important rule is to begin every command with a tab. If you want to check the tabs in your description file,
issue the command,$cat –v –t –e makefile
You can continue a long line by placing a backslash (\) at the end. Make sure the backslash is right before the newline;
don’t let any white space slip in between. A set of lines continued by backslashes is parsed as one line.
Use the # sign to begin a comment.
Some Basic Rules of Syntax
Commands need not occupy separate lines in the description file. You can place a command on a dependency line, preceded by a semicolon:
Plot_prompt : prompt.0; cc –o plot_prompt prompt.oA single target can appear on multiple dependency
lines. This can be a useful practice when you are indicating different kinds of dependencies:
File.o : /usr/src/file.ccc –c /usr/src/file.c
.
.File.o : global.h defs.h
Macros
Description files of the form name = text string are macro definitions.
Subsequent references to $(name) ${name}are interpereted as text string
These for instance are all valid macro definitions:LIBES = -1X11objs = drawable.o plot_points.o root_data.oCC = /usr/fred/bin/cc23 = “This is the (23)rd run”OPT = DEBUG_FLAG = # empty now, but assign –g for debuggingBINDER = /usr/local/bin
Macros
An entry in the same description file might look like this:
plot: ${objs}${CC} –o plot $(DEBUG_FLAG) ${objs} ${LIBES}mv plot /usr/local/bin
When you invoke make plot, the command evaluates to:
/usr/fred/bin/cc –o plot drawable.o plot_points.o root_data.o -1X11mv plot /usr/local/bin
Macros
Reason for macros; You can refer conveniently to files or command
options that appear repeatedly in the description file. Macros permit variations from one build to the next.
Macros
Syntax for macros A macro definition is a line containing an equal sign. Single-character macro names do not require either
parentheses or braces;A=XYZ can be referred to as $A, $(A), or ${A}
It is permissible to use macros in macro definitions, as in
ABC = XYZFILE = TEXT.$(ABC)
If you refer to a macro without defining it make substitutes a NULL string.
The order that macros are defined is not important.
Internally Defined Macros
make predefines a number of common commands in macros. The ${CC} macro is always recognized by make as the
C compiler. The ${LD} macro is always recognized as the linker.
If you see a description file like this:basic.o : basic.c
${CC} –c basic.cIs normally the same asbasic.o : basic.c
cc –c basic.c
Macro Definitions on the Command Line
You can define macros on the make command line. The following invocation:
$ make jgref DIR=/usr/proj
If the definition on your command line consists of several words, enclose them in double or single quotes.
$ make jgref “DIR=/usr/proj /usr/lib /usr/proj/lib“In the Bourne and Korn shells, you can define
the macro before the make command:$ DIR=/usr/proj make jgref
Priority of Macro Assignments
Here is the priority from least to greatest Internal (default) definitions of make. Current shell environment variables. This includes macros that you enter
on the make command line, if they precede the make command itself. Description file macro definitions. Macros that you enter on the make command line, if they follow the
make command itself.This may be changed by invoking make with the –e option
Internal (default) definitions of make. Description file macro definitions. Current shell environment variables. This includes macros that you enter
on the make command line, if they precede the make command itself. Macros that you enter on the make command line, if they follow the
make command itself.
Macro String Substitution
Suppose you have the macro definition,SRCS = defs.c redraw.c calc.c
The description file command,ls ${SRCS: .c=.o}
then produces the output,calc.o defs.o redraw.o
String substitution is severely restricted; can take place only at the end of the macro or immediately before white space.
LETTERS = xyz xyzabc abcxyz…
echo $(LETTERS: xyz=DEF)produces the output,DEF xyzabc abcDEF
Internal Macros for Prerequisites and Targets
make defines several macros of its own each time it reads a dependency line. The $@ macro evaluates to the current target.An entry compiling an executable program uses @ as the name of the output file:plot_prompt : basic.o prompt.occ –o $@ basic.o prompt.o The $? macro evaluates to a list of prerequisites that are newer than the
current target.The following description entry rebuilds the library with any object files that are newer than the library itself:libops : interact.o sched.o gen.oar r $@ $?
The $^ expands to a space delimited list of the prerequisites.
Clean
The clean is used to remove unwanted/unused files from the program being compiled. This is done in two different ways $ clean – used to remove –o files. $ make clean – used to remove –o files as well as
executables. An example of these can be seen in the example below;clean: rm –f *-o *.~ corecleanall:rm –f *-o *.~ core $(EXE)
Sample Makefile
This is a primordial makefile made famous by Dr. John Weiss.
References
"Make (software)." Wikipedia, the Free Encyclopedia. Web. 17 Jan. 2012. <http://en.wikipedia.org/wiki/Make_(software)>.
Oram, Andrew, and Steve Talbott. Managing Projects with Make. Sebastopol, CA: O'Reilly & Associates, 1993. Print.
Questions?
Appendix A, Options.
Standard options are: -b Accept description files from previous implementations
of make. -d Debug mode – print detailed information about internal
flags and the last-modified times of files. -e Let environment variables override macro definitions
inside description files. -f Following argument is a description file. -i Ignore error codes. Same as .IGNORE: in description
file. -k Error terminates work on current branch of hierarchy,
but not on other branches. -n Echo command lines, but do not execute them. Even
lines beginning with @ are echoed.
Appendix A, Options (cont.).
Standard options are: -p Print out macro definitions, suffixes, suffix rules,
and explicit description file entries. -q Return zero or non-zero status, depending on
whether the target file is or is not up to date. -r Do not use the default rules. -s Do not echo command lines. Same as .SILENT: in
description file. -t Touch target files (making them appear up to date),
without executing any other commands.
Appendix B, Internal Macros.
Standard options are: $? The list of prerequisites that have been changed more recently than
the current target. Can be used only in normal description file entries, not suffix rules.
$@ The name of the current target, except in description file entries for making libraries, where it becomes the library name.
$$@ The name of the current target. Can be used only to the right of the colon in dependency lines.
$< The name of the current prerequisite that has been modified more recently than the current target. Can be used only in suffix rules and the .DEFAULT entry.
$* The name – without the suffix – of the current prerequisite that has been modified more recently than the current target. Can be used only in suffix rules.
$% The name of the corresponding .o file when the current target is a library module. Can be used in both normal description file entries and suffix rules.