Отладка рекурсивных makefile с переопределенными аргументами

Вопрос или проблема

Я пытаюсь понять следующую рекурсивную цель и почему она реализована таким образом:

Makefile верхнего уровня и цель:

collect:
    file_list="file_list.txt"
    for makefile in $(ALL_PROJECTS) ; do \
        $(MAKE) -s -f $$(basename $$makefile) --directory=$$(dirname $$makefile) GetDependenciesFile RELATIVE_DIR="$$(dirname $$makefile)" DEPENDENCIES_FILE="file_list"; \
    done;

Makefile, который содержит рекурсивную цель, которую я пытаюсь понять:

.PHONY: GetDependenciesFile
$(if $(filter GetDependenciesFile, $(.OVERRIDEN)),OVERRIDEN,) GetDependenciesFile: DependenciesFile.tmp
ifeq ("$(DEPENDENCIES_FILE)","")
    echo "DEPENDENCIES_FILE не указан"
else
    cat DependenciesFile.tmp >> $(DEPENDENCIES_FILE)
endif


DependenciesFile.tmp:
    echo "$(ALL_DEPENDENCIES)" >> DependenciesFile.tmp

Это упрощенная версия того, с чем я имею дело (я удалил sed и другие очевидные шаги, такие как сортировка и удаление дубликатов).

Я понимаю, что цель состоит в том, чтобы пройтись по всем makefile, содержащимся в $(ALL_PROJECTS), и в каждом makefile добавить содержимое переменной $(ALL_DEPENDENCIES) в DependenciesFile.tmp, а затем содержимое которого добавляется в $(DEPENDENCIES_FILE), которое является file_list.txt из верхнего уровня.

Что я не понимаю, так это эта конкретная строка:

$(if $(filter GetDependenciesFile, $(.OVERRIDEN)),OVERRIDEN,) GetDependenciesFile: DependenciesFile.tmp

Я пытался найти OVERRIDEN в makefile, но ничего не нашел. Я не понимаю, что происходит, когда оценивается результат if и почему это ставится перед именем цели.

Есть ли у вас предложения?

Ответ или решение

Вопрос касается понимания конструкции в рекурсивном Makefile и, в частности, использования конструкции $(if $(filter GetDependenciesFile, $(.OVERRIDEN)),OVERRIDEN,) GetDependenciesFile: DependenciesFile.tmp. Давайте подробно разберем, что здесь происходит.

Общий контекст

Рекурсивный Makefile выполняет несколько уровней сборки, организуя зависимость и обработку файлов для каждого из проектов, перечисленных в $(ALL_PROJECTS). Цель состоит в том, чтобы собрать все зависимости для каждого проекта и записать их в общий файл file_list.txt.

Конструкция

В строке $(if $(filter GetDependenciesFile, $(.OVERRIDEN)),OVERRIDEN,) GetDependenciesFile: DependenciesFile.tmp используется условная конструкция. Давайте раскроем её по частям:

  • $(filter GetDependenciesFile, $(.OVERRIDEN)): Эта часть проверяет, содержит ли переменная .OVERRIDEN целевой объект GetDependenciesFile. Переменная .OVERRIDEN используется в GNU Make для отслеживания переопределенных цели. Если цель переопределена, $(filter) вернет значение GetDependenciesFile, в противном случае — пустую строку.

  • $(if ... , OVERRIDEN,): Конструкция $(if ...) проверяет первый аргумент (в данном случае результат $(filter ...)). Если он не пуст (то есть цель GetDependenciesFile переопределена), то в качестве результата будет вернено слово OVERRIDEN. Если же он пуст, результат будет пустой строкой.

  • Вся конструкция $(if ... , OVERRIDEN,) GetDependenciesFile: DependenciesFile.tmp фактически генерирует правило для цели GetDependenciesFile, которое может быть либо просто GetDependenciesFile: DependenciesFile.tmp (если цель не переопределена), либо OVERRIDEN GetDependenciesFile: DependenciesFile.tmp (если она переопределена).

Зачем это нужно

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

Если следить за тем, какие цели были переопределены, можно избежать проблем, связанных с конфликтующими определениями и неправильной обработкой зависимостей.

Резюме

Таким образом, строка $(if $(filter GetDependenciesFile, $(.OVERRIDEN)),OVERRIDEN,) GetDependenciesFile: DependenciesFile.tmp позволяет создать правило для получения файла зависимостей, которое учитывает состояние переопределения цели. Если цель переопределена, к ней добавляется префикс OVERRIDEN, что может указывать другим частям системы сборки, что целью управляют особые условия.

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

Если есть дополнительные вопросы по этому вопросу, или если нужны дальнейшие пояснения, пожалуйста, дайте знать!

Оцените материал
Добавить комментарий

Капча загружается...