[an error occurred while processing this directive]
A makefile allows you to automate the process of compiling, linking and running a program. Basically, you describe in the makefile what the dependencies are. For example, when you want to create an executable file, you usually link an object file, so this would be a dependency in a makefile: the executable depends on the object file, if the object file changes, then relink it to recreate the executable. Similarly, the object file depends on the source file, so another dependency in the makefile would be: when the source file changes, then recompile it to recreate the object file. Notice that the dependencies can effect each other. If the source file changes, then the object file will be recreated, but then since this is a new object file, the executable will have to be recreated. In this way, you are freed from the task of always recompiling and relinking. All you do is change the source code, and then make the executable using the makefile. The makefile will check to see what other files need to be recreated, and will only recreate those that are affected by the changed source file.
I will use the compiler g++ to compile my C ++ programs. By replacing all occurences of g++ with gcc, it is possible to compile C programs. Here is an example of a makefile that would create an executable called my_prog from the C++ source file my_prog.cpp
my_prog: my_prog.cpp g++ -o my_prog my_prog.cpp
Since g++ can compile and link, I only have to describe one dependency: the executable depends on the source code. Just put the above lines into a file named makefile. Note that the second line must begin with a tab.
Here is a more complicated example. Suppose I have a file called my_prog.cpp that has a statement #include "my_inc.h", and that the body of my_inc.h is in my_inc.cpp. Then, I would put the following lines in my makefile to describe the dependencies
my_prog: my_prog.o my_inc.o g++ -o my_prog my_prog.o my_inc.o my_prog.o: my_prog.cpp g++ -c my_prog.cpp my_inc.o: my_inc.cpp g++ -c my_inc.cpp
The -o option indicates the name of the executable. The -c option tells g++ to compile, but not to link. By separating the dependencies as above, it reduces the amount of recompiling that needs to be done. For example, once the .o files exist, only the file that changes needs to be recompiled.
The compiler for Ada programs is also gcc, but the linker is gnatbl. Here is a simple example to run a file named my_prog.adb
my_prog: my_prog.ali gnatbl -o my_prog my_prog.ali my_prog.ali: my_prog.adb gcc -c my_prog.adb
Here is an example that uses a package specification, my_pack.ads, and a package body, my_pack.adb. I am assuming that there is a statement 'with my_pack;' in my_prog.adb. It is not necessary to compile the specification file, .ads.
my_prog: my_prog.ali my_pack.ali gnatbl -o my_prog my_prog.ali my_prog.ali: my_prog.adb my_pack.ads gcc -c my_prog.adb my_pack.ali: my_pack.ads my_pack.adb gcc -c my_pack.adb
As a final example, suppose that my_prog.adb uses a generic package specification, my_gen_pack.ads, and a generic body, my_gen_pack.adb. Notice that the .ali file depends on the generic package.
my_prog: my_prog.ali gnatbl -o my_prog my_prog.ali my_prog.ali: my_prog.adb my_gen_pack.o gcc -c my_prog.adb my_gen_pack.o my_gen_pack.ads my_gen_pack.adb gcc -c my_gen_pack.adb
The command to read the makefile is make -k my_prog, the -k option indicates that compilation should continue even if errors are found. The argument to the make command is the name of the executable that you want to create. It is possible to have the dependencies for many executables in the makefile, so the argument indicates which one to build. Make will only rebuild those units that depend on other units that have been modified.
If you are using emacs, then you can use the M-x compile my_prog command to call the makefile from within emacs. The advantage to this is that when you hit ENTER on an error in the compilation window, you are taken to that line and column in the source code. You can also just use C-x ` to visit each error in sequence. Very handy!