Makefile компилирует библиотеку в другом каталоге, когда она не существует или каталог был изменен - PullRequest
0 голосов
/ 29 июня 2018

Привет, у меня есть make-файл, который компилирует мою библиотеку, а затем компилирует программу. То, что я хочу сделать, это то, что make-файл перекомпилируется всегда, я изменяю файлы моей библиотеки для этого, я думал в этом

ifneq ("$(wildcard $(PATH_LIB.A)","")
FILE_EXIST = 1
else
FILE_EXIST = 0
endif

$(MAIN_PROCESS): $(PATH_LIB.A) check_lib
...thing to do...

$(PATH_LIB.a):
FILE_EXIST = 0

check_lib:
ifeq("$(FILE_EXIST)","0")
    $(MAKE) -C $(PATH_MAKEFILE_LIB.A)
endif

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

1 Ответ

0 голосов
/ 29 июня 2018

Make не является языком сценариев, как bash или python. Для этого нужно описание взаимозависимостей между целями и предпосылками, а также рецепты для их построения. В вашем случае (но я не уверен, что понял все детали) вы можете попробовать:

$(MAIN_PROCESS): $(PATH_LIB.A)
    ...thing to do...

$(PATH_LIB.A):
    $(MAKE) -C $(PATH_MAKEFILE_LIB.A)

И это все (но продолжайте читать, это еще не все понятно). Это говорит сделать это:

  1. $(MAIN_PROCESS) зависит от $(PATH_LIB.A), плюс то, что нужно сделать, чтобы построить $(MAIN_PROCESS), если он не существует или если он старше $(PATH_LIB.A).
  2. $(PATH_LIB.A) не зависит ни от чего, плюс что делать, если его не существует.

Это почти работает. Почти только потому, что если $(PATH_LIB.A) уже существует, но устарел (в отношении своих собственных исходных файлов), он не будет перестроен. Решение состоит в том, чтобы объявить его как phony :

.PHONY: $(PATH_LIB.A)

$(MAIN_PROCESS): $(PATH_LIB.A)
    ...thing to do...

$(PATH_LIB.A):
    $(MAKE) -C $(PATH_MAKEFILE_LIB.A)

Таким образом, make всегда будет пытаться восстановить его, даже если он уже существует. Подзадача сделает это при необходимости, иначе она просто скажет вам, что она была обновлена. Но это еще не все: поскольку make всегда пытается перестроить $(PATH_LIB.A), он будет считать, что $(MAIN_PROCESS) также необходимо перестроить, даже если субмарина ничего не делала, потому что $(PATH_LIB.A) была до дата.

Если это проблема, могут быть использованы более хитрые решения, например, использование еще одной подзадачи. Идея заключается в следующем:

  1. Используйте условные выражения make для создания двух разных контекстов вызова с двумя разными правилами для вашей цели $(MAIN_PROCESS).
  2. При первом вызове make используется первый контекст, где $(MAIN_PROCESS) зависит от phony $(PATH_LIB.A), но его рецепт вместо ...thing to do... является вторым вызовом make в другой контекст.
  3. Для этого второго вызова $(MAIN_PROCESS) зависит от non-phony $(PATH_LIB.A) и будет иметь свой обычный рецепт.

Два контекста различаются благодаря специальной переменной make (SECONDPASS в приведенном ниже коде).

Пример: * +1051 *

host> cat lib/Makefile
foo.a: foo.c
    touch $@

host> cat Makefile
ifeq ($(SECONDPASS),)
$(MAIN_PROCESS): $(PATH_LIB.A)
    $(MAKE) SECONDPASS=1

.PHONY: $(PATH_LIB.A)

$(PATH_LIB.A):
    $(MAKE) -C $(dir $@)
else
$(MAIN_PROCESS): $(PATH_LIB.A)
    touch $@
endif

host> make --no-print-directory
make -C lib/
touch foo.a
make SECONDPASS=1
touch bar

host> make --no-print-directory
make[1]: 'foo.a' is up to date.
make SECONDPASS=1
make[1]: 'bar' is up to date.

host> touch lib/foo.c

host> make --no-print-directory
make -C lib/
touch foo.a
make SECONDPASS=1
touch bar

host> touch lib/foo.a

host> make --no-print-directory
make -C lib/
make[1]: 'foo.a' is up to date.
make SECONDPASS=1
touch bar
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...