1. Makefile conditional judgment function
Conditional statements may be controlled according to the value of a variable is make
performed or ignoring Makefile
specific 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:
ifeq
Indicates 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.ifeq
The 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;endif
It is the end mark of the judgment statement, and the end of the condition judgment in the Makefile must be there;
In fact, ifneq
and ifeq
to 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 b
definition is b = $(a)
. While the variable a
is empty, but the ifdef
judgment 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 ifeq
instead 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
Makefile
files.
In one Makefile
use indicator include
comprising another Makefile
file.
4. Define the command package
Command packet bit like a function, a continuous synthesizing a same command, to reduce the Makefile
code 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 rm
order not to create the file clean
command, but delete the task, delete the current directory of all .o
the end of the file name and test
file.
As to the working directory does not exist clean
when the command file, shell
enter the make clean
command, the command rm -rf *.o test
will always be executed, and this is our desired result.
If the file name exists under the current directory clean
when a file of the case would have been different, when we shell
execute 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 rm
will not be executed.
To solve this problem, delete clean
files or the Makefile
target will be clean
declared as false object.
Methods a goal statement said pseudo goal is to make it as a special target .PHONY
dependent, as follows:
.PHONY:clean
So clean
it was declared as a pseudo target, regardless of whether there is in the current directory clean
the file, when we execute make clean
the rm
will be executed.
And when a target is declared as a pseudo-target, make
it will not try to find the implicit relationship to create it when executing this rule. This is also to improve the make
efficiency 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 clean
full 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 Makefile
file, 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 bbb
after re-execution make
, echo
the 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 make
the following output, regardless of whether the presence of the current directory bbb
the file, when we execute make bbb
the echo
will 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$