使用 Makefile 进行 Fortran 编译 - 解决依赖问题

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

我尝试使用以下 Makefile 来编译我编写的 Fortran 程序(AltitudeCalculator.f90),该程序使用另一个 Fortran 模块(COESA.f90 中包含的 COESA_module)作为依赖项:

我的项目的文件夹结构是这样的:

Project/
├── src/
│   ├── COESA.f90
│   ├── AltitudeCalculator.f90
├── include/
├── build/
├── bin/
├── Makefile

这是我当前的 Makefile 迭代:

# Compiler settings
FC = gfortran
FFLAGS = -O2 -Wall -Wno-unused-function -Wno-maybe-uninitialized
DEPFLAGS = -MMD -MP
INCLUDE = -Iinclude

# Directories
SRCDIR = ./src
BUILDDIR = ./build
BINDIR = ./bin

# Source files
SRCS = $(wildcard $(SRCDIR)/*.f90)
OBJS = $(patsubst $(SRCDIR)/%.f90,$(BUILDDIR)/%.o,$(SRCS))
EXECUTABLE = $(BINDIR)/AltitudeCalculator
$(info EXECUTABLE is $(EXECUTABLE))

# Generate dependency files
DEPFILES = $(SRCS:.f90=.d)
$(info DEPENDENCY FILES are $(DEPFILES))
-include $(DEPFILES)

# Dependencies
#DEPS = $(filter-out $(BUILDDIR)/AltitudeCalculator.mod,$(patsubst $(SRCDIR)/%.f90,$(BUILDDIR)/%.mod,$(SRCS)))
DEPS = $(BUILDDIR)/COESA.mod $(BUILDDIR)/coesa_module.mod $(BUILDDIR)/AltitudeCalculator.mod
$(info DEPENDENCIES are $(DEPS))

# Targets
all: $(EXECUTABLE)

$(EXECUTABLE): $(OBJS) $(DEPS)
    @mkdir -p $(@D)
    $(info Building executable: $@)
    $(FC) $(FFLAGS) $(INCLUDE) -o $@ $(OBJS)

#$(BUILDDIR)/%.o: $(SRCDIR)/%.f90 $(DEPS)
$(BUILDDIR)/%.o: $(SRCDIR)/%.f90 $(DEPS)
    @mkdir -p $(@D)
    $(info Compiling: $<)
    $(FC) $(FFLAGS) $(INCLUDE) -c $< -o $@

$(BUILDDIR)/%.mod: $(SRCDIR)/%.f90
    @mkdir -p $(@D)
    $(info Generating module: $@)
    $(FC) $(FFLAGS) -J$(BUILDDIR) -c $< -o $@
    @cp $@ .

clean:
    $(info Cleaning up...)
    rm -rf $(BUILDDIR)/* $(BINDIR)/* ./*.mod

.PHONY: all clean

使用此 Makefile 编译代码时,我收到以下错误消息:

EXECUTABLE is ./bin/AltitudeCalculator
DEPENDENCY FILES are ./src/AltitudeCalculator.d ./src/COESA.d
DEPENDENCIES are ./build/COESA.mod ./build/coesa_module.mod ./build/AltitudeCalculator.mod
Generating module: build/COESA.mod
gfortran -O2 -Wall -Wno-unused-function -Wno-maybe-uninitialized -J./build -c src/COESA.f90 -o build/COESA.mod
Generating module: build/AltitudeCalculator.mod
gfortran -O2 -Wall -Wno-unused-function -Wno-maybe-uninitialized -J./build -c src/AltitudeCalculator.f90 -o build/AltitudeCalculator.mod
Compiling: src/AltitudeCalculator.f90
gfortran -O2 -Wall -Wno-unused-function -Wno-maybe-uninitialized -Iinclude -c src/AltitudeCalculator.f90 -o build/AltitudeCalculator.o
src/AltitudeCalculator.f90:3:8:

    3 |     use COESA_module, only: State, COESA_atmosphere
      |        1
Fatal Error: Cannot open module file ‘coesa_module.mod’ for reading at (1): No such file or directory
compilation terminated.
make: *** [Makefile:41: build/AltitudeCalculator.o] Error 1

我的文件夹结构现在看起来像这样:

Project/
    ├── src/
    │   ├── COESA.f90
    │   ├── AltitudeCalculator.f90
    ├── include/
    ├── build/
    │   ├── AltitudeCalculator.mod
    │   ├── COESA.mod
    │   ├── coesa_module.mod
    ├── bin/
    ├── Makefile
    ├── AltitudeCalculator.mod
    ├── COESA.mod

当我手动将 coesa_module.mod 复制到当前目录(与 Makefile 同一级别)时,编译工作。但我必须编译两次,而且这似乎不是一个干净的过程。我尝试使用这条线

@cp $@ .

将所有模块复制到工作目录中,但由于未知原因,无法复制 coesa_module.mod。

这里有什么问题?

makefile module compilation dependencies fortran
1个回答
0
投票

如果有人好奇,ChatGPT 给了我这个 CMakeLists.txt 的解决方案:

# Specify the minimum version of CMake
cmake_minimum_required(VERSION 3.12)

# Set the project name
project(US_standard_atmosphere_1976 Fortran)

# Add executable target
add_executable(AltitudeCalculator src/AltitudeCalculator.f90 src/COESA.f90)

# Set the output directory for the executable
set_target_properties(AltitudeCalculator PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin
)

但我不知道是什么原因导致了我的 Makefile 中的问题。也许我将来会坚持使用构建自动化软件。

© www.soinside.com 2019 - 2024. All rights reserved.