2014-09-10 3 views
0

Рассмотрим следующий файл makefile. Я намерен называть его «make var = xxx» для нормального здания и «делать помощь» или «чистить» или «делать showVars» в другое время. Когда я делаю фактическую сборку, мне нужно убедиться, что переменная 'var' передается в командной строке, но я не требую ее для других целей, таких как clean. В настоящее время проверка сбрасывается в любое время, когда var не указывается, что является безопасным, но раздражающим и ненужным, когда вы просто чистите или обманываете. Как я могу запустить проверку только для моих целей сборки, а не в другое время?Условные проверки в make-файле

var= 

$(if $(var),,$(error var was not specified at commandline!)) 

var_RELEASE=`echo $(var) | sed -e 's/-/_/g'` 

.PHONY all showVars clean prep rpm 

all: prep rpm 

prep: 
# Do prep work. Requires valid var and var_RELEASE 

rpm: 
# Build rpm. Requires valid var_RELEASE 

help: 
# Does not require var and var_RELEASE 

showVars: 
# Display all vars. Requires valid var and var_RELEASE 

clean: 
# Does not require var and var_RELEASE 

UPDATE:

За предложение Максима ниже, используя $ (MAKECMDGOALS), чтобы проверить, какая цель была определена и игнорируя те, которые не требуют, чтобы вар быть установлено:

# Check if var is empty for prep and rpm targets, bail out if so. 
ifneq ($(MAKECMDGOALS),clean) 
ifneq ($(MAKECMDGOALS),help) 
ifneq ($(MAKECMDGOALS),showvars) 
$(if $(var),,$(error var was not specified at commandline! See 'make help')) 
endif 
endif 
endif 

Это работает, но это немного грубо ... возможно вообще упростить это?

+1

Вы можете использовать 'filter':' ifeq ($ (фильтр чистой помощи showvars, $ (MAKECMDGOALS))) '' а затем проверить var' и потерпеть неудачу, если не установлены. – MadScientist

ответ

3

Вы можете использовать MAKECMDGOALS, чтобы выяснить, какие цели были указаны в командной строке:

Марка установят специальные переменные MAKECMDGOALS в список целей, которые вы указали в командной строке. Если в командной строке не было задано никаких заданий, эта переменная пуста. Обратите внимание, что эту переменную следует использовать только в особых обстоятельствах.

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

+0

Проблема с этим: мне не нужны значения, установленные в make-файле (как «defaults»). Для некоторых целей пользователь должен указать значение, или процесс должен прекратиться (и было бы очень приятно - бонусные баллы), если бы я мог напечатать результаты моей целевой задачи «сделать помощь» в этом случае). Однако другие цели не нуждаются в ценности. – Jon

+0

Хммм, но эта переменная дает некоторую помощь ... см. Мою измененную запись с моей текущей реализацией. Не очень, но это работает. Благодаря! – Jon

2

Другим возможным решением может быть добавление фиктивной цели, которая проверяет переменную в рецепте:

var= 

var_RELEASE=`echo $(var) | sed -e 's/-/_/g'` 

.PHONY: all showVars clean prep rpm checkVar 

all: prep rpm checkVar 

prep: 
# Do prep work. Requires valid var and var_RELEASE 

rpm: 
# Build rpm. Requires valid var_RELEASE 

help: 
# Does not require var and var_RELEASE 

showVars: 
# Display all vars. Requires valid var and var_RELEASE 

clean: 
# Does not require var and var_RELEASE 

checkVar: 
    @if [ ! "$(var)" ]; then \ 
     echo "var was not specified"; \ 
     return 1; \ 
    fi 

all теперь зависит от checkVar цели, чей рецепт простой тест оболочки при $(var) расширяется к непустая строка. Если $(var) пусто, то рецепт вернет код возврата ненулевой, и сделать выдаст ошибку, с полезным сообщением:

$ make 
var was not specified 
make: *** [checkVar] Error 1 
$ make var=hello 
$ 
0

Я подозреваю, что вы также хотите следующую особенность. Только если значение VAR (позвольте мне изменить на верхний регистр, я как переменные таким образом) изменилось, вы хотели бы перестроить свои целевые объекты, которые этого требуют. Например, как будто VAR был файлом, но это не так, это переменная.

Я буду решать вашу проблему с помощью этой дополнительной функции.

В подобной ситуации я использую то, что я называю «надежными переменными». Обычно Make использует файлы в качестве предварительных условий. Мы можем взломать переменную, чтобы вести себя так.

Кроме того, вы получите именно такую ​​диагностическую жалобу, которую хотите, когда переменная не указана, или когда она указана, но пуста.

Причина для удвоения функций заключается в том, что таким образом пользователям удобнее пользоваться функцией DEPENDABLE_VAR, они ничего не должны знать о eval.

Здесь вы:

define DEPENDABLE_VAR_FUNCTION 

$(shell \ 
if [[ `cat $1 2>/dev/null` != '$($1)' ]]; then \ 
    echo -n $($1) > $1 ; \ 
    if [ ! -s $1 ]; then \ 
     rm $1 ; \ 
    fi; \ 
fi) 

endef 

define DEPENDABLE_VAR 
$(eval $(call DEPENDABLE_VAR_FUNCTION,$1)) 
endef 


# declare VAR to be dependable 
$(call DEPENDABLE_VAR,VAR) 

.PHONY: all clean 
all: rpm 

rpm: VAR 
    touch [email protected] 

clean: 
    rm -rf VAR rpm 
Смежные вопросы