Writing rules ---- Rule contains two parts, one is dependency, one is a way to generate the target. In Makefile, the order of the rules is very important, because only one ultimate goal is in Makefile, other goals are coming from this target, so be sure to let Make know what your ultimate goal is. In general, it may be a lot of targets defined in makefile, but the target in the first rule will be established as the final goal. If there are many objectives in the first rule, then the first goal will become the final goal. This goal is made by Make. Ok, let's take a look at how to write rules. First, the rules example foo.O: foo.c defs.h # foo module cc -c -g foo.c See this example, you should not be very strange, and I have said before, foo.o is our goal. , Foo.c and defs.h are the source files dependent on the target, and only one command "cc -c -g foo.c" (starting with the Tab). This rule tells us two things: 1, the dependency of the file, foo.o relies on the file of foo.c and defs.h, if foo.c and defs.h's file date is newer than the foo.o file date Or foo.o does not exist, then dependence occurs. 2. Generate (or update) the foo.o file. That is the CC command, which explains how to generate foo.o file. (Of course, foo.c files) DEFS.H files) Second, the syntax of the rules Targets: prerequisites command ... or this: targets: prerequisites; command command ... targets is a file name, separated by space, you can use wildcard . In general, our goal is basically a file, but it may be multiple files. Command is a command line if it is not with "Target: prerequisites", then, must start with the [Tab key], if Prerequisites are in one line, then the semicolon is separated by sections. (See) prerequisites is the file (or dependent target) that is dependent on the target. If a file is to be new than the target file, then the goal is considered "Out of", it is considered to be reborn. This has been told in front. If the command is too long, you can use a backslash box ('/') as a newline. Make has no restrictions on how many characters on a line. The rule tells make two things, dependencies, and how to become a target file. In general, Make will execute commands with UNIX standard shell, that is, / bin / sh. Third, using wildcards in rules If we want to define a series of similar files, we naturally remember to use wildcards. Make supports three wildcards: "*", "?" and "[...]. This is the same as UNIX's B-shell. Wave number ("~") characters also have a relatively special purpose in the file name. If it is "~ / test", this means the TEST directory under the $ HOME directory of the current user. And "~ hchen / test" represents the Test directory under the host directory of the user's hCHEN.
(These are small knowledge under UNIX, Make also supports) and under Windows or MS-DOS, the user does not have a host directory, then the directory referred to by the Wave is determined according to the environment variable "home". Wildcard replaces your series of files, such as "* .c" means that the suffix is C. One requires us to pay attention, if there is a wildcard in our file name, such as "*", you can use the escape character "/", such as "*" to represent the true "*" character, not any length String. Ok, or let's take a few examples: Clean: rm -f * .o, I don't say much, this is the wildcard support supported by the operating system shell. This is a wildcard in the command. Print: * .c lpr -p $? Touch Print The above example illustrates that wildcards can also be in our rules, the target print relies on all [.c] files. Where "$?" Is an automated variable, I will tell you later. Objects = * .o above this example, indicating that the harness can also be used in the variable. Not to say [* .o] will start, no! The value of Objects is "* .o". The variable in makefile is actually a macro in C / C . If you want a wildcard to expand in the variable, that is, the value of Objects is all the collection of file names of [.o], then you can: Objects: = $ (Wildcard * .o) This method of use by keyword "Wildcard" pointed out that we will discuss later about Makefile's keywords. Fourth, the file search is in some major projects, with a large number of source files, our usual practice is to classify this many source files and store them in different directories. So, when Make needs to find the dependencies of the document, you can add a path before the file, but the best way is to tell Make with a path, let Make go automatically. The special variable "vpath" in the makefile file is to complete this feature. If this variable is not specified, Make will only find dependencies and destination files in the current directory. If this variable is defined, Make will find a file in the specified directory when the current directory is not found. VPATH = src: ../ Headers The above definition specifies two directories, "src" and "../headers", make will search in this order. The directory is separated by a "colon". (Of course, the current directory is always the highest priority search) Another way to search the file is the use of the "vPath" keyword (note, it is not a variable, this is a key " Word, this is similar to the VPath variable mentioned above, but it is more flexible. It can specify different files in different search directories. This is a very flexible function. Its usage is three: 1, vPath is in line with mode
Document specified search directory
.
2, vpath
Clear compliance mode
Search catalog of files.
3. VPath Clear all file search directories that have been set. VAPTH use
Need to include "%" characters. "%" Means matching zero or several characters, for example, "%. H" means all files ending with ".h".
Specify the file set to search, and
Then specified
The directory of the search of the file set. E.g:
vpath% .h ../headers This statement is indicated that Make is required to search all files ending with ".h" in the ".h" directory. (If a file is not found in the current directory), we can use the vPath statement in consecutive search strategies. If the continuous vPath statement appears, or repeated
So, Make will perform a search in the order of the vPath statement. Such as:
Vpath% .c foo vPath% blish vpath%. C bar Bar represents ".C" ended file, first in the "foo" directory, then "BLISH", and finally the "bar" directory. VPath% .c foo: bar vPath% BLISH, the statement, ".C" ended file, first in the "foo" directory, then the "bar" directory, and finally the "blish" directory. 5. In one example of the pseudo target, we mentioned a "clean" goal, this is a "pseudo-target", clean: rm * .o Temp is like "clean" in our previous example, ie However, we have generated many file compilation files, and we should also provide a "target" to clear their "target" for completeness and use. (Use this goal with "make clean") because we do not generate this file with "Clean". "Pseudo Target" is not a file, just a label, because "pseudo-target" is not a file, so Make cannot generate its dependencies and decide whether it is to be executed. We only indicate this "goals" by displaying to take effect. Of course, "pseudo-target" is named with the file name, otherwise it will lose the meaning of "pseudo-target". Of course, in order to avoid this situation to be renowned, we can use a special tag ".phony" to display a "pseudo-target", explain to make, regardless of this file, this goal is " Pseudo-target. .Phony: Clean as long as there is this statement, whether there is a "clean" file, you want to run the "clean", only "make clean". So the whole process can be written like this: .phony: Clean Clean: rm * .o Temp pseudo-target generally has no dependencies. However, we can also specify the dependencies dependent on the pseudo target. The pseudo target can also be used as a "default target" as long as it is placed in the first one. One example is that if your makefile needs to generate a number of executable files, you just want to simply knock an opportunity, and all the target files are written in a makefile, then you can use "PseudoT" This feature: All: PROG1 PROG2 PROG3.PHONY: ALL PROG1: PROG1.O Utils.o cc -o prog1 prog1.o utils.o prog2: prog2.o cc -o prog2.o prog3: prog3.o sort.o Utils.o cc -o prog3 prog3.o sort.o utils.o We know that the first goal in makefile will be used as its default target. We declare a "all" pseudo-target that relies on the other three goals. Since the characteristics of the pseudo objective are always being executed, the three goals depending on the dependence are always like "all". Therefore, the rules of the other three goals will always be resolution. Just achieve the goal of us to generate multiple goals. ".Phony: all" declares that "all" is "pseudo-target". Just mention, from the above example we can see that the goal can also be dependent. Therefore, the pseudo target can also be dependent.