我正在阅读 Managing Projects with GNU Make ,同时尝试为我的Fortran项目编写一个简洁的Makefile
。我在以下代码出现的地方迷路了,
define make-depend
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -M $1 | \
$(SED) 's,\($$(notdir $2)\) *:,$$(dir $2) $3: ,' > $3.tmp
$(MV) $3.tmp $3
endef
%.o: %.c
$(call make-depend,$<,$@,$(subst .o,.d,$@))
$(COMPILE.c) -o $@ $<
关于我的阅读
现在,对象文件和依赖项文件在逻辑上是链接的:如果有的话 存在另一个必须存在。因此,我们真的不在乎是否 依赖文件丢失。如果是,则目标文件也会丢失 并且两者都将在下一次构建时更新。
好吧,我不理解粗体中的部分;如何编译源文件($(COMPILE.c) -o $@ $<
)并同时生成其依赖文件($(call make-depend,$<,$@,$(subst .o,.d,$@))
)?我的意思是,它怎么能起作用?
也许我的Fortran经验误导了我,因为我已经习惯了我可以查看一个源文件来查找它所依赖的其他源文件(寻找USE
语句,然后编译那些源文件(或重复这个过程),并且只有在我可以编译一个源文件之后。
如果需要,我可以上传我想写的短Makefile
,但它显然不起作用。具体来说,
make
选择一个.f90
文件,比如说some.f90
,用some.d
创建关联的依赖文件$(call make-depend,$<,$@,$(subst .o,.d,$@))
,然后在尝试编译时失败{ {1}} some.f90
$(COMPILE.c) -o $@ $<
取决于some.o
,此时someother.o
确实列出了some.d
。make
将导致尝试编译someother.f90
,这将以任一方式结束
2.1)成功,如果someother.o
不依赖于任何其他.o
文件,在这种情况下make
将返回到步骤1.,选择另一个.f90
文件。 />
2.2)或错误,但生成someother.d
,我应该手动进入第2步。粗暴地说,如果十次足够,我会在make
之前多次运行for ((i = 1; i <= 10; i++)); do make; done
。
这是一项尚未奏效的尝试:
# ====================================================================================================
FC = mpifort
FLIBS = -llapack -lblas
FCFLAGS = -ffree-form -ffree-line-length-0 -fimplicit-none -fdefault-real-8
# ====================================================================================================
PROGRAM := main
SRCDIR := src
OBJDIR := obj
MODDIR := mod
DEPDIR := dep
SRC := $(wildcard $(SRCDIR)/*.f90)
OBJ := $(patsubst $(SRCDIR)/%,$(OBJDIR)/%,$(SRC:.f90=.o))
MOD := $(shell echo $(patsubst $(SRCDIR)/%,$(MODDIR)/%,$(SRC:.f90=.mod)) | tr '[:upper:]' '[:lower:]')
DEP := $(patsubst $(SRCDIR)/%,$(DEPDIR)/%,$(SRC:.f90=.d))
# ====================================================================================================
$(PROGRAM): $(OBJ)
$(FC) $(FCFLAGS) -o $@ $^ $(LDFLAGS) $(FLIBS)
# ====================================================================================================
ifneq "$(MAKECMDGOALS)" "clean"
-include $(DEP)
endif
# $(call make-depend,source-file,object-file,depend-file)
define make-depend
./dep-gen.sh < $1 | sed -e 's,\([^ ]*\),'"$(OBJDIR)"'/\1,g' \
-e 's,.*,'"$2 $3"': &,' > $(DEPDIR)/$(notdir $3)
endef
# ====================================================================================================
$(OBJDIR)/%.o: $(SRCDIR)/%.f90
@echo '************************************************************ target %.o'
$(call make-depend,$<,$@,$(DEPDIR)/$(subst .o,.d,$(notdir $@)))
$(FC) $(FCFLAGS) $(FLIBS) -c $< -J $(MODDIR) -o $@
# ====================================================================================================
.PHONY: clean veryclean
clean:
$(RM) $(OBJ) $(MOD) $(DEP)
veryclean: clean
$(RM) $(PROGRAM)
# ====================================================================================================
bash脚本dep-gen.sh
从标准输入中获取file.f90
文件,并将files.o
文件所依赖的file.o
文件的空格分隔列表发送到标准输出。