[Linux operating system] Getting started with makefile: one rule-two functions-three variables

In Linux, makefile is a very important tool for automating the construction and management of projects. It helps developers easily compile and link programs while also handling issues like dependencies and incremental builds. In the makefile, we will focus on one rule, two functions and three automatic variables in the makefile.
insert image description here


1. A rule

1.1 Rules Explanation

Makefile consists of a series of rules, each rule defines a target (target) , and the dependencies (dependencies) and build commands (recipe) required to generate the target .

When the dependencies of the target change, Makefile will automatically execute the generation command according to the rules to update the target.

The basic format of a Makefile rule is as follows:

target: dependencies
    recipe
  • targetis the target of the rule, that is, the file to generate or the action to perform. Can be a filename, a label (for example all), or a pseudo-target (to .PHONYdeclare).
  • dependenciesare files or targets that the target depends on. The Make utility rebuilds the target when any one of its dependencies changes.
  • recipeis the sequence of commands to build the target. Each command must start with the Tab key and be on the same line. It can be any shell command such as compiling, linking, copying files, etc.

There can be multiple rules in the Makefile, and each rule is on its own line. The Make tool automatically determines the build order based on the dependencies of the rules.

In addition, Makefile also supports some special targets and variables:

  • .PHONY: Declare a pseudo-target, indicating that the target does not correspond to any actual file. Usually used to define some special operations, eg clean.
  • .DEFAULT_GOAL: Defines the default target. If no target is specified, that target is built by default.
  • $(CC): Define variables. Variables can be used in Makefile to replace commonly used commands and options, which is convenient for management and modification.

It should be noted that the rules and commands in the Makefile must strictly follow the indentation rules, and the commands must start with the Tab key. Otherwise, the Make tool may not parse and execute correctly.


1.2 Examples of rules

Here is a simple Makefile example:

CC = gcc
CFLAGS = -Wall -g

all: hello

hello: main.o hello.o
    $(CC) $(CFLAGS) -o hello main.o hello.o

main.o: main.c
    $(CC) $(CFLAGS) -c main.c

hello.o: hello.c
    $(CC) $(CFLAGS) -c hello.c

clean:
    rm -f hello *.o

1.3 Code Explanation

This Makefile defines a target all, which depends on the target hello. The target helloin turn depends on the target main.oand hello.o. The dependencies between these targets tell the Make tool that helloit needs to build main.oand before building the target hello.o.

The build commands below each target are indented with the Tab key, which is a syntax requirement for Makefiles. In this example, the build command uses the $(CC)and $(CFLAGS)variables to specify the compiler and compile options.

In addition to the rules above, a target is defined cleanthat cleans generated object files and executables.

Using this Makefile, the following commands can be executed in the terminal:

  • make: builds all targets, which will build allthe targets by default, ie hello.
  • make hello: Build hellotarget.
  • make clean: Cleans up generated object files and executables.

When the command is executed make, the Make tool will determine which files need to be recompiled according to the target and dependencies, and then execute the corresponding generation command. If the target is already up-to-date, the Make tool skips building it.

After executing makethe command, if the source file has not been modified, the Make tool will output a result similar to the following:

make: 'hello' is up to date.

This indicates that the target is already up to date and there are no files that need to be rebuilt.

If make cleanthe command is executed, the Make tool will perform a cleanup operation, deleting the generated object files and executable files.


2. Two functions

In Makefile, in addition to $(wildcard pattern)functions, there is also a commonly used function $(patsubst pattern,replacement,text). It is used to replace the part of the specified text that matches the pattern with the specified string.

$(wildcard pattern)The usage and examples of the and functions are introduced below $(patsubst pattern,replacement,text):

2.1 $(wildcard pattern)

$(wildcard pattern)The function is used to match a filename pattern and returns a list of files matching the pattern.

For example, suppose the following files exist in the current directory: file1.txt, file2.txt, file3.dat.

FILES := $(wildcard *.txt)
all:
    @echo $(FILES)

After running makethe command, the output is:

file1.txt file2.txt

Explanation : $(wildcard *.txt)Match all .txtfiles ending in the current directory, file1.txtand return the file list sum file2.txt. Then, $(FILES)assign the list of files to the variable FILES, and finally alluse @echothe command in the target to output FILESthe value of the variable.


2.2 $(patsubst pattern,replacement,text)

$(patsubst pattern,replacement,text)The function is used to replace the part of the specified text that matches the pattern with the specified string.

For example, suppose you have a list of filenames FILESthat you want to .txtreplace with .o.

FILES := file1.txt file2.txt file3.dat
TARGETS := $(patsubst %.txt,%.o,$(FILES))

all: $(TARGETS)

%.o: %.txt
    @echo Generating $@ from $<
    @touch $@

After running makethe command, the output is:

Generating file1.o from file1.txt
Generating file2.o from file2.txt

Explanation : Replace the file names ending with in $(patsubst %.txt,%.o,$(FILES))the list with the file names ending with , and generate a new file list , ie , , . Then, use it as a dependency in your target , generating a file for each.$(FILES).txt.oTARGETSfile1.ofile2.ofile3.datall$(TARGETS).txt.o


3. Three variables

In Makefile, there are three commonly used variables: $@, $<and $^. They represent the object file, the first dependent file, and the list of all dependent files, respectively.

The following describes the usage and examples of these three variables:

3.1 $@

$@Indicates the target file, that is, the target in the current rule.

For example, suppose you have a rule that looks like this:

all: main.o utils.o
    gcc $^ -o $@

After running makethe command, the output is:

gcc main.o utils.o -o all

Explanation: $^Indicates all dependent files, namely main.oand utils.o. $@Indicates the object file, ie all. In this rule, gcc $^ -o $@the command compiles and links all dependent files into an executable file all.


3.2 $<

$<Indicates the first dependent file, that is, the first dependent file in the current rule.

For example, suppose you have a rule that looks like this:

main.o: main.c
    gcc -c $<

After running makethe command, the output is:

gcc -c main.c

Explanation: $<Indicates the first dependent file, ie main.c. In this rule, gcc -c $<the command main.ccompiles the file into an object file main.o.


3.3 $^

$^Represents a list of all dependent files.

For example, suppose you have a rule that looks like this:

all: main.o utils.o
    gcc $^ -o $@

After running makethe command, the output is:

gcc main.o utils.o -o all

Explanation: $^Indicates all dependent files, namely main.oand utils.o. $@Indicates the object file, ie all. In this rule, gcc $^ -o $@the command compiles and links all dependent files into an executable file all.


Summarize

To sum up, one rule, two functions and three automatic variables in makefile are important tools that we often use in Linux development. By using these tools flexibly, we can build and manage projects more efficiently and improve development efficiency.

Guess you like

Origin blog.csdn.net/Goforyouqp/article/details/132146556