Simple and easy to understand Makefile introduction (04)-conditional judgment (ifeq, ifneq, ifdef and ifndef), define command package define and pseudo target

1. Makefile conditional judgment function

Conditional statements may be controlled according to the value of a variable is makeperformed or ignoring Makefilespecific portion, conditional statements may be a comparison between two different variables or constants and variables.

The following are some keywords used in condition judgment:

Keyword Features
ifeq Determine whether the parameters are not equal, equal to true, unequal to false
ifneq Determine whether the parameters are not equal, unequal is true, and equal is false
ifdef Determine whether there is a value, there is a value of true, and no value is false
ifndef Determine whether there is a value, no value is true, and a value is false

2. ifeq and ifneq

The use of conditional judgment is as follows:

ifeq (first, second)
ifeq 'first' 'second'
ifeq `first` `second`
ifeq `first` 'second'
ifeq 'first' `second`

Example:

first = $(CXX)
second = g++

all:
ifeq ($(first), $(second))
	echo `first == second`
else
	echo `first != second`
endif

Output after executing make

wohu@ubuntu:~/cpp/ifeq$ make
echo `first == second`
first == second
wohu@ubuntu:~/cpp/ifeq$

Use conditional statements to three keywords ifeq, else, endif. among them:

  • ifeqIndicates the beginning of a conditional statement and specify a comparison condition (equal). Use a space to separate the brackets and keywords, and use a comma to separate the two parameters. The variable reference in the parameter is expanded when the variable value is compared. ifeqThe latter is executed when the condition is met, and the condition is not met and ignored;
  • else Indicates the part that is executed when the condition is not met. Not all conditional statements need to execute this part;
  • endifIt is the end mark of the judgment statement, and the end of the condition judgment in the Makefile must be there;

In fact, ifneqand ifeqto use exactly the same, but the statement is executed after the condition is reversed.

3. ifdef and ifndef

The usage is as follows:

ifdef VARIABLE_NAME

Its main function is to judge whether the value of the variable is empty, example 1

a =
b = $(a)
all:
ifdef b
	echo yes
else
	echo  no
endif

Output after executing make

wohu@ubuntu:~/cpp/ifeq$ make
echo yes
yes
wohu@ubuntu:~/cpp/ifeq$ 

Example 2

a =
all:
ifdef a 
	echo yes
else
	echo  no
endif

Output after executing make

wohu@ubuntu:~/cpp/ifeq$ make
echo  no
no
wohu@ubuntu:~/cpp/ifeq$ 

Through the comparison of two examples, we can see that the printed result of example 1 is yes yes, and the printed result of example 2 is yes when we execute make no.

The reason is that in Example 1, the variable bdefinition is b = $(a). While the variable ais empty, but the ifdefjudgment is true, in this way judge obviously there is not enough, so need to use when we need to determine whether the value of a variable is empty ifeqinstead ifdef.

Note: You can not use variables in conditional expressions automation, automated variable effective when the rules of command, not a complete statement of conditional discharge points in two different Makefilefiles.

In one Makefileuse indicator includecomprising another Makefilefile.

4. Define the command package

Command packet bit like a function, a continuous synthesizing a same command, to reduce the Makefilecode amount in the later easy to maintain.

grammar:

define <command-name>
command
...
endef

Example:

# Makefile 内容
define run_demo_makefile
@echo -n "Hello"
@echo " Makefile!"
@echo "这里可以执行多条 Shell 命令!"
endef

all:
	$(run_demo_makefile)

carried out make

wohu@ubuntu:~/cpp/func$ make
Hello Makefile!
这里可以执行多条 Shell 命令!
wohu@ubuntu:~/cpp/func$ 

5. Makefile pseudo target

The so-called pseudo-target can be understood in this way. It does not create a target file, but just wants to execute the commands below the target. The existence of pseudo-targets can help us find commands and execute them.

If you need to write such a rule, the command defined by the rule is not to create a file, but to explicitly specify it to execute some specific commands through the make command. Examples:

clean:
    rm -rf *.o test

Rules in rmorder not to create the file cleancommand, but delete the task, delete the current directory of all .othe end of the file name and testfile.

As to the working directory does not exist cleanwhen the command file, shellenter the make cleancommand, the command rm -rf *.o testwill always be executed, and this is our desired result.

If the file name exists under the current directory cleanwhen a file of the case would have been different, when we shellexecute the command make clean, because the rules do not rely on this document, the target is considered to be the latest and not to execute commands defined by the rules. Therefore, the command rmwill not be executed.

To solve this problem, delete cleanfiles or the Makefiletarget will be cleandeclared as false object.

Methods a goal statement said pseudo goal is to make it as a special target .PHONYdependent, as follows:

.PHONY:clean

So cleanit was declared as a pseudo target, regardless of whether there is in the current directory cleanthe file, when we execute make cleanthe rmwill be executed.

And when a target is declared as a pseudo-target, makeit will not try to find the implicit relationship to create it when executing this rule. This is also to improve the makeefficiency of the implementation, but also do not worry about the goals and the same name as the file name we fail to compile.

When writing a pseudo-target, it is necessary to declare that the target is a pseudo-target, and then it is the rule definition of the pseudo-target. Target cleanfull written format is as follows:

.PHONY:clean
clean:
    rm -rf *.o test

Example:
Directory structure

wohu@ubuntu:~/cpp/ifeq$ tree
.
└── Makefile

0 directories, 1 file
wohu@ubuntu:~/cpp/ifeq$ 

Only one Makefilefile, as follows:

a = 123
bbb:
	echo "a is $(a)"

The output of make is as follows:

wohu@ubuntu:~/cpp/ifeq$ make 
echo "a is 123"
a is 123
wohu@ubuntu:~/cpp/ifeq$ make bbb
echo "a is 123"
a is 123
wohu@ubuntu:~/cpp/ifeq$ 

Create the file manually bbbafter re-execution make, echothe statement will not be executed

wohu@ubuntu:~/cpp/ifeq$ ls
Makefile
wohu@ubuntu:~/cpp/ifeq$ touch bbb
wohu@ubuntu:~/cpp/ifeq$ make
make: 'bbb' is up to date.
wohu@ubuntu:~/cpp/ifeq$ 

After adding a fake target

a = 123
.PHONY: bbb
bbb:
	echo "a is $(a)"

Perform makethe following output, regardless of whether the presence of the current directory bbbthe file, when we execute make bbbthe echowill be executed.

wohu@ubuntu:~/cpp/ifeq$ ls
bbb  Makefile
wohu@ubuntu:~/cpp/ifeq$ make bbb
echo "a is 123"
a is 123
wohu@ubuntu:~/cpp/ifeq$ 

Guess you like

Origin blog.csdn.net/wohu1104/article/details/111022292