Нужно гибкое определение целевых зависимостей в Makefile - PullRequest
0 голосов
/ 01 февраля 2019

Я хочу поместить две цели в Makefile, exec1 и exec2.Зависимости для exec1 должны выглядеть как

exec1: aux1.o bal.o exec1.f90
bal.o: aux1.o bal.f90

, а для exec2 как

exec2: aux2.o bal.o exec1.f90
bal.o: aux2.o bal.f90

Короче говоря: мне нужно make, чтобы понять, что bal.o имеет разныезависимости в зависимости от того, строится exec1 или exec2.Как я могу «объяснить» это в моем Makefile?

Проблема в том, что если я пытаюсь собрать exec2, обязательно, чтобы aux1.o не был собран.Причина в том, что aux1.f90 имеет несколько модулей с тем же именем, что и модули в aux2.f90, и если aux1.f90 сначала компилируется в aux1.o, то компиляция bal.f90 вместо этого получит свои модули из aux1.f90из aux2.f90, который действительно нужен, и возникнет массовая путаница.

Ответы [ 3 ]

0 голосов
/ 01 февраля 2019

Вы должны использовать отдельный Makefile и использовать целевой-зависимый Makefile ("рекурсивно").

Основной Makefile:

exec1 exec2:
    $(MAKE) -f Makefile.$@

И у вас есть Makefile.exec1:

exec1: aux1.o bal.o exec1.f90
    @echo "$^ => $@"

bal.o: aux1.o bal.f90
    @echo "$^ => $@"

И Makefile.exec2 тоже:

exec2: aux2.o bal.o exec1.f90
    @echo "$^ => $@"

bal.o: aux2.o bal.f90
    @echo "$^ => $@"

Тест (после touch aux2.o bal.f90):

$ gmake -s exec1
aux1.o bal.f90 => bal.o
aux1.o bal.o exec1.f90 => exec1
$ gmake -s exec2
aux2.o bal.f90 => bal.o
aux2.o bal.o exec1.f90 => exec2

(я использую FreeBSDи на нем GNU make равен gmake - предположим, что вы используете GNU make, а -s подавляет сообщения «debug»).

Надеюсь, идея ясна.

0 голосов
/ 01 февраля 2019

Чистое решение GNU make:

exec1: aux1.o bal.o exec1.f90

bal.o: $(if $(filter exec1,${MAKECMDGOALS}),aux1.o,aux2.o) bal.f90
# It will fail if someone will try building BOTH `exec1` and `exec2`
# If you care about this case, let's put some safeguards in:
ifeq ($words $(filter exec1 exec2,${MAKECMDGOALS}),2)
  $(error You cannot build exec1 and exec2 simultaneously)
endif
0 голосов
/ 01 февраля 2019

Команда make находит много интересных, неожиданных применений.У вас один.

Было бы неплохо, если бы вы могли отдельно собрать bal1.o и bal2.o, но я полагаю, что это не будет служить вашему делу, или вы вряд ли бы задали вопрос.

В вашей ситуации я бы попробовал следующее: построить bal1.o и bal2.o по отдельности, , хотя это (само по себе) не будет работать в вашем случае. Затем, с помощью команд сборки с отступом табуляциивременно создайте символическую ссылку с именем bal.o, которая указывает либо на bal1.o, либо на bal2.o.Как только ссылка выполнит свою функцию, удалите ее.

Например:

exec1: aux1.o bal1.o exec1.f90; rm -f aux2.o && ln -s bal1.o bal.o && command-to-build-exec1 && rm bal.o
bal1.o: aux1.o bal.f90
.PHONY: bal.o

(строка .PHONY наименее важна. Вы можете опустить ее, но если ваш makeэто GNU Make, тогда он сообщает GNU Make, что фактический файл bal.o не будет построен.)

Точка с запятой ; может быть заменена новой строкой, за которой следует горизонтальная табуляция, если хотите, но я делаюне знаю, как сделать переполнение стека правильно представить символ табуляции.Точка с запятой работает.

Конечно, вы замените command-to-build-exec1 любой командой в вашем конкретном случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...