Considere o seguinte Makefile como um MWE:
###################################################################
# first bunch
###################################################################
FORTRAN1 = ifort -c
PATH1 = sub/
FILE1 = first.f90
SOURCE1 = $(FILE_TEST:%=$(PATH1)%)
OBJECT1 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE1))))
###################################################################
#second bunch
###################################################################
FORTRAN2 = ifort -traceback -c
PATH2 = sub/
FILE2 = second.f90
SOURCE2 = $(FILE2:%=$(PATH2)%)
OBJECT2 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE2))))
###################################################################
# first rule
###################################################################
all: $(OBJECT1)
lnk/%.o: $(PATH1)%.f90
$(FORTRAN1) -o $@ $<
###################################################################
# second rule
###################################################################
all: $(OBJECT2)
lnk/%.o: $(PATH2)%.f90
$(FORTRAN2) -o $@ $<
Quando executo este script, os seguintes comandos são executados:
ifort -traceback -c -o lnk/first.o sub/first.f90
ifort -traceback -c -o lnk/second.o sub/second.f90
Em outras palavras, tanto a primeira quanto a segunda regras usam FORTRAN2=ifort -traceback -c
, enquanto a primeira regra deveria usar FORTRAN1=ifort -c
. Você poderia me ajudar o que é responsável por esse comportamento estranho? Como posso conseguir que $(FORTRAN1)$
a primeira regra seja usada?
EDITAR #1:
Seguindo a sugestão do MadScientist, tentei o seguinte:
###################################################################
# first bunch
###################################################################
FORTRAN1 = ifort -c
PATH1 = sub/
FILE1 = first.f90
SOURCE1 = $(FILE_TEST:%=$(PATH1)%)
OBJECT1 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE1))))
###################################################################
#second bunch
###################################################################
FORTRAN2 = ifort -traceback -c
PATH2 = sub/
FILE2 = second.f90
SOURCE2 = $(FILE2:%=$(PATH2)%)
OBJECT2 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE2))))
###################################################################
# first rule
###################################################################
$(OBJECT1): lnk/%.o: $(PATH1)%.f90
$(FORTRAN1) -o $@ $<
###################################################################
# second rule
###################################################################
$(OBJECT2): lnk/%.o: $(PATH2)%.f90
$(FORTRAN2) -o $@ $<
No entanto, ele executa apenas um (ou seja, o primeiro) comando:
ifort -c -o lnk/first.o sub/first.f90
EDITAR #2:
O problema foi que removi os all:
alvos. O conteúdo correto do arquivo deve ser:
###################################################################
# first bunch
###################################################################
FORTRAN1 = ifort -c
PATH1 = sub/
FILE1 = first.f90
SOURCE1 = $(FILE_TEST:%=$(PATH1)%)
OBJECT1 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE1))))
###################################################################
#second bunch
###################################################################
FORTRAN2 = ifort -traceback -c
PATH2 = sub/
FILE2 = second.f90
SOURCE2 = $(FILE2:%=$(PATH2)%)
OBJECT2 = $(addprefix lnk/,$(addsuffix .o,$(basename $(FILE2))))
###################################################################
# first rule
###################################################################
all: $(OBJECT1)
$(OBJECT1): lnk/%.o: $(PATH1)%.f90
$(FORTRAN1) -o $@ $<
###################################################################
# second rule
###################################################################
all: $(OBJECT2)
$(OBJECT2): lnk/%.o: $(PATH2)%.f90
$(FORTRAN2) -o $@ $<
Make não é uma linguagem de script: não é o caso de make ler o makefile e "executá-lo" enquanto ele é processado. Make lê todo o makefile completamente, além de todos os arquivos incluídos, e depois de terminar ele inicia o processamento.
Só pode haver uma regra padrão com o mesmo conjunto de metas e pré-requisitos. No seu makefile você tem:
Como as variáveis
PATH1
ePATH2
têm o mesmo valor, make vê isto:a segunda regra é idêntica à primeira regra e, portanto, a substitui e a primeira regra é perdida. Depois que toda essa análise for concluída, ENTÃO make começa a tentar construir objetos e ver qual regra deve ser usada para corresponder a qual alvo. Como há apenas uma regra padrão correspondente, ela é usada para todos os objetos.
Existem algumas maneiras diferentes de fazer isso. Uma delas é usar regras de padrão estático em vez de regras de padrão completo:
Agora, essas regras correspondem apenas a esses objetos exatos.