【问题标题】:syntax error near unexpected token in makefile生成文件中意外标记附近的语法错误
【发布时间】:2021-09-22 14:51:37
【问题描述】:

我正在尝试在 Makefile 中创建一个模板以重用 Python virtualenv。 在 Makefile 我定义:

ENV_CREATE ?= $(shell python3 -m virtualenv venv) 并在目标中:

set_up:
    $(ENV_CREATE) ; \
    . venv/bin/activate

由于 Makefiule 目标执行,我得到了

/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `echo created virtual environment CPython3.7.9.final.0-64 in 333ms   creator CPython3Posix(dest=/Users/marian/Work/git/sigma/sphere/sphere-data-platform/venv, clear=False, no_vcs_ignore=False, global=False)   seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/Users/marian/Library/Application Support/virtualenv)     added seed packages: pip==21.1.2, setuptools==57.0.0, wheel==0.36.2   activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator ; . venv/bin/activate    python3 -m pip install -r requirements.txt -r requirements-dev.txt ; '
make: *** [setup] Error 2

我做错了什么?

【问题讨论】:

  • 您可以在设置ENV_CREATE 后立即使用$(info ENV_CREATE=[$(ENV_CREATE)]) 来检查它的值。它看起来正确吗?
  • 是的 ENV_CREATE=[created virtual environment CPython3.7.9.final.0-64 in 300ms creator CPython3Posix(dest=/Users/marian/Work/git/sigma/sphere/sphere-data-platform/venv, clear=False, no_vcs_ignore=False, global=False) seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/Users/marian/Library/Application Support/virtualenv) added seed packages: pip==21.1.2, setuptools==57.0.0, wheel==0.36.2 activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator]
  • 该文本不是有效的命令(或命令),可以传递给您正在尝试执行的 shell。 set_up 规则的命令部分中的$(ENV_CREATE) 语句的用途是什么?
  • 我正在尝试使用变量创建和激活 Python 虚拟环境,因此我可以在其他目标中重新使用它以避免代码重复,例如:CREATE_ENV = $(shell python3 ...)。然后在其他目标中:$(CREATE_ENV) ; \ install_requirements

标签: python bash makefile virtualenv


【解决方案1】:

为什么不直接使用另一个目标?

venv:
      python3 -m virtualenv venv


set_up: venv
        . venv/bin/activate

这样,您只需在虚拟环境不存在时创建它。

【讨论】:

    【解决方案2】:

    ENV_CREATE ?= $(shell...) 中,右侧似乎是非递归评估的(即立即)。因此,ENV_CREATE 变量被分配了这个 shell 脚本的结果:[created ...

    在您的配方中,您使用此 make 变量 ($(ENV_CREATE)) 的扩展作为 shell 语法,虽然它不是 shell 语法,但它是 python3 -m virtualenv venv 的输出消息。

    在已经是...一个shell脚本的配方中使用shell make 函数绝对没有意义。试试:

    ENV_CREATE ?= python3 -m virtualenv venv
    
    set_up:
        $(ENV_CREATE) ; \
        . venv/bin/activate
    

    Make 将在将配方传递给 shell 之前对其进行扩展。那么传递给shell的是:

    python3 -m virtualenv venv ; . venv/bin/activate
    

    但请注意,将采购 (. venv/bin/activate) 作为配方的最后一个命令可能不会有任何用处。

    【讨论】:

      【解决方案3】:

      设法找到最好的方法。好像我不需要$(shell python 3...) 构造。 我已经使用 Make 命令(无 shell)定义了变量并将其作为单线注入:

      ENV_CREATE := python3 -m virtualenv venv ; . venv/bin/activate ;
      
      setup:
      $(ENV_CREATE) python3 -m pip install -r requirements.txt
      
      

      现在我可以以同样的方式在其他目标中重复使用$(ENV_CREATE)(集成测试、单元测试等)

      【讨论】:

        猜你喜欢
        • 2011-08-02
        • 2012-08-31
        • 2012-10-20
        • 2012-09-29
        • 2013-12-11
        • 1970-01-01
        • 1970-01-01
        • 2015-05-10
        相关资源
        最近更新 更多