Gnu сделать авто-зависимость генерации - PullRequest
0 голосов
/ 04 июля 2018

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

SRCS := $(wildcard *.cpp */*.cpp)

DEPDIR := .d
DEPS := $(SRCS:%.cpp=$(DEPDIR)/%.d)

# Temporary .Td dependence file... ?
DEPFLAGS = -MT $@ -MD -MP -MF $(DEPDIR)/$*.Td

# Isn't it better a order-only prerequisite?
$(shell mkdir -p $(dir $(DEPS)) >/dev/null)

%.o: %.cpp # Removal of implicit rules... ? Twice?
%.o: %.cpp $(DEPDIR)/%.d  # Dependency on .d... ?
        g++ -o $@ $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c $<
        # Avoid some bugs?
        mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $@

# If the `%.d` dependency is removed, is this still necessary?
.PRECIOUS = $(DEPDIR)/%.d
$(DEPDIR)/%.d: ;

-include $(DEPS)

Чтобы не делать этот вопрос слишком долгим, чтобы глубоко обсудить, почему я считаю, что все строки, прокомментированные во фрагменте выше, являются ненужными, я задам его в краткой форме; есть ли разница в поведении, если я просто изменю этот фрагмент на:

SRCS := $(wildcard *.cpp */*.cpp)
DEPDIR := .d
DEPS := $(SRCS:%.cpp=$(DEPDIR)/%.d)

DEPFLAGS := -MT $@ -MD -MP -MF $(DEPDIR)/$*.d

$(DEPDIR)/%:
        mkdir -p $@

%.o: %.cpp | $(DEPDIR)/$(dir %)
        g++ -o $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c $<
        # touch $(DEPDIR)/$.d # ??

-include $(DEPS)

У меня есть еще два дополнительных сомнения; в первой ссылке выше сказано, что

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

Однако в gist (вторая ссылка выше) команда touch удалена, и, поскольку файл зависимостей больше не является обязательным условием какого-либо правила, есть ли основания продолжать его включать? Применима ли эта «ошибка gcc» в любой форме?

Второе сомнение связано с созданием каталога, перенесенного в правило только для заказа; мне нужно сделать правило "только для заказа" $(DEPDIR)/% правило .PRECIOUS? Я не знаю, попытается ли make удалить каталог, если рецепт %.o не удастся, потому что я не знаю конкретных особенностей правил только для заказа.

1 Ответ

0 голосов
/ 04 июля 2018

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

Я не знаю, что вы подразумеваете под своим комментарием Удаление неявных правил ...? Дважды . Необходимо удалить неявное правило, чтобы гарантировать использование нашего нового неявного правила, и мы удаляем его только один раз.

Временный файл .Td используется в случае, если кто-то использует ^ C или аналогичный файл, чтобы уничтожить свою работу прямо в середине создания этого файла. Записывая во временный файл, затем только атомарно заменяя реальный файл, как только мы узнаем, что он завершен, нам никогда не придется беспокоиться о частичных файлах, которые могут вызвать следующий вызов make, чтобы вызвать ошибку или, что еще хуже, не перекомпилировать исходные файлы, которые должны быть перекомпилировать.

Что касается комментария об объектных файлах, более старых, чем файл зависимостей, то сначала суть, на которую вы ссылаетесь, использует clang, а не GCC, и, возможно, у Clang нет этой проблемы (или, возможно, она есть, но люди не осознают этого). Во-вторых, это обновление в блоге является относительно недавним, так как люди сообщали мне об этой проблеме в GCC. Я сам этого не видел (я использую только GCC), поэтому, возможно, это проблема только с некоторыми версиями GCC.

Относительно .PRECIOUS, make никогда (в настоящее время) рекурсивно не удаляет каталоги, поэтому он не будет удалять непустые каталоги независимо от этого параметра.

...