我在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有关?似乎最后一个文件的路径在某种程度上是错误的。非常感谢任何帮助!
答案 0 :(得分:3)
您遇到的问题是
ROOT_DIR = "C:\Users\Charlie\"
OBJ_DIR = $(ROOT_DIR)\obj
规则
$(OBJ_DIR)/%.o: %.f90
扩展为
"C:\Users\Charlie\"obj/%.o: %.f90
被解析为静态模式规则
"C: \Users\Charlie\"obj/%.o: %.f90
也就是说,使用目标"C
,目标模式\Users\Charlie\"obj/%.o
和先决条件模式%.f90
。抱怨"C
与模式\Users\Charlie\"obj/%.o
不匹配。
GNU make中有一些hacky代码(至少在MinGW中;我认为Cygwin的行为不同,因为它希望你使用它的unix-ish目录结构)来识别绝对的Windows路径,但它不处理引用。只要您的OBJ_DIR
不包含空格,请使用
ROOT_DIR = C:\Users\Charlie\
应该启动Windows路径识别。
然而......在手工制作的Makefile中看到绝对路径是相当不寻常的。你确定要这样做吗?更常见的方法是使用相对路径,以便在将源代码复制到其他目录时不必更改Makefile。假设Makefile位于根目录中,那将是
ROOT_DIR = .
或者只是简单地修改ROOT_DIR
变量并说
MOD_DIR = mod
OBJ_DIR = obj
哦,并回答下一个即将出现的问题:为了让make
使用
$(OBJ_DIR)/%.o: %.f90
规则,您需要使$(TARGET)
具有与$(OBJ_DIR)/%.o
模式匹配的先决条件。那可能是
OBJS_F = $(patsubst %.f90,$(OBJ_DIR)/%.o,$(notdir $(SRCS_F)))
答案 1 :(得分:3)
我认为以下样式的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&#39;文件处理协议。
文件名是大小写的:parametricStudy.f90
将标识parametricStudy.F90
,如果存在,
并且.F90
将gfortran
(在Windows或其他任何地方)解释为表示a
Fortran 90源文件。因此成功的命令行编译。
但模式规则对文件处理协议无动于衷。这只是一种模式
匹配规则,.f90
不匹配不变.F90
。