Makefile
In a Unix environment when working with C++ or C, a Makefile can be a very handy thing. Instead of typing several separate commands each time you update a file and want to recompile, you can just type make
and the Makefile is executed.
A Makefile is a plain-text file traditionally named “Makefile” or “makefile” that resides in the same directory as your program source.
No matter which technique shown here you use (Quick and Dirty or Long and Explicit), the basic setup of a Makefile is as follows:
main_program: dependency_1 dependency_2 dependency_3... dependency_n
command for main_program
Note that the second line is indented while the first is not. And then, following that, you’ll have n number of dependency definitions like the following:
dependency_n: dependency_a dependency_b dependency_c...
command for dependency_n
The dependencies for dependencies (i.e. dependency_a, dependency_b, etc.) are usually files, and not other dependencies, that determine when dependency_n’s command should be run. For example, take the following dependency definition:
main.o: main.cpp header.h
g++ -Wall -c main.cpp
In this example, when main.cpp
or header.h
is changed and the Makefile is run, the command for main.o
will be executed. That command happens to be g++ -Wall -c main.cpp
.
Here are some examples of Makefiles:
Quick and Dirty
prog5: main.o readData.o car.o radio.o
g++ -o $@ main.o readData.o car.o radio.o
Here, prog5
is the name of the executable that will be made. g++
is the compiler I’m using. Each .o
file will be created from a .cpp
(or whatever C++ extension you choose) file of the same name.
I say that this Makefile is dirty because if you update a header file (i.e. one typically ending in .h
) and recompile, this Makefile will not notice any changes. This isn’t normally a problem because after initially creating your header files, you probably won’t be making any changes to them except to perhaps update a function prototype, and of course if you do that, you’ll need to update the corresponding implementation file (i.e. a .cpp
file) as well.
Long and Explicit
myProgram: main.o stu.o cla.o readData.o
g++ -o myProgram main.o stu.o cla.o readData.o
main.o: main.cpp header.h
g++ -Wall -c main.cpp
stu.o: stu.cpp header.h stu.h
g++ -Wall -c stu.cpp
cla.o: cla.cpp header.h cla.h
g++ -Wall -c cla.cpp
readData.o: readData.cpp header.h
g++ -Wall -c readData.cpp
Here, myProgram
is the executable that will be created, while each .o
file is created with its own explicit definition of dependencies. For example, cla.o
depends on cla.cpp
, header.h
, and cla.h
; if any of those files changes, cla.o
will be recompiled. The -Wall
is a g++ option to turn on all warnings about your source.