Jusqu'à présent, je l'Makefile
suivante pour obtenir 2 executables avec toutes les sources dans le même répertoire:Modifier Makefile pour obtenir un formulaire simple pour 2 executables
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
Tout fonctionne très bien. Maintenant, je voudrais utiliser un formulaire de base en utilisant %.o
et %.f90
variables combinées avec "$<
" variable.
J'ai essayé de faire l'équivalent de Makefile
ci-dessus comme ceci:
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
Mais malheureusement, en tapant "make" produit:
make: *** No rule to make target `SRC_SEQ', needed by `OBJ_SEQ'. Stop.
Je ne sais pas comment contourner cette erreur. Peut-être que je devrais utiliser la dépendance .f90.o:
mais je ne sais pas clairement où le mettre. Désolé si c'est un problème débutant mais toute aide est la bienvenue.
MISE À JOUR 1:
De l'avis de Vroomfondel, je l'ai fait les modifications suivantes:
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
et je reçois les erreurs:
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
Comme vous pouvez le voir, le fichier explicitSeq.f90
est compilé 2 fois: est-ce le comportement attendu du fichier Makefile modifié? Merci pour votre aide
MISE À JOUR 2:
Je pense que je pourrais utiliser la règle suivante:
%.o: %.f90
$(GFORTRAN) -o [email protected] -c $<
mais le problème est que je dois compiler aussi quelques *.f90
fichiers avec $(MPI_FORTRAN)
. Je ne sais pas comment différencier les 2 cas de fichiers OBJ (* .o) (avec le compilateur et gfortan compilateur mpif90)
MISE À JOUR 3:
J'ai presque la solution. J'ai fait:
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)
Malheureusement, je dois taper 3 fois "make" pour obtenir les 2 exécutables.Voici la sortie de ces 3 "fait":
d'abord "faire":
$ 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
deuxième "marque":
$ 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
troisième "faire":
$ 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
Est-il possible de faire seulement un simple "make" pour compiler tout au lieu d'avoir à taper 3 fois "make"?
Je suspecte que les lignes cp -pf $(SRC_SEQ) [email protected]
et cp -pf $(SRC_PAR) [email protected]
causent des problèmes relativement aux dépendances $(DIR_SEQ)/%.f90
et $(DIR_PAR)/%.f90
.
Merci, peut-être que je vais commencer une prime.
Vous devez écrire vos noms de variables dans '$()' lorsque vous les lisez. Le formulaire sans '$()' n'est utilisé que dans les affectations. – Vroomfondel
@Vroomfondel Pourriez-vous jeter un coup d'œil sur mes ** MISE À JOUR 1 ** et ** MISE À JOUR 2 **? – youpilat13
La règle 'explicitSeq: $ (DIR_SEQ)/$ (OBJ_SEQ)' évaluera à 'explicitSeq: tmpSeqDir/explicitSeq.f90 explUtilSeq.f90' (notez le chemin manquant pour le second fichier) qui n'est pas ce que nous voulons. Pourquoi sa prétention de ne pas savoir comment faire cela je ne sais pas cependant. J'y reviendrai plus tard. BTW quelle marque utilisez-vous? – Vroomfondel