Обнаружение (не) GNU Make, когда кто-то запускает `make` - PullRequest
5 голосов
/ 04 августа 2010

У меня есть проект, чей make-файл использует функции, эксклюзивные для GNU Make. К сожалению, есть платформы, которые мы должны поддерживать, где GNU make по-прежнему не используется по умолчанию при запуске make.

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

Что я могу написать в Makefile, чтобы отличить make GNU от make не-GNU, распечатать явную ошибку и выйти?

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

Ответы Беты и Дана Молдинга выглядят действительно красиво и просто, но в AIX 6.1 реализация make не может справиться ни с одним из них:

$ cat testmake

foo:
        touch foo

ifeq ($(shell $(MAKE) -v | grep GNU),)
$(error this is not GNU Make)
endif

ifeq "${MAKE_VERSION}" ""
$(info GNU Make not detected)
$(error ${MIN_MAKE_VER_MSG})
endif


$ /usr/bin/make -f testmake
"testmake", line 5: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 6: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 7: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 8: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 11: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 12: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 13: make: 1254-055 Dependency line needs colon or double colon operator.
make: 1254-058 Fatal errors encountered -- cannot continue.

Я сталкиваюсь с похожими проблемами как в архаичной, так и в современной версиях (Solaris 8 и 10) марки Sun. Это менее критично, но было бы неплохо справиться.

Ответы [ 2 ]

6 голосов
/ 14 мая 2013

Как уже отмечалось, GNU make проверяет GNUmakefile до makefile или Makefile, я использовал тривиальное исправление, такое как вы описали, по умолчанию (приманка) Makefile, которое вызывает ошибку / предупреждение :

default:
    @echo "This requires GNU make, run gmake instead"
    exit 70

GNU делает документацию рекомендует использовать имя GNUmakefile, когда Makefile является GNU make конкретным, так что это мое предпочтительное решение.

На платформах, где нативный make предпочитает другое имя Makefile, вы можете внести изменения в это, например, во FreeBSD у меня есть вышеупомянутая приманка в BSDmakefile, которая используется вместо Makefile (таким образом, система make не может испортить мою сборку). AFAICT в AIX или Solaris make не имеют альтернативного имени, которое вы могли бы использовать таким образом.

Одна проблема с оболочкой Makefile, которая пытается вызвать GNU make, передает все аргументы.

Кажущийся переносимым тест (до сих пор он работал на смеси древних систем OSF1, BSD и Solaris), вы можете использовать SOMETHING=$(shell ...), чтобы определить, работает ли GNU make, не версии GNU не установлено SOMETHING. Из-за отложенной оценки переменных вы не можете использовать это так легко, как можно было бы ожидать. Это основывается на реализации, которая молча обрабатывает имена макросов с пробелами при расширении с помощью $() (т. Е. Обрабатывает $(shell foo) как имя переменной / макроса, а не функцию , даже если присвоение такому имени в этом реализация вызовет ошибку).

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

GNUMAKE=$(shell echo GNUMAKE)

default: gnumake all

gnumake:
        @[ "$(GNUMAKE)" = "GNUMAKE" ] || { echo GNU make required ; exit 70; }

Предполагается, что у вас есть оболочка POSIX sh.

(Я видел тесты, которые проверяют $(MAKE) -v, когда обе системы и GNU make называются "make", система make сговаривается против вас и вызывает GNU make ... Вам понадобятся некоторые тщательная проверка переменных среды PATH, MAKE и, возможно, SHELL для обработки каждого случая.)

2 голосов
/ 04 августа 2010

Я не знаю ни одной внутренней функции, которая определенно уникальна для GNUMake, но вот kludge: вызовите «make -v» и проанализируйте вывод для «GNU» (так как кажется маловероятным, что Make не из GNU сделаетсделайте MAKE установленным для GNU Make):

ifeq ($(shell $(MAKE) -v | grep GNU),)
$(error this is not GNU Make)
endif

РЕДАКТИРОВАТЬ:
Как и Дэн Молдинг, я начинаю видеть реальный размер этой проблемы.Как написано, для этого требуется Makefile, который синтаксически корректен во всех версиях Make.У меня нет доступа к Sun Make (и я не могу найти руководства для него), поэтому я не знаю, возможно ли это вообще, или как написать его, если он есть, или как проверить его, если я это сделал.

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

default:
  ./runGNUMake.pl

Вот и все, вот и весь make-файл.Затем напишите сценарий runGNUMake на Perl (или bash, или как вам угодно), который будет выполнять что-то вроде моего «make -v» kludge, а затем либо напечатаете сообщение об ошибке, либо запустите «make -f realMakefile».

...