Как проверить, существует ли в строке параметр Makefile GNU - PullRequest
0 голосов
/ 03 февраля 2020

Я пытаюсь заставить это правило работать. Это полностью взрывает весь мой Makefile.

Это должно проверить, что значение для version, которое передал пользователь, существует в переменной PYVERSION.

Поведение фактического смешано потому что я пробовал так много разных вещей. Я не эксперт GNU, поэтому я пробовал ${version} и $(version) и $version и то же самое для PYVERSION. Текущая версия, которую я выложил здесь всегда , идет в блок else, независимо от того, что ввод version.

PYVERSIONS := "3.5 3.6 3.7 3.8"

.PHONY: venv
venv:
    if test $(findstring ${version}, $(PYVERSIONS)); then
        /Library/Frameworks/Python.framework/Versions/${version}/bin/python3 -m venv venv
    else
        $(error Bad python version given (${version}) project only supports ${PYVERSIONS})
    fi;
  • , называемый как make venv version=3.5 должен успешно выполнить блок if и создать venv.

  • , вызывая его как make venv version=2.7, должен вызвать сообщение об ошибке в блоке else.

Я пытался подписаться на эту запись

Обновление

С помощью @Beta это окончательное решение, которое я получил для работы.

PYVERSIONS := "3.6 3.7 3.8"
PYPATH := /Library/Frameworks/Python.framework/Versions

.PHONY: venv
venv:
    @if test $(findstring ${version}, $(PYVERSIONS)) ; \
    then \
      echo "Creating virtual environment for python ${version}"; \
      $(PYPATH)/${version}/bin/python3 -m venv venv; \
    else \
      echo "Unsupported python version (${version}). Project supports $(PYVERSIONS)"; \
    fi

Ответы [ 2 ]

2 голосов
/ 05 февраля 2020

На самом деле не согласен с @ бета здесь. Поскольку ответ известен еще до того, как вы начнете выполнять рецепт, $(error …) - это ясный путь к go.

Теперь make сохраняет весь рецепт как одну рекурсивно расширенную переменную , Когда make решит построить venv (например, вы наберете make venv), он развернет весь рецепт, прежде чем передать каждую результирующую строку по очереди на fre sh экземпляры оболочки.

Дело в том, что когда make расширяет ваш рецепт, всегда расширяет $(error Bad python version given …), а make останавливается даже перед вызовом оболочки.

Как обойти это?

PYVERSIONS := 3.6 3.7 3.8
PYPATH := /Library/Frameworks/Python.framework/Versions

pyversion = $(or $(filter ${version},${PYVERSION}),$(error $$version [${version}] must be exactly one of ${PYVERSIONS}))

.PHONY: venv
venv:
    echo "Creating virtual environment for python ${version}"
    $(PYPATH)/${pyversion}/bin/python3 -m venv venv

Итак,

  • Вы набираете make venv
  • Make расширяет рецепт
  • Make расширяет pyversion
    • Make расширяет $(filter ${version},3.6 3.7 3.8)
      • Если вы не установили версию в командной строке или среде на одну из трех благословенных строк, make останавливается тут же с полезным сообщением NICE
      • OTOH, если он был установлен соответствующим образом, make счастлив и начинает выполнять рецепт

Другие приятные характеристики :

  • Код выхода python3 возвращается в make (большая дыра в вашем оригинальном рецепте imho).

В все выглядит лучше, чем в оболочке .

1 голос
/ 03 февраля 2020

Вы смешиваете синтаксис оболочки с синтаксисом Make.

Если вы хотите обработать это условным условием shell , вы должны поместить все это в одну строку в рецепте (так как каждый строка выполняется в своей собственной подоболочке):

venv:
    if test $(findstring ${version}, $(PYVERSIONS)) ; then echo $(version)/bin/python3 venv; else  echo bad version $(version); fi

или вы можете обернуть строку с помощью обратной косой черты:

venv:
    if test $(findstring ${version}, $(PYVERSIONS)) ; \
  then \
   echo $(version)/bin/python3 venv; \
  else \
   echo bad version $(version); \
  fi

(Обратите внимание, что перед * стоит только одна TAB 1011 *.)

Если вы хотите использовать Сделать условным в правиле:

venv:
ifeq ($(findstring ${version}, $(PYVERSIONS)),)
    echo bad version $(version);
else
    echo echo $(version)/bin/python3 venv;
endif

Если вы хотите использовать команду Maker error, вы иметь проблему. Make выполнит оценку условия перед выполнением любого правила, поэтому, если вы используете error, то, если действительный номер версии не задан, Make выдаст ошибку , даже если venv не было целью. Это Можно использовать error, но это больно, поэтому вы должны сначала решить, стоит ли эффект цена.

...