2016-01-31 4 views
0

Видимо нет булева типа в GNU Make не условный, так это казалось лучшим решением:Переменная в make-файле условна?

$(DEF_TARGET): 
     if [ "$(CHECK)" != "y" ]; then \ 
       var=foo; \ 
       $(if $(filter foo,$(var)),result=true,result=false); \ 
     fi 

Проблема заключается в том, что независимо от того, если var=foo или var=bar, result всегда будет false. Замена $(var) с foo или bar приведет к правильному результату.

Почему это не работает? Есть ли лучшее решение проблемы?

Edit:

После Makefile запускается с помощью команды make -f make.txt

.PHONY: all 
all: 
     X=aaa; \ 
     Y=aaa; \ 
     if [[ '$(filter $(X),$(Y))' ]]; then echo "matched!"; else echo "not matched!"; fi 

выход:

X=aaa; \ 
Y=aaa; \ 
if [[ '' ]]; then echo "matched!"; else echo "not matched!"; fi 
not matched! 

Почему терпят неудачу, когда X и Y присваиваются значения в мишени рецепт?

+0

'[" CHECK "! =" Y "]' (условная часть оболочки, часть целевого рецепта) сравнивает буквенную строку '' CHECK "' с литеральной строкой '' y "' и всегда будет оценивать true , Какую логику нужно строить? – bobah

+0

К сожалению, это была ошибка ввода. Я хочу создать операцию 'OR', чтобы я мог проверять несколько слов в' $ (var) 'и иметь' result = true', если совпадение найдено. В этом примере я просто проверяю 'foo', пока не получу его для работы. –

+0

@PeterSmith причина, по которой у вас возникают проблемы, заключается в том, что вы пытаетесь сделать с рецептом make-файла, что они не предназначены для выполнения. То, что вы хотите, лучше всего делать за пределами рецепта или, возможно, даже без Make, просто с помощью сценария оболочки. –

ответ

0

Makefile

.PHONY: all 
all: 
     @echo "$(filter $(X),$(Y))" 

Тесты

$ make -f make.txt X='xxx yyy' Y='aaa bbb' 

$ make -f make.txt X='xxx yyy' Y='aaa xxx' 
xxx 
$ make -f make.txt X='bbb yyy' Y='aaa bbb' 
bbb 

GNU Bash обрабатывает непустой строки как true в логическом контексте. Поэтому рецепт с оболочкой состоянием уровня может быть:

all: 
     if [[ '$(filter $(X),$(Y))' ]]; then echo "matched!"; else echo "not matched!"; fi 
+0

Ваш пример отлично работает, когда «X» и «Y» присваиваются значения в командной строке, но когда я пытаюсь назначить их в целевом рецепте, он терпит неудачу. Я обновил вопрос на примере. Вы знаете, что я делаю неправильно? –

+0

Рецепт полностью оценивается make-файлом перед передачей ему элемента управления. Вы можете использовать макрос '$ (shell ...)' для получения вывода команды оболочки. – bobah

2

Видимо нет булева типа в GNU Сделайте условные

Ясно there is, еще присутствие $(if ...) макроса не имеет смысла!

Способ чтения рецептов (то есть, блок команд оболочки, которые строят цель) , чтобы понять, что делает хранит рецепт в виде одного рекурсивно расширенной переменной. Рецепт расширяется только тогда, когда сделать необходимо передать некоторые команды оболочке.

Рецепт разворачивается один раз в полном объеме. Каждая строка результирующего расширения затем выполняется один за другим. Каждое исполнение выполняется в экземпляре экземпляра оболочки.

Так, принимая оригинал Makefile, давайте предположим, что вы попросили сделать построить ${DEF_TARGET}. Сделать расширяет рецепт:

if [ "$(CHECK)" != "y" ]; then \ 
      var=foo; \ 
      $(if $(filter foo,$(var)),result=true,result=false); \ 
    fi 
  • ${CHECK} не станет ничего (скажем)
  • $(if $(filter foo,$(var)),result=true,result=false)

    • Во-первых, ${var} расширяется и становится пустой (скажем) , Обратите внимание, что строка var=foo в рецепте: не интерпретировано make! Это команда оболочки.
    • Далее, $(filter foo,) расширен и также пуст.
    • изготовитель разворачивает $(if ,result=true,result=false), что дает result=false конечно.

      if [ "" != "y" ]; then \ 
          var=foo; \ 
          result=false; \ 
      fi 
      

      Сделать видит это как только одной линии связи с обратными косыми чертами.

Так, не перепутать переменные оболочки и сделать переменные. Все составляют переменные исчезают к тому времени, когда оболочка получает свои рецепты. ничего не знает о переменных оболочки.

Ваш оригинальный оболочки фрагмент может быть что-то вроде: (применяется TIMTOWTDI)

result=$(if $(filter y,${CHECK}),true,false) 

. Оболочка получает result=true или result=false в зависимости от величины переменная CHECK.

+0

Заключение: Я пытаюсь что-то сделать с помощью инструмента, который я недостаточно понимаю. Я попытаюсь исправить это сейчас. –

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