In my opinion you have not got the essence of make(1):
- Make stores in the makefiles a set of dependency rules (dependencies between files) in your build directory in order to build your project.
- There are dependency lines, and build lines, the dependencies start in column 0 of the line, while the buid lines start with a tab char.
- the rule lines have two parts, the file that is to be built, a colon (
:
), and the list of files it depends on (so that if one or more of these files is modified, the rule is applied)
- If the rule has to be applied, then the set of build lines below the rule (until the next rule or a variable definition rule if found) is executed in order to build the file.
Example
Your file hello.c
will be compiled into hello.s
to create an assembler file, and then the assembly code is assembled to generate an object code hello.o
. Finally, this file is linked to generate the file hello
(or hello.exe
, if you are in windows).
You arrange your makefile to generate all the files, in a way that if you modify e.g. the assembler file hello.s
, only the assembler pass, and the linker pass is done, but not the compiling phase that should overwrite the assembler file before assembling. This can be done with this Makefile:
# this is the linking phase. The first rule in the file is the
# default target rule, so by default, executing make will try this
# rule (but only if hello.exe was modified before hello.o)
hello.exe: hello.o
gcc -o hello.exe hello.o
# Now, the assembling phase. The hello.o file depends on the
# hello.s assembly code, so to assemble it we call the assembler
hello.o: hello.s
as -o hello.o hello.s
# now, we specify the dependency from the hello.s assembler file
# from the hello.c source code file.
hello.s: hello.c
gcc -c -S -o hello.s hello.c
Now, if it is the first time you execute make and you have only the file hello.c
(and Makefile
of course) the make program will generate the following sequence of commands:
$ make
gcc -c -S -o hello.s hello.c
as -o hello.o hello.s
gcc -o hello.exe hello.o
$ _
but if you later modify the file hello.s
(I will touch(1)
it, to change its modification date:
$ touch hello.s
$ make
as -o hello.o hello.s
gcc -o hello.exe hello.o
$ _
but if you touch hello.c
, everything will be made again:
$ touch hello.c
$ make
gcc -c -S -o hello.s hello.c
as -o hello.o hello.s
gcc -o hello.exe hello.o
$ _
Make builds a dependency graph and follows it in order to build the target you have specified in the command line, so if you use make with a target, it will stop as soon as the target is built:
$ make hello.o
gcc -c -S -o hello.s hello.c
as -o hello.o hello.s
$ _
I recommend you to read a book on make. A good one is the GNU Make documentation that is online on your system as an info file: just execute:
$ info make
(and info
will open a text screen to allow you to read the full documentation of make
)