2015-05-22 2 views
1

Мне нужно отложить включение фрагментов зависимостей до второго времени расширения, потому что файл make, который я редактирую, сам является включенным файлом, и у меня не будет списка исходных файлов для генерации включений до вторичного расширения.Gnu make: возможно ли отложить включение директивы для вторичного расширения?

.SECONDEXPANSION: 
AUTO_DEPENDENCY_FILES = $(patsubst %.cc, depend/%.d, $(CC_SRC_FILES)) 

# the following does the work because the include argument is not a rule 
# prerequisite therefore no secondary expansion occurs 
include $$(AUTO_DEPENDENCY_FILES) 

depend: 
    -mkdir depend 

all: autodepend 

autodepend: depend autodepend_include 

autodepend_include: $$(AUTO_DEPENDENCY_FILES) 
    @echo \"$^\" 

$$(AUTO_DEPENDENCY_FILES): depend 

depend/%.d: | %.cc 
    # generate .d files that do not exist 
    $(COMPILE.cc) -E $*.cc > /dev/null 

%.o: %.cc 
    # update .d files that exist 
    $(COMPILE.cc) -o [email protected] $< 

Обратите внимание на COMPILE.cc очень длинная строка, которая включает в себя -MP -MMD -MFdepend/$*.d флаги для генерации автоматической зависимости.

+0

Почему у вас нет списка до второго времени расширения? Вы учитываете перезагрузку, связанную со встроенными включенными файлами? –

+0

Проблема в том, что я не знаю имя файла _any_ include до конца первой фазы. – ThomasMcLeod

+0

Что заполняет 'CC_SRC_FILES'? Что генерирует файлы 'depend /%. D'? Что делает список доступным во время второго этапа, но не во время первого? –

ответ

1

Я не знаю, что есть чистое решение этой проблемы, но с небольшим взломом вы можете получить то, что хотите.

Учитывая основной Makefile из:

$(info main one) 

include depend.mk 

$(info main two) 

CC_SRC_FILES := $(addsuffix .c,a b c d e f) 

$(info main three) 

и depend.mk из:

$(info depend one) 

AUTO_DEPENDENCY_FILES = $(patsubst %.c,%.d,$(CC_SRC_FILES)) 
$(info AUTO_DEPENDENCY_FILES := $(AUTO_DEPENDENCY_FILES)) 
$(info MAKE_RESTARTS := $(MAKE_RESTARTS)) 
$(info CC_SRC_FILES := $(CC_SRC_FILES)) 

$(info depend two) 

вы получите следующий результат при запуске make:

main one 
depend one 
AUTO_DEPENDENCY_FILES := 
MAKE_RESTARTS := 
CC_SRC_FILES := 
depend two 
main two 
main three 
make: `all' is up to date. 

Который не удивительно, учитывая порядок присвоения и включения файлы и т.д.

Вот где ужасный хак приходит.

Когда сделайте встречает include директиву, которая ссылается на файл, который не существует сделайте прилипает файл в списке «отсутствует include файлы» и продолжает разбор make-файла.

Когда он попадает в конце Makefile (ов), он пытается рассматривать каждую запись в этом списке в качестве потенциальной цели цели 1 и пытается сделать файл.

Как только make-файлы были созданы, перезагрузите себя и повторите попытку.

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

Если мы depend.mk выглядеть следующим образом:

$(info depend one) 

include hack.mk 

AUTO_DEPENDENCY_FILES = $(patsubst %.c,%.d,$(CC_SRC_FILES)) 
$(info AUTO_DEPENDENCY_FILES := $(AUTO_DEPENDENCY_FILES)) 
$(info MAKE_RESTARTS := $(MAKE_RESTARTS)) 
$(info CC_SRC_FILES := $(CC_SRC_FILES)) 

$(info depend two) 

hack.mk: $(if $(MAKE_RESTARTS),,force) 
     @echo creating hack.mk 
     @echo 'CC_SRC_FILES := $(CC_SRC_FILES)' > '[email protected]' 

force: ; 

Тогда наш выход из make становится:

main one 
depend one 
depend.mk:3: hack.mk: No such file or directory 
AUTO_DEPENDENCY_FILES := 
MAKE_RESTARTS := 
CC_SRC_FILES := 
depend two 
main two 
main three 
creating hack.mk 
main one 
depend one 
AUTO_DEPENDENCY_FILES := a.d b.d c.d d.d e.d f.d 
MAKE_RESTARTS := 1 
CC_SRC_FILES := a.c b.c c.c d.c e.c f.c 
depend two 
main two 
main three 
make: `all' is up to date. 

Который дает нам значение, где мы хотим его.

Это не очень, но оно действительно работает.

Смежные вопросы