许多程序从模块中调用子程序,函数和/或元素树。假设所有这些元素都包含在单独的文件中,有些则调用其他元素。我想知道在Makefile的上下文中编译过程中这些元素/文件之间的依赖关系。我将以Fortran为例,但这个问题至少与有些语言无关。
假设程序具有以下依赖项:
MyProgram
来电subroutineA
和subroutineB
。 subroutineA
来电subroutineC
。subroutineB
调用functionD
并使用模块pi
中定义的参数constants
。subroutineC
使用模块pi
中定义的参数constants
。functionD
什么都不打电话。(constants
模块可以是给定here的模块。)每个程序,子例程,函数或模块都在具有匹配名称的文件中定义。
相应的Makefile可以用至少三种方式编写,如下图所示,我想知道哪种方式最好。在示例Makefile中,我假设在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模式规则预编译子例程和函数,但单独预编译模块。最后,它在最后编译/链接它们。
%.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
具有完整的directed acyclic graph依赖项:
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 $<
对于我的问题,让我们假设Makefile有足够的文件和/或被足够多的不同开发人员用来保证使用Makefile而不是手动编译,但没有那么多明确写出依赖关系的文件是不合理的或不可能的。
在Makefile中为这些东西写出显式依赖项是重要的,好的做法还是必要的?在什么情况下最好使用“Explicit Makefile”方法而不是“More Standard Makefile”?
此外,该问题的答案取决于是否涉及模块?