Make command tutorial details
makeIs a necessary tool for building projects.
Make Concept
MakeThis word in English means "production ".MakeThe command directly uses this to make a file. For example, to make a filea.txtTo execute the following command.
$ make a.txt
However, if you enter this command, it does not work. BecauseMakeThe command itself does not know how to makea.txtSomeone needs to tell it how to call other commands to accomplish this goal.
For example, assume thata.txtDependent onb.txtAndc.txtIs the next two file connections (catCommand. So,makeYou need to know the following rules.
a.txt: b.txt c.txt cat b.txt c.txt > a.txt
That is to say,make a.txtThere are two steps behind this command: Step 1: Confirmb.txtAndc.txtMust already exist. UsecatCommand to merge the two files and output them as new files.
Rules like this are written inMakefileFile,MakeThe command depends on this file for construction.MakefileFile can also be writtenmakefileOr use the command line parameter to specify another file name.
$ Make-f rules.txt # Or $ make --file=rules.txt
The code above specifiesmakeCommand basisrules.txtFile.
In short,makeOnlyShellCommand to build the tool. The rule is simple. You need to specify which file to be built, which source files it depends on, and how to re-build the file when there are changes to those files.
Makefile format
Building rules are all written inMakefileWhat should I learn in the file?MakeCommand, you must learn how to writeMakefileFile.
Overview
MakefileA file consists of a series of rules (rules. The format of each rule is as follows.
<target> : <prerequisites> [tab] <commands>
The part before the colon in the first line above is called "target "(target), The part after the colon is called the precondition (prerequisites); The second line must be composedtabKey first, followed by the Command (commands).
"Target" is required and cannot be omitted; "preconditions" and "command" are optional, but either of them must exist at least.
Each rule defines two things: What are the preconditions for building goals and how to build them. The following describes in detail the three components of each rule.
Target)
A target (target) To form a rule. The target is usually a file name, specifyingMakeCommand to build the object, such asa.txt. The target can be a file name or multiple file names, which are separated by spaces.
In addition to the file name, the target can also be the name of an operation, which is called a "pseudo target "(phony target).
clean: rm *.o
The purpose of the above Code iscleanIt is not a file name, but an operation name. It belongs to the "pseudo target" and serves to delete the object file.
$ make clean
However, if the current directory contains a file namedcleanThe command is not executed. BecauseMakeFoundcleanIf the file already exists, it is deemed that there is no need to re-build the file, and the specifiedrmCommand.
To avoid this situation, you can clearly declarecleanIs a "pseudo-target", written as follows.
.PHONY: cleanclean: rm *.o temp
StatementcleanIs "pseudo target,makeIt will not check whether there iscleanBut execute the corresponding command every time you run the command. Image.PHONYThere are still many built-in target names. You can view the manual.
IfMakeThe target is not specified when the command is run. It is executed by default.MakefileThe first target of the file.
$ make
Code execution aboveMakefileThe first target of the file.
Preconditions (prerequisites)
Preconditions are usually a group of file names separated by spaces. It specifies the criteria for determining whether to re-build the "target": As long as a pre-file does not exist or has been updated (the pre-Filelast-modificationThe timestamp is a new timestamp), and the "target" needs to be rebuilt.
result.txt: source.txt cp source.txt result.txt
In the above Code, buildresult.txtThe prerequisites are:source.txt. If the current directory is,source.txtAlready existsmake result.txtIt can run normally. Otherwise, you must write another rule to generatesource.txt.
source.txt: echo "this is the source" > source.txt
In the code above,source.txtIf there is no precondition, it means it has nothing to do with other files, as long as the file does not exist, every callmake source.txt.
$ make result.txt$ make result.txt
The preceding command is executed twice in a row.make result.txt. The first execution will first createsource.txtAnd then createresult.txt. The second execution,MakeFoundsource.txtNo changes (the timestamp is laterresult.txt,result.txtWill not be regenerated.
If you need to generate multiple files, the following statement is often used.
source: file1 file2 file3
In the code above,sourceIs a pseudo-target with only three pre-files and no corresponding commands.
$ make source
Runmake sourceThe command is generated at a time.file1,file2,file3Three files. This is much more convenient than the following method.
$ make file1$ make file2$ make file3
Command (commands)
Command (commands) Indicates how to update the target file.ShellCommand. It is a specific command for building a "target", and its running result is usually to generate the target file.
Each command line must have onetabKey. If you want to use other keys, you can use built-in variables..RECIPEPREFIXStatement.
.RECIPEPREFIX = > all: > echo Hello, world
The above Code uses.RECIPEPREFIXSpecified, greater (>) SubstitutiontabKey. Therefore, the beginning of each line of command becomes greater than the number, insteadtabKey.
Note that each line of commands is in a separateshell. TheseShellThere is no inheritance relationship between them.
var-lost: export foo=bar echo "foo=[$$foo]"
After the above code is executed (make var-lost).foo. Because the two-line command is executed in two different processes. One solution is to write two-line commands in one line, separated by semicolons.
var-kept: export foo=bar; echo "foo=[$$foo]"
Another solution is to add a backslash before the line break.
var-kept: export foo=bar; \ echo "foo=[$$foo]"
The last method is to add.ONESHELL:Command.
.ONESHELL: var-kept: export foo=bar; echo "foo=[$$foo]"
Syntax comment of Makefile
Well no (#) InMakefile.
# This is the annotation result.txt: source.txt # This is the annotation cp source.txt result.txt # this is also the Annotation
Echo (echoing)
Under normal circumstances,makeEach Command is printed and then executed. This is called Echo ).
Test: # This is a test
Execute the above rule and you will get the following result.
$ Make test # This is a test
Add@To close the echo.
Test: @ # This is a test
Execute nowmake test, There will be no output.
Because you need to know which command is being executed during the build processechoAdd@.
Test: @ # test @ echo TODO
Wildcard
Wildcard (wildcardSpecifies a set of qualified file names.MakefileAndBashConsistent, mainly with the star number (*), Question mark (?) And[...]. For example,*.oIndicates that all suffixes areo.
clean: rm -f *.o
Pattern Matching
MakeThe command allows matching of file names similar to regular operations. The primary match character is%. For example, assume that the current directory containsf1.cAndf2.cThe two source code files must be compiled into the corresponding object files.
%.o: %.c
It is equivalent to the following statement.
f1.o: f1.cf2.o: f2.c
Match character%You can build a large number of files of the same type with only one rule.
Variables and value pairs
MakefileYou can use equal signs to customize variables.
txt = Hello Worldtest: @echo $(txt)
In the above Code, the variabletxtEqualHello World. When calling, the variables must be placed in$( ).
CallShellVariable, you need to add a dollar sign before the dollar sign, this is becauseMakeThe command will escape the dollar sign.
test: @echo $$HOME
Sometimes, the value of a variable may point to another variable.
v1 = $(v2)
In the above Code, the variablev1Is another variable.v2. In this case, a problem occurs,v1Is the value extended during definition (static extension) or Runtime (dynamic extension )? Ifv2The value of is dynamic, and the results of the two extension methods may be very different.
To solve similar problems,MakefileA total of four value assignment operators (=、:=、?=、+=). For the differences between them, seeStackOverflow.
VARIABLE = value # extension during execution. Recursive extension is allowed. VARIABLE: = value # extended during definition. VARIABLE? = Value # The value is set only when the variable is null. VARIABLE + = value # append the value to the end of the VARIABLE.
Built-in Variables (Implicit Variables)
MakeCommand provides a series of built-in variables, such,$(CC)Pointing to the current compiler,$(MAKE)Point to the currently usedMakeTool. This is mainly for cross-platform compatibility. For a detailed list of built-in variables, see the manual.
output: $(CC) -o output input.c
Automatic Variables)
MakeThe command also provides some automatic variables whose values are related to the current rule. There are mainly the following.
$@Indicates the current target, that isMakeThe target currently built by the command. For example,make fooOf$@It refersfoo.
a.txt b.txt: touch $@
It is equivalent to the following statement.
a.txt: touch a.txtb.txt: touch b.txt
$<It refers to the first precondition. For example, the rule ist: p1 p2, Then$<It refersp1.
a.txt: b.txt c.txt cp $< $@
It is equivalent to the following statement.
a.txt: b.txt c.txt cp b.txt a.txt
$?All preconditions for updating a specific target are separated by spaces. For example, the rule ist: p1 p2, Wherep2Timestamp ratiotNew,$?It refersp2.
$^All preconditions are separated by spaces. For example, the rule ist: p1 p2, Then$^It refersp1 p2.
$*Identifier%Matching part, such%Matchf1.txtInf1,$*Indicatesf1.
$(@D)And$(@F)Point$@Directory Name and file name. For example,$@Yessrc/input.c, Then$(@D)Issrc,$(@F)Isinput.c.
$(<D)And$(<F)Point$<Directory Name and file name.
For a list of all automatic variables, see the manual. The following is an example of automatic variables.
dest/%.txt: src/%.txt @[ -d dest ] || mkdir dest cp $< $@
The above code willsrcDirectorytxtFile, copydestDirectory. First, JudgedestWhether the directory exists. If it does not exist, create a new directory. Then,$<Refers to the front file (src/%.txt),$@Refers to the target file (dest/%.txt).
Judgment and loop
MakefileUseBashSyntax to complete the judgment and loop.
ifeq ($(CC),gcc) libs=$(libs_for_gcc) else libs=$(normal_libs) endif
The code above checks whether the current compiler isgccAnd specify different library files.
LIST = one two threeall: for I in $ (LIST); do \ echo $ I; \ done # is equivalent to all: for I in one two three; do \ echo $ I; \ done
The running result of the above Code.
onetwothree
Function
MakefileYou can also use functions in the following format.
$ (Function arguments) # Or $ {function arguments}
MakefileProvides many built-in functions for calling. Below are several common built-in functions.
shellFunction executionshellCommand
srcfiles := $(shell echo src/{00..99}.txt)
wildcardFunction is used inMakefile, ReplaceBash.
srcfiles := $(wildcard src/*.txt)
The replacement function is written as follows: variable name + colon + replacement rule.
min: $(OUTPUT:.js=.min.js)
The code above indicates thatOUTPUTIn.jsReplace all.min.js.
The Makefile instance executes multiple targets.
.PHONY: cleanall cleanobj cleandiffcleanall : cleanobj cleandiff rm programcleanobj : rm *.ocleandiff : rm *.diff
The above code can call different targets, delete objects with different extension names, or call a target (cleanall) To delete all specified types of files.
Compile a C Project
edit : main.o kbd.o command.o display.o cc -o edit main.o kbd.o command.o display.omain.o : main.c defs.h cc -c main.ckbd.o : kbd.c defs.h command.h cc -c kbd.ccommand.o : command.c defs.h command.h cc -c command.cdisplay.o : display.c defs.h cc -c display.cclean : rm edit main.o kbd.o command.o display.o .PHONY: edit clean
Makefile on the Experiment Platform
Makefile writing Analysis of the Linux kernel module
Makefile-General Makefile Writing Method for demo writing
Makefile: a common method for writing Makefile in the subdirectory of a large project
This article permanently updates the link address: