We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
书写规则
<条件判断> <makefile或shell命令1> else <makefile或shell命令2> endif
其中shell命令仅当整个条件表达式位于某一目标下,并在行首有<tab>制表符才能正常被使用。而条件判断语句有以下四个:
shell
<tab>
判断两字符串是否相等,相等则执行命令1,否则执行命令2。
命令1
命令2
ifeq (<参数1>,<参数2>)
或者
ifeq "<参数1>" "<参数2>"
ifeq '<参数1>' '<参数2>'
即ifeq的否定,判断两字符串是否相等,不相等则执行命令1,否则执行命令2。
ifeq
判断字符串是否为空,如果不为空则执行命令1,否则执行命令2。
ifdef <参数>
即ifdef的否定,判断字符串(的定义)是否为空,如果为空则执行命令1,否则执行命令2。
ifdef
注意: ifdef判断的是变量的定义而非实际值 如: var = ifdef var result = True else result = False 其中$(result)为False,但 pre = var = $(pre) ifdef var result = True else result = False 其中$(result)为True。
注意: ifdef判断的是变量的定义而非实际值 如:
var = ifdef var result = True else result = False
其中$(result)为False,但
$(result)
False
pre = var = $(pre) ifdef var result = True else result = False
其中$(result)为True。
True
利用以上条件表达式,以及变量赋值规则即可完成本次作业中Makefile相关题目。 但假设题目B中有f1.cpp, f1.h, ..., fn.cpp, fn.h,那么仅使用条件表达式不足以完成题目要求,自然想到利用循环解决问题。 题目中给出的阮一峰的博客中所提到的for循环,实质为shell脚本,仅能在目标内调用,笔者并不很熟悉,大家可以自行深入了解。 另外,条件判断式在Makefile文件读取时计算,在使用如$@, $<等,在运行时定义的自动化变量时,可能出现错误。 下从Makefile提供的内置函数出发,通过变量实现循环与条件判断的流程控制。
Makefile
f1.cpp
f1.h
fn.cpp
fn.h
$@
$<
$(<函数名> <参数1>(,<参数2>,<...>))
$(if <条件参数>,<返回值1>)
$(if <条件参数>,<返回值1>,<返回值2>)
判断条件参数(的值)是否为空,为空则函数值为返回值1,否则函数值为返回值2,无返回值2参数则为空串。
条件参数
返回值1
返回值2
($foreach <中间变量名>,<列表参数>,<表达式>)
类比c++中的foreach,此函数的作用是将列表参数中每个以空格分隔的字符串取出,赋值到中间变量,再计算表达式的值。将所得值以空格分隔组成新的字符串作为函数值。 例:
c++
foreach
列表参数
中间变量
表达式
($foreach i,one two three,$(i).o)
上一语句的值为one.o two.o three.o。
one.o two.o three.o
其他辅助函数 ($findstring <子串>,<原串>) 在原串中匹配到子串则函数值为字串,否则为空。 ($patsubst <模式串>,<替换模式串>,<字典串>) 字典串中有复数个以空格(或<tab>,回车)分隔的子串,在字典串中匹配符合模式串模式的子串,并用替换模式串替换,作为函数值。 例: ($patsubst %.o,%.cpp,one.o two.o three.o) 函数值为one.cpp two.cpp three.cpp
($findstring <子串>,<原串>)
在原串中匹配到子串则函数值为字串,否则为空。
原串
子串
字串
($patsubst <模式串>,<替换模式串>,<字典串>)
字典串中有复数个以空格(或<tab>,回车)分隔的子串,在字典串中匹配符合模式串模式的子串,并用替换模式串替换,作为函数值。 例:
字典串
模式串
替换模式串
($patsubst %.o,%.cpp,one.o two.o three.o)
函数值为one.cpp two.cpp three.cpp
one.cpp two.cpp three.cpp
利用上述内置函数,可以在变量定义时进行控制,从而完成对任意多个源文件的条件编译,样例如下:
F1 = True F2 = False F3 = True F4 = False F5 = True F6 = False F7 = True LIST := 1 2 3 4 5 6 7 FILEO := $(foreach i,$(LIST),$(if $(findstring TRUE,$(F$(i))),f$(i).o)) FILEH := $(patsubst %.o,%.h,$(FILEO)) DEF := $(patsubst f%.o,-D __F%__,$(FILEO))
其中$(FILEO)为f1.o f3.o f5.o f7.o,$(FILEH)为f1.h f3.h f5.h f7.h,$(DEF)为-D __F1__ -D __F3__ -D __F5__ -D __F7__。
$(FILEO)
f1.o f3.o f5.o f7.o
$(FILEH)
f1.h f3.h f5.h f7.h
$(DEF)
-D __F1__ -D __F3__ -D __F5__ -D __F7__
f%.o:f%.cpp f%.h g++ -c $< -o $@ $(patsubst f%.o,-D __F%__,$@)
以上代码可以完成f*.cpp的编译,与对应的宏定义,说明能够利用运行时定义的自动化变量。 再添加相关目标(main, main.o, clean)等,即可完成题目要求。
f*.cpp
main
main.o
clean
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Makefile中if判断
条件表达式
书写规则
其中
shell
命令仅当整个条件表达式位于某一目标下,并在行首有<tab>
制表符才能正常被使用。而条件判断语句有以下四个:条件判断1:ifeq
判断两字符串是否相等,相等则执行
命令1
,否则执行命令2
。或者
或者
条件判断2:ifneq
即
ifeq
的否定,判断两字符串是否相等,不相等则执行命令1
,否则执行命令2
。条件判断3:ifdef
判断字符串是否为空,如果不为空则执行
命令1
,否则执行命令2
。条件判断4:ifndef
即
ifdef
的否定,判断字符串(的定义)是否为空,如果为空则执行命令1
,否则执行命令2
。利用以上条件表达式,以及变量赋值规则即可完成本次作业中
Makefile
相关题目。但假设题目B中有
f1.cpp
,f1.h
, ...,fn.cpp
,fn.h
,那么仅使用条件表达式不足以完成题目要求,自然想到利用循环解决问题。题目中给出的阮一峰的博客中所提到的for循环,实质为shell脚本,仅能在目标内调用,笔者并不很熟悉,大家可以自行深入了解。
另外,条件判断式在
Makefile
文件读取时计算,在使用如$@
,$<
等,在运行时定义的自动化变量时,可能出现错误。下从
Makefile
提供的内置函数出发,通过变量实现循环与条件判断的流程控制。Makefile中内置函数
书写规则
if函数
或者
判断
条件参数
(的值)是否为空,为空则函数值为返回值1
,否则函数值为返回值2
,无返回值2
参数则为空串。foreach函数
类比
c++
中的foreach
,此函数的作用是将列表参数
中每个以空格分隔的字符串取出,赋值到中间变量
,再计算表达式
的值。将所得值以空格分隔组成新的字符串作为函数值。例:
上一语句的值为
one.o two.o three.o
。利用上述内置函数,可以在变量定义时进行控制,从而完成对任意多个源文件的条件编译,样例如下:
其中
$(FILEO)
为f1.o f3.o f5.o f7.o
,$(FILEH)
为f1.h f3.h f5.h f7.h
,$(DEF)
为-D __F1__ -D __F3__ -D __F5__ -D __F7__
。以上代码可以完成
f*.cpp
的编译,与对应的宏定义,说明能够利用运行时定义的自动化变量。再添加相关目标(
main
,main.o
,clean
)等,即可完成题目要求。The text was updated successfully, but these errors were encountered: