Это связано с моим предыдущим вопросом: Почему .PHONY не работает в этой ситуации? .
У меня есть система make-файлов, которую я написал, чтобы облегчить ее разработчикам, которыене знакомы с make, чтобы делать свои задачи.Короче говоря, есть общая часть, которая будет одинаковой для всех проектов, и набор make-файлов, специфичных для данного проекта.Специфические проекты включают в себя общие.По какой-то причине он отлично работал на make 3.80, но когда я попробовал его на make 3.81, я столкнулся с несколькими проблемами.Это заставило меня внести изменения, которые упомянуты в посте выше.Теперь у меня возникли новые проблемы, поэтому я решил сделать еще один пост.Как и в этом посте, я сделал гораздо меньший и более простой набор make-файлов, которые показывают проблему.К сожалению, «простой» корпус состоит из 6 файлов.Извини за это.Сначала я начну с «конкретных проектов» (они должны быть простыми):
makefile:
TARGETS:=\
Lib1.mk \
Lib2.mk \
my_prog.mk \
include generic/top.mk
Lib1.mk:
BINARY:=Lib1
TYPE:=LIB
LOCATION:=a/location
include generic/rules.mk
Lib2.mk:
BINARY:=Lib2
TYPE:=LIB
LOCATION:=another/location
LIBS:=Lib1
include generic/rules.mk
my_prog.mk:
BINARY:=my_prog
TYPE:=EXE
LOCATION:=some/location
LIBS:=Lib1 Lib2
include generic/rules.mk
Краткое описание: Makefile просто перечисляет имена всех целей.Цель - это исполняемый файл или библиотека.BINARY - это имя библиотеки или исполняемого файла (расширения добавляются общей частью).ТИП - это EXE или LIB.LOCATION - это место, куда должен идти бинарный файл.LIBS - это библиотеки, от которых зависит этот двоичный файл.Реальные управляют созданием для пользователя всего материала -L, rpath и т. Д. (А также их эквивалентов для визуальной студии).Теперь для общих (они выполняют РЕАЛЬНУЮ работу):
generic / top.mk:
ALL_BINS:=
.PHONY: all
all:
include $(TARGETS)
all: $(ALL_BINS)
%.so %.exe:
mkdir -p $(dir $@)
touch $@
clean:
rm -rf out
и наконец ..
generic / rules.mk:
ifeq (EXE,$(TYPE))
$(BINARY).FULL_FILE_NAME:=out/$(LOCATION)/$(BINARY).exe
else
$(BINARY).FULL_FILE_NAME:=out/$(LOCATION)/lib$(BINARY).so
endif
$(BINARY).DEP_LIBS:=$(foreach a,$(LIBS),$($(a).FULL_FILE_NAME))
ALL_BINS+=$(BINARY)
$(BINARY): $($(BINARY).FULL_FILE_NAME)
$($(BINARY).FULL_FILE_NAME): $($(BINARY).DEP_LIBS)
BINARY:=
LOCATION:=
LIBS:=
Хорошо, в этом состоянии все работает нормально.Make корректно обрабатывает все зависимости, и если я коснусь любого из файлов, он будет корректно «строить» только те, которые ему нужны, и ничего более.Проблема возникает, когда вы берете строку m_prog.mk из makefile и перемещаете ее в верхнюю часть списка, например:
TARGETS:=\
my_prog.mk \
Lib1.mk \
Lib2.mk \
Кажется, что проблема в том, что онаПроходя через rules.mk для my_prog.mk , он еще не знает, каков полный путь к библиотеке для Lib1 и Lib2 (они являются пустыми строками).В конце концов, он считает, что my_prog ни от чего не зависит, и пытается построить его не по порядку.В этом примере вы просто видите, что он сначала «касается» my_prog, а затем других 2. Конечно, когда у меня есть настоящие команды компилятора и компоновщика, он выдает ошибку.
Назад, когда я просто имелЦели .PHONY зависят друг от друга (поэтому my_prog зависит от Lib1 и Lib2), жизнь была легкой и гармоничной.Теперь, когда я не могу этого сделать, жизнь стала более трудной.
Вы можете сказать: «Черт, просто приведите это в правильный порядок!».До сих пор это было обработано автоматически через make для конечных пользователей.Фактически, большинство клиентов размещают вещи в алфавитном порядке.Они не знают или не заботятся о том, в каком порядке они зависят друг от друга.Было бы ужасно сказать им, чтобы переупорядочить все это сейчас.Извините за длину этого поста.Буду признателен за любые ответы!