Иногда вам нужен Makefile, чтобы иметь возможность работать в разных целевых ОС, и вы хотите, чтобы сборка завершилась сбоем раньше, если требуемый исполняемый файл отсутствует, PATHа не запускался в течение, возможно, долгого времени до сбоя.
Превосходное решение, предоставленное инженером, требует постановки цели . Однако, если у вас есть много исполняемых файлов для тестирования и ваш Makefile имеет много независимых целей, каждая из которых требует тестов, то каждая цель требует тестовой цели в качестве зависимости. Это требует много дополнительного набора текста, а также времени обработки, когда вы задаете более одной цели за раз.
Решение, предоставляемое 0xf, может тестировать исполняемый файл без создания цели. Это экономит много времени на ввод и выполнение, когда есть несколько целей, которые могут быть созданы либо по отдельности, либо вместе.
Мое улучшение последнего решения состоит в том, чтобы использовать whichисполняемый файл ( whereв Windows), а не полагаться на наличие --versionопции в каждом исполняемом файле непосредственно в ifeqдирективе GNU Make , а не определять новую переменную, и использовать GNU Make errorфункция, чтобы остановить сборку, если необходимый исполняемый файл отсутствует ${PATH}. Например, чтобы проверить lzopисполняемый файл:
ifeq (, $(shell which lzop))
$(error "No lzop in $(PATH), consider doing apt-get install lzop")
endif
Если у вас есть несколько исполняемых файлов для проверки, вы можете использовать foreachфункцию с whichисполняемым файлом:
EXECUTABLES = ls dd dudu lxop
K := $(foreach exec,$(EXECUTABLES),\
$(if $(shell which $(exec)),some string,$(error "No $(exec) in PATH")))
Обратите внимание на использование :=оператора присваивания, который требуется для немедленного вычисления выражения RHS. Если ваш Makefile изменит PATH, то вместо последней строки выше вам понадобится:
$(if $(shell PATH=$(PATH) which $(exec)),some string,$(error "No $(exec) in PATH")))
Это должно дать вам результат, похожий на:
ads$ make
Makefile:5: *** "No dudu in PATH. Stop.