Я хочу, чтобы мой make-файл был более независимым от порядка! - PullRequest
1 голос
/ 27 января 2011

Это связано с моим предыдущим вопросом: Почему .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 для конечных пользователей.Фактически, большинство клиентов размещают вещи в алфавитном порядке.Они не знают или не заботятся о том, в каком порядке они зависят друг от друга.Было бы ужасно сказать им, чтобы переупорядочить все это сейчас.Извините за длину этого поста.Буду признателен за любые ответы!

Ответы [ 2 ]

1 голос
/ 27 января 2011

Если вы устанавливаете переменные с помощью оператора присваивания: =, присваивание оценивается немедленно.

Если вы устанавливаете переменные, используя просто = в качестве оператора присваивания, они оцениваются лениво, как можно позже (во время фактического использования).

См. http://www.gnu.org/software/automake/manual/make/Flavors.html.

0 голосов
/ 28 января 2011

Есть несколько способов сделать то, что вы хотите. Самым чистым, вероятно, является использование vpath. Просто измените rules.mk:

$(BINARY).DEP_LIBS:=$(foreach a,$(LIBS),$(a).so)
ALL_BINS+=$(BINARY)

vpath %.so out/$(LOCATION)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...