Home >Backend Development >C#.Net Tutorial >makefile rules
Contents
1. Introduction 3
1.1. Preliminary work 3
1.2. Introduction to Makefile 3
1.3. Introduction to rules 4
1.4. How make works 4
1.5. Using variables 5
1.6. Simplified commands 6
1.7. Another Style 6
1.8. Cleanup 7
2. Makefile 7
2.1. Makefile name 7
2.2. Contains 8
2.3. 'MAKEFILE' variable 8
2.4. How to regenerate the makefile 8
2.5. Reload the makefile 9
3. Rules 9
3.1.Example 9
3.2.Rule syntax 9
3.3.Wildcard 10
3.3.1.Defects of wildcard 10
3.3.2.wildcard function 11
3.4.Directory search 11
3.4.1.'VPATH' 11
3.4.2. Selective search 12
3.4.3. Using automatic variables 12
3.4.4. Directory search and implicit rules 12
3.5. PHONY target 13
3.6. FORCE target 14
3.7. Empty target 14
3.8 .Built-in extraordinary goals 14
3.9. One rule with multiple goals 15
3.10. One goal with multiple rules 15
3.11. Static mode rules 16
3.11.1. Syntax 16
3.11.2. Static mode rules and implicits Rule 17
3.12. Double colon rule 17
3.13. Automatically generate dependencies 17
4. Write command 18
4.1. Echo 18
4.2. Execute 19
4.3. Parallel execution 19
4.4. Error 19
4.5. Interrupt make 20
4.6. Recursive use 20
4.6.1. 'MAKE' variables 20
4.6.2. Passing variables to submake 21
5. Command line arguments 21
6. References 25
6.1. Directives 25
6.2. Functions 26
6.3. Automatic variables 27
6.4. Extraordinary variables 29
GNU Make uses
The Make program was originally designed to maintain C program files to prevent unnecessary recompilation. When using the command line compiler, a header file in a project is modified. How to ensure that all files containing this header file are compiled? The current 10-machine version generation uses a batch program. Compiling those files depends on the maintainer of the program. When modules refer to each other's header files, it is a pain to find all the files that need to be recompiled. ;After finding these files, modify the batch process to compile. In fact, these tasks can be completed automatically by the make program. The make tool is very useful for maintaining some files that have interdependencies. It provides a set of codes for the relationship between files and commands (programs that are called to update other files when files change). method. The basic concept of the Make tool is similar to the PRoglog language. You tell make what needs to be done, provide some rules, and make does the rest.
1. Introduction
The make job automatically determines which parts of the project need to be recompiled and executes commands to compile them. Although make is mostly used for C programs, you can use it for any language as long as a command-line compiler is provided. In fact, the application scope of the make tool is not limited to programming. You can use it to describe any task and change some files that need to automatically update other files.
1.1. Preparatory work
If you want to use make, you must write a file called "makefile". This file describes the relationship between the files in the project and provides commands to update each file. A typical project is like this: the executable file is updated by the target file, and the target file is updated by compiling the source file.
After the Makefile is written, it is enough to execute make every time the source file is changed, and all necessary recompilation will be performed. The Make program uses the database in the makefile and the last modification time of the file to determine which file needs to be updated; for the file that needs to be updated, make executes the commands recorded in the database.
You can provide command line parameters to make to control which files need to be recompiled.
1.2. Makefile introduction
Makefile tells make what to do, in most cases how to compile and link a program.
Here is a simple makefile describing how to compile and link an editor consisting of 8 C files and 3 header files:
edit: main.o kbd.o command.o display.o
insert.o serach.o files .o utils.o
cc –o edit main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc –c main.c
kdb.o : kbd.c defs.h command.h
cc –c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer. h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
Separate long lines for easier reading, which has the same effect as using one long line of. Just run make when using this makefile to create the executable file "edit"; if you want to delete the executable file and target file, execute make clean
make to recompile the editor, each changed C file must be recompiled; If the header file is changed, each C file containing the header file must be recompiled; each compilation produces an object file corresponding to the original file. Eventually, the object files are linked together to produce a new executable file.
1.3. Introduction to rules
The rules in the makefile are as follows:
TARGET … : DEPENDENCIES …
COMMAND
…
Target (TARGET) files generated by the program, such as executable files and target files; the target can also be an action to be performed, such as "clean".
Dependencies (DEPENDENCIES) are input files used to generate targets. A target usually depends on multiple files.
Command (COMMAND) is an action executed by make. One can have multiple commands, each occupying one line. Note: The starting character of each command line must be the TAB character!
Commands in dependency rules are usually responsible for generating target files when dependent files change. Make executes these commands to update or generate targets. Rules can have no dependencies, such as rules containing target "clean".
Rules explain how and when to redo files in the rule, and make executes to generate or update targets based on dependency relationships; rules also explain how and when to perform actions. Some of the rules may seem complicated, but they all fit the above pattern.
1.4. How make works
By default, make starts from the first target (the first target that does not start with ‘.’), which is called the default target. In the above makefile, the default goal is to update the executor 'edit', so put this goal at the front. When executing make, the make program reads the makefile from the current directory and starts processing the first rule; in the example, this rule is to relink 'edit'; before make can process this rule, it must process the ones on which 'edit' depends. Rules for files, in this case the target file. These files are processed according to their own rules: each '.o' file is updated by compiling the source file; when the source file or header file in the dependency relationship is newer than the target file, or the target file does not exist, it must be recompiled.
Other rules are processed because their target is a dependency of the target. Rules that have no dependency on the target will not be processed unless make processing is specified (such as make clean).
Before recompiling the target file, make will try to update its dependencies: source files and header files. The makefile in the example does not specify any operations on source files and header files: '.c' and '.h' files are not the target of any rules. After confirming that all object files are up to date, make decides whether to relink 'edit': if 'edit' does not exist, or any object file is newer than it, the linking work will proceed.
In this way, if we change insert.c and run make, make will compile this file to update 'insert.o' and then link 'edit'; if we modify 'command.h' and run make, 'kbd.o', 'command .o', 'files.o' will be regenerated, linked to 'edit'.
1.5. Using variables
In the example, in the rule 'edit', the target file is listed twice:
edit : main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
Such repetition can easily lead to errors: Suppose a new target file is added to the project , might just add it to a list; this risk is eliminated by using variables: variables allow a predefined string to be replaced in multiple places.
In the makefile, you can write this line to define the 'object' variable:
objects = main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
So the target file is needed Where a list is named, use $(object) instead of the value of the variable. The following is the makefile after using variables:
objects = main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $ (objects)
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit $(objects)
1.6. Simplified commands
Writing out compilation commands for each file is not necessary, because make can do it by itself To do; there is an implicit rule for updating '.o' files with '.c' files, use 'cc -c' command. Make will use 'cc -c main.c -o main.o' to compile main.c into main.o, so the command can be omitted in the rules for generating object files.
When the '.c' file is used in this way, it will be automatically added to the dependency relationship; therefore, the '.c' file can be omitted from the dependency relationship under the premise of omitting the command. The following is a simplified makefile:
objects = main.o kbd.o command.o display.o
insert.o search.o files.o utils.o edit : $(objects)
cc -o edit $(objects) main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer. h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
-rm edit $(objects)
1.7. Another style
If the targets in the makefile are all generated by implicit rules, the rules can be grouped according to dependency relationships:
objects = main.o kbd.o command.o display.o
insert.o search.o files.o utils.o edit : $(objects)
cc -o edit $(objects) $(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h
Here 'defs.h' is used as a dependency for all target files. Whether this style is good or bad comes down to personal preference, it's very compact, but it looks a little clearer to have the dependent information for each target together.
1.8. Cleanup
Writing rules will not compile the program. Makefiles usually describe how to do other things: such as cleaning up the directory by deleting object files and executable files in the directory. The example is written like this:
clean:
rm edit $(objects)
The actual situation is that we need to handle some unexpected events: there is a file called 'clean'; if rm makes an error, we do not want the make process to stop. , the modified version is as follows:
.PHONY : clean
clean :
-rm edit $(objects)
Such a rule cannot be placed at the beginning of the makefile, because this is not what we do by default. Since 'clean' is not a dependency on 'edit', this rule will not be executed when running make without arguments; to execute this rule, 'make clean' must be run.
2.Makefile
Makefile contains five types of content: explicit rules, implicit rules, variable definitions, directives and comments.
1. Explicit rules describe how to generate the target of the rule. It lists the files that the target depends on and specifies the command to generate or update the target.
2. Implicit rules describe how to generate a type of file based on the file name, indicating that the target may Depending on the file whose file name is similar, the corresponding command is specified.
3. Instructions are similar to compiler pseudo-instructions, including:
4. Instruct make to read another makefile
5. Decide whether to ignore part of the makefile
6. Define a variable
7. The start of '#' in a line is Comments until the end of the line unless a line continuation character is encountered. There cannot be comments in 'define' and commands, otherwise comments can appear anywhere.
2.1.makefile names
By default, make searches for makefiles with the following names: 'GNUmakefile', 'makefile' and 'Makefile' (note case). Normally your makefile should be called 'makefile' or 'Makefile'. 'GNUmakefile' is not recommended, unless your makefile is customized for GNU make, other make does not consider the name to be the name of a makefile.
If you use a non-standard named makefile, you must use the command switch '-f' or '--file'. The argument '-f NAME' or '--file NAME' tells make to read in NAME as a makefile. If multiple switches are used, all files will be concatenated sequentially. If this option is used, standard makefile names are not automatically detected.
2.2. Contains the
‘include’ directive to tell make to pause processing of the remaining content and read in other makefiles. The syntax is as follows:
include FILENAMES...
There can be spaces at the beginning of this line, but TAB characters are not allowed. If the filename contains variables or functions, these will be expanded.
2.3. ‘MAKEFILE’ variable
If the environment variable ‘MAKEFILE’ is defined, make considers its value to be a series of space-separated file names, which are read by the make program before processing other makefiles. This is similar to the include directive; targets in these files do not affect the default targets, and make does not consider it an error if the file is not found.
The main purpose of this variable is to communicate when referencing the make program recursively
2.4. How to regenerate the makefile
Sometimes the makefile is generated from other files, such as RCS or SCCS files. If the makefile is generated from other files, make needs to read the latest version of the makefile.
After reading in all makefiles, make considers each makefile to be a target and attempts to update it; if there is a rule in the makefile on how to update it, or there are implicit rules that apply, the required updates will be performed. After all makefiles have been checked, if any have changed, make will restart reading (make will try to update again, but usually it will not change anymore, because it is already the latest).
If a file uses the double colon rule and provides commands but no dependencies, the file will always be updated. In the case of makefiles, if the makefile double-colon rule provides commands but no dependencies, then the makefile will always be regenerated, which will lead to a cycle: make is just constantly updating the makefile, but not doing any work. To avoid this situation, make will not regenerate makefiles with double colon rules that only have commands without dependencies.
If the '-f' or '--file' option is not used, make will try the default makefile file name. Unlike specifying the '-f' or '--file' options, make cannot determine whether these files should exist. However, if a default makefile does not exist but can be generated by running make rules, you may want these rules to be run so that the makefile can be used.
So, if there is no default makefile, make attempts to generate it in the order in which the makefile names are looked up, until it succeeds or runs out of names. Note that it is not an error if make cannot find or generate a makefile; a makefile is not always required.
When using the '-t' or '--toUCh' options, it is undesirable to use an outdated makefile to decide which target to touch. So the '-t' option has no effect on makefile updates; similar '-q' (or '--question') and '-n' (or '--just-print') do not prevent makefile updates, because outdated makefiles will Produces incorrect output. This way 'make -f mfile -n foo' will update 'mfile', read it in, print out the commands needed to update 'foo' but not run them. The commands related to 'foo' are the contents of the updated 'mfile'.
But sometimes you don’t want to update the makefile, you can use the makefile as a target on the command line. When the makefile is explicitly specified as a target, the ‘-t’ option also applies to them.
In this way, 'make -f mfile -n mfile foo' will read 'mfile' and print out the updated command to be executed. The command of 'foo' is the content of the current 'mfile'.
2.5. Overload makefile
You can use the ‘include’ directive to include other makefiles and add target variable definitions. However, make does not allow different commands for the same target, and there are other ways to achieve the goal.
Suppose there are 'makefile' and 'mfile', 'makfile' should contain 'mfile', but both have rules for target 'foo'. This is a rule that can be written in 'makefile' to match any pattern, indicating that when make does not find the target in 'makefile', search for 'mfile':
foo:
frobnicate > foo
%: force
@$( MAKE) -f mfile $@
force: ;
When executing 'make foo', make found 'makefile' and executed the command 'frobnicate > foo'; When executing 'make bar', no corresponding response was found in 'makefile' The rules, then the mode rules apply, execute the command 'make -f mfile bar', other targets not mentioned in 'makefile' are also similar.
This method all works because the pattern of the pattern rule is '%', which can match any target; this rule relies on 'force', which ensures that the command will be executed even if the target exists; the command of the 'force' rule is Empty prevents 'make' from searching for implicit rules for it - this would cause a dependency cycle.
3. Rules
The rules in the makefile describe how to generate a specific file, which is the target of the rule. Rules list the target's dependency files and specify commands to build or update the target.
The order of the rules is not important, except to determine the default target: the default target is the first rule in the first makefile; if the first rule has multiple targets, the first target is the default. There are two exceptions: targets starting with '.' are not default targets; pattern rules have no effect on default targets.
Usually one of the rules we write is to compile the entire program or all programs specified in the makefile.
3.1. Example
foo.o : foo.c defs.h # module for twiddling the frobs
cc -c -g foo.c
It targets 'foo.o' and depends on 'foo.c' and ' defs.h', there is a command 'cc -c -g foo.c'. The command line begins with the TAB character to identify it as a command.
This rule explains two things:
8. How to decide whether 'foo.o' is old: if it doesn't exist, or if 'foo.c' or 'defs.h' is newer than it.
9. How to update the 'foo.o' file: by running the 'cc' program. The command does not mention 'defs.h', so we can guess that 'foo.c' contains it, which is the reason why 'defs.h' is placed in the dependency relationship.
3.2. The syntax of rules
The syntax is as follows:
TARGETS : DEPENDENCIES
COMMAND
...
or
TARGETS : DEPENDENCIES ; COMMAND
COMMAND
...
TARGETS is the file name separated by spaces, and the wildcard character can be used . Usually a rule has only one goal, but occasionally it has multiple goals.
The command line starts with the TAB key. The first command can be on the next line following the dependency relationship; or on the same line, after the semicolon; both methods have the same effect.
Because the '$' symbol is used as a variable reference, if you want to use the '$' symbol in a rule, you must write two: '$$'. You can use the '' symbol to split a long line, but this is not necessary because make has no limit on the length of the line.
3.3. Wildcard characters
The file name in the rule can contain wildcard characters, such as ‘*’, ‘?’.
The character '~' before the file name has special meaning. Used alone, or followed by a '/', it represents the user's home directory. For example, '~/bin' is expanded to /home/you/bin'; if '~' is followed by a word, it represents the home directory of the user indicated by the word. For example, '~john/bin' expands to '/home/john/bin'.
Wildcards are automatically expanded in targets, dependencies, and commands. In other cases, wildcards are expanded unless the 'wildcard' function is explicitly used. The special meaning of wildcard characters can be closed using the '' symbol.
Example:
clean:
rm -f *.o
and
print: *.c
lpr -p $?
touch print
Wildcard characters are not expanded when defining variables, for example:
objects = *.o
then The value of objects is the string '*.o'; but if you use objects in a target, dependency or command, expansion will occur. To set objects to expanded content, use:
objects := $(wildcard *.o)
3.3.1. Defects of wildcards
This is an example of using wildcards, but the result is not what you expect. Assume the executable 'foo' is generated from all '.o' files in the current directory:
objects = *.o foo : $(objects)
cc -o foo $(CFLAGS) $(objects)
objects variable The value is the string '*.o'. Wildcard expansion is done in rule 'foo', so all existing '.o' files become dependent on 'foo' and are recompiled if necessary.
But what if all ‘.o’ files are deleted? When the wildcard does not match any file, everything remains as is: then 'foo' depends on a file called '*.o'; since this file is unlikely to exist, the 'make' program reports that it cannot generate '*.o' 'Error in the file, this is not the expected result.
It is actually possible to obtain the desired results with wildcards, but requires complex techniques, including the 'wildcard' function and the string replacement function.
3.3.2.wildcard function
Wildcards are automatically performed in rules. However, wildcards are not expanded in variable assignments and function arguments. If wildcard expansion is required in these cases, the 'wildcard' function must be used. The syntax is as follows:
$(wildcard PATTERN...)
This string appearing anywhere in the makefile will be replaced by a space-separated list of existing files matching any file name format. If no file matches a pattern, the pattern is ignored from the output of 'wildcard'. Note that this is different from the wildcard processing described above.
One function of the 'wildcard' function is to find all the '.c' files in the directory:
$(wildcard *.c)
You can get the target file from the C file list by replacing the suffix '.c' with '.o' The list:
$(patsubst %.c,%.o,$(wildcard *.c))
In this way, the makefile in the previous section is rewritten as:
objects := $(patsubst %.c,%.o,$ (wildcard *.c)) foo: $(objects)
cc -o foo $(objects)
This makefile uses the implicit rules for compiling C programs, so there is no need to write explicit rules for compilation. (‘:=’ is a variant of ‘=’)
Note: ‘PATTERN’ is case-sensitive.
3.4. Directory search
For large systems, source files and target files are usually placed in different directories. The directory search function allows make to automatically search for dependent files in multiple directories. When you redistribute files, you do not need to change the rules, just change the search path.
3.4.1. ‘VPATH’
make variable ‘VPATH’ lists the directory list that make should search. In many cases, the current directory does not contain dependent files, and 'VPATH' describes a search list of all files, including those that are the target of the rule.
If a target or dependent file is not found in the current directory, 'make' searches for a file with the same name in the directory listed in 'VPATH'. If found, that file becomes a dependent file; rules can use the files as if they were in the current directory.
In the 'VPATH' variable, directory names are separated by colons or spaces; the order in which the directories are listed determines the order in which make searches. (Note: The GNU make directory names transplanted to Win32 in pSOSystem 2.5 must be separated by semicolons, hereafter referred to as Win32 GNU make). For example: VPATH = src:../headers then the rule
foo.o : foo.c
is interpreted as
foo.o : src/foo.c
assuming 'foo.c' does not exist in the current directory, in ' src' directory.
3.4.2. Selective search
Similar to the 'VPATH' variable but more selective is the 'vpath' directive (note that it is lowercase), which can specify the search path for files that match a specific pattern. This allows you to specify different search paths for different types of files.
The 'vpath' directive has three forms:
10.'vpath PATTERN DirectorIES'
Specify search paths DIRECTORIES for file names matching PATTERN. The separation of directories is the same as that of 'VPATH'
11.'vpath PATTERN'
Clear to Match the search path specified by the file name of PATTERN
12.'vpath'
Clear all search paths previously specified with 'vpath'
The pattern of 'vpath' is a string containing '%': this string must match what needs to be searched Depending on the file name, the '%' character matches 0 or more arbitrary characters. For example: '%.h' matches any file ending with '.h' (if there is no %, the PATTERN must be exactly the same as the dependent file, which is not commonly used).
When there is no dependent file in the current directory, if the PATTERN in 'vpath' matches the dependent file name, the directories listed in DIRECTORIES in the command will be processed the same as in 'VPATH'. Example:
vpath %.h ../headers
tells make to look for '.h' files not found in the current directory in the ../headers directory.
If multiple 'vapth' pattern matches rely on file names, make will process them one by one and search in all specified directories. Make processes 'vapth' in the order they appear in the makefile; multiple 'vapth's of the same mode are independent of each other.
vpath %.c foo
vpath % blish
vpath %.c bar
will search for '.c' files in the order of 'foo', 'blish', 'bar'. And
vpath %.c foo:bar
vpath % blish
searches in the order of 'foo', 'bar', 'blish'.
3.4.3. Using automatic variables
The results of the directory search do not change the commands in the rule: the commands are executed as is. Therefore, you must write commands that are suitable for directory search functions. This can be done by using automatic variables like '$^'. '$^' represents all dependent files in the rule, including the directory names where they are located (see directory search); '$@' represents the target. For example:
foo.o : foo.c
cc -c $(CFLAGS) $^ -o $@
Normally, dependent files also contain header files, but these files are not mentioned in the command: variable '$< ;' represents the first dependent file:
VPATH = src:../headers
foo.o : foo.c defs.h hack.h
cc –c $(CFLAGS) $< -o $@
3.4. 4. Directory search and implicit rules
Specifying directory search using 'VPATH' and 'vpath' will also affect implicit rules. For example: the file 'foo.o' has no explicit rules, make will consider the implicit rules: if 'foo.c' exists, compile it; if the file does not exist, search in the corresponding directory; if 'foo.c' ' exists in any directory, the implicit rules of C compilation are applied.
It is often necessary for commands with implicit rules to use automatic variables so that file names obtained by directory searches can be used without additional effort.
3.5.PHONY TARGET
The Phony target is not an actual file name: just the name of the command to be executed when explicitly requested. There are two reasons to use phony targets: to avoid conflicts with files of the same name and to improve performance.
If you write a rule that does not generate a target file, its command will be executed every time the target is made. For example:
clean:
rm *.o temp
Because the 'rm' command does not generate a 'clean' file, this command will be executed every time 'make clean' is executed. If a 'clean' file appears in the directory, the rule is invalid: there is no dependent file, the file 'clean' is always the latest, and the command will never be executed; to avoid this problem, use '.PHONY' to specify the target. For example:
.PHONY: clean
Executing 'make clean' in this way will ignore whether the 'clean' file exists or not.
It is known that the phony target is not an actual file generated by other files, and make will skip the implicit rule search. This is why declaring a phony target will improve performance, even if you don't worry about the actual file existing or not. The complete example is as follows:
.PHONY : clean
clean :
rm *.o temp
phony target should not rely on the real target file. If so, the command will be executed every time make updates this file. As long as the phony target is not dependent on the real target, the rule's commands will only be executed when this target is specified.
Phony targets can have dependencies. When there are multiple programs in a directory, it is more convenient to put them in a makefile. Because the default target is the first target in the makefile, this phony target is usually called 'all', and its dependent files are each program:
all : prog1 prog2 prog3
.PHONY : all
prog1 : prog1.o utils.o
cc -o prog1 prog1.o utils.o
prog2 : prog2.o
cc -o prog2 prog2.o
prog3 : prog3.o sort.o utils.o
cc -o prog3 prog3.o sort.o utils. o
In this way, using 'make' will generate all three programs.
When one phony target is a dependency of another, its function is equivalent to a subroutine, for example:
.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff
rm program
cleanobj :
rm *.o
cleandiff :
rm *. diff
3.6.FORCE target
When a rule has no dependencies and no command, and its target is not an existing filename, make assumes that this target is always updated when the rule is run. This means that if a rule relies on this target, its commands are always executed.
clean: FORCE
rm $(objects)
FORCE:
In the example, the target 'FORCE' meets this extraordinary condition, so that the target 'clean' that relies on it is forced to execute its command. The name 'FORCE' has no special meaning, it is just commonly used. Using 'FORCE' in this way has the same effect as '.PHONY : clean'. Using '.PHONY' is more clear and efficient, but not all 'makes' support it; so many makefiles use 'FORCE'.
3.7. Empty target
An empty target is a variant of the phony target: an action used to perform an explicit request. The difference from the phony target is that this target file can actually exist. The content of the target file is irrelevant and is usually empty. The purpose of the empty target file is to use its last modification time to record the time when the command was last executed. This is achieved by updating the target file using the 'touch' command.
print: foo.c bar.c
lpr -p $?
touch print
Using this rule, when executing 'make print', if any file has changed since the last 'make print', the 'lpr' command will implement. The automatic variable '$?' is used to print out only those files that have changed.
3.8. Built-in extraordinary goals
Some names have extraordinary meanings when they exist as goals.
13..PHONY The dependencies of this target are considered to be phony targets. When processing these targets, the command is executed unconditionally, regardless of whether the file name exists or its last modification time.
14..SUFFIXES The dependencies of this target are considered to be a suffix. List, used when checking suffix rules
15..DEFAULT The rules for this target are used on targets with no rules (explicit or implicit). If the 'DEFAULT' command is defined, this set of commands will be executed for all dependent files that are not regular targets
16..PRECIOUS The dependent files of this target will receive special treatment: if make is killed or the execution of the command is interrupted, these targets It is not deleted; and if the target is an intermediate file, it will not be deleted when no longer needed. The target pattern of implicit rules (such as %.o) can be used as the dependent file of '.PRECIOUS', so that the intermediate files generated by these rules can be saved.
17..INTERMEDIATE The target's dependent files are considered intermediate files; if the target has no dependent files, all target files in the makefile are considered intermediate files.
18..IGNORE When executing commands that rely on rules for this target, make will ignore errors. The commands of this rule itself are meaningless. If the rule has no dependencies, it means that errors in all command executions are ignored. This usage is only for backward compatibility; since it will affect all commands, it is not particularly useful. It is recommended to use other more selective methods of ignoring errors.
19..SILENT When executing a rule-dependent command for this target, make does not print the command itself. The rule's command makes no sense. When '.SILIENT' has no dependencies, it means that all commands in the makefile will not be printed when executed. This rule is only provided for backward compatibility.
20..EXPORT_ALL_VARIABLES simply exists as a target, instructing make to output all variables to the child process.
When the suffix of a defined implicit rule is used as a target, it is also considered an extraordinary target; the same is true for the connection of two suffixes, such as '.c.o'. These targets are suffix rules, an outdated (but still widely used) way of defining implicit rules. The suffix usually starts with '.', so extraordinary targets also start with '.'.
3.9. One rule with multiple goals
A rule with multiple goals has the same effect as writing multiple rules, each with one goal. The same command applies to all targets, but its effectiveness will vary by substituting '$@' for the actual target. The dependencies of all targets in the rules are the same.
This is useful in two situations:
★ Only dependencies, no commands required. For example:
kbd.o command.o files.o: command.h
21. All targets have the same command. The commands do not need to be exactly the same, as '$@' can be used in the command:
bigoutput littleoutput : text.g
generate text.g -$(subst output,,$@) > $@
and
bigoutput : text. g
generate text.g -big > bigoutput
littleoutput : text.g
generate text.g -little > littleoutput
Equal. It is assumed here that the program 'generate' produces two outputs: one using the '-big' option and one using the '-little' option. If you imagine using the '$@' change command to change the dependency relationship, it cannot be achieved through ordinary multi-objective rules, but it can be achieved through pattern rules.
3.10. One target with multiple rules
A file can be the target of multiple rules, and the dependencies of all rules are merged. If the target is older than any of the dependent files, the command is executed.
A file can only have one set of commands executed. If multiple rules give commands for the same file, make uses the last group and prints an error message (exception: if the file name starts with '.', no error message is printed. This is for compatibility with other make ). There is no reason to write the makefile like this, which is why make gives the error message.
An additional rule with only dependencies can give additional dependency files for many files at once. For example, the 'objects' variable represents all the output of the compiler in the system. A simple way to illustrate that all files must be redone when 'config.h' changes is as follows:
objects = foo.o bar.o
foo.o : defs. h
bar.o : defs.h test.h
$(objects) : config.h
There is no need to change the actual target file generation rules. This rule can be inserted or proposed when additional dependencies need to be added or deleted. Another trick is that additional dependencies can be represented by variables. When make is executed, variables can be assigned values:
extradeps=
$(objects) : $(extradeps)
When the command `make extradeps=foo.h' is executed 'foo.h' is considered to be a dependent file for every object file, but this is not the case for a simple 'make' command.
3.11. Static pattern rules
Static pattern rules can specify multiple targets, and use the target name to suggest the name of the dependent file; more general than ordinary multi-target rules because the dependency relationship does not need to be the same: dependency relationship Must be similar but not necessarily identical.
3.11.1. Syntax
TARGETS ...: TARGET-PATTERN: DEP-PATTERNS ...
COMMANDS
...
TARGETS list indicates the target of the rule application, and can contain wildcards, which is the same as the target of ordinary rules. TARGET-PATTERN and DEP-PATTERNS indicate how the dependency relationship of the target is calculated: the target matching TARGET-PATTERN extracts a part of the name, called the stem (stem), and the stem is replaced with DEP-PATTERNS to form the dependency file name.
Each pattern usually contains a '%' character. When TARGET-PATTERN matches a target, the '%' character can match any part of the target name; this part is the stem, and the rest of the pattern must match exactly. For example, 'foo.o' matches '%.o', which is the stem; the targets 'foo.c' and 'foo.out' do not match this pattern.
The target's dependency file name is formed by replacing '%' in DEP-PATTERNS with the stem: if the dependency pattern is '%.c', replacing the stem 'foo' can result in 'foo.c'. It is also legal if the dependency pattern does not contain '%', and this dependency file is valid for all targets.
If you need to use the '%' character in a pattern rule, you must add the '' character in front of it. If the '' character before '%' is meaningful, you must add '' in front of it, and other '' characters do not need to be used. Treat it like this. For example, 'the%weird%pattern' is preceded by 'the%weird' and followed by 'pattern'. The last '' remains as it is because it does not affect the '%' character.
The following example compiles 'foo.o' and 'bar.o' from the corresponding '.c' files:
objects = foo.o bar.o
$(objects): %.o: %.c
$(CC ) -c $(CFLAGS) $< -o $@
Each target must match the target pattern, and a warning will be given for unmatched targets. If only some files in the list match the pattern, you can use the filter function to remove unmatched file names:
files = foo.elc bar.o lose.o $(filter %.o,$(files)): %.o : %.c
$(CC) -c $(CFLAGS) $< -o $@
$(filter %.elc,$(files)): %.elc: %.el
emacs -f batch-byte -compile $<
In the example, the result of `$(filter %.o,$(files))' is `bar.o lose.o'; the result of `$(filter %.elc,$(files))' is `foo.elc'. The following example illustrates the use of '$*':
bigoutput littleoutput : %output : text.g
generate text.g -$* > $@
When the command `generate' is executed, '$*' expands to the stem 'big' ' or 'little'.
3.11.2. Static pattern rules and implicit rules
Static pattern rules and implicit rules have a lot in common as pattern rules. They both have target patterns and construct patterns that rely on file names. The difference is that when make decides How to apply the rules.
Implicit rules can be applied to any target that matches its pattern, but only for targets without a specified command. If there are multiple applicable implicit rules, only one will be used, depending on the order of the rules.
Conversely, static mode rules apply to the explicit target list in the rule, not to other targets and always apply to each target specified. If there are two conflicting rules and both have commands, this is an error.
The advantages of static mode rules over implicit rules are as follows:
22. Implicit rules can be overridden for some files that cannot be classified syntactically, but can be explicitly listed
23. The precise contents of the directory cannot be determined, and some files are irrelevant files may cause make to apply the wrong implicit rules; the end result may depend on the order of the implicit rules. When applying static pattern rules, this uncertainty does not exist: the rules apply to clearly specified goals.
3.12. Double-colon rules
The target of Double-colon rules is followed by ‘::’ instead of ‘:’. When a target appears in multiple rules, its processing is different from that of ordinary rules.
When a target appears in multiple rules, all rules must be of the same type: all plain or all double colon. If it is a double colon, the rules are independent of each other; if the target needs to be updated, the command of the rule is executed; the result may be that it is not executed, or some of them are executed, or all the rules are executed.
The fact that double colon rules for the same target are completely isolated, each rule is processed separately, just like the rules for different targets; the rules are processed in the order they appear in the makefile. The really meaningful rules of this type are those in The order of command execution is irrelevant.
This kind of rule is sometimes obscure but not very useful; it provides a mechanism to treat targets differently by relying on file updates, which is rare. Each such rule should provide the command; if not, the applicable implicit rule will be used.
3.13. Automatically generate dependencies
In the makefile, many rules are that some target files depend on some header files. For example: 'main.c' uses 'defs.h' via '#include', so the rule:
main.o: defs.h
tells make to update 'main.o' when 'defs.h' changes. When the program is relatively large, many such rules need to be written; and the makefile must be carefully updated every time '#include' is added or deleted. Many modern compilers can write these rules for you, usually through the '-M' option of the compiler, for example the command:
cc –M main.c
Output the following:
main.o : main.c defs. h
This way you don’t have to write these rules, the compiler will do it for you.
Note that 'main.o' mentioned in such a dependency relationship will not be considered an intermediate file by the implicit rule, which means that make will not delete it after using it. When using the old 'make' program, the usual practice is to use the 'make depend' command to use the compiler's function to generate dependencies. This command will generate a 'depend' file containing all automatically generated dependencies, and then use ' include' to read it in.
When using GNU's make, the ability to regenerate makefiles makes this practice obsolete: there is never an explicit request to update dependencies, as it always regenerates any outdated makefiles.
The recommended approach for automatic dependency generation is to make a makefile for each source file. For each source file 'NAME.c', there is a makefile 'NAME.d', which lists all the files that the target file 'NAME.o' depends on, so that when the source file is updated, it needs to be scanned to generate new dependencies. relation. An example is a pattern rule that generates dependency file 'NAME.d' from 'NAME.c':
%.d: %.c
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< ;
sed '''s/($*).o[ :]*/1 $@/g''' > The $@'
-e option is used when the $(CC) command fails (exit status is non-0) ), the shell exits immediately. Usually the return value of the shell is the return value of the last command (sed) in the pipeline, so make will not notice the compiler error.
When using the GNU C compiler (gcc), you can use the '-MM' option instead of the '-M' option, thus omitting the dependency on the system header file. The purpose of the 'sed' command is to convert
main.o : main.c defs.h
into
main.o main.d : main.c defs.h
so that each '.d' file depends on '. The o' file corresponds to the source file and header file, and make can update the dependency file when the original text or header file changes.
If the rules for generating '.d' files are defined, you can use the 'include' directive to read in all files:
sources = foo.c bar.c
include $(sources:.c=.d)
Example Use substitution variables to convert the list of source files 'foo.c bar.c' into a list of dependent relational files. Because '.d' files are like other files and require no more work, make will regenerate them when needed.
4. Write commands
The commands of the rules are composed of shell commands that are executed one by one. In addition to commands written after dependencies separated by semicolons, each command line must start with a tab character. A blank line and a comment line can appear in the command line and are ignored during processing (note: a blank line starting with a tab character is not The 'empty' line is an empty command).
Any program can be used in the command, but these programs are executed by $(SHELL).
4.1. Echo
Usually make prints out the command to be executed, which is called echo. This is the same phenomenon as typing the command yourself. When a line is preceded by an '@' character, the command is no longer echoed and the '@' character is discarded before being passed to the shell. Typical usage is only valid for print commands, such as the 'echo' command:
@echo About to make distribution files
When make uses the '-n' or '--just-print' option, show everything that is going to happen, but not Excuting an order. Only in this case, the command line is still displayed even if the command starts with '@'. This option is useful to see what make is actually doing.
The '-s' or '--silent' option prevents all echoes from make, just like all commands starting with '@'; a '.SILENT' rule without dependencies has the same effect, but '@' is more flexible.
4.2. Execution
When you need to execute a command to update the target, make creates a subshell for each line to execute. This means that shell commands such as 'cd' that set local variables for a process (change the current directory of the process) will not affect subsequent commands. If you need 'cd' to affect the next command, put them on one line separated by semicolons, so that make thinks it is a command passed to the shell program (note: this requires shell support):
foo : bar/lose
cd bar ; gobble lose > ../foo
Another form uses the line continuation character:
foo : bar/lose
cd bar;
gobble lose > ../foo
The name of the shell program is obtained through the 'SHELL' variable of.
(*UNIX) Unlike most variables, the 'SHELL' variable is not set through the environment (that is, it needs to be set in the makefile), because the 'SHELL' environment is a personal choice, and if different people's choices will affect the function of the makefile If so, this is bad.
4.3. Parallel execution
GNU make can execute several commands at a time. Usually make executes one command at a time, waits for its return, and then executes the next one. Use '-j' or '--jobs' to execute multiple commands at the same time. If there is a positive number after '-j', it indicates the number of commands that can be executed at one time; if there is no parameter after '-j', there is no limit to the number of commands that can be executed. The default number is one.
One annoying problem is that if multiple commands are executed at the same time, their output will be mixed together; another problem is that two processes cannot get input from the same device.
4.4. Error
When each shell command returns, make will check its return status. If the command is executed successfully, the next command is executed. After the last command is executed, the rule execution ends.
If there is an error (returns non-zero status), make abandons the current rule, and possibly all rules.
Sometimes command execution errors are not a problem, such as using the 'mkdir' command to ensure that the directory exists: if the directory exists, 'mkdir' will report an error, but you still want make to continue.
To ignore errors with a command, use the '-' character before the command. The '-' character is discarded before being passed to the shell:
clean:
-rm -f *.o
If using '-i' or '--ignore' -errors' option, make will ignore errors generated by all commands; an '.IGNORE' rule without dependencies has the same effect, but '-' is more flexible.
When ignoring errors, make considers the error a success and just notifies you of the command's exit status and the error is ignored. If make does not tell you to ignore the error, when the error occurs, it means that the target cannot be updated successfully, and of course the targets that directly or indirectly depend on it cannot succeed; the commands of these targets will not be executed because their prerequisites are not met.
Normally make will exit immediately with a non-zero status. However, if the '-k' or '-keep-going' option is given, make will handle other dependencies and make necessary updates before exiting. For example, if an error is encountered while compiling one object file, 'make -k' will continue to compile other object files.
It is generally believed that your purpose is to update the specified target. When make knows that this is impossible, it will immediately report a failure; the '-k' option indicates that the real purpose is to test the possibility of updating the program: find out more possibilities before compiling. Many irrelevant questions.
If the command fails, assuming it updates the target file, the file is incomplete and cannot be used - at least not fully updated. However, the last modification time of the file indicates that it is already the latest, and the file will not be updated the next time make is run. This situation is the same as the command being killed; it is usually correct to delete the target when the command fails; make does this for you when '.DELETE_ON_ERROR' is the target. Although you always want make to do this, this is not customary; so you must explicitly ask make to do this (other make does this automatically).
4.5. Interrupt make
If make encounters an error when executing a command, the target file updated by the command may be deleted: make checks whether the modification time of the file has changed. The purpose of removing the target is to ensure that it is regenerated the next time make is executed. Why did you do this? Suppose you press 'Ctrl-c' while the compiler is running. At this time, the compiler writes and generates the object file 'foo.o'. 'Ctrl-c' kills the compiler, leaving an incomplete file, but its modification time is newer than the source file 'foo.c'; at this time, make also receives the 'Ctrl-c' signal to delete this incomplete file , if make does not do this, it will think that 'foo.o' does not need to be updated the next time make is run, and strange errors will occur during linking.
You can use the ‘.PRECIOUS’ rule to prevent target files from being deleted. When make updates the target, it will detect whether it is a dependency of '.PRECIOUS' and decide whether to delete the target when the command error or interruption occurs. If you want the update of the target to be an atomic operation, or to record the modification time, or must always exist to prevent other types of errors, these are the reasons why you must do this.
4.6. Recursive use
Recursive use of make is to use the make command in the makefile. This technique is useful when you break a large system into several subsystems and provide a makefile for each subsystem. For example, if there is a subdirectory 'subdir' with its own makefile and you want make to run in the self-directory, you can do this:
subsystem:
cd subdir; $(MAKE)
or
subsystem:
$(MAKE) -C subdir
You can copy this; example to use make recursively
4.6.1. 'MAKE' variable
Recursive make must use the 'MAKE' variable, not an explicit make command:
subsystem:
cd subdir; $(MAKE)
The The value of the variable is the name of the make being called. Using 'MAKE' in a command does something extraordinary: it changes `-t' (`--touch'), `-n' (`--just-print') and `-q' (`--question' ') the meaning of the option. Using the example above, consider the 'make –t' command (the '-t' option marks the target as up-to-date but does not run the command). Furthermore, the '-t' option will create a 'subsystem' file that is actually desired. The operation is to run 'cd subdir; make –t'; but this will execute the command, which is inconsistent with the original meaning of '-t'.
This extraordinary feature does the expected job. When the command line contains the variable 'MAKE', the options '-t', '-n' and '-q' do not apply. Regardless of these flags that cause the command not to be executed, commands containing the 'MAKE' variable are always executed. The normal 'MAKEFLAGS' mechanism passes these flags to the submake so that requests for print commands are propagated to the subsystem.
4.6.2. Pass variables to sub-make
Variables in the upper-level (top-level) make can be explicitly passed to the sub-make through the environment. In submakes, these variables are defined by default, but definitions in submakefiles are not overridden unless the '-e' option is used.
To pass down, or output variables, make adds them to the environment variables when running the command; sub-make, you can use environment variables to initialize the variable table. Unless explicitly requested, make only outputs variables set in the initial environment or on the command line and variable names consist only of letters, numbers, and underscores. Some shells cannot handle environment variables with other characters.
Special variables 'SHELL' and 'MAKEFLAGS' are always output. If the 'MAKEFILE' variable has a value, it will also be output. Make automatically outputs variables defined on the command line through 'MAKEFLAGS'.
If you want to export a specific variable, use the 'export' command:
export VARIABLE...
If you want to prevent a variable from being exported, use the 'unexport' command:
unexport VARIABLE...
For convenience, you can define the variable When exporting it:
export VARIABLE = value
and
VARIABLE = value
export VARIABLE
have the same effect.
If you want to export all variables, just use the 'export' command itself.
The variable 'MAKELEVEL' will change when passed level by level. The value of this variable is a string indicating the number of nesting levels. The top-level 'make' is, the value of the variable is '0'; the value of the sub-make is '1' '; sub-make has a value of '2', and so on.
The purpose of ‘MAKELEVEL’ is to test it in a conditional directive, thus writing a makefile that behaves differently when run recursively and when run directly.
The following content is copied from the GNU Make Manual
5. Command line parameters
`-b'
`-m'
These options are ignored for compatibility with other versions of
`make'. `-C DIR'
`--directory =DIR'
Change to directory DIR before reading the makefiles. If multiple
`-C' options are specified, each is interpreted relative to the
previous one: `-C / -C etc' is equivalent to `-C /etc '. This is
typically used with recursive invocations of `make' (*note
Recursive Use of `make': Recursion.). `-d'
`--debug'
Print debugging information in addition to normal processing. The
debugging information says which files are being considered for
remaking, which file-times are being compared and with what
results, which files actually need to be remade, which implicit
rules are considered and which are applied--everything interesting
about how `make' decides what to do. `-e'
`--environment-overrides'
Give variables taken from the environment precedence over
variables from makefiles. *Note Variables from the Environment:
Environment. `-f FILE'
`--file=FILE'
`--makefile=FILE'
Read the file named FILE as a makefile. `-h'
`--help'
Remind you of the options that `make' understands and then exit .
`-i'
`--ignore-errors'
Ignore all errors in commands executed to remake files. `-I DIR'
`--include-dir=DIR'
Specifies a directory DIR to search for included makefiles . If several `-I' options are
used to specify several directories, the directories are searched
in the order specified. `-j [JOBS]'
`--jobs=[JOBS]'
Specifies the number of jobs ( commands) to run simultaneously.
With no argument, `make' runs as many jobs simultaneously as
possible. If there is more than one `-j' option, the last one is
effective.
`-k'
`- -keep-going'
Continue as much as possible after an error. While the target that
failed, and those that depend on it, cannot be remade, the other
dependencies of these targets can be processed all the same. `-l [LOAD]'
`--load-average[=LOAD]'
`--max-load[=LOAD]'
Specifies that no new jobs (commands) should be started if there
are other jobs running and the load average is at least LOAD (a
floating-point number). With no argument, removes a previous load
limit. *Note Parallel Execution: Parallel. `-n'
`--just-print'
`--dry- run'
`--recon'
Print the commands that would be executed, but do not execute them.
`-o FILE'
`--old-file=FILE'
`--assume-old=FILE'
Do not remake the file FILE even if it is older than its
dependencies, and do not remake anything on account of changes in
FILE. Essentially the file is treated as very old and its rules
are ignored. `-p'
`--print-data-base'
Print the data base (rules and variable values) that results from
reading the makefiles; then execute as usual or as otherwise
specified. This also prints the version information given by the
`- v' switch (see below). To print the data base without trying to
remake any files, use `make -p -f /dev/null'. `-q'
`--question'
"Question mode". Do not run any commands, or print anything; just
return an exit status that is zero if the specified targets are
already up to date, one if any remaking is required, or two if an
error is encountered. `-r'
`--no-builtin-rules'
Eliminate use of the built-in implicit rules.You can still define your own by writing
pattern rules. The `-r' option also clears out the default list
of suffixes for suffix rules .But you can still define your own suffixes with a
rule for `.SUFFIXES', and then define your own suffix rules. `-s'
`--silent'
`--quiet'
Silent Operation; do not print the commands as they are executed.
`-S'
`--no-keep-going'
`--stop'
Cancel the effect of the `-k' option. This is never necessary
except in a recursive `make' where `-k' might be inherited from
the top-level `make' via `MAKEFLAGS' or if you set `-k' in `MAKEFLAGS' in your
environment. `-t'
`--touch'
Touch files (mark them up to date without really changing them)
instead of running their commands. This is used to pretend that
the commands were done, in order to fool future invocations of
`make'. `-v'
`--version'
Print the version of the `make' program plus a copyright, a list
of authors, and a notice that there is no warranty; then exit.
`-w'
`--print-directory'
Print a message containing the working directory both before and
after executing the makefile. This may be useful for tracking
down errors from complicated nests of recursive `make' commands. `--no-print-directory'
Disable printing of the working directory under `-w'. This option
is useful when `-w' is turned on automatically, but you do not
want to see the extra messages. `-W FILE'
`--what-if=FILE'
`--new-file=FILE'
`--assume-new=FILE'
Pretend that the target FILE has just been modified. When used
with the `-n' flag, this shows you what would happen if you were
to modify that file. Without `-n', it is almost the same as
running a `touch' command on the given file before running `make',
except that the modification time is changed only in the
imagination of `make'. `--warn-undefined-variables'
Issue a warning message whenever `make' sees a reference to an
undefined variable. This can be helpful when you are trying to
debug makefiles which use variables in complex ways. 6.参考
6.1.指令
`define VARIABLE'
`endef'
Define a multi-line, recursively-expanded variable.
*Note Sequences::. `ifdef VARIABLE'
`ifndef VARIABLE'
`ifeq (A,B)'
`ifeq "A" "B"'
`ifeq 'A' 'B''
`ifneq (A,B)'
`ifneq "A" "B"'
`ifneq 'A' 'B''
`else'
`endif'
Conditionally evaluate part of the makefile. `include FILE'
Include another makefile. `override VARIABLE = VALUE'
`override VARIABLE := VALUE'
`override VARIABLE += VALUE'
`override define VARIABLE'
`endef'
Define a variable, overriding any previous definition, even one
from the command line.
`export'
Tell `make' to export all variables to child processes by default. `export VARIABLE'
`export VARIABLE = VALUE'
`export VARIABLE := VALUE'
`export VARIABLE += VALUE'
`unexport VARIABLE'
Tell `make' whether or not to export a particular variable to child
processes.
`vpath PATTERN PATH'
Specify a search path for files matching a `%' pattern.
*Note The `vpath' Directive: Selective Search. `vpath PATTERN'
Remove all search paths previously specified for PATTERN. `vpath'
Remove all search paths previously specified in any `vpath'
directive.
6.2.函数
`$(subst FROM,TO,TEXT)'
Replace FROM with TO in TEXT. `$(patsubst PATTERN,REPLACEMENT,TEXT)'
Replace Words matching PATTERN with REPLACEMENT in TEXT. `$(strip STRING)'
Remove excess whitespace characters from STRING. `$(findstring FIND,TEXT)'
Locate FIND in TEXT. `$(filter PATTERN...,TEXT)'
Select words in TEXT that match one of the PATTERN words. `$(filter-out PATTERN...,TEXT)'
Select words in TEXT that *do not* match any of the PATTERN words. `$(sort LIST)'
Sort the words in LIST lexicographically, removing duplicates. `$(dir NAMES...)'
Extract the directory part of each file name. `$(notdir NAMES...)'
Extract the non-directory part of each file name. `$(suffix NAMES...)'
Extract the suffix (the last `.' and following characters) of each
file name. `$(basename NAMES...)'
Extract the base name (name without suffix) of each file name. `$(addsuffix SUFFIX,NAMES...)'
Append SUFFIX to each word in NAMES. `$(addprefix PREFIX,NAMES...)'
Prepend PREFIX to each word in NAMES. `$(join LIST1,LIST2)'
Join two parallel lists of words. `$(word N,TEXT)'
Extract the Nth word (one-origin) of TEXT. `$(words TEXT)'
Count the number of words in TEXT. `$(firstword NAMES...)'
Extract the first word of NAMES. `$(wildcard PATTERN...)'
Find file names matching a shell file name pattern (*not* a `%'
pattern). `$(shell COMMAND)'
Execute a shell command and return its output. `$(origin VARIABLE)'
Return a string describing how the `make' variable VARIABLE was
defined. `$(foreach VAR,WORDS,TEXT)'
Evaluate TEXT with VAR bound to each word in WORDS, and
concatenate the results.
6.3.自动变量
`$@'
The file name of the target. `$%'
The target member name, when the target is an archive member. `$<'
The name of the first dependency. `$?'
The names of all the dependencies that are newer than the target,
with spaces between them. For dependencies which are archive
members, only the member named is used
with spaces between them. For dependencies which are archive
members, only the member named is used
`$^'
`$+'
The names of all the dependencies, with spaces between them. For
dependencies which are archive members, only the member named is
used. The value of `$^' omits duplicate
dependencies, while `$+' retains them and preserves their order. `$*'
The stem with which an implicit rule matches `$(@D)'
`$(@F)'
The directory part and the file-within-directory part of `$@'. `$(*D)'
`$(*F)'
The directory part and the file-within-directory part of `$*'. `$(%D)'
`$(%F)'
The directory part and the file-within-directory part of `$%' `$(
`$(^F)'
The directory part and the file-within-directory part of `$^' `$(+D)'
`$(+F)'
The directory part and the file-within-directory part of `$+' `$(?D)'
`$(?F)'
The directory part and the file-within-directory part of `$?'
6.4.非凡变量
`MAKEFILES'
Makefiles to be read on every invocation of `make'. `VPATH'
Directory search path for files not found in the current directory. `SHELL'
The name of the system default command interpreter, usually
`/bin/sh'. You can set `SHELL' in the makefile to change the
shell used to run commands.
`MAKE'
The name with which `make' was invoked. Using this variable in
commands has special meaning. `MAKELEVEL'
The number of levels of recursion (sub-`make's). `MAKEFLAGS'
The flags given to `make'. You can set this in the environment or
a makefile to set flags. `SUFFIXES'
The default list of suffixes before `make' reads any makefiles.
以上就是makefile规则的内容,更多相关文章请关注PHP中文网(www.php.cn)!