
Я пытаюсь собрать две разные библиотеки из исходного кода 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 файлами обходит эту проблему.
Ваше здоровье