我正在 Windows 上使用 mingw 运行 makefile。我看过很多关于这个主题的 SO 链接,但它们似乎都是针对 C 或 c++ 的。我不确定是否适用相同的规则,而且由于我使用的是 Windows,语法似乎也有点不同。以下是一些其他引用资料:
How to place object files in separate subdirectory (我认为最有前途)
Using a make file to compile files in separate directories
Flat object file directory structure output with GNU Make
我目前拥有的是(逐字记录)
VPATH =\
user \
static \
computations \
solvers\\steadyState \
solvers\\transient \
solvers\\transient\\momentum \
solvers\\transient\\induction
FC = gfortran
TOP_DIR = .
MOD_DIR = $(TOP_DIR)\\mod
OBJ_DIR = $(TOP_DIR)\\obj
FCFLAGS = -g
FCFLAGS += -J$(MOD_DIR) -fopenmp -fimplicit-none -Wuninitialized
TARGET = parametricStudy
SRCS_F =\
user\\constants.f90 \
static\\myExceptions.f90 \
static\\myDebug.f90 \
static\\scalarField.f90 \
static\\vectorField.f90 \
static\\myIO.f90 \
user\\simParams.f90 \
static\\solverSettings.f90 \
static\\myTime.f90 \
computations\\myError.f90 \
static\\coordinates.f90 \
user\\griddata.f90 \
static\\myAllocate.f90 \
static\\BCs.f90 \
user\\rundata.f90 \
computations\\myDel.f90 \
computations\\vectorOps.f90 \
static\\myExport.f90 \
computations\\applyBCs.f90 \
solvers\\steadyState\\mySOR.f90 \
solvers\\steadyState\\myPoisson.f90 \
solvers\\transient\\induction\\initializeBBCs.f90 \
solvers\\transient\\induction\\initializeBfield.f90 \
solvers\\transient\\induction\\initializeSigmaMu.f90 \
solvers\\transient\\momentum\\initializeUBCs.f90 \
solvers\\transient\\momentum\\initializeUfield.f90 \
solvers\\transient\\inductionSolver.f90 \
solvers\\transient\\momentumSolver.f90 \
solvers\\transient\\MHDSolver.f90 \
user\\MOONS.f90 \
parametricStudy.f90
OBJS_F = $(patsubst %.f90,$(OBJ_DIR)\\%.o,$(notdir $(SRCS_F)))
all: $(TARGET)
$(TARGET): $(OBJS_F)
$(FC) -o $@ $(FCFLAGS) $(OBJS_F)
$(OBJ_DIR)\\%.o: %.f90
$(FC) $(FCFLAGS) -c -o $@ $<
clean:
del $(OBJ_DIR)\\*.o $(MOD_DIR)\\*.mod parametricStudy.exe
list:; @echo " "
@echo " "
@echo "Source files:"
@echo $(SRCS_F)
@echo " "
@echo "Object files:"
@echo $(OBJS_F)
@echo " "
@echo "Compiler : $(FC)"
@echo "Include directory : $(INC_DIR)"
@echo "Root directory : $(ROOT_DIR)"
@echo "Bin directory : $(BIN_DIR)"
@echo "Modules directory : $(MOD_DIR)"
@echo "Modules directory : $(MOD_DIR)"
@echo "Object directory : $(OBJ_DIR)"
@echo " "
使用它,我可以执行以下命令(再次,逐字)
C:\Users\Charlie\Desktop\development\FORTRAN_LIB>gmake
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\const
ants.o user/constants.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\myExc
eptions.o static/myExceptions.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\myDeb
ug.o static/myDebug.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\scala
rField.o static/scalarField.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\vecto
rField.o static/vectorField.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\myIO.
o static/myIO.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\simPa
rams.o user/simParams.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\solve
rSettings.o static/solverSettings.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\myTim
e.o static/myTime.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\myErr
or.o computations/myError.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\coord
inates.o static/coordinates.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\gridd
ata.o user/griddata.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\myAll
ocate.o static/myAllocate.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\BCs.o
static/BCs.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\runda
ta.o user/rundata.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\myDel
.o computations/myDel.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\vecto
rOps.o computations/vectorOps.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\myExp
ort.o static/myExport.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\apply
BCs.o computations/applyBCs.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\mySOR
.o solvers\\steadyState/mySOR.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\myPoi
sson.o solvers\\steadyState/myPoisson.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\initi
alizeBBCs.o solvers\\transient\\induction/initializeBBCs.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\initi
alizeBfield.o solvers\\transient\\induction/initializeBfield.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\initi
alizeSigmaMu.o solvers\\transient\\induction/initializeSigmaMu.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\initi
alizeUBCs.o solvers\\transient\\momentum/initializeUBCs.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\initi
alizeUfield.o solvers\\transient\\momentum/initializeUfield.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\induc
tionSolver.o solvers\\transient\\induction/inductionSolver.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\momen
tumSolver.o solvers\\transient\\momentum/momentumSolver.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\MHDSo
lver.o solvers\\transient/MHDSolver.f90
gfortran -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized -c -o .\\obj\MOONS
.o user/MOONS.f90
gmake: *** No rule to make target `.\\obj\parametricStudy.o', needed by `paramet
ricStudy'. Stop.
C:\Users\Charlie\Desktop\development\FORTRAN_LIB>gfortran -g -J.\\mod -fopenmp -
c -o .\\obj\parametricStudy.o parametricStudy.f90
C:\Users\Charlie\Desktop\development\FORTRAN_LIB>gmake
gfortran -o parametricStudy -g -J.\\mod -fopenmp -fimplicit-none -Wuninitialized
.\\obj\constants.o .\\obj\myExceptions.o .\\obj\myDebug.o .\\obj\scalarField.o
.\\obj\vectorField.o .\\obj\myIO.o .\\obj\simParams.o .\\obj\solverSettings.o .\
\obj\myTime.o .\\obj\myError.o .\\obj\coordinates.o .\\obj\griddata.o .\\obj\myA
llocate.o .\\obj\BCs.o .\\obj\rundata.o .\\obj\myDel.o .\\obj\vectorOps.o .\\obj
\myExport.o .\\obj\applyBCs.o .\\obj\mySOR.o .\\obj\myPoisson.o .\\obj\initializ
eBBCs.o .\\obj\initializeBfield.o .\\obj\initializeSigmaMu.o .\\obj\initializeUB
Cs.o .\\obj\initializeUfield.o .\\obj\inductionSolver.o .\\obj\momentumSolver.o
.\\obj\MHDSolver.o .\\obj\MOONS.o .\\obj\parametricStudy.o
请注意,收到错误后,我可以在错误发生后显式编译 parametricStudy.f90:
gfortran -g -J.\\mod -fopenmp -c -o .\\obj\parametricStudy.o parametricStudy.f90
然后输入
gmake
同样,这不会导致任何错误。我很困惑。
这是屏幕截图我的目录:
也许这和TARGET有关系?看起来最后一个文件的路径有些错误。非常感谢任何帮助!
最佳答案
我认为下面的 makefile 风格可以解决这个问题。我用样本C测试了它
项目,不是 fortran,但这对于 make
问题和解决方案并不重要。
# VPATH: Tell `make` to look for in `user` for prerequisites it can't find here
VPATH = user
# If e.g. you also want `make` to look for for prerequisites in `../include`, then:
# VPATH = user:../include
FC = gfortran
TOP_DIR = .
MOD_DIR = $(TOP_DIR)\\mod
OBJ_DIR = $(TOP_DIR)\\obj
FCFLAGS = -g
FCFLAGS += -J$(MOD_DIR) -fopenmp -fimplicit-none -Wuninitialized
TARGET = parametricStudy
SRCS_F =\
user\\constants.f90 \
...
parametricStudy.f90
OBJS_T1 = $(patsubst %.f90,%.o,$(SRCS_F))
OBJS_T2 = $(notdir $(OBJS_T1))
# The object files are all to be obj\<name>.o
OBJS_F = $(patsubst %.o,$(OBJ_DIR)\\%.o,$(OBJS_T2))
all: $(TARGET)
$(TARGET): $(OBJS_F)
$(FC) -o $@ $(FCFLAGS) $(OBJS_F)
# How to make an obj\*.o from the matching *.f90. `make` considers the VPATH
$(OBJ_DIR)\\%.o: %.f90
$(FC) $(FCFLAGS) -c -o $@ $<
clean:
del $(OBJ_DIR)\\*.o $(MOD_DIR)\\*.mod parametricStudy.exe
使用相对路径TOP_DIR = .
而不是绝对ROOT_DIR
是已经提供的好建议
作者:@Wintermute。
启用所需的模式规则:
$(OBJ_DIR)\\%.o: %.f90
要启动,您必须让 make
觉得任何先决条件 *.f90
都在这里,按照模式,
不在其他目录中,例如user\constants.f90
这就是VPATH
实现。
继续后续开发
还没有看到 makefile 所在目录的列表我 只能大胆假设,但我所看到的假设是:
该目录实际上并不包含名为 parametricStudy.f90
的文件,
但是一个名为 parametricStudy.F90
的文件,如果将其重命名为 parametricStudy.f90
,
然后 makefile 将找到并编译它。
是吗?
这如何解释事实:模式规则:
$(OBJ_DIR)\\%.o: %.f90
无法匹配任何parametricStudy.f90
,因此不存在此类文件。然而你说:
gfortran -g -J.\\mod -fopenmp -c -o .\\obj\parametricStudy.o parametricStudy.f90
编译成功。
您正在 Windows 上进行构建,因此工具链订阅 Windows 的文件处理协议(protocol)。
文件名不区分大小写:parametricStudy.f90
将识别 parametricStudy.F90
(如果存在),
和 .F90
将被 gfortran
(在 Windows 或其他任何地方)解释为表示
Fortran 90 源文件。这样命令行编译就成功了。
但是模式规则与文件处理协议(protocol)无关。这只是一个模式
匹配规则,不变的.f90
与.F90
不匹配。
关于makefile - 使用 make 将目标文件存储在单独的目录中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28121161/