2010-06-23 2 views
4

Я использую Make и у меня есть make-файл, который устанавливает переменную со значением, которое мне нужно переопределить из родительского make-файла. Я попытался установить переменную в родительском make-файле и использовать export, чтобы передать ее в подмакету, но переменная не использует переданное значение, вместо этого оно использует значение, явно заданное в под-Makefile.Переопределение подменю назначенных переменных в родительском make-файле

Я знаю, что переменные, указанные в командной строке, переопределяют любые обычные назначения в make-файле (если не используется override), но есть ли способ достичь этого для подземелий без необходимости указывать его в командной строке для каждого вызова (потому что их довольно много, и мне нравится оставаться СУХОЙ)?

UPDATE

Я должен отметить, что я не могу изменить файл submake, потому что это из внешнего хранилища, которую мы отслеживаем и не имеют права изменять его, поэтому мне нужно работать родительский уровень makefile, чтобы повлиять на подделку.

Пример

Вот представитель цель в родительском Makefile, который звонит в submake:

$.PHONY (external_lib) 
$(external_lib): 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_a 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_b 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_c 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_d 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_e 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_f 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_g 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_h 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) make_i 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) library 
+0

1) Вы готовы изменить файл подкачки? 2) указание переменной в командных строках может быть DRYER, чем вы думаете, можете ли вы дать нам образец родительского файла с несколькими командами MAKE? – Beta

ответ

4

(Похоже, что Вы используете что-то другое, чем GNUMake, который является единственным Make я знаю, так возьмите это с зерном соли.)

Сначала вы можете сделать свой Makefile опрятнее, делая компоненты отдельных целей :

COMPONENTS = make_a make_b make_c make_d make_e make_f make_g make_h make_i \ 
     library 

.PHONY: external_lib $(COMPONENTS) 
$(external_lib): $(COMPONENTS) 

$(COMPONENTS): 
    @$(MAKE) -s -C $(source_dir)/project/component $(PROJECTVARS) [email protected] 

(. Если вы беспокоитесь о столкновении имен, есть простые способы борьбы с этим)

Теперь, если вы хотите, чтобы переопределить переменную с именем, скажем, VAR, вы можете это сделать все в одном месте:

COMPONENTS = make_a make_b make_c make_d make_e make_f make_g make_h make_i \ 
     library 

.PHONY: external_lib $(COMPONENTS) 
$(external_lib): $(COMPONENTS) 

$(COMPONENTS): 
    @$(MAKE) -s -C $(source_dir)/project/component $(PROJECTVARS) VAR=$(VAR) [email protected] 

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

COMPONENTS = make_a make_b make_c make_d make_e make_f make_g make_h make_i \ 
     library 

.PHONY: external_lib $(COMPONENTS) 
$(external_lib): $(COMPONENTS) 

VARNAME = VAR 
$(COMPONENTS): 
    @$(MAKE) -s -C $(source_dir)/project/component $(PROJECTVARS) \ 
$(VARNAME)=$($(VARNAME)) [email protected] 

make_c: VARNAME=OtherVar 
make_h: VARNAME=YetAnotherVar 

Если вы хотите переопределить несколько переменных для некоторых целей, это немного сложнее ...

+0

Целевые значения переменных - это расширение GNU, я считаю. – JesperE

0

Раздел 5.7.2 из make.info (гну сделать это):

The special variable `MAKEFLAGS` is always exported. ... 

Variables are _not_ normally passed down if they were created by 
default by `make` (Implicit Rules) 

if you want to export specific variables to sub-`make`, use the 
`export` directive. 

    export VARIABLE ... 

Итак, моя рекомендация - либо использовать переменную MAKEFLAGS, либо явно export, которую вы хотите использовать.

+0

Спасибо John, но, как я уже упоминал в своем вопросе, я попытался использовать экспорт, но потому, что sub-makefile явно назначает эту переменную, он не использует экспортированное значение, которое передается. – TheJuice

0

Вам нужно будет проверить, имеет ли переменная уже значение, прежде чем назначать его в суб-макете.

С GNU Make вручную (http://www.gnu.org/software/make/manual/make.html) Раздел 6.5:

Если вы хотите переменной быть установлено значение, только если он еще не установлен, то вы можете использовать оператор сокращенную ?=' instead of =». Эти две настройки переменной `Foo» идентичны (см происхождение функции):

FOO ?= bar 

и

ifeq ($(origin FOO), undefined) 
FOO = bar 
endif 
1

Если вы не хотите, чтобы ваш суб-Makefile, чтобы переопределить значение, установленное родительский, имеет под-makefile присваивать значение с помощью синтаксиса VARIABLE ?= value. Это будет выполнять только назначение, если переменная еще не определена. В вашем случае переменная будет определена в родительском make-файле, поэтому присваивание не будет выполнено.

Обновление: Если вы не можете изменить суб-файл, то у вас нет большого количества опций. Я бы, вероятно, рекомендовал установить переменную в командной строке при вызове файла суб-файла. Для ясности оберните эти определения в переменную make. Например,

CUSTOM_DEFINITIONS := VAR1=value1 VAR2=value2 VAR3=value3 
$(external_lib): 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) $(CUSTOM_DEFINITIONS) make_a 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) $(CUSTOM_DEFINITIONS) make_b 
    $(MAKE) -C $(source_dir)/project/component $(PROJECTVARS) $(CUSTOM_DEFINITIONS) make_c 

Это не самое подходящее решение, но это можно сделать из родительского make-файла.

+0

К сожалению, я не могу внести (постоянные) изменения в файл подкачки. – TheJuice

1

Помимо использования Экспорт который не всегда рекомендуется, вы можете передать переменные в суб-сделать файлы, как это -

**HOSTCC = gcc** 
CC= MIPS-GCC 
FLAGS = -O2 -Wall -DSELECT_PROBLEM 
M="CC=$(CC) $(FLAGS)" 

все:

cd ../rng ; $(MAKE) $(M) **HOSTCC=$(HOSTCC)** ; 

, так что если ваш файл суб-файла имеет по 2 файла, каждый из них требует различной инструментальной цепочки компиляции, вы можете делать то, что показано выше.

+0

Спасибо, Роберт за форматирование. –

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