Essential Knowledge Before Practicing Makefile

Clickthe blue text

Follow us

In the previous article, we discussed some concepts and principles of Makefile. Next, let’s talk about some key points regarding Makefile.

Essential Knowledge Before Practicing Makefilemake and make cleanEssential Knowledge Before Practicing Makefile

Rules for generating target files (make command):

Executing the make command will generate the corresponding target files based on the rules defined in the Makefile in the current directory.

If the Makefile has a different name, such as makefile.linux, you need to use the make parameters (-f or –file) to execute the corresponding Makefile, for example:

make -f makefile.linux

Rules for cleaning target files (make clean command):

Every Makefile should include a rule to clean target files (such as .o and other target files), which not only facilitates recompilation but also helps keep the files clean. It is advisable to develop the habit of writing such a rule when creating Makefiles. A common style is:

clean:    rm $(obj) *.o

A more robust approach is (reason: if a clean file exists in the current directory, this command will fail), the solution is to add a phony target: .PHONY:clean:

.PHONY:clean
clean:    rm $(obj) *.o

Note:

  • <span>clean</span> rules should not be placed at the beginning of the file; otherwise, it will become the default target for make. Generally, clean is always placed at the end of the file.

Essential Knowledge Before Practicing MakefileWriting RulesEssential Knowledge Before Practicing Makefile

Display rules (@ character):

When using the @ character before a command, that command will not be displayed when executed. For comparison: Example of a command with @ character:

rice@rice:~/rice_file/mkfile$ cat Makefile
exec:  @echo "rice makefile"
rice@rice:~/rice_file/mkfile$ make
rice makefile

Example of a command without @ character:

rice@rice:~/rice_file/mkfile$ cat Makefile
exec:  echo "rice makefile"
rice@rice:~/rice_file/mkfile$ make
echo "rice makefile"
rice makefile

Note:

The make command parameters <span>-s</span> or <span>--silent</span> or <span>--quiet</span> will completely suppress command display.

Command execution rules:

When a dependent target is newer than the target, make will execute the subsequent commands one by one. To apply the result of the previous command to the next command, use semicolon separation between the two commands, and do not write both commands on the same line.

Example 1:

Makefile:

exec:    @cd /home/rice    @pwd

Result:

/home/rice/rice_file/mkfile

Example 2:

Makefile:

exec:    @cd /home/rice;pwd

Result:

/home/rice

From the above two examples, we can demonstrate the rules of command dependencies.

Command error rules (- symbol):

When a command finishes running, make checks the return code of each command. If the return is successful, make will execute the next command. When all commands return successfully, make completes execution. If a command in a rule fails (non-zero exit code), make will terminate the execution of the current rule, which may terminate the execution of all rules.

Sometimes, a command error does not indicate a failure. For example, the mkdir command creates a directory; if the directory does not exist, mkdir will not produce an error. If the directory already exists, an error will occur. From the example, the error from mkdir does not affect other commands because I only need the directory to exist, so the error from mkdir should not terminate the command rule’s execution.

To solve the above problem, simply add a symbol before the command in the Makefile, so that even if the command fails, subsequent commands will still be executed.

.PHONY:clean
clean:    -rm $(obj) *.o

Essential Knowledge Before Practicing MakefileVariablesEssential Knowledge Before Practicing Makefile

Variable Definition

Makefile also supports variable definitions, which simplify and make our Makefile more reusable. Variable definitions are generally in uppercase letters, and the assignment method is similar to that in C language.

DIR = ./src/

To use the variable, enclose it in parentheses and add a dollar sign.

FOO = $(DIR)

Makefile supports other assignment methods besides using ‘=’ such as ‘:=’ and ‘?=’. Next, let’s compare the differences between these methods:

Assignment symbol ‘=’:

PARA = RICE
CURPARA = $(PARA)
PARA = rice
print:  @echo $(CURPARA)

Result:

rice

The value of variable CURPARA is not “RICE. Its value is the last assigned value of PARA. This shows that the assignment symbol “= can leverage another variable, allowing the real value of the variable to be defined later. In other words, the real value of the variable depends on the last effective value of the variable it references.

Assignment symbol ‘:=:

PARA = RICE
CURPARA := $(PARA)
PARA = rice
print:  @echo $(CURPARA)

Result:

RICE

The value of variable CURPARA is “RICE. The difference between “= and “:= is that “:= only takes the first assigned value.

Assignment symbol ‘?=:

PARA = RICE
PARA ?= rice
print:  @echo $(PARA)

Result:

RICE

If the first line is removed, the result will be:

rice

This indicates that if the variable PARA has not been assigned a value before, then this variable will be “rice. If it has been assigned a value before, it will use the previously assigned value.

Assignment symbol ‘+=:In Makefile, variables are strings, and sometimes we need to add some strings to an already defined variable. In this case, we use the symbol “+=:

OBJ = main1.o main2.o
OBJ += main3.o

OBJ will have the value: “main1.o, main2.o, main3.o”. This shows that “+= is used for appending to variables.

Built-in Variables:

Some built-in variables are predefined, usually including CC, PWD, CLFAG, etc. Some have default values, while others do not. For example:

  • CPPFLAGS: Options needed by the preprocessor, such as:-l

  • CFLAGS: Parameters used during compilation-Wall -g -c

  • LDFLAGS: Options used for linking libraries-L -l

Among them, default values can be modified. For example, CC has a default value of cc, but can be changed to gcc: CC=gcc

Automatic Variables:

Makefile syntax provides some automatic variables that allow us to complete the writing of Makefile more quickly. These automatic variables can only be used in the commands of rules. Common automatic variables include:

  • $@: The target in the rule

  • $: The first dependency file in the rule

  • $^: All dependency files in the rule

CC = gcc
OBJ = main.o add.o
output: $(OBJ)  $(CC) -o $@ $^
main.o: main.c  $(CC) -c $<
add.o: add.c  $(CC) -c $<
.PHONY:clean
clean:  @rm $(OBJ) output

Essential Knowledge Before Practicing MakefilePattern RulesEssential Knowledge Before Practicing Makefile

Pattern rules use % in the target and dependencies to match corresponding files. We can still use the previous example in pattern rule format as follows:

CC = gcc
OBJ = main.o add.o
output: $(OBJ)  $(CC) -o $@ $^
%.o: %.c  $(CC) -c $<
.PHONY:clean
clean:  @rm $(OBJ) output

Where:

main.o is generated from main.c and add.o is generated from add.c.Essential Knowledge Before Practicing MakefileFunctionsEssential Knowledge Before Practicing MakefileMakefile provides a variety of functions, among which the two most commonly used are (wildcard, patsubst).wildcard function: Used to find files of a specified type in a specified directory. Function parameters: directory + file type, usage:

SRC = $(wildcard ./src/*.c)
print:  @echo $(SRC)

Result:

./src/add.c ./src/main.c

Indicates: Find all files with the suffix.c in the directory ./src and assign them to the variable SRC. After the command is executed, the value of the SRC variable is: ./src/add.c ./src/main.c

patsubst function: Used for matching and replacing. Function parameters: original pattern + target pattern + file list, usage::

SRC = $(wildcard ./src/*.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
print:  @echo $(OBJ)

Result:

./src/add.o ./src/main.o

Indicates: Replace all files with the suffix.c in the variable with.o. After the command is executed, the value of the OBJ variable is: ./src/add.o ./src/main.oEssential Knowledge Before Practicing MakefileEssential Knowledge Before Practicing MakefileEssential Knowledge Before Practicing Makefile

I will continue to update articles and learning materials.

You can add the author’s WeChat to exchange and learn together.

Essential Knowledge Before Practicing Makefile

Author’s WeChat ID: wueroo1314

To join the discussion group, please add the author’s WeChat

Fan DIY

WeChat ID: Rice_DIY

Technology | Open Source | Sharing

Long press to follow…

Essential Knowledge Before Practicing Makefile

Leave a Comment