
Estou tentando construir duas bibliotecas diferentes a partir do código-fonte Fortran, uma com suporte a OMP e outra sem. Assim, os arquivos %.o da mesma fonte diferem dependendo dos sinalizadores do compilador. Ao alterar/recompilar um arquivo de origem, ar ainda precisa de todos os arquivos o para reconstruir a biblioteca. Para evitar a recompilação de todos os arquivos de origem, quero armazenar os arquivos o de arquivos de origem não alterados em dois diretórios diferentes, um com arquivos o incluindo suporte omp, o outro sem. Estou feliz por ter que criar arquivos para isso naquele diretório onde as bibliotecas estão finalmente localizadas.
No entanto, não consigo reconstruir a biblioteca em um único comando devido ao comportamento da variável vpath. Aqui está o arquivo make:
SRC :=
FORTRAN = ifort
OPTSSEQ = -mkl=sequential -DThreadUnSafe -warn nounused -warn declarations -O3 -DTIMEDETAIL
DRVOPTS = $(OPTS)
NOOPT =
LOADER = ifort
LOADOPTS =
kernel=$(shell uname -r)
ARCH = ar
ARCHFLAGS= cr
RANLIB = ranlib
LibName=Lib_LM_$(FORTRAN)_$(kernel)_1.0.a
.SUFFIXES:
.SUFFIXES: .f90 .o
include Moduls.mk
vpath %.f90 src/
vpath %.o NoOMP/
OBJS = $(patsubst %.f90,%.o,$(SRC))
$(LibName): $(OBJS)
$(ARCH) $(ARCHFLAGS) $@ $?
$(RANLIB) $@
%.o : %.f90
$(FORTRAN) $(OPTSSEQ) -c $? -o $(addprefix NoOMP/,$@)
clean:
-rm *.mod
-rm NoOMP/*.o
-rm *.smod
-rm $(LibName)
Isso resulta na construção bem-sucedida de todos os arquivos %.o após "make clean", já que todos os arquivos %.f90 são lidos em src/ e todos os arquivos %.o são gravados em NoOMP/. No entanto, a construção do arquivo falha porque o prefixo "NoOMP" nos arquivos %.o foi eliminado. Assim, ar reclama que não consegue encontrar os arquivos %.o. Somente se eu executar "make" novamente, o arquivo será compilado porque os arquivos %.o terão o prefixo NoOMP. Adicionar um comando de prefixo à linha de construção do arquivo funciona bem se for construído do zero. No entanto, se apenas um único arquivo for alterado, os arquivos inalterados terão um prefixo "NoOMP/NoOMP/", resultando em uma anulação novamente.
Embora isso seja terrivelmente irritante, pelo que entendi no manual, esse é o comportamento padrão do GNU make. Se eu estiver errado, como posso reparar o makefile, se estiver certo, como posso contornar esse problema.
Responder1
Resolvido
os exemplos funcionam ao mudar a linha
$(ARCH) $(ARCHFLAGS) $@ $?
para
$(ARCH) $(ARCHFLAGS) $@ $(addprefix NoOMP/,$?)
Acima eu havia descartado essa solução, mas meu teste foi baseado $^
em vez de $?
. Enquanto o primeiro reconstruirá todo o arquivo a partir de arquivos %.o antigos e novos, o último atualizará apenas o arquivo existente com novos arquivos %.o. Ao reconstruir todo o arquivo a partir de arquivos %.o antigos e novos, os arquivos %.o antigos terão o prefixo errado, os novos o certo. Assim, excluir arquivos %.o antigos atualizando o arquivo com arquivos %.o recém-compilados contorna esse problema.
Saúde