Я хочу попробовать и проверить, что исполняемый файл (в данном случае Python pip
) находится на определенном пути (виртуальной среде) в Makefile (это будет сделано до запуска команды make
для установки всех требований и является мерой безопасности чтобы они не попали в системный python по ошибке).
(Кроме того, да, я знаю, что могу форсировать виртуальную среду для pip, но это не только для меня, поэтому я не могу гарантировать, что это сделано...)
У меня было несколько попыток, но в настоящее время это:
DIRENV := $(shell pwd)/.direnv/
PIP := $(shell which pip)
.PHONY: check-pip
check-pip:
FOUND_PIP := $(if $(findstring $(PIP),$(DIRENV)),found,)
$(info FOUND_PIP=$(FOUND_PIP))
ifeq ($(FOUND_PIP),found)
$(info Found pip on the path)
else
$(error ERROR: Cannot find pip))
endif
$(DIRENV)
и $(PIP)
верны, если я их распечатаю.
Есть 2 проблемы с этим:
findstring
работать!ifeq
независимо выполняет обе части условного предложения.❯ make check-pip
FOUND_PIP=
Found pip on the path
Makefile:37: *** ERROR: Cannot find pip. Stop.
И просто для уточнения версии make
:
❯ make --version
GNU Make 4.2.1
Каждая строка рецепта makefile выполняется в отдельной оболочке. Нельзя использовать такие переменные.
Вы должны написать свой рецепт проверки, используя синтаксис оболочки.
.PHONY: check-pip
check-pip:
case "$(PIP)" in \
("$(DIRENV)"/*) echo "Found pip on the path" ;; \
(*) echo "Cannot find pip"; exit 1 ;; \
esac
Обратите внимание: вам это нужно, если вы хотите проверить это только тогда, когда пользователь специально запускает цель check-pip
.
Если вы хотите проверять это всегда, когда пользователь запускает make
, независимо от того, какую цель он указывает, вы можете использовать операции с make-файлом, но вы не должны помещать их в рецепт, потому что они запускаются при разборе make-файла, а не при сборке цели. . И вам вообще не нужна check-pip
цель.
Что, если я поставлю его в зависимость от пары других целей?
Вы можете сделать это. Я не уверен, что понял вопрос...?
Я имею в виду, если у меня есть пара рецептов по установке/очистке и переустановке среды, и я хочу, чтобы эта проверка прошла, прежде чем они что-либо сделают.
Кстати, это работает, спасибо! Хотя кавычки вокруг $(DIRENV)*
нужно удалить, иначе они соответствуют неправильной строке.
Извините, кавычки должны были быть только вокруг переменной, а не символа шара. Зафиксированный.
Вот что вы должны понять: рецепт в make-файле (вещь после цели/пререквизитов, с отступом TAB) — это сценарий оболочки. Поэтому, когда вы пишете рецепты, вы должны использовать синтаксис оболочки, а не синтаксис makefile.