Skip to content
New issue

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流程控制相关 #41

Open
BBQGOD opened this issue Mar 18, 2021 · 0 comments
Open

Makefile流程控制相关 #41

BBQGOD opened this issue Mar 18, 2021 · 0 comments

Comments

@BBQGOD
Copy link

BBQGOD commented Mar 18, 2021

Makefile中if判断

条件表达式

书写规则

<条件判断>
<makefile或shell命令1>
else
<makefile或shell命令2>
endif

其中shell命令仅当整个条件表达式位于某一目标下,并在行首有<tab>制表符才能正常被使用。而条件判断语句有以下四个:

条件判断1:ifeq

判断两字符串是否相等,相等则执行命令1,否则执行命令2

ifeq (<参数1>,<参数2>)

或者

ifeq "<参数1>" "<参数2>"

或者

ifeq '<参数1>' '<参数2>'

条件判断2:ifneq

ifeq的否定,判断两字符串是否相等,不相等则执行命令1,否则执行命令2

条件判断3:ifdef

判断字符串是否为空,如果不为空则执行命令1,否则执行命令2

ifdef <参数>

条件判断4:ifndef

ifdef的否定,判断字符串(的定义)是否为空,如果为空则执行命令1,否则执行命令2

注意:
ifdef判断的是变量的定义而非实际值
如:

var = 
ifdef var
result = True
else
result = False

其中$(result)False,但

pre = 
var = $(pre)
ifdef var
result = True
else
result = False

其中$(result)True

利用以上条件表达式,以及变量赋值规则即可完成本次作业中Makefile相关题目。
但假设题目B中有f1.cpp, f1.h, ..., fn.cpp, fn.h,那么仅使用条件表达式不足以完成题目要求,自然想到利用循环解决问题。
题目中给出的阮一峰的博客中所提到的for循环,实质为shell脚本,仅能在目标内调用,笔者并不很熟悉,大家可以自行深入了解。
另外,条件判断式在Makefile文件读取时计算,在使用如$@, $<等,在运行时定义的自动化变量时,可能出现错误。
下从Makefile提供的内置函数出发,通过变量实现循环与条件判断的流程控制。

Makefile中内置函数

书写规则

$(<函数名> <参数1>(,<参数2>,<...>))

if函数

$(if <条件参数>,<返回值1>)

或者

$(if <条件参数>,<返回值1>,<返回值2>)

判断条件参数(的值)是否为空,为空则函数值为返回值1,否则函数值为返回值2,无返回值2参数则为空串。

foreach函数

($foreach <中间变量名>,<列表参数>,<表达式>)

类比c++中的foreach,此函数的作用是将列表参数中每个以空格分隔的字符串取出,赋值到中间变量,再计算表达式的值。将所得值以空格分隔组成新的字符串作为函数值。
例:

($foreach i,one two three,$(i).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

利用上述内置函数,可以在变量定义时进行控制,从而完成对任意多个源文件的条件编译,样例如下:

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__

f%.o:f%.cpp f%.h
g++ -c $< -o $@ $(patsubst f%.o,-D __F%__,$@)

以上代码可以完成f*.cpp的编译,与对应的宏定义,说明能够利用运行时定义的自动化变量。
再添加相关目标(main, main.o, clean)等,即可完成题目要求。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant