Makefile устанавливается, если переменная пуста

Я хочу установить переменную, если она пуста. Я попытался таким образом:

....
TEST := $(something)
...
TEST ?= $(something else)

Первый $(something) может возвращать пустую строку, однако условное присваивание? = работает только в том случае, если предыдущая переменная не задана, а не пустая.

Любое элегантное решение для установки переменной, если пустое?


ИЗМЕНИТЬ Я нашел это решение:

....
TEST := $(something)
...
TEST += $(something else)
TEST := $(word 1, $(TEST))

но я думаю, что будет еще один элегантный.

Ответ 1

Любое элегантное решение для установки переменной, если пустое?

GNU make вряд ли известен элегантными решениями. Если вы не найдёте изящные шторы и минные поля. Я знаю только два способа выполнить то, что вы хотите:

  • Стандартное решение ifeq/endif:

    ifeq ($(TEST),)
    TEST := $(something else)
    endif
    
  • Используйте функцию $(if):

    TEST := $(if $(TEST),$(TEST),$(something else))
    

    Можно попытаться также скомпоновать эту конструкцию в функцию, но это нецелесообразно. Функция имела бы скрытую ловушку, изредка разбивающую $(something else), если она содержит , (для которой есть только сворачивающиеся обходные пути). (Встроенные функции, такие как $(if), невосприимчивы к ошибке ,.)

Тест на элегантность зависит от вас.

Ответ 2

Из GNU make, глава 7.2, Синтаксис условных выражений:

"Часто вы хотите проверить, имеет ли переменная непустое значение. Когда значение является результатом сложного расширения переменных и функций, расширения, которые вы считаете пустыми, могут фактически содержать пробельные символы и, следовательно, не рассматриваться как пустые. Однако вы можете используйте функцию strip, чтобы избежать интерпретации пробела как непустого значения. Например:

ifeq ($(strip $(foo)),)
text-if-empty
endif

оценит text-if-empty, даже если расширение $ (foo) содержит пробельные символы. "

Ответ 3

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

TEST := $(or $(TEST),$(something else))

Ответ 4

В случае, если вам необходимо определить, является ли переменная неопределенной или просто имеет пустое значение, используйте функцию $ (origin VARNAME):

ifeq ($(origin VARNAME),undefined)
VARNAME := "now it finally defined"
endif

Обратите внимание, что VARNAME не окружен $() - вы буквально даете имя переменной.

Ответ 5

Согласно gnu make docs:

Если youd, как переменная, которая будет установлена в значение только в том случае, если она еще не установлена, вы можете использовать сокращенный оператор '? = Вместо' =

Ответ 6

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

Предположим, что в Makefile у нас есть следующее правило с check target, и нам нужно проверить, был ли передан var.

check:
    @[ "${var}" ] && echo "all good" || ( echo "var is not set"; exit 1 )

Чтобы проверить это, выполните следующие команды

$ make check 
  var is not set
  make: *** [check] Error 1  

$ make check var=test
  all good 

Итак, теперь мы можем передать значение переменной или значение по умолчанию, если оно не было передано bash-скрипту, который будет отвечать за выполнение логики. что-то вроде следующего:

@[ "${var}" ] && ./b.sh ${var} || ./b.sh 'ss'

Ниже b.sh может выглядеть b.sh, хотя вы можете добавить к нему больше логики.

#!/bin/sh
echo $1