到現在爲止,我用下面的Makefile
拿到2個可執行文件在同一目錄中的所有來源:修改Makefile來得到一個簡單的形式爲2個可執行
GFORTRAN = gfortran -Wall
CC = gcc -Wall
MPI_FORTRAN = mpif90 -Wall
MPI_CC = mpicc -Wall
LD = -lm
.SUFFIXES : .o .f90
all: explicitSeq explicitPar
explicitSeq : explicitSeq.o explUtilSeq.o
$(GFORTRAN) -o [email protected] explicitSeq.o explUtilSeq.o
explicitSeq.o : explicitSeq.f90
$(GFORTRAN) -c $(*F).f90
explUtilSeq.o : explUtilSeq.f90
$(GFORTRAN) -c $(*F).f90
explicitPar : explicitPar.o explUtilPar.o updateBound.o readParam.o
$(MPI_FORTRAN) -o [email protected] explicitPar.o explUtilPar.o updateBound.o readParam.o
.f90.o:
$(MPI_FORTRAN) -c $(*F).f90
clean :
/bin/rm -f *.o explicitSeq explicitPar
一切工作正常。現在,我想使用一個使用%.o
和%.f90
變量並結合「$<
」變量的基本表格。
我試圖讓上面的等效Makefile
這樣的:
GFORTRAN = gfortran -Wall
CC = gcc -Wall
MPI_FORTRAN = mpif90 -Wall
MPI_CC = mpicc -Wall
LD = -lm
SRC_SEQ = explicitSeq.f90 explUtilSeq.f90
OBJ_SEQ = explicitSeq.o explUtilSeq.o
SRC_PAR = explicitPar.f90 explUtilPar.f90 updateBound.f90 readParam.f90
OBJ_PAR = explicitPar.o explUtilPar.o updateBound.o readParam.o
all: explicitSeq explicitPar
explicitSeq : OBJ_SEQ
$(GFORTRAN) -o [email protected] $<
OBJ_SEQ: SRC_SEQ
$(GFORTRAN) -c $<
explicitPar : OBJ_PAR
$(MPI_FORTRAN) -o [email protected] $<
OBJ_PAR: SRC_PAR
$(MPI_FORTRAN) -c $<
clean :
/bin/rm -f *.o explicitSeq explicitPar
但不幸的是,輸入 「make」 產生:
make: *** No rule to make target `SRC_SEQ', needed by `OBJ_SEQ'. Stop.
我不知道如何繞過這個錯誤。也許我應該使用依賴.f90.o:
但我不知道該把它放在哪裏。對不起,如果這是一個初學者的問題,但任何幫助,歡迎。
更新1:
從Vroomfondel的建議下,我做了以下修改:
GFORTRAN = gfortran-mp-4.9 -Wall
CC = gcc -Wall
MPI_FORTRAN = mpif90 -Wall
MPI_CC = mpicc -Wall
LD = -lm
SRC_SEQ = explicitSeq.f90 explUtilSeq.f90
OBJ_SEQ = explicitSeq.o explUtilSeq.o
SRC_PAR = explicitPar.f90 explUtilPar.f90 updateBound.f90 readParam.f90
OBJ_PAR = explicitPar.o explUtilPar.o updateBound.o readParam.o
all: explicitSeq explicitPar
explicitSeq : $(OBJ_SEQ)
$(GFORTRAN) -o [email protected] $<
$(OBJ_SEQ): $(SRC_SEQ)
$(GFORTRAN) -c $<
explicitPar : $(OBJ_PAR)
$(MPI_FORTRAN) -o [email protected] $<
$(OBJ_PAR): $(SRC_PAR)
$(MPI_FORTRAN) -c $<
clean :
/bin/rm -f *.o explicitSeq explicitPar
和我得到的錯誤:
gfortran-mp-4.9 -Wall -c explicitSeq.f90
gfortran-mp-4.9 -Wall -c explicitSeq.f90
gfortran-mp-4.9 -Wall -o explicitSeq explicitSeq.o
Undefined symbols for architecture x86_64:
"_computenext_", referenced from:
_MAIN__ in explicitSeq.o
"_initvalues_", referenced from:
_MAIN__ in explicitSeq.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make: *** [explicitSeq] Error 1
正如你可以看到,文件explicitSeq.f90
被編譯2次:它是從修改後的Makefile中預期的行爲嗎?感謝您的幫助
更新2:
我想我可以使用以下規則:
%.o: %.f90
$(GFORTRAN) -o [email protected] -c $<
但問題是,我還編譯$(MPI_FORTRAN)
一些*.f90
文件。我不知道如何區分2例obj的文件(*的.o)(與gfortan編譯器和編譯器mpif90)
更新3:
我有差不多的解決方案。我做了:
GFORTRAN = gfortran -Wall
CC = gcc -Wall
MPI_FORTRAN = mpif90 -Wall
MPI_CC = mpicc -Wall
LD = -lm
DIR_SEQ = tmpSeqDir
DIR_PAR = tmpParDir
SRC_SEQ = explicitSeq.f90 explUtilSeq.f90
OBJ_SEQ = $(addprefix $(DIR_SEQ)/,$(SRC_SEQ:.f90=.o))
SRC_PAR = explicitPar.f90 explUtilPar.f90 updateBound.f90 readParam.f90
OBJ_PAR = $(addprefix $(DIR_PAR)/,$(SRC_PAR:.f90=.o))
all: explicitSeq explicitPar
explicitSeq: $(OBJ_SEQ)
$(GFORTRAN) -o [email protected] $^
$(DIR_SEQ)/%.o: $(DIR_SEQ)/%.f90
$(GFORTRAN) -c $< -o [email protected]
explicitPar: $(OBJ_PAR)
$(MPI_FORTRAN) -o [email protected] $^
$(DIR_PAR)/%.o: $(DIR_PAR)/%.f90
$(MPI_FORTRAN) -c $< -o [email protected]
$(OBJ_SEQ): | $(DIR_SEQ)
$(OBJ_PAR): | $(DIR_PAR)
$(DIR_SEQ):
mkdir [email protected]
cp -pf $(SRC_SEQ) [email protected]
$(DIR_PAR):
mkdir [email protected]
cp -pf $(SRC_PAR) [email protected]
clean:
rm -f *.o explicitSeq explicitPar
rm -f $(DIR_SEQ)/*
rmdir $(DIR_SEQ)
rm -f $(DIR_PAR)/*
rmdir $(DIR_PAR)
不幸的是,我必須連續輸入3次「make」才能獲得2個可執行文件。下面是這3個 「品牌」 輸出:
第一 「讓」:
$ make
mkdir tmpSeqDir
cp -pf explicitSeq.f90 explUtilSeq.f90 tmpSeqDir
gfortran -Wall -o explicitSeq tmpSeqDir/explicitSeq.o tmpSeqDir/explUtilSeq.o
gfortran: error: tmpSeqDir/explicitSeq.o: No such file or directory
gfortran: error: tmpSeqDir/explUtilSeq.o: No such file or directory
Makefile:17: recipe for target 'explicitSeq' failed
make: *** [explicitSeq] Error 1
二 「作」:
$ make
gfortran -Wall -c tmpSeqDir/explicitSeq.f90 -o tmpSeqDir/explicitSeq.o
gfortran -Wall -c tmpSeqDir/explUtilSeq.f90 -o tmpSeqDir/explUtilSeq.o
gfortran -Wall -o explicitSeq tmpSeqDir/explicitSeq.o tmpSeqDir/explUtilSeq.o
mkdir tmpParDir
cp -pf explicitPar.f90 explUtilPar.f90 updateBound.f90 readParam.f90 tmpParDir
mpif90 -Wall -o explicitPar tmpParDir/explicitPar.o tmpParDir/explUtilPar.o tmpParDir/updateBound.o tmpParDir/readParam.o
gfortran: error: tmpParDir/explicitPar.o: No such file or directory
gfortran: error: tmpParDir/explUtilPar.o: No such file or directory
gfortran: error: tmpParDir/updateBound.o: No such file or directory
gfortran: error: tmpParDir/readParam.o: No such file or directory
Makefile:23: recipe for target 'explicitPar' failed
make: *** [explicitPar] Error 1
三 「作」:
$ make
mpif90 -Wall -c tmpParDir/explicitPar.f90 -o tmpParDir/explicitPar.o
mpif90 -Wall -c tmpParDir/explUtilPar.f90 -o tmpParDir/explUtilPar.o
mpif90 -Wall -c tmpParDir/updateBound.f90 -o tmpParDir/updateBound.o
mpif90 -Wall -c tmpParDir/readParam.f90 -o tmpParDir/readParam.o
mpif90 -Wall -o explicitPar tmpParDir/explicitPar.o tmpParDir/explUtilPar.o tmpParDir/updateBound.o tmpParDir/readParam.o
是否可以只做一個簡單的「make」來編譯所有,而不必輸入3次「make」?
我懷疑行cp -pf $(SRC_SEQ) [email protected]
和cp -pf $(SRC_PAR) [email protected]
導致相對於$(DIR_SEQ)/%.f90
和$(DIR_PAR)/%.f90
相關性的問題。
謝謝,也許我會開始賞金。
您需要在訪問(讀取)它們時在'$()'中寫入變量名稱。沒有'$()'的表單只用於賦值。 – Vroomfondel
@Vroomfondel你可以看看我的**更新1 **和**更新2 **嗎? – youpilat13
規則'explicitSeq:$(DIR_SEQ)/ $(OBJ_SEQ)'將計算爲'explicitSeq:tmpSeqDir/explicitSeq.f90 explUtilSeq.f90'(注意第二個文件的丟失路徑),這不是我們想要的。然而,爲什麼它聲稱不知道如何做到這一點,我不知道。稍後再研究它。順便說一句,你正在使用? – Vroomfondel