2016-05-19 5 views
0

Предположит следующее Makefile (см here, что это хорошо для):Проверка, существует ли переменная установлена ​​вышестоящего

target-1-raw: 
    target-1-body 
target-2-raw: 
    target-2-body 
target-3-raw: 
    target-3-body 

%-raw: 
    echo "Error: Target [email protected] does not exist!"  
%: 
    @$(MAKE) [email protected] 3>&2 2>&1 1>&3 

Я пытаюсь, чтобы убедиться, что пользователь вызывается без суффикса -raw, т.е. как это:

make target-1 

и не так:

make target-1-raw 

Итак, я хотел бы установить переменные в правиле цели % и проверить от всех других целей, которые это переменное было установлено:

check: 
    #??? If FLAG is not set, then abort with an error message. 

target-1-raw: check 
    target-1-body 
target-2-raw: check 
    target-2-body 
target-3-raw: check 
    target-3-body 

%-raw: 
    echo "Error: Target [email protected] does not exist!"  
%: 
    #??? set FLAG 
    @$(MAKE) [email protected] 3>&2 2>&1 1>&3 

Я пробовал различные способы реализации линий, начиная с #??? безуспешно. Если я использую средства make (например, ifndef и ifeq, тогда кажется, что все оценивается не тогда, когда я хочу их). Я также пытался использовать оболочку if [], но безуспешно. Итак, если это вообще возможно, то какой инструмент здесь мой друг?

ответ

1

Я пытаюсь, чтобы убедиться, что пользователь вызывается без суффикса -raw

Я не вижу, что цели служит этим. make и Makefiles - это инструменты, предназначенные для людей, на которых обычно полагаются, чтобы иметь некоторое представление о том, что они делают. Нет никаких особых причин активно запрещать пользователям вашего Makefile выполнять сборку без обмена потоками, если это то, чего они действительно хотят.

Итак, я хотел бы установить переменную в правиле целевого% и проверить все остальные объекты, заданные этой переменной.

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

Итак, если это вообще возможно, то какой инструмент является моим другом здесь?

Главный механизм, с помощью которого рецепт make может записывать постоянную информацию для последующих команд или правил, заключается в записи файлов. Содержание таких файлов или даже их простое существование можно использовать для влияния на последующие команды. Тем не менее, для такой работы, как ваша, это кажется очень хрупким. Тем не менее, это может выглядеть следующим образом:

target-1-raw: 
    temp='[email protected]'; test -e $${temp%-raw}-check \ 
     || echo warning: target '[email protected]' made directly 
    target-1-body 

%-raw: 
    echo "Error: Target [email protected] does not exist!"  
%: 
    touch [email protected] 
    @$(MAKE) [email protected] 3>&2 2>&1 1>&3 
    rm [email protected] 

Уверяю вас, однако, что если я когда-либо получил Makefile, содержащий такую ​​конструкцию, то я бы не впечатлило, и мой первый импульс будет сорвать его. Я предлагаю вам прекратить просмотр свободы ваших пользователей как проблему для решения.

+0

Думаю, я не проявил себя хорошо. Я хочу помочь пользователям.Вместо того, чтобы просто писать о предполагаемом использовании в документации, я хочу выпустить предупреждение. Аборт был всего лишь одним примером (может быть, не самым подходящим) действия, которое можно предпринять. – AlwaysLearning

+0

Кроме того, возможно ли экспортировать переменную среды в родительскую оболочку родительского 'make'? Будет ли у ребенка 'make' доступ к такой переменной? – AlwaysLearning

+0

@AlwaysLearning, представленный вами 'Makefile' не вызывает' make' для вывода в 'stderr', что действительно невозможно сделать без создания модифицированной версии. Вместо этого он вызывает 'make'' stdout' как 'stderr' оболочки и * vise versa *. Это тонкая, но важная разница. Тождества и состояния стандартных потоков являются аспектом среды выполнения каждого процесса; нет универсального 'stdout' и т. д. –

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