Penguin
Blame: MakefileHowto
EditPageHistoryDiffInfoLikePages
Annotated edit history of MakefileHowto version 72, including all changes. View license author blame.
Rev Author # Line
62 IanMcDonald 1 __Makefiles are easy.__ In fact, to build a simple program that doesn't depend on any libraries, you don't even need a makefile. make(1) is smart enough to figure it all out itself. For instance, if you have a file "foo.c" in the current directory:
63 JohnMcPherson 2 <verbatim>
3 $ ls
4 foo.c
62 IanMcDonald 5
63 JohnMcPherson 6 $ make foo
7 cc foo.c -o foo
8 </verbatim>
9 make(1) will detect the type of file and compile it for you, automatically naming the executable the same as the input file (gcc(1) foo.c will give you a file called a.out unless you manually specify a name for it). If you need libraries, you can specify them by setting the __LDFLAGS__ variable on the command line.
71 FredrickHithers 10
63 JohnMcPherson 11 Of course, most useful projects contain more than one file. __A makefile describes the dependencies between files.__ It is called Makefile (with a capital M). Each line will typically consist of a filename, a colon and a list of dependencies. for instance, a simple make file to link together two object files foo.o and bar.o might look like:
12 <verbatim>
13 program: foo.o bar.o
14 </verbatim>
62 IanMcDonald 15 Each filename (before the colon) is called a __target__. You can make a specific target by executing
63 JohnMcPherson 16 <verbatim>
17 $ make target
18 </verbatim>
62 IanMcDonald 19
20 make is smart enough to use the first rule in the Makefile as the default action, so:
63 JohnMcPherson 21 <verbatim>
22 $ ls
23 Makefile foo.c bar.c
62 IanMcDonald 24
63 JohnMcPherson 25 $ make
26 cc bar.c -c -o bar.o
27 cc foo.c -c -o foo.o
28 cc foo.o bar.o -o program
29 </verbatim>
62 IanMcDonald 30 See the CompilingHowto for more info on the steps required to turn source code into an executable.
31
32 You can get your Makefiles made automatigically for you using AutoTools.
33 -----
34 !!Dynamic updating
35
63 JohnMcPherson 36 Occasionally you might want to specify something special to happen, for a specific file. This can be done by providing some rules to build that target. This is done indented, on the next line after the dependencies are listed. Our sample make file again:
37 <verbatim>
38 program: foo.o bar.o
62 IanMcDonald 39
63 JohnMcPherson 40 bar.c:
62 IanMcDonald 41 echo 'char *builddate="' `date` '";' >bar.c
63 JohnMcPherson 42 </verbatim>
62 IanMcDonald 43 Note that the line that begins "echo" must be indented by __one tab__. If this isn't done make(1) will abort with a weird error message like "Missing delimiter". The echo line makes a one line C file with a variable called "builddate", set to the current date and time. This is a useful thing to do for your program if you wanted to know when this particular version was compiled. (Not that this is the only way, or in fact the best way to get this information, but it's a good example.)
44
45 Running this would produce:
63 JohnMcPherson 46 <verbatim>
47 $ make
48 echo 'char *builddate="' `date` '"' >bar.c
49 cc -c -o bar.o bar.c
50 cc -c -o foo.o foo.c
51 cc foo.o bar.o -o program
52 </verbatim>
62 IanMcDonald 53 -----
54
55 !! Phony targets
56
57 You can have "phony" targets -- targets which don't actually create a file, but do something. These are created like normal targets: for instance, to add a "all" target to our makefile we'd add (probably at the top, so it becomes the default target):
63 JohnMcPherson 58 <verbatim>
59 all: foo
60 </verbatim>
62 IanMcDonald 61
63 JohnMcPherson 62 This rule won't run if there exists a file called "all" in the directory (if someone was stupid enough to create one somehow). So we can tell make(1) that this is a phony target and should be rebuilt always this is by using the target .PHONY. so, we can add to our Makefile:
63 <verbatim>
64 .PHONY: all
65 </verbatim>
62 IanMcDonald 66 To add a clean target is fairly simple too, add:
63 JohnMcPherson 67 <verbatim>
68 clean:
62 IanMcDonald 69 rm -f bar.o bar.c foo.o foo.c
63 JohnMcPherson 70 </verbatim>
62 IanMcDonald 71 and add clean to the list of phony targets:
63 JohnMcPherson 72 <verbatim>
73 .PHONY: all clean
74 </verbatim>
62 IanMcDonald 75 -----
76
77 !! Selective building
78
79 Why use a makefile, instead of a script to rebuild everything from scratch?
80
81 If you have a rule that reads
63 JohnMcPherson 82 <verbatim>
83 objectfile.o: foo.c foo.h bar.c bar.h Makefile
84 </verbatim>
62 IanMcDonald 85 then make(1) will check the last modification date of objectfile.o against the last modification date of all the files that follow it (foo.c, foo.h, bar.c, bar.h and the Makefile itself). If none of these things have changed, then it won't recompile objectfile.o.
86
87 Build lines like this with careful reference to #includes in your source - if your foo.h #includes bar.h, it has to be on the Makefile line - otherwise, changes to bar.h won't cause a recompile of objectfile.o and you might get confused as to why your constants aren't what you thought they should be.
88
89 Or, you could have make determine all your header file dependencies for you! If foo.h #includes bar.h, and bar.h #includes another.h, which #includes etc.h, it could very quickly become difficult to keep track of it all. Not to mention it may result in huge dependency lines! Instead, you can have a header file as a target and list its #included files as its dependencies. Then use the 'touch' command to update the timestamp. For example, if foo.c #includes foo.h, and both foo.h and bar.c #include bar.h, we could use this Makefile:
63 JohnMcPherson 90 <verbatim>
91 executable: foo.o bar.o
62 IanMcDonald 92 $(CC) foo.o bar.o -o executable
63 JohnMcPherson 93 foo.o: foo.c foo.h Makefile
94 bar.o: bar.c bar.h Makefile
95 foo.h: bar.h
62 IanMcDonald 96 touch foo.h
63 JohnMcPherson 97 bar.h:
98 </verbatim>
62 IanMcDonald 99
100 So if you edit bar.h to change some constants or function definitions, Make will see that foo.h needs to be updated and 'touch' it. Then it will know it must also update foo.o in (in addition to bar.o) since foo.h appears new. This way each target only lists files that it is __directly__ dependent on. Let make figure out the rest -- that's what it's supposed to do!
101
102 ''Or you could decide that mindless drone work is a waste of time and just use makedepend to spare yourself the hassle.'' --AristotlePagaltzis
103
104 You should consider that using this touch could affect the configuration management system you are using (e.g. RCS or CVS), if it goes by the timestamp to determine the need to commit/checkin: you might suddenly have lots of files to commit, or lots of files locked! At the very least the new timestamp will confuse your friends and confound your enemies. However, makedepends can generate an unreadable and therefore unmaintainable monstrosity, partly because it cites every system dependency (e.g. stdio), and also as it recurses through the subdep files it cites each reference to stdio by the subdeps as if it were a separate dependency. So, depending on the size of your project, and how often you have to make major adjustments by hand to the makefiles, and how many headers each file uses, you may want to decide whether or not to use this touch method (which would indeed keep the dependencies nicely hierarchical), or use makedepends. To have it both ways, I believe you could precede the touch with "cp -p foo.h foo.h_preserveDate; touch foo.h" and then under the foo.o dependency you could after the compile then do "cc foo.c; mv foo.h_preserveDate foo.h" which would preserve the original date on the foo.h checked-out file. This would still keep the hierarchical nature, which is quite valuable because it eliminates redundancy in separate places (two distant places to maintain one fact is very bad). -- LindaBrock
105
106 -----
107
108 !! Makefiles in subdirectories
109
110 With larger projects you often have subdirectories with their own Makefile. To allow make to run these Makefiles with the options passed to make use the $(MAKE) variable. This variable actually callse a second make process to make the Makefile in the subdirectory. To specify the Makefile's subdirectory use the -C option of make.
111
112 Example Makefile:
63 JohnMcPherson 113 <verbatim>
62 IanMcDonald 114 all: Documentation/latex/refman.pdf
115
116 install: Documentation/latex/refman.pdf
117 cp Documentation/latex/refman.pdf Documentation/!KeithleyMeter.pdf
118
119 Documentation: Doxyfile Makefile src/keithleyMeter.cc hdr/keithleyMeter.h
120 # Dosen't use all the options you passed to make
121 make clean
122 # make the Documentation folder
123 /Applications/Doxygen.app/Contents/Resources/doxygen
124
125 Documentation/latex/refman.pdf: Documentation
126 # Uses the options you passed to make
127 $(MAKE) -C Documentation/latex
128
129 clean:
130 rm -rf Documentation
63 JohnMcPherson 131 </verbatim>
62 IanMcDonald 132
63 JohnMcPherson 133 For a counter-argument against having separate make processes for sub-directories (and instead using makefile fragments but only one make process), see
134 [Recursive Makefile considered harmful (PDF)|http://aegis.sourceforge.net/auug97.pdf]
62 IanMcDonald 135
136 -----
137
138 !! Rules
139
140 The real power from makefiles comes when you want to add your own "rules" for files. If we have a program called "snozzle" that takes a ".snoz" file and produces a ".c" file we can add:
63 JohnMcPherson 141 <verbatim>
142 %.c: %.snoz
62 IanMcDonald 143 snozzle $< -o $@
63 JohnMcPherson 144 </verbatim>
145 $< expands to the first dependency, and $@ the target. So, if foo.c is built from foo.snoz we can now:
146 <verbatim>
147 $ ls
148 Makefile foo.snoz
149 $ make
150 snozzle foo.snoz -o foo.c
151 cc -c -o foo.o foo.c
152 echo 'char *builddate="' `date` '"' >bar.c
153 cc -c -o bar.o bar.c
154 cc foo.o bar.o -o foo
155 rm foo.c
156 </verbatim>
62 IanMcDonald 157 Note that foo.c is removed by make at the end -- make(1) removes intermediate files itself when it's done. Smart, eh?
158
159 -----
160
161 !! EnvironmentVariable~s
162
163 The only other major thing left to mention about Make is environmental variables. It uses $(''variable'') as an expando. thus the rule:
63 JohnMcPherson 164 <verbatim>
165 %c: %.snoz
62 IanMcDonald 166 snozzle $(SNOZFLAGS) $<
63 JohnMcPherson 167 </verbatim>
62 IanMcDonald 168 would let you specify the arguments to snozzle. This is useful if you call snozzle in multiple places, but want to be able to make one change to update the flags.
169
63 JohnMcPherson 170 make(1) uses these variables for its compilers. The compiler it uses for compiling C is "CC", You can set the environment variable "CC" to your own favourite C compiler if you so wish. CFLAGS is used for the flags to the C compiler. Thus setting CFLAGS to "-g -Wall" will compile all programs with debugging (-g) and with all warnings enabled (-Wall). Environment variables can be defined in make by using "VARIABLE=value" for example:
171 <verbatim>
172 CFLAGS=-g -Wall
173 </verbatim>
62 IanMcDonald 174
175 So, our full make file would become:
63 JohnMcPherson 176 <verbatim>
177 CFLAGS=-g -Wall
178 SNOZFLAGS=--with-extra-xyzzy
62 IanMcDonald 179
63 JohnMcPherson 180 all: program
62 IanMcDonald 181
63 JohnMcPherson 182 clean:
62 IanMcDonald 183 rm -f foo.c foo.o bar.c bar.o
184
63 JohnMcPherson 185 .PHONY: clean all
62 IanMcDonald 186
63 JohnMcPherson 187 program: foo.o bar.o
62 IanMcDonald 188
63 JohnMcPherson 189 bar.c:
62 IanMcDonald 190 echo 'char *builddate="' `date` '";' >bar.c
191
63 JohnMcPherson 192 %.c: %.snoz
62 IanMcDonald 193 snozzle $(SNOZFLAGS) $< -o $@
63 JohnMcPherson 194 </verbatim>
62 IanMcDonald 195 * CPPFLAGS command line flags to cpp
196 * CFLAGS command line flags to cc
197 * CXXFLAGS command line flags to c++
198 * LDFLAGS command line flags to ld
199 * ASFLAGS command line flags to as
200
201 If you specify your own command line you will have to explicitly include these variables in it.
202
203 You can also check if an environment variable has been set and initialise it to something if it has not. ie.
63 JohnMcPherson 204 <verbatim>
205 DESTDIR ?= /usr/local
206 </verbatim>
62 IanMcDonald 207 will set DESTDIR to /usr/local if it is not already defined
208
209 To append to the environment variables use the += operator:
63 JohnMcPherson 210 <verbatim>
211 CFLAGS += -g -Wall
212 </verbatim>
62 IanMcDonald 213 This allows the user to specify system specific optimizations in their shell environment.
214
215 __Note__ : As you may have noticed, make uses $ to identify variables - both environment and defined in the file. To put a literal $ in a makefile, use $$. However, bash also uses $ to identify variables, and will consume the $ when it is passed to whatever program you're running. To therefore pass a literal $ to a program you must use \$$ - note the single \, not double. - OrionEdwards
216
217 -----
218
219 !! An example makefile
63 JohnMcPherson 220 <verbatim>
62 IanMcDonald 221 1: CXXFLAGS=-g
222 2:
223 3: sim: car.o road.o sim.o event.o
224 4: g++ $(LDFLAGS) sim.o car.o road.o event.o -lm -o sim
225 5:
226 6: car.o: car.cc car.h sim.h event.h road.h Makefile
227 7: sim.o: sim.cc sim.h car.h road.h event.h Makefile
228 8: road.o: road.cc road.h sim.h event.h car.h Makefile
229 9: event.o: event.cc event.h sim.h Makefile
63 JohnMcPherson 230 </verbatim>
62 IanMcDonald 231 This makefile is for a car simulator written in C++. (It was written by Dr. Tony !McGregor from TheUniversityOfWaikato).
232
233 * Line 1 sets up the environment variables to the C++ compiler, ensuring everything is compiled with debugging info on.
234 * Line 3 is the first target in the file, so when you run 'make' it will 'make sim'. sim depends on car.o, road.o etc (targets that are defined on lines 6-9).
235 * Line 4 is indented; because we want to add extra smarts to the compiling of sim (we want to link to the math library libm.a); so when 'make sim' is executed and the .o's are up to date, that line will be executed.
236 * Lines 6-9 are targets for the various object files that will be generated. They say that car.o is built from car.cc, car.h etc. This probably means that car.h somewhere #include's event.h, road.h... Every time you run 'make car.o', it will compare the last modification date on all the files listed against the modification date of car.o. If car.o is newer, it is up to date and no compiling is necessary. Otherwise, make will recompile everything it needs to.
237
238 ----
239
240 !! Functions
241
242 It is possible to call some predefined functions in makefiles. A full list of them can be found in the manual, of course (http://www.gnu.org/software/make/manual/html_chapter/make_8.html#SEC83).
243
244 Perhaps you want to find all the .c files in directory for later use:
63 JohnMcPherson 245 <verbatim>
246 SOURCES := $(wildcard *.c)
247 </verbatim>
62 IanMcDonald 248 Given these, maybe you want to know the names of their corresponding .o files:
63 JohnMcPherson 249 <verbatim>
250 OBJS := $(patsubst %.c, %.o, $(SOURCES))
251 </verbatim>
62 IanMcDonald 252 You can do things like adding prefixes and suffixes, which comes in handy quite often. For example, you could have at the top of the makefile a variable where you set the libraries to be included:
63 JohnMcPherson 253 <verbatim>
254 LIBS := GL SDL stlport
255 </verbatim>
62 IanMcDonald 256 And then use
63 JohnMcPherson 257 <verbatim>
258 $(addprefix -l,$(LIBS))
259 </verbatim>
62 IanMcDonald 260 in a later rule to add a -l prefix for every library mentioned in LIBS above.
261
262 Finding files in multiple directories is a good example of the usage of foreach
63 JohnMcPherson 263 <verbatim>
264 DIRS := src obj headers
265 FILES := $(foreach dir, $(DIRS), $(wildcard $(dir)/*))
266 </verbatim>
62 IanMcDonald 267
268 ----
269 !!Automatic dependency calculation
270
69 PerryLorier 271 If you are creating a Makefile for C/C++ gcc can calculate dependency information for you. The quickest way to get this going is to add the -MD flag to your CFLAGS first. You will then need to know the names of the .d files in your makefile. I do something like this:
63 JohnMcPherson 272 <verbatim>
273 DEPS := $(patsubst %.o,%.d,$(OBJS))
274 </verbatim>
62 IanMcDonald 275
276 Then near the end of the makefile, add an
63 JohnMcPherson 277 <verbatim>
278 -include $(DEPS)
279 </verbatim>
62 IanMcDonald 280 It might also help to make a 'deps' target:
63 JohnMcPherson 281 <verbatim>
282 deps: $(SOURCES)
62 IanMcDonald 283 $(CC) -MD -E $(SOURCES) > /dev/null
63 JohnMcPherson 284 </verbatim>
62 IanMcDonald 285 '-E' tells gcc to stop after preprocessing. When using -E, the processed C file is sent to STDOUT. Therefore to avoid the mess on the screen, send it to /dev/null instead. Using this command all of the *.d files will be made.
286
287 ----
288 !!Comments
289
290 As your Makefile gets longer, you may want to insert comments to explain what the file is supposed to do. Comment lines, which are ignored by make, begin with a '#':
63 JohnMcPherson 291 <verbatim>
292 deps: $(SOURCES)
62 IanMcDonald 293 # the following line makes all of the .d files.
294 $(CC) -MD -E $(SOURCES) > /dev/null
63 JohnMcPherson 295 </verbatim>
62 IanMcDonald 296 You can also put a comment on the same line as another statement:
63 JohnMcPherson 297 <verbatim>
298 -include $(DEPS) # this includes everything in DEPS
299 </verbatim>
62 IanMcDonald 300 ----
301 !!Gotchas
302
303 Some [OperatingSystem]s use filesystems (such as [MicrosoftWindows] [FAT], [FAT32] and [NTFS](?) and [Apple]'s [HFS]) that are case insensitive, and can cause problems. (This implies you are using [Cygwin] on windows or [Darwin] on [MacOSX]). Particularly as unix packages often have a file named INSTALL which has installation instructions, the command "make install" says
63 JohnMcPherson 304 <verbatim>
305 make: Nothing to be done for install
306 </verbatim>
62 IanMcDonald 307 You can fix this in your make(1) files by adding:
63 JohnMcPherson 308 <verbatim>
309 .PHONY: install
310 </verbatim>
62 IanMcDonald 311 This will tell make that the "install" target is a "phony" target, and doesn't actually refer to a file and should always be rebuilt.
312
313 If you are on an [OS] such as [FreeBSD] you might need to invoke 'gmake' for a GNU compatible make.
314
315 Shell variables in Makefiles
316
317 There may come a time you need to use shell scripting complicated enough to require shell vars in a Makefile but make has issues since $ is the prefix for Make vars too, to escape the $, just use $$, so this:
63 JohnMcPherson 318 <verbatim>
319 for e in * ; do echo $e ; done
320 </verbatim>
62 IanMcDonald 321 becomes:
63 JohnMcPherson 322 <verbatim>
323 for e in * ; do echo $$e ; done
324 </verbatim>
62 IanMcDonald 325 It's a simple change but I didn't see it written anywhere obvious :)
326
327 ----
328 See Also:
329 * MakefileVariables
65 KenFoskey 330 * http://www.gnu.org/software/make/manual/ - GNU make manual, warning this is huge.
62 IanMcDonald 331
332 ----
333
334 !! Requests
335
336 I'd like to know something about makedepend and such things. Maybe some links to other or "official" make HOWTOs would be useful as well. Thanks. -- Someone
337
338 Dear Someone,
339 Take a look at [the make manual | http://www.gnu.org/software/make/manual/html_chapter/make.html], especially [section 4.14 | http://www.gnu.org/software/make/manual/html_chapter/make_4.html#SEC51]. Basically 'make depend' is not really needed anymore.
340
341 ----
342
343 I cannot find info about the meaning of '@AMDEP_TRUE@' variables in a Makefile. At the moment i get the error:
344 make: AMDEP_TRUE@: Kommando nicht gefunden
345 make: *** [[arandom.lo] Fehler 127
346 thx, !FlorianKonnertz
347
348 This isn't really anything to do with make. The autoconf/configure methods that many projects use take a template file (such as Makefile.in) and use that to create a makefile. autoconf uses things like @CXXFLAGS@ for its variables, and should replace @...@ vars with something that makes sense to make. If you have a makefile that still has @...@ variables in it, then it's a bug and there is a bug in the package.
349
350 ----
351
352 I have a question. I have a directory called src. Within this directory, a group publishes designs inside directories:
353
63 JohnMcPherson 354 <verbatim>
64 AristotlePagaltzis 355 Release_010405
356 Release_010505
357 Release_010605
358 Release_032304
359 Release_082903
63 JohnMcPherson 360 </verbatim>
62 IanMcDonald 361
362 If there is a file called baja.c inside one of these directories that is newer than baja.o, I want to compile. I was able to make a list of all the baja.c files within the Release directories using wildcard:
363
364 NEWSOURCES = $(wildcard Release_*/baja.c)
365
366 However, I don't know how to tell Make which is the latest file. The following grabs the first of the list.
367
368 baja.local: $(NEWSOURCES)
369 cp $< .
370
371 ''You could try using __$?__ which gives you the names of the prerequisites which are newer than the target. If there can be several of those and you only need the latest, though, you have to do it in the recipe, using shell tools.'' --AristotlePagaltzis
64 AristotlePagaltzis 372
373 ----
374 CategoryHowto

PHP Warning

lib/blame.php:177: Warning: Invalid argument supplied for foreach() (...repeated 2 times)