Ruan Yifeng: Make command tutorial

Source: Internet
Author: User

Ruan Yifeng: Make command tutorial

The code is converted into an executable file, called compile. compile this file first, or compile that file first (that is, the compilation schedule), called build ).

Make is the most commonly used build tool. It was born in 1977 and is mainly used for C language projects. But in fact, any project that needs to be re-built as long as a file changes can be built using Make.

This article describes how to use the Make command. From a simple introduction, you can understand it by using the command line. My references mainly refer to Isaac Schlueter's Makefile file tutorial and GNU Make manual.

I. Concepts of Make

The word "Make" is used in English ". The Make command directly uses this to Make a file. For example, you can execute the following command to prepare the.txt file.

$ make a.txt

However, if you enter this command, it does not work. For the sake of makecommand, if you do not know how to execute a.txt, someone needs to tell it how to call other commands to accomplish this goal.

For example, if the.txt file depends on B .txt and c.txt, it is the product of the next two file connections (cat command. Make needs to know the following rules.

a.txt: b.txt c.txt    cat b.txt c.txt > a.txt

That is to say, the command "make a.txt" is actually divided into two steps: Step 1: confirm that B .txt and c.txt must already exist. Step 2: Use the cat command to merge the two files and output them as new files.

Rules like this are all written in a file called Makefile, And the Make command relies on this file for construction. Makefile can also be written as makefile or specified as another file name using command line parameters.

$ Make-f rules.txt # Or $ make --file=rules.txt

The lifecycle Code indicates that the makecommand is constructed based on the rules in the rules.txt file.

In short, make is just a tool built based on the specified Shell command. 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.

Ii. Makefile format

Building rules are written in Makefile files. To learn how to Make commands, you must learn how to compile Makefile files.

2.1 Overview

Makefile consists of a series of rules. The format of each rule is as follows.

<target> : <prerequisites> [tab]  <commands>

The part before the first line of the colon is called the target, and the part after the colon is called the prerequisites. The second line must begin with a tab key, 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.

2.2 target)

A target constitutes a rule. The target is usually a file name, indicating the object to be built by the Make command, such as a.txt above. 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 the "pseudo target" (phony target ).

clean:      rm *.o

The goal of the above code is "clean". It 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 named clean, this command will not be executed. Because Make finds that the clean file already exists, it is deemed that there is no need to re-build it, and the specified rm command will not be executed.

To avoid this situation, you can explicitly declare that "clean" is a "pseudo-target". The statement is as follows.

.PHONY: cleanclean:        rm *.o temp

After "clean" is declared as a "pseudo-target", make will not check whether there is a file called "clean", but will execute the corresponding command every time it runs. There are still many built-in target names such as. PHONY. You can view the manual.

If no target is specified when the Make command is run, the first target of the Makefile file is executed by default.

$ make

The above code executes the first target of the Makefile file.

2.3 prerequisites (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 last-modification timestamp of the pre-file is newer than the target timestamp ), "goal" needs to be rebuilt.

result.txt: source.txt    cp source.txt result.txt

In the above Code, the precondition for building result.txt is source.txt. If source.txt already exists in the current directory, make result.txt can run normally. Otherwise, you must write another rule to generate source.txt.

source.txt:    echo "this is the source" > source.txt

In the prepare Code, there is no precondition after source.txt, which means it has nothing to do with other files. As long as the file does not exist, it will be generated every time you call make source.txt.

$ make result.txt$ make result.txt

The above command runs make result.txt twice in a row. The first execution will first create source.txt, and then create result.txt. During the second execution, Make finds that source.txt has not changed (the timestamp is later than result.txttasks, so no operations will be performed, and result.txt will not be generated again.

If you need to generate multiple files, the following statement is often used.

source: file1 file2 file3

In the above Code, source is a pseudo-target with only three pre-files and there is no corresponding command.

$ make source

After the make source command is executed, three files, file1, file2, and file3, are generated at one time. This is much more convenient than the following method.

$ make file1$ make file2$ make file3
2.4 command (commands)

Commands indicates how to update the target file, which consists of one or more Shell commands. 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 a tab key. If you want to use another key, you can declare it with the built-in variable. RECIPEPREFIX.

.RECIPEPREFIX = >all:> echo Hello, world

The above Code uses. RECIPEPREFIX to specify a greater than (>) to replace the tab key. Therefore, the beginning of each line of command becomes greater than the number, rather than the tab key.

Note that each line of commands is executed in a separate shell. There is no inheritance relationship between these shells.

var-lost:    export foo=bar    echo "foo=[$$foo]"

After the above code is executed (make var-lost), the foo value cannot be obtained. 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 the. ONESHELL: Command.

.ONESHELL:var-kept:    export foo=bar;     echo "foo=[$$foo]"
Iii. Makefile syntax 3.1 comments

# Indicates the comment in Makefile.

# This is the description of result.txt: source.txt # This is the annotation cp source.txt result.txt # this is also the Annotation
3.2 echo (echoing)

Normally, make prints each command and then executes it. 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 @ in front of the command to close the echo.

Test: @ # This is a test

If you execute make test again, no output will be generated.

Because you need to know which command is being executed during the build process, you usually only add @ before the annotation and pure echo command @.

Test: @ # test @ echo TODO
3.3 wildcard characters

A wildcard (wildcard) is used to specify a set of qualified file names. The wildcards of Makefile are the same as those of Bash. They mainly include the star number (*) and question mark (?) And […] . For example, *. o indicates all files with the suffix "o.

clean:        rm -f *.o
3.4 pattern matching

The Make command allows matching of file names similar to regular operations. The major match character used is %. For example, if the current directory contains two source code files: f1.c and f2.c, You need to compile them into the corresponding object files.

%.o: %.c

It is equivalent to the following statement.

f1.o: f1.cf2.o: f2.c

With the matching character %, you can build a large number of files of the same type with only one rule.

3.5 variables and value pairs

Makefile allows you to use equal signs to customize variables.

txt = Hello Worldtest:    @echo $(txt)

In the above Code, the variable txt is equal to Hello World. During the call, the variable needs to be placed in $.

To call the Shell variable, you need to add a dollar sign before the dollar sign, because the Make command will escape the dollar sign.

test:    @echo $$HOME

Sometimes, the value of a variable may point to another variable.

v1 = $(v2)

In the code above, the value of variable v1 is another variable v2. In this case, a problem occurs. Is the v1 value extended during definition (static expansion) or runtime expansion (dynamic expansion )? If the v2 value is dynamic, the results of the two extension methods may be very different.

To solve similar problems, Makefile 1 provides four value assignment operators (=,: = ,? =, + =), See StackOverflow for their differences.

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.
3.6 built-in Variables (Implicit Variables)

The Make command provides a series of built-in variables, such as $ (CC) pointing to the current compiler, and $ (MAKE) pointing to the current Make tool. This is mainly for cross-platform compatibility. For a detailed list of built-in variables, see the manual.

output:    $(CC) -o output input.c
3.7 Automatic Variables)

The Make command also provides some automatic variables whose values are related to the current rule. There are mainly the following.

(1) $ @

$ @ Indicates the current target, which is the target currently built by the Make command. For example, make foo's $ @ indicates foo.

a.txt b.txt:     touch $@

It is equivalent to the following statement.

a.txt:    touch a.txtb.txt:    touch b.txt

(2) $ <

$ <Indicates the first precondition. For example, if the rule is t: p1 p2, then $ <indicates p1.

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 

(3) $?

$? All preconditions for updating a specific target are separated by spaces. For example, the rule is t: p1 p2, where the timestamp of p2 is newer than t, $? It refers to p2.

(4) $ ^

$ ^ Indicates all preconditions, which are separated by spaces. For example, if the rule is t: p1 p2, $ ^ indicates p1 p2.

(5) $ *

$ * Refers to the part where the matching character % matches. For example, if % matches f1 in f1.txt, $ * Indicates f1.

(6) $ (@ D) and $ (@ F)

$ (@ D) and $ (@ F) point to the directory name and file name of $ @ respectively. For example, if $ @ is src/input. c, the value of $ (@ D) is src, and the value of $ (@ F) is input. c.

(7) $ (<D) and $ (<F)

$ (<D) and $ (<F) point to the directory name and file name of $ <respectively.

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 copies the txt file under the src directory to the dest directory. First, determine whether the dest directory exists. If it does not exist, create a new directory. Then, $ <refers to the prefix file (src/cmd.txt) and $ @ refers to the target file (dest/cmd.txt ).

3.8 judgment and loop

Makefile uses Bash syntax to complete judgment and loop.

ifeq ($(CC),gcc)  libs=$(libs_for_gcc)else  libs=$(normal_libs)endif

The code above checks whether the current compiler is gcc and then specifies 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
3.9 Functions

Makefile can also use functions in the following format.

$ (Function arguments) # Or $ {function arguments}

Makefile provides many built-in functions for calling. Below are several common built-in functions.

(1) shell functions

The shell function is used to execute shell commands.

srcfiles := $(shell echo src/{00..99}.txt)

(2) wildcard Function

The wildcard function is used to replace the Bash wildcard in Makefile.

srcfiles := $(wildcard src/*.txt)

(3) Replacement Functions

The replacement function is written as follows: variable name + colon + replacement rule.

min: $(OUTPUT:.js=.min.js)

The code above means to replace all. js in the variable OUTPUT with. min. js.

Iv. Makefile instance

(1) execute multiple targets

.PHONY: cleanall cleanobj cleandiffcleanall : cleanobj cleandiff        rm programcleanobj :        rm *.ocleandiff :        rm *.diff

The preceding code can call different targets, delete objects with different extension names, or call cleanall to delete all objects of the specified type.

(2) compile C language projects

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

Today, the Make command is introduced here. In the next article, I will introduce how to use Make to build a Node. js project.

(End)

This article permanently updates the link address:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.