Проверьте make зависимости через статическую библиотеку - PullRequest
0 голосов
/ 31 октября 2019

Я собираю несколько исполняемых файлов, используя make на Linux. Каждый исполняемый файл имеет свою собственную папку, собственный небольшой make-файл, который включает общий makefile.rules. Поэтому для создания проектов я вызываю каждый make-файл индивидуально с родительским make-файлом.

Примерно так:

# Find Makefiles
MKFLS += $(subst Makefile,,$(shell find */ -name Makefile ))

# Standard build rules, pass down to subordinate make files
all debug install: tags
    @$(foreach folder,$(MKFLS), $(MAKE) -C $(folder) $@ || exit;)

Я помещаю общий код в статическую библиотеку. У каждого также есть своя собственная папка и makefile. Я делаю зависимости при создании как исполняемых, так и статических библиотек для exe или lib с помощью:

$(CC) $(CFLAGS) -c -MMD -MP -o $@ $<

Затем включаю сгенерированные файлы (только для этого exe или lib):

-include $(OBJECTS:.o=.d)

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

Сначала каждый исполняемый файл make определяет статическую библиотеку и место ее создания:

# My Libraries
LOCALLIBS += $(UTILSLIB)/libone.a
LIBSRC += $(UTILSDIR)/onelib
LOCALLIBS += $(UTILSLIB)/libtwo.a
LIBSRC += $(UTILSDIR)/twolib

Затем в глобальномMakefile правил, который включен:

# Rules For Library Dependencies
# Include library dependencies if they exist
-include $(shell find $(LIBSRC) -name \*.d )

# Rule to make libraries that are part of this source tree
$(LOCALLIBS):
    $(foreach folder,$(LIBSRC), $(MAKE)-C $(folder) $(MAKECMDGOALS) || exit;)
    @touch $(LOCALLIBS)

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

Итак ... Есть ли способ исправить это? Какой правильный способ сделать это?

1 Ответ

0 голосов
/ 01 ноября 2019

Чтобы получить результат, который вы запрашиваете, вы должны предоставить Make обязательные списки для объектных файлов, библиотек и исполняемых файлов.

У вас уже есть метод для объектных файлов. Вы генерируете файлы списка зависимостей:

$(CC) $(CFLAGS) -c -MMD -MP -o $@ $<

и затем включаете их:

-include $(OBJECTS:.o=.d)

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

Этот подход будет не работать для библиотек. Он работает для объектных файлов, поскольку исходные файлы содержат списки заголовочных файлов (как директивы #include), а компилятор ($(CC)) знает, как преобразовать их в списки предварительных требований. У инструмента для создания библиотек ($(AR), или что вы используете) нет таких файлов для чтения и нет возможности создавать такие списки. Но не важно;для каждой библиотеки вы должны как-то указать список вещей, которые вы хотите в ней , , поэтому ваше правило библиотеки должно выглядеть примерно так:

libone.a: alpha.o beta.o
    $(AR) -cvq $@ $^.    # or whatever you use

Это заботится о библиотеках. Теперь исполняемые файлы. Предположим, у вас есть исполняемый файл prime, для которого требуется код из alpha и gamma. Правило будет выглядеть примерно так:

prime: gamma.o libone.a
    $(CXX) -o $@ $^.    # or whatever you use

Вот и все. Исполняемый файл prime не зависит от gamma.h;если вы измените gamma.h, Make заметит, что gamma.o устарел, и поэтому prime. И prime не зависит от alpha.h;если вы измените alpha.h, Make заметит, что alpha.o устарел, и поэтому libone.a, а значит, prime.

(Дальнейшие улучшения могут быть возможны, как только вызаставить это много работать.)

...