Есть ли способ автоматически сгенерировать дерево зависимостей в Makefile?

#python #c #makefile #compilation

#python #c #makefile #Сборник

Вопрос:

Абстрактный вопрос: Я программирую программу среднего размера на C / C с высокой степенью модульности. Он имеет общий интерфейс, который позволяет вам загружать несколько разных источников с одинаковыми объявлениями функций, но разными реализациями и получать исполняемые файлы с разными функциональными возможностями.

Я разрабатываю систему make, которая может выполнять обязанности по сборке. В настоящее время он способен извлекать специализированные источники на основе содержимого файла конфигурации (для процесса make) и сбрасывать их во временную папку с соответствующими общими именами. Теперь мне нужно только скомпилировать проект.

Проблема в том, что у меня переменное количество источников, и заголовки, от которых зависят источники, могут меняться в зависимости от отдельных реализаций. Другими словами, статический makefile не справится с задачей.

‘1.’ Используя только систему Makefile, есть ли какой-нибудь способ автоматически сгенерировать список объектов (.o) файлов, которые Main.cpp требуется компиляция?

Я знаю, что мог бы сделать это, написав небольшой скрипт на python, который вызывает мой makefile, который впоследствии создает пользовательский makefile, анализируя c-файлы, проверяя их зависимости, начиная с базового Main.cpp файл.

Но я не хотел обращаться к этому хакерскому решению, если было более стандартизированное решение или какой-то способ сделать это в make.

‘2.’
Если система makefile не способна на это, должен ли я продолжить с моим пользовательским скриптом python или есть более элегантное решение?

……………

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

Мне нужен какой-то способ автоматического создания этого дерева, основанный на содержимом моих C-файлов.

Прошу прощения, если это «глупый» вопрос, я относительно новичок в мире make — и, как большинство, я самоучка.

Спасибо!

Не стесняйтесь задавать любые вопросы.

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

Комментарии:

1. Есть ли какая-нибудь хорошая команда оболочки, которую вы можете использовать для поиска источников?

2. Для генерации списка объектов достаточно ли сканировать временную папку? То есть, содержит ли временная папка все исходные файлы, которые должны быть скомпилированы, и никакие другие (не говоря уже о заголовках на данный момент).

Ответ №1:

Да, если вы используете GCC! Вот часть Makefile, которая есть у меня в текущем проекте (для всех реальных применений я размещу это в открытом доступе, получайте удовольствие).

 CC=$(CROSS)gcc -c -g -Wall -Werror -ansi -pedantic $(DEFINES) -I./include

%.o: %.c .d/%.d
    # Your build code here

.d/%.d: %.c
    @$(CC) -MM $< -MF $@

-include $(OBJECTS:%.o=.d/%.d)
-include $(LOBJECTS:%.o=.d/%.d)
  

Если я что-то пропустил, дайте мне знать, и я снова проверю свой Makefile.

Обратите внимание, что $ (OBJECTS) — это список объектов, которые я хочу видеть в своем двоичном файле, а $ (LOBJECTS) — это список объектов, который компилируется в статический архив. $ (OBJECTS) и $ (LIB) (которые создаются с помощью $ (LOBJECTS), затем компилируются в конечный исполняемый файл. Итак, все это работает в нескольких сборках объектов разных типов с последующим связыванием и т.д.

О да, убедитесь, что вы mkdir .d , иначе, вероятно, произойдет сбой. Вы захотите проверить пустой .d каталог в вашем управлении версиями.

Единственное предостережение здесь в том, что вы должны указать источники. Однако, если вы хотите, вы могли бы настроить какой-нибудь небольшой инструмент для использования find , чтобы найти все ваши исходники для вас.

Наконец, это, вероятно, можно исправить, чтобы сделать его более эффективным и более читаемым, используя несколько целевых объектов ( %.o .d/%d ); мне придется изучить это. Спасибо, что напомнили мне.

Ответ №2:

Один из способов упростить сборку — пропустить зависимости. Просто перекомпилируйте все каждый раз. Только если сборку приходится выполнять много раз или это занимает «много времени», определение которого зависит от использования, и зависимости сильно меняются, имеет ли смысл выполнять подробную сборку зависимостей.

Комментарии:

1. Нет. Это не очень хороший ответ и абсолютно нелепый. Настройка зависимостей занимает 1 минуту! Зачем тратить время на перекомпиляцию всего каждый раз?

2. @mathepic: в большинстве моих недавних проектов время на компиляцию всего составляет от одной до пяти секунд. Это действительно стоит проблемы с обслуживанием?

3. @wallyk Если вам приходится компилировать более 12 раз, поскольку настройка занимает всего минуту (а вы обычно это делаете), то да.

4. @mathepic: Если сборка, полностью ориентированная на зависимость, всегда создает все, то при использовании более сложного makefile выигрыш равен нулю.

5. @wallyk С каких пор сборки на основе зависимостей создают все? Весь смысл в том, что они этого не делают.