Makefile 目标文件的自动排序“*”。o";在Fortran生成文件中

Makefile 目标文件的自动排序“*”。o";在Fortran生成文件中,makefile,dependencies,fortran,wildcard,Makefile,Dependencies,Fortran,Wildcard,这里我有两个Fortran90文件和一个makefile: # Script to generate the dependencies MAKEDEPEND=/path/to/fort_depend.py # $(DEP_FILE) is a .dep file generated by fort_depend.py DEP_FILE = my_project.dep # Source files to compile OBJECTS = mod_file1.f90 \

这里我有两个Fortran90文件和一个makefile:

# Script to generate the dependencies
MAKEDEPEND=/path/to/fort_depend.py

# $(DEP_FILE) is a .dep file generated by fort_depend.py
DEP_FILE = my_project.dep

# Source files to compile
OBJECTS = mod_file1.f90 \
          mod_file2.f90

# Make sure everything depends on the .dep file
all: $(actual_executable) $(DEP_FILE)

# Make dependencies
.PHONY: depend
depend: $(DEP_FILE)

# The .dep file depends on the source files, so it automatically gets updated
# when you change your source
$(DEP_FILE): $(OBJECTS)
    @echo "Making dependencies!"
    cd $(SRCPATH) && $(MAKEDEPEND) -w -o /path/to/$(DEP_FILE) -f $(OBJECTS)

include $(DEP_FILE)
文件内容main\u mod.f90

module main_mod

contains

  subroutine add(a, b)
    implicit none
    integer, intent(in) :: a, b
    print *, (a+b)
  end subroutine add

end module main_mod
文件内容main_mod2.f90

module main_mod2
  use main_mod

contains

  subroutine add2(a, b)
    implicit none
    integer, intent(in) :: a, b

    call add(a, b)
  end subroutine add2

end module main_mod2
makefile中,我自动从当前目录生成一个“.o”文件列表:

F90 = /usr/bin/gfortran
COMPFLAGS    =  -c
%.o: %.f90
        $(F90) $(COMPFLAGS) $*.f90

all: $(patsubst %.f90,%.o,$(wildcard *.f90))
创建项目时,make文件中的通配符语句会生成一个对象文件列表,如:

main_mod2.o main_mod.o
然后编译失败,因为首先需要编译文件main_mod.f90,这将为我们提供main_mod.o和main_mod.mod,它们在main_mod2.f90中使用。然后将成功编译main_mod2.f90。这意味着目标文件的排列必须是:

main_mod.o main_mod2.o

现在的问题是,在一般情况下,当我使用通配符创建对象文件列表时,如何执行对象文件的正确排列?

。。。在规则中指定它们

main_mod2.o: main_mod.o

虽然gcc确实有
-M
和相关的标志,用于对C/C++文件执行此操作,但遗憾的是,它们不能与gfortran一起工作。实际上,这是可能的,但前提是您已经知道依赖关系。 因此,您需要一个外部程序来生成依赖项

在我的项目中,我使用并将以下内容添加到我的makefile中:

# Script to generate the dependencies
MAKEDEPEND=/path/to/fort_depend.py

# $(DEP_FILE) is a .dep file generated by fort_depend.py
DEP_FILE = my_project.dep

# Source files to compile
OBJECTS = mod_file1.f90 \
          mod_file2.f90

# Make sure everything depends on the .dep file
all: $(actual_executable) $(DEP_FILE)

# Make dependencies
.PHONY: depend
depend: $(DEP_FILE)

# The .dep file depends on the source files, so it automatically gets updated
# when you change your source
$(DEP_FILE): $(OBJECTS)
    @echo "Making dependencies!"
    cd $(SRCPATH) && $(MAKEDEPEND) -w -o /path/to/$(DEP_FILE) -f $(OBJECTS)

include $(DEP_FILE)

fort_depend.py
基本上只是在一个给定的文件中列出所有模块
使用的
d。

我有一个类似的问题,我在我的makefile中解决了它。您不应该引用FortDependes.py,而应该引用二进制文件。您可以使用find-name-fortube来定位此文件

这是我的制作文件。链接到我的github

#具有自动依赖性生成的Makefile
#注意:在运行之前,您需要安装fortdenden`pip install fortdenden`
#FortDependen路径可能不同,因此请确保编辑makeDependen变量
##编译器标志
FC=gfortran#Fortran编译器
FFLAGS=-g-Wall-Wextra#-O2#注意:编译器优化标志如-O2会干扰调试
链接器=$(FC)-o
FCLINKS=-g
#FFLAGS=-Wall-Wextra-fopenmp#OpenMP
#$(DEP_文件)是由fort_depend.py生成的.DEP文件
DEP_FILE=my_project.DEP
PROG=main.exe
#要编译的源文件
SOURCES:=$(shell find$(SOURCE\u DIR)-名称'*.f95')
对象:=$(源:.f95=.o)
##依赖项的自动生成
makeDependen=~/anaconda3/envs/dev/bin/fortdependen
依赖:=$(shell$(MAKEDEPEND)-f$(源)-o$(DEP_文件))
包括$(DEP_文件)
#达成所有目标
全部:$(进度)
%.o:%.f95
@回声“-------------------------------------”
@echo“将文件编译为对象”
@回声“-------------------------------------”
$(FC)$(FFLAGS)-c$<
$(程序):$(对象)
@回声“-------------------------------------”
@echo“创建可执行文件”
@回声“-------------------------------------”
$(链接器)$(程序)$(对象)$(FCLINKS)
清洁:
rm-r*.mod*.o*.exe*.dep

如果您注意到,在我的问题中,我问“当使用通配符生成对象文件列表时,我如何指定排列?”。我不想为每个文件手动指定规则,这就是我问这个问题的原因。如果我的项目中有2000个文件呢?您认为手动方法有效吗?您需要在某个地方指定它们。规则只是最明显的解决方案。我怀疑GNU make中应该有一些内置功能,告诉maker程序首先检测并编译最独立的源文件(称为layer1),然后编译layer2,这取决于layer1,然后是layer3。。等等它可能是关键字或标志,也可能是对maker的提示。我试图找到它是否存在:))我相信gcc对此有所帮助,但我不确定它是否扩展到gfortran。我可以为此编写lua或python脚本,但在此之前,我想确保gfortran makefile结构真的没有希望。在这种情况下,
main\u mod2
中的代码使用
main\u mod
中的代码。在一般情况下,地狱里怎么能猜出哪个代码使用哪个?@Beta“地狱里怎么能猜出哪个代码使用哪个?”-你是对的!!!但请看一看优素林出色的回答,做这样的事情!!!谢谢你这个难以置信的回答!我现在唯一的问题是python脚本总是给我以下错误:回溯(最近一次调用last):文件“fort_depend.py”,第161行,在args.D:TypeError中的arg中:“NoneType”对象不可iterable。你以前有过类似的错误吗?我怎样才能修好它?再次感谢。好的,我想我已经修复了那个错误。您能用最新的更改再试一次吗?
fort_depend.py
允许您为我可能难以置信的特定用例指定预处理器宏。我还没有找到另一个Fortran依赖项生成器允许您这样做。我运行“/fort_dependen.py-f mod_file1.f90 mod_file2.f90”将文件解析为python脚本。然而,当它在字典中查找时,有一些错误。下面是错误消息:回溯(上次调用):文件“/fort_depend.py”,第172行,在运行中(files=args.files,verbose=args.verbose,overwrite=args.overwrite,macros=macros,output=output)文件“/fort_depend.py”,第9行,在运行mod2fil=File_objs_to_mod dict(FIL_objs=l)类型错误:File_objs_to_mod dict()获取了意外的关键字参数“FIL_OBJS”。如果你能解决这个问题,我会很高兴的。谢谢此外,如果您觉得这解决了您的问题,您可以单击“接受”(如果愿意,还可以单击“向上投票”):