Well, I have news for you... Your days of command line compiling are (mostly) over, because YOU will learn how to write Makefiles.
Makefiles are special format files that together with the
For this session you will need these files:
note: I use g++ for compiling. You are free to change it to a compiler of your choice
The make utility
If you runmakethis program will look for a file named
If you have several makefiles, then you can execute them with the command:
make -f MyMakefileThere are several other switches to the
make
man make
.
Build Process
- Compiler takes the source files and outputs object files
- Linker takes the object files and creates an executable
Compiling by hand
The trivial way to compile the files and obtain an executable, is by running the command:g++ main.cpp hello.cpp factorial.cpp -o hello
The basic Makefile
The basic makefile is composed of:target: dependencies
[tab] system commandThis syntax applied to our example would look like:
all: g++ main.cpp hello.cpp factorial.cpp -o hello
[Downloadhere]
To run this makefile on your files, type:
make -f Makefile-1On this first example we see that our target is called
We also see that there are no dependencies for target
Finally, make compiles the program according to the command line we gave it.
Using dependencies
Sometimes is useful to use different targets. This is because if you modify a single file in your project, you don't have to recompile everything, only what you modified.Here is an example:
all: hello hello: main.o factorial.o hello.o g++ main.o factorial.o hello.o -o hello main.o: main.cpp g++ -c main.cpp factorial.o: factorial.cpp g++ -c factorial.cpp hello.o: hello.cpp g++ -c hello.cpp clean: rm -rf *o hello
Now we see that the target
Each of the dependencies are searched through all the targets available and executed if found.
In this example we see a target called
Using variables and comments
You can also use variables when writing Makefiles. It comes in handy in situations where you want to change the compiler, or the compiler options.# I am a comment, and I want to say that the variable CC will be # the compiler to use. CC=g++ # Hey!, I am comment number 2. I want to say that CFLAGS will be the # options I'll pass to the compiler. CFLAGS=-c -Wall all: hello hello: main.o factorial.o hello.o $(CC) main.o factorial.o hello.o -o hello main.o: main.cpp $(CC) $(CFLAGS) main.cpp factorial.o: factorial.cpp $(CC) $(CFLAGS) factorial.cpp hello.o: hello.cpp $(CC) $(CFLAGS) hello.cpp clean:
rm -rf *o hello
[Downloadhere]
As you can see, variables can be very useful sometimes. To use them, just assign a value to a variable before you start to write your targets. After that, you can just use them with the dereference operator $(VAR).
Where to go from here
With this brief introduction to Makefiles, you can create some very sophisticated mechanism for compiling your projects. However, this is just a tip of the iceberg. I don't expect anyone to fully understand the example presented below without having consulted some
CFLAGS=-c -Wall LDFLAGS= SOURCES=main.cpp hello.cpp factorial.cpp OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=hello all: $(SOURCES) $(EXECUTABLE) $(EXECUTABLE): $(OBJECTS) $(CC) $(LDFLAGS) $(OBJECTS) -o $@ .cpp.o: $(CC) $(CFLAGS) $< -o $@[Download
If you understand this last example, you could adapt it to your own personal projects changing only 2 lines, no matter how many additional files you have !!!.