如何在makefile中使用virtualenv

dev*_*ev9 34 makefile virtualenv

我想在处理指定的virtualenv时执行几个操作.

例如命令

make install
Run Code Online (Sandbox Code Playgroud)

相当于

source path/to/virtualenv/bin/activate
pip install -r requirements.txt
Run Code Online (Sandbox Code Playgroud)

可能吗?

Kla*_*aus 34

在make中,您可以运行shell作为命令.在这个shell中,您可以在从comandline开始的shell中执行所有操作.例:

install:
    ( \
       source path/to/virtualenv/bin/activate; \
       pip install -r requirements.txt; \
    )
Run Code Online (Sandbox Code Playgroud)

必须注意;\.

打开和关闭括号之间的所有内容都将在shell的单个实例中完成.

  • 在这种情况下,不需要`()`.make已经为规则体中的每一行生成一个新的shell实例.您只需要使用continuation标记来读取行并在单个shell中执行它们,而不是像默认情况下那样在多个shell中执行它们. (14认同)
  • 我收到“源:找不到命令”,所以我最终不得不使用同义词。例如改变上面的3:`。路径/到/virtualenv/bin/activate; \` 我希望这可以帮助在这里绊倒的其他人:-) (5认同)

one*_*elf 30

我喜欢使用仅在requirements.txt更改时运行的东西:

venv: venv/bin/activate

venv/bin/activate: requirements.txt
    test -d venv || virtualenv venv
    . venv/bin/activate; pip install -Ur requirements.txt
    touch venv/bin/activate

test: venv
    . venv/bin/activate; nosetests project/test

clean:
    rm -rf venv
    find -iname "*.pyc" -delete
Run Code Online (Sandbox Code Playgroud)

  • @zean_7 只需输入 `make` 就会执行 makefile 中的第一个目标,在本例中为 `venv`。由于“venv”依赖于“venv/touchfile”,只要“requirements.txt”(其依赖项)已更改,该配方也会运行。`venv/touchfile` 只是一个空文件,用于跟踪虚拟环境的修改时间。 (2认同)

Hol*_*lly 22

通常make在不同的子 shell 中运行配方中的每个命令。但是,设置.ONESHELL:将在同一个子 shell 中运行配方中的所有命令,允许您激活 virtualenv,然后在其中运行命令。

请注意,这.ONESHELL:适用于整个 Makefile,而不仅仅是单个配方。它可能会改变现有命令的行为,完整文档中可能出现的错误的详细信息。这不会让你激活一个 virtualenv 以在 Makefile 之外使用,因为命令仍然在子 shell 内运行。

参考文档:https : //www.gnu.org/software/make/manual/html_node/One-Shell.html

例子:

.ONESHELL:

.PHONY: install
install:
    source path/to/virtualenv/bin/activate
    pip install -r requirements.txt
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是最好的解决方案 (3认同)

mat*_*ndr 16

我喜欢设置我的 Makefile,以便它使用一个.venv目录(如果存在),但默认使用 PATH。

对于本地开发,我喜欢使用虚拟环境,所以我运行:

# Running this:  # Actually runs this:
make venv        # /usr/bin/python3 -m venv .venv
make deps        # .venv/bin/python setup.py develop
make test        # .venv/bin/python -m tox
Run Code Online (Sandbox Code Playgroud)

如果我要安装到容器中或安装到我的计算机中,我可能会通过跳过来绕过虚拟环境make venv

# Running this:  # Actually runs this:
make deps        # /usr/bin/python3 setup.py develop
make test        # /usr/bin/python3 -m tox
Run Code Online (Sandbox Code Playgroud)

设置

在 Makefile 的顶部,定义以下变量:

VENV           = .venv
VENV_PYTHON    = $(VENV_PYTHON)/bin/python
SYSTEM_PYTHON  = $(or $(shell which python3), $(shell which python))
# If virtualenv exists, use it. If not, find python using PATH
PYTHON         = $(or $(wildcard $(VENV_PYTHON)), $(SYSTEM_PYTHON))
Run Code Online (Sandbox Code Playgroud)

如果./.venv存在,您将得到:

VENV          = .venv
VENV_PYTHON   = .venv/bin/python
SYSTEM_PYTHON = /usr/bin/python3
PYTHON        = .venv/bin/python
Run Code Online (Sandbox Code Playgroud)

如果没有,您将得到:

VENV           = .venv
VENV_PYTHON    = $(VENV_PYTHON)/bin/python
SYSTEM_PYTHON  = $(or $(shell which python3), $(shell which python))
# If virtualenv exists, use it. If not, find python using PATH
PYTHON         = $(or $(wildcard $(VENV_PYTHON)), $(SYSTEM_PYTHON))
Run Code Online (Sandbox Code Playgroud)

注意:/usr/bin/python3可能是您系统上的其他内容,具体取决于您的PATH.

然后,在需要的地方,运行像这样的 python 东西:

$(PYTHON) -m tox
$(PYTHON) -m pip ...
Run Code Online (Sandbox Code Playgroud)

您可能想要创建一个名为“ venv”的目标来创建.venv目录:

$(VENV_PYTHON):
    rm -rf $(VENV)
    $(SYSTEM_PYTHON) -m venv $(VENV)

venv: $(VENV_PYTHON)
Run Code Online (Sandbox Code Playgroud)

以及deps安装依赖项的目标:

deps:
    $(PYTHON) setup.py develop
    # or whatever you need:
    #$(PYTHON) -m pip install -r requirements.txt
Run Code Online (Sandbox Code Playgroud)

例子

这是我的 Makefile:

# Variables
VENV           = .venv
VENV_PYTHON    = $(VENV)/bin/python
SYSTEM_PYTHON  = $(or $(shell which python3), $(shell which python))
PYTHON         = $(or $(wildcard $(VENV_PYTHON)), $(SYSTEM_PYTHON))

## Dev/build environment

$(VENV_PYTHON):
    rm -rf $(VENV)
    $(SYSTEM_PYTHON) -m venv $(VENV)

venv: $(VENV_PYTHON)

deps:
    $(PYTHON) -m pip install --upgrade pip
    # Dev dependencies
    $(PYTHON) -m pip install tox pytest
    # Dependencies
    $(PYTHON) setup.py develop

.PHONY: venv deps

## Test

test:
    $(PYTHON) -m tox

.PHONY: test

## Build source distribution, install

sdist:
    $(PYTHON) setup.py sdist

install:
    $(SYSTEM_PYTHON) -m pip install .

.PHONY: build install
Run Code Online (Sandbox Code Playgroud)


小智 15

我很幸运.

install:
    source ./path/to/bin/activate; \
    pip install -r requirements.txt; \
Run Code Online (Sandbox Code Playgroud)

  • 例如@@ Adil将此添加到makefile的第一行:``SHELL:= / bin / bash``。调整为您使用的任何外壳。 (2认同)
  • @Adil,或者使用 POSIX 点命令而不是 `source`,如 `. ./path/to/bin/activate` (2认同)

Sau*_*abh 12

这是运行您想要在 virtualenv 中运行的东西的另一种方法。

BIN=venv/bin/

install:
    $(BIN)pip install -r requirements.txt

run:
    $(BIN)python main.py
Run Code Online (Sandbox Code Playgroud)

PS:这不会激活 virtualenv,但会完成工作。希望你觉得它干净而且有用。


SIO*_*SIO 5

基于上面的答案(感谢@Saurabh 和@oneself!)我编写了一个可重用的 Makefile,负责创建虚拟环境并保持更新:https : //github.com/sio/Makefile.venv

它通过在 virtualenv 中引用正确的可执行文件来工作,并且不依赖于“激活”shell 脚本。下面是一个例子:

test: venv
    $(VENV)/python -m unittest

include Makefile.venv
Run Code Online (Sandbox Code Playgroud)

考虑到 Windows 和其他操作系统之间的差异,Makefile.venv 应该可以在任何提供 Python 和 make 的操作系统上正常工作。