Fortran 模块的编译依赖以及 make 的 INCLUDE 语句

问题描述 投票:0回答:1

我正在使用 MinGW 编译 Fortran 源代码并在 Windows 上制作。

源文件扩展名是

.f
.for
-
.for
是模块(某些
.for
文件甚至包含多个模块)。

我有一个通用的 makefile ;基本上是

# Source directories
dirs := . srkf

# Executable to create
Executable = D:\Executables\a.exe
# -------------------------------------------------------

# Obj dir
Objets_dir = ../obj

VPATH = $(dirs) $(Objets_dir)

# Creation of .for list
Sourmod := $(foreach dir,$(dirs),$(wildcard $(dir)/*.for))

# Creation of .f list
Sources := $(foreach dir,$(dirs),$(wildcard $(dir)/*.f))

# Obj list
Objmod = $(patsubst %.for,%.o,$(Sourmod))
Objets = $(patsubst %.f,%.o,$(Sources))

# Full path to .o
TempObjets = $(addprefix $(Objets_dir)/, $(notdir $(Objmod) $(Objets)))

    
# Comp options
cpl = gfortran
cpl_opt = -ffpe-trap=invalid,zero,overflow -O3 -Wall
lnk = gfortran
lnk_opt = 

# Compilation
$(Objets_dir)/%.o:%.for
    $(cpl) -J$(Objets_dir) $(cpl_opt) -c $< -o $(Objets_dir)\$(notdir $@)
$(Objets_dir)/%.o:%.f
    $(cpl) -I$(Objets_dir) $(cpl_opt) -c $< -o $(Objets_dir)\$(notdir $@)

# Link
$(Executable): $(TempObjets)
    $(lnk) -o $@ $^ $(lnk_opt)

clean:
    @-rm -rf $(Objets_dir) $(Executable)

首先编译模块,但是:

  • 编辑和更新 .for 文件不会导致使用所述 .for 文件中包含的模块重新编译 .f 文件,并且
  • 项目的一小部分由于外部限制,我将被要求使用一些(基本的)
    include
    语句(而不是模块,尽管我仍然会在其他地方使用模块),以及相同类型的依赖关系问题出现了。如果我有一个
    foo.f
    文件,其中某个地方有
    include 'bar.inc'
    ,那么修改
    bar.inc
    文件并编译代码不会导致
    foo.f
    被重新编译。

这显然是有问题的。

为了解决这个问题,有人建议我以这种方式修改makefile(自动创建依赖文件)

# Source directories
dirs := . srkf

# Executable to create
Executable = D:\Executables\a.exe
# -------------------------------------------------------

# Obj dir
Objets_dir ?= ../obj

VPATH = $(dirs) $(Objets_dir)

# Creation of .for list
Sourmod := $(foreach dir,$(dirs),$(wildcard $(dir)/*.for))

# Creation of .f list
Sources := $(foreach dir,$(dirs),$(wildcard $(dir)/*.f))

# Obj list
Objmod = $(patsubst %.for,%.o,$(Sourmod))
Objets = $(patsubst %.f,%.o,$(Sources))

# Full path to .o
TempObjets = $(addprefix $(Objets_dir)/, $(notdir $(Objmod) $(Objets)))
DEPENDS = $(patsubst %.o,%.d,$(TempObjets))

# Comp options
cpl = gfortran
FFLAGS = -ffpe-trap=invalid,zero,overflow -O3 -Wall
lnk = gfortran
lnk_opt = 

all: $(Executable)

# Compilation
$(Objets_dir)/%.o:%.for
    $(cpl) -J$(Objets_dir) $(FFLAGS) -c $< -o $@

$(Objets_dir)/%.o:%.f
    $(cpl) -I$(Objets_dir) $(FFLAGS) -c $< -o $@

$(Objets_dir)/%.d: %.for
    @-(echo -n $(Objets_dir)/;$(cpl) -cpp -MM -J$(Objets_dir) -fsyntax-only $(FFLAGS) -c $<) > $@

$(Objets_dir)/%.d: %.f
    @-(echo -n $(Objets_dir)/;$(cpl) -cpp -MM -I$(Objets_dir) -fsyntax-only $(FFLAGS) -c $<) > $@

-include $(DEPENDS)

# Link
$(Executable): $(TempObjets)
    $(lnk) $(lnk_opt) -o $@ $^

# Clean
clean:
    @-rm -rf $(Objets_dir)/* $(Executable)

#all:
#   @echo $(value Sources)
#   @echo $(value Objets)
#   @echo $(value TempObjets)

这确实适用于包含:修改

bar.inc
文件并编译代码现在确实会导致
foo.f
被重新编译 - 太棒了。

但是修改模块(

.for
文件)仍然不会导致使用该模块(或
.for
文件中存在的模块)重新编译文件。

您将如何编写此 makefile,以便考虑两种行为/依赖关系?

makefile fortran include gnu-make
1个回答
0
投票

如果您希望在重建任何模块 (

.f
) 文件时重建所有 Fortran (
.for
) 文件,只需对 makefile 进行以下更改即可:

# Obj target lists
Objmod = $(patsubst %.for,$(Objets_dir)/%.o,$(notdir $(Sourmod)))
Objets = $(patsubst %.f,$(Objets_dir)/%.o,$(notdir $(Sources)))

# All objects
TempObjets = $(Objmod) $(Objets)

# Make sure all .f objects are rebuilt after any .for objects are built
$(Objets) : $(Objmod)
© www.soinside.com 2019 - 2024. All rights reserved.