Переопределение вложенных назначенных переменных в родительском make-файле - PullRequest
5 голосов
/ 23 июня 2010

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

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

UPDATE

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

Пример

Вот репрезентативная цель в родительском make-файле, который вызывает 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

Ответы [ 5 ]

5 голосов
/ 24 июня 2010

(Вы, кажется, используете что-то другое, кроме 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) $@

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

Теперь, если вы хотите переопределить переменную, скажем, 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) $@

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

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)) $@

make_c: VARNAME=OtherVar
make_h: VARNAME=YetAnotherVar

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

1 голос
/ 09 мая 2012

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

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

all:

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

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

1 голос
/ 23 июня 2010

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

Обновление: Если вы не можете изменить подфайл-файл, тогда вы не сможетене так много вариантовВозможно, я бы порекомендовал установить переменную в командной строке, когда вы вызываете файл sub-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 голосов
/ 23 июня 2010

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

Из руководства по 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
0 голосов
/ 23 июня 2010

Раздел 5.7.2 make.info (это gnu make):

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 переменную, которую вы хотите использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...