我在一个单独的目录中有两个源文件library.f90
和toolbox.f90
。这些编译成目标文件,在编译主文件时链接,恰当地称为main
。最初,我有这个Makefile:
TARGET = main
SRC = ${TARGET}.f95
FC = /usr/bin/gfortran
CFLAGS = -O2 -std=gnu -Wfatal-errors -I${INCLUDE}
INCLUDE = /home/ma/include
OBJ = library.o toolbox.o
OBJ_SRC = $(subst .o,.f90,${OBJ})
all: ${TARGET}
${TARGET}: ${SRC} ${OBJ}
@${FC} ${CFLAGS} -pedantic -Wall ${OBJ} ${SRC} -o ${TARGET}
${OBJ}:
@echo "Compiling $(subst .o,,$@)"
@${FC} ${CFLAGS} -c ${INCLUDE}/$(subst .o,.f90,$@) -o $@
clean:
@rm -vf ${TARGET} ${OBJ}
但在编辑源文件library.o
或toolbox.o
时,这不会重新编译library.f90
(或toolbox.f90
)。我认为这是因为缺少依赖关系,所以我将Makefile调整为如下所示:
TARGET = main
SRC = ${TARGET}.f95
FC = /usr/bin/gfortran
CFLAGS = -O2 -std=gnu -Wfatal-errors -I${INCLUDE}
INCLUDE = /home/ma/include
OBJ = library.o toolbox.o
all: ${TARGET}
${TARGET}: ${SRC} ${OBJ}
@${FC} ${CFLAGS} -pedantic -Wall ${OBJ} ${SRC} -o ${TARGET}
${OBJ}: ${OBJ_SRC}
@echo "Compiling $(subst .o,,$@)"
@${FC} ${CFLAGS} -c ${INCLUDE}/$(subst .o,.f90,$@) -o $@
clean:
@rm -vf ${TARGET} ${OBJ}
然而,这会抛出错误
make: *** No rule to make target 'library.f90', needed by 'library.o'. Stop.
我不明白这一点,因为没有规则来构建${SRC}
,但是make会识别那里的依赖项并按预期编译源文件。
答案 0 :(得分:2)
在您的第一个版本中,目标文件'规则没有指定任何先决条件。这就是为什么make没有检查library.f90
是否已经改变,因此没有重新创建它。
您的第二个版本略胜一筹,但现在意味着library.o
和toolbox.o
都取决于 library.f90
和toolbox.f90
,意思是如果其中任何一个被更改,则两个都重建,如果其中任何一个丢失,则两个构建都将失败。
至于你的规则失败的原因:它在当前目录中寻找library.f90
,但是根据规则我推断出这些来源位于子目录/home/ma/include
中。
更好的解决方案是:
${OBJ} : %.o : ${INCLUDE}/%.f90
${FC} ${CFLAGS} -c $^ -o $@
(我还删除了前导@
,因为我觉得查看它尝试运行的实际命令非常有用。)