gnu make, vpath, дополнительный каталог файлов, путаница

gnu make, vpath, дополнительный каталог файлов, путаница

Я пытаюсь собрать две разные библиотеки из исходного кода Fortran, одну с поддержкой OMP, другую без. Таким образом, файлы %.o из одного и того же исходного кода отличаются в зависимости от флагов компилятора. При изменении/перекомпиляции одного исходного файла ar по-прежнему нужны все o-файлы для пересборки библиотеки. Чтобы избежать перекомпиляции всех исходных файлов, я хочу сохранить o-файлы из неизмененных исходных файлов в двух разных каталогах, один с o-файлами, включающими поддержку omp, другой без них. Я счастлив, что мне придется делать makefiles для этого в том каталоге, где в конечном итоге находятся библиотеки.

Однако я не могу перестроить библиотеку одной командой из-за поведения переменной vpath. Вот файл 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)

Это приводит к успешной сборке всех файлов %.o после "make clean", поскольку все файлы %.f90 считываются из src/, а все файлы %.o записываются в NoOMP/. Однако сборка архива завершается неудачей, поскольку префикс "NoOMP" в файлах %.o отбрасывается. Таким образом, ar жалуется, что не может найти файлы %.o. Архив собирается только если я снова запускаю "make", поскольку тогда файлы %.o имеют префикс NoOMP. Добавление команды префикса в строку сборки архива работает нормально, если он собирается с нуля. Однако, если изменился только один файл, неизмененные файлы имеют префикс "NoOMP/NoOMP/", что снова приводит к прерыванию.

Хотя это ужасно раздражает, насколько я понял руководство, это поведение GNU make по умолчанию. Если я не прав, как я могу исправить makefile, если я прав, как я могу обойти эту проблему.

решение1

Решено

примеры работают при изменении строки

    $(ARCH) $(ARCHFLAGS) $@ $?

к

    $(ARCH) $(ARCHFLAGS) $@ $(addprefix NoOMP/,$?)

Выше я исключил это решение, но мой эксперимент был основан на $^. $?В то время как первый перестроит весь архив из старых и новых %.o файлов, последний только обновит существующий архив новыми %.o файлами. При перестройке всего архива из старых и новых %.o файлов старые %.o файлы будут иметь неправильный префикс, новые — правильный. Таким образом, исключение старых %.o файлов путем обновления архива новыми %.o файлами обходит эту проблему.

Ваше здоровье

Связанный контент