将以下 Makefile 视为 MWE:
###################################################################
# first bunch
###################################################################
FORTRAN1 = ifort -c
PATH1 = sub/
FILE1 = first.f90
SOURCE1 = $(FILE_TEST:%=$(PATH1)%)
OBJECT1 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE1))))
###################################################################
#second bunch
###################################################################
FORTRAN2 = ifort -traceback -c
PATH2 = sub/
FILE2 = second.f90
SOURCE2 = $(FILE2:%=$(PATH2)%)
OBJECT2 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE2))))
###################################################################
# first rule
###################################################################
all: $(OBJECT1)
lnk/%.o: $(PATH1)%.f90
$(FORTRAN1) -o $@ $<
###################################################################
#SECOND RULE
###################################################################
all: $(OBJECT2)
lnk/%.o: $(PATH2)%.f90
$(FORTRAN2) -o $@ $<
当我运行此脚本时,将执行以下命令:
ifort -traceback -c -o lnk/first.o sub/first.f90
ifort -traceback -c -o lnk/second.o sub/second.f90
换句话说,第一条和第二条规则都使用
FORTRAN2=ifort -traceback -c
,而第一条规则应该使用FORTRAN1=ifort -c
。您能帮我看看是什么造成了这种奇怪的行为吗?我怎样才能实现第一条规则应该使用$(FORTRAN1)$
?
Make 不是一种脚本语言:make 不会读取 makefile 并在处理时“执行”它。 Make 完全读取整个 makefile 以及所有包含的文件,然后在完成后开始处理。
只能有一个具有相同目标和先决条件的模式规则。在你的 makefile 中你有:
PATH1 = sub/
PATH2 = sub/
lnk/%.o: $(PATH1)%.f90
...
lnk/%.o: $(PATH2)%.f90
...
由于
PATH1
和 PATH2
变量具有相同的值,因此 make 会看到:
lnk/%.o: sub/%.f90
...
lnk/%.o: sub/%.f90
...
第二条规则与第一条规则相同,因此它会覆盖第一条规则,并且第一条规则会丢失。然后在所有这些解析完成之后,THEN make 开始尝试构建对象并查看应该使用哪个规则来匹配哪个目标。由于只有一个匹配的模式规则,因此它用于所有对象。
有几种不同的方法可以做到这一点。一种是使用静态模式规则而不是完整的模式规则:
$(OBJECT1) : lnk/%.o: $(PATH1)%.f90
...
$(OBJECT2) : lnk/%.o: $(PATH2)%.f90
...
现在这些规则仅匹配那些确切的对象。