| Message |
There is a whole book (and man page) about the program "make" and the files it reads. Typically the file is called "Makefile". The reason for having it at all is to simplify compiling large projects.
For a simple program you won't need a makefile, and can compile and link it in a single line:
gcc test.c -o test
This compiles test.c and produces "test" as an executable. (This example assumes you are using Unix or Cygwin as a development platform).
You can even compile more than one source file and link them together in one line:
gcc test.c test2.c -o test
This compiles test.c and test2.c and links them to produce "test" executable.
However once you get many files in your project this gets tedious, and more importantly, the command above would recompile every file even if only some have changed.
This is where "make" comes into it. The example below is a small "Makefile" that I used for compiling a small server. It compiles 3 files (tinywebserver.cpp utils.cpp and messages.cpp).
However it uses the relationship between the .cpp and the .o files to work out which ones to compile. Typing "make" in this case recompiles all required files and creates "tinywebserver".
CC=g++
CCFLAGS=-g -Wall
O_FILES = tinywebserver.o utils.o messages.o
tinywebserver : $(O_FILES)
$(CC) $(CCFLAGS) -o tinywebserver $(O_FILES)
.SUFFIXES : .o .cpp
.cpp.o :
$(CC) $(CCFLAGS) -c $<
clean:
rm tinywebserver *.o
(Note, the indented lines have a <tab> at the start, not a series of spaces, otherwise they won't work).
Now if you change one file (like utils.cpp) and then type "make" it recompiles utils.cpp and then relinks.
There is still a problem with this example. If an include file is changed (for example, utils.h) then this won't force a recompile as the dependency of utils.cpp and tinywebserver.cpp is not known by make.
One way around this is to simply force a recompile of everything when you change include files (type "make clean") however this is a rather brute-force approach, and you might forget.
Fortunately there is a way of working this out. Using the -MM option in gcc you can find out dependencies, like this:
$ gcc -MM tinywebserver.cpp
tinywebserver.o: tinywebserver.cpp utils.h clients.h
$ gcc -MM utils.cpp
utils.o: utils.cpp utils.h
The output from that can be used as input to make to tell it what files depend on what.
If we modify the Makefile a bit we can get it to generate these dependency files, and then use them next time around:
CC=g++
CCFLAGS=-g -Wall
O_FILES = tinywebserver.o utils.o messages.o
tinywebserver : $(O_FILES)
$(CC) $(CCFLAGS) -o tinywebserver $(O_FILES)
# pull in dependency info for *existing* .o files
-include $(O_FILES:.o=.d)
.SUFFIXES : .o .cpp
.cpp.o :
$(CC) $(CCFLAGS) -c $<
$(CC) -MM $(CFLAGS) $*.cpp > $*.d
clean:
rm tinywebserver *.o *.d
(New stuff in bold). Now, each time you type "make" it uses the dependency files (the .d files) generated last time you compiled to work out what needs to be recompiled, even if you only changed an include file, this time around.
The only caveat is that if you add a new .cpp file you would need to do a "make clean" (or at least regenerate the .d files) so it knows about the new dependencies.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | top |
|