gnu make, vpath, diretório de arquivo extra o, confusão

gnu make, vpath, diretório de arquivo extra o, confusão

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

informação relacionada