Not very strict translation of the material
mrbook.org/tutorials/make At one time, I really didn’t have enough such a manual for understanding basic things about make. I think it will be at least interesting to someone. Although this technology is dying off, it is still used in very many projects.
Karma on the hub "Transfers" was not enough, as soon as the opportunity arises - I will add there too. Added to Translations. If there are errors in the design, please indicate them. I will correct.
The article will be interesting first of all to students programming in C / C ++ on UNIX-like systems from the very roots, without using IDE.
Compiling a project with handles is a tedious task, especially when the source files become more than one, and for each of them you need to compile and link commands each time. But it is not all that bad. Now we will learn to create and use makefiles. A makefile is a set of instructions for the make program that helps you build a software project with just one touch.
To practice, you will need to create a microscopic project a la Hello World from four files in one directory:
main.cpp#include <iostream> #include "functions.h" using namespace std; int main(){ print_hello(); cout << endl; cout << "The factorial of 5 is " << factorial(5) << endl; return 0; }
hello.cpp #include <iostream> #include "functions.h" using namespace std; void print_hello(){ cout << "Hello World!"; }
factorial.cpp #include "functions.h" int factorial(int n){ if(n!=1){ return(n * factorial(n-1)); } else return 1; }
functions.h void print_hello(); int factorial(int n);
All in a crowd can be downloaded
from here.
The author used the C ++ language, which is not necessary to know, and the g ++ compiler from gcc. Any other compiler is also likely to work. Files slightly tweaked for gcc 4.7.1 to build
')
Make program
If you run
make
the program will try to find the file with the name of the default
Makefile
in the current directory and execute instructions from it. If there are several makefiles in the current directory, you can point to the necessary one like this:
make -f MyMakefile
There are many other parameters that we do not need. You can find out about them in the man page.
Assembly process
The compiler takes the source code files and retrieves the object files from them. Then the linker takes the object files and gets the executable file from them. Build = compile + link.
Compiling hands
The easiest way to build a program:
g++ main.cpp hello.cpp factorial.cpp -o hello
Each time it is inconvenient to type, so we will automate.
The easiest Makefile
It should have the following parts:
: [tab]
For our example, the makefile will look like this:
all: g++ main.cpp hello.cpp factorial.cpp -o hello
Please note that the line with the command must start with a tab! Save it as
Makefile-1
in the project directory and start the build with the command
make -f Makefile-1
In the first example, the target is
all
. This is the default target for the makefile, which will be executed if no other target is specified explicitly. Also, this goal has no dependencies in this example, so make immediately starts to execute the desired command. And the command in turn starts the compiler.
Dependency usage
Using multiple targets in the same makefile is useful for large projects. This is due to the fact that when changing a single file, you do not need to rebuild the entire project, and it will be possible to manage to reassemble only the modified part. 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
This should be saved under the name
Makefile-2
all in the same directory
Now
all
has only a dependency, but no command. In this case, make, when invoked, will consistently perform all the dependencies in the file for this target.
A new
clean
target has been added. It is traditionally used to quickly clean up all project build results. Cleaning starts like this:
make -f Makefile-2 clean
Using variables and comments
Variables are widely used in makefiles. For example, this is a convenient way to consider the possibility that a project will be built by another compiler or with other options.
This is a
Makefile-3
Variables are very handy. To use them you just need to assign them a value before they are used. After that, you can substitute their value in the right place in this way:
$(VAR)
What to do next
After this briefing, you can already try creating simple makefiles yourself. Further it is necessary to read serious textbooks and manuals. As a final chord, you can try to independently disassemble and realize such a universal makefile, which can be adapted to almost any project in two touches:
CC=g++ 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 $@
Makefile-4
Successes!