Как обрабатывать расширения оболочки в GNU Make под Ubuntu?
Учитывая этот очень простой Makefile
:
all:
@mkdir -pv test/{a,b}
Я получаю этот вывод на OS X 10.6.8 и CentOS 5.5:
mkdir: created directory `test'
mkdir: created directory `test/a'
mkdir: created directory `test/b'
Но на Ubuntu 11.04 я получаю следующее:
mkdir: created directory `test'
mkdir: created directory `test/{a,b}'
Выполнение команды mkdir -pv test/{a,b}
вручную в оболочке на всех платформах дает ожидаемый результат.
Версия GNU Make одинакова на всех платформах:
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program is built for [PLATFORM]
Чем отличается Ubuntu и почему не работает расширение оболочки?
Ответы
Ответ 1
Проблема, вероятно, в том, что Make spawns /bin/sh
. Обычно это символическая ссылка на вашу системную оболочку по умолчанию.
Вариант 1
Вы можете убедиться, что он указывает на bash (так как это базис). Вероятно, теперь это /bin/dash или/bin/sh, в зависимости от вашей версии Ubuntu.
Вариант 2
Более простой вариант:
SHELL=/bin/bash
all:
@echo a{3,4}
@bash -c 'echo a{3,4}'
Это печатает тот же результат дважды, если вы не закомментируете строку SHELL=
Вариант 3
Если вы не можете/не хотите изменять файл make, вы можете вызвать его так:
make SHELL=/bin/bash
остерегайтесь взаимодействия с суб файлами или включает. Вы можете посмотреть опцию make -e
и ключевое слово make export
: http://www.gnu.org/s/hello/manual/make/Variables_002fRecursion.html
Ответ 2
Прошло много времени с тех пор, как я использовал Make...
Существует несколько способов указать конкретную оболочку для использования. По умолчанию оболочка для старого Make была оригинальной оболочкой Bourne. Если вам нужна другая оболочка, вам нужно было установить ее самостоятельно.
Вы используете Linux и GNU, поэтому я предполагаю, что вы используете BASH как оболочку по умолчанию. Попробуйте выполнить эту команду в Make:
echo "random = $RANDOM"
Если это просто печатает random =
и не включает случайное число, ваш Make использует оболочку Bourne в качестве оболочки по умолчанию вместо BASH. (Что странно, потому что я не думал, что в Linux есть настоящая оболочка Bourne...) Чтобы обойти это:
- Вы можете добавить макрос
SHELL
, указывающий на оболочку BASH.
- Вы можете включить оболочку в свою команду.
Вместо:
@mkdir -pv test/{a,b}
Положите это:
/bin/bash -c @mkdir -pv test/{a,b}
Указывает, что вы хотите использовать BASH, а не стандартную /bin/sh Bourne shell.
Если echo random = $RANDOM
печатает случайное число, вы используете BASH (или, по крайней мере, Kornshell), но BRACE EXPANSION может не быть установлен. Попробуйте использовать это в своем файле Makefile:
set -o
И убедитесь, что braceexpand
включен. Это может быть отключено при запуске Make.