何时在Makefiles中明确指定依赖项? 介绍

何时在Makefiles中明确指定依赖项? 介绍,makefile,fortran,dependencies,fortran90,Makefile,Fortran,Dependencies,Fortran90,许多程序从模块中调用子程序、函数和/或元素树。假设所有这些元素都包含在单独的文件中,有些元素调用其他元素。我想知道在Makefiles上下文中编译过程中这些元素/文件之间的依赖关系。例如,我将使用Fortran,但这个问题至少在某种程度上与语言无关 例子 假设程序具有以下依赖项: MyProgram调用subroutineA和subroutineB subroutineA调用subroutineC 子例程b调用函数d,并使用模块常量中定义的参数pi 子程序c使用模块常量中定义的参数pi 函数d

许多程序从模块中调用子程序、函数和/或元素树。假设所有这些元素都包含在单独的文件中,有些元素调用其他元素。我想知道在Makefiles上下文中编译过程中这些元素/文件之间的依赖关系。例如,我将使用Fortran,但这个问题至少在某种程度上与语言无关

例子 假设程序具有以下依赖项:

  • MyProgram
    调用
    subroutineA
    subroutineB
  • subroutineA
    调用
    subroutineC
  • 子例程b
    调用
    函数d
    ,并使用模块
    常量中定义的参数
    pi
  • 子程序c
    使用模块
    常量中定义的参数
    pi
  • 函数d
    不调用任何内容
(常量模块可以是给定的模块。)每个程序、子例程、函数或模块在文件中定义,并具有匹配的名称

相应的Makefile至少可以用三种方式编写,如下所示,我想知道哪种方式最好。在示例Makefiles中,我假设在Makefile的前面已经设置了常用的Makefile变量:

  • F90
    设置为适当的Fortran编译器(例如
    FC=ifort
  • FFLAGS
    是一组编译器标志(例如
    FFLAGS=-O2
平凡的生成文件 所有内容都会立即编译:

MyProgram: constants.f90 myprogram.f90 subroutineA.f90 subroutineB.f90 subroutineC.f90 functionD.f90 
    $(FC) $^ $(FFLAGS) -o $@
更多“标准”Makefile 通过Makefile模式规则预编译子例程和函数,但单独预编译模块。最后,它将它们编译/链接到一起

%.o: %.f90
    $(FC) $^ -c $(FFLAGS) -o $@

%.o %.mod: %.f90
    $(FC) $^ -c $(FFLAGS)

MyProgram: constants.o constants.mod myprogram.o subroutineA.o subroutineB.o functionC.o 
    $(FC) $(filter %.o,$^) $(FFLAGS) -o $@
显式生成文件 显式表示每个依赖项。这使得
make
具有完整的依赖关系:

MyProgram: constants.o myprogram.o subroutineA.o subroutineB.o subroutineC.o functionD.o constants.mod
    $(FC) $(filter %.o,$^ ) -o $@

myprogram.o: myprogram.f90 subroutineA.o subroutineB.o
    $(FC) -c $< -o $@

subroutineA.o: subroutineA.f90 subroutineC.o
    $(FC) -c $< -o $@

subroutineB.o: subroutineB.f90 functionD.o constants.o constants.mod
    $(FC) -c $< -o $@

subroutineC.o: subroutineC.f90 constants.o constants.mod
    $(FC) -c $< -o $@

functionD.o: functionD.f90
    $(FC) -c $< -o $@

constants.o constants.mod: constants.f90
    $(FC) -c $<
MyProgram:constants.o MyProgram.o subroutineA.o subroutineB.o subroutineC.o function d.o constants.mod
$(FC)$(筛选器%.o,$^)-o$@
myprogram.o:myprogram.f90子例程a.o子例程b.o
$(FC)-c$<-o$@
子程序A.o:子程序A.f90子程序C.o
$(FC)-c$<-o$@
子程序B.o:子程序B.f90函数D.o常量.o常量.mod
$(FC)-c$<-o$@
subroutineC.o:subroutineC.f90 constants.o constants.mod
$(FC)-c$<-o$@
函数D.o:函数D.f90
$(FC)-c$<-o$@
constants.o constants.mod:constants.f90
$(FC)-c$<
我的问题 对于我的问题,让我们假设Makefile有足够的文件和/或被足够多的不同开发人员使用,以保证使用Makefile而不是手动编译,但是没有太多的文件导致显式写出依赖项是不合理或不可能的

在Makefile中写出这些东西的显式依赖关系是重要的、良好的做法还是必要的?在什么情况下最好使用“显式生成文件”方法而不是“更标准的生成文件”?


此外,该问题的答案是否取决于是否涉及模块

或者让编译器生成依赖项列表。大多数生成文件都有隐式和显式规则。