如何在 Makefile 中激活 virtualenv?
我试过了:
venv:
@virtualenv venv
active:
@source venv/bin/activate
我也试过:
active:
@. venv/bin/activate
它不会激活 virtualenv.
操作方法如下:
您可以使用 () 在 Makefile 中执行 shell 命令;
例如
echoTarget:
(echo "I'm an echo")
只需确保在 shell 命令的每一行之前放置一个制表符。 也就是说,您之前需要一个标签(回声“我是回声”)
以下是激活 virtualenv 的方法:
activate:
( \
source path/to/virtualenv/activate; \
pip install -r requirements.txt; \
)
UPD 21 年 3 月 14 日
virtualenv 中
pip install
的另一个变体:
# Makefile
all: install run
install: venv
: # Activate venv and install smthing inside
. venv/bin/activate && pip install -r requirements.txt
: # Other commands here
venv:
: # Create venv if it doesn't exist
: # test -d venv || virtualenv -p python3 --no-site-packages venv
test -d venv || python3 -m venv venv
run:
: # Run your app here, e.g
: # determine if we are in venv,
: # see https://stackoverflow.com/q/1871549
. venv/bin/activate && pip -V
: # Or see @wizurd's answer to exec multiple commands
. venv/bin/activate && (\
python3 -c 'import sys; print(sys.prefix)'; \
pip3 -V \
)
clean:
rm -rf venv
find -iname "*.pyc" -delete
所以你可以用不同的“标准”方式运行
make
:
make
- 目标为默认值all
make venv
- 只创建 virtualenvmake install
- 创建 venv 并执行其他命令make run
- 在 venv 中执行您的应用程序make clean
- 删除 venv 和 python 二进制文件当需要执行配方来更新目标时,它们是通过为配方的每一行调用一个新的子 shell 来执行的。 --- GNU 制作
由于配方的每一行都在单独的子 shell 中执行,我们应该在配方的同一行中运行 python 代码。
用于显示当前 python 环境源的简单 python 脚本(文件名:
whichpy.py
):
import sys
print(sys.prefix)
运行python虚拟环境(
Make
食谱运行在sh
而不是bash
,使用.
激活虚拟环境是正确的语法):
test:
. pyth3.6/bin/activate && python3.6 whichpy.py
. pyth3.6/bin/activate; python3.6 whichpy.py
以上2种食谱都可以接受,我们可以随意使用反斜杠/换行符将一个食谱分成多行。
Makefile 不能直接激活环境。这对我有用:
activate:
bash -c "venv/bin/activate"
如果您遇到权限被拒绝的错误,请使 venv/bin/activate 可执行:
chmod +x venv/bin/activate
我通过在 Makefile 的开头将
ACTIVATE_LINUX:=. venv/bin/activate
变量与 .ONESHELL:
结合起来,建立了一个简单的方法来做到这一点:
.ONESHELL:
.PHONY: clean venv tests scripts
ACTIVATE_LINUX:=. venv/bin/activate
setup: venv install scripts
venv:
@echo "Creating python virtual environment in 'venv' folder..."
@python3 -m venv venv
install:
@echo "Installing python packages..."
@$(ACTIVATE_LINUX)
@pip install -r requirements.txt
clean:
@echo "Cleaning previous python virtual environment..."
@rm -rf venv
正如在其他答案中指出的那样,
Make
食谱在 sh
而不是 bash
上运行,因此在 .
变量中使用 ACTIVATE_LINUX
而不是 @
来激活虚拟环境是正确的语法。
我把这个策略和
.ONESHELL:
结合起来。如 this StackOverflow anwser 所示,通常 Make
在不同的子 shell 中运行配方中的每个命令。但是,设置 .ONESHELL:
将在同一子 shell 中运行配方中的所有命令,从而允许您激活虚拟环境,然后在其中运行命令。这正是 make install
目标中发生的事情,这种方法可以应用于任何需要激活环境以在项目中运行一些 python 代码的地方。
因此您可以运行以下 make 目标:
make
- 目标为默认设置;make venv
- 只创建虚拟环境;make install
- 激活venv
并执行pip install
命令;和make clean
- 删除以前的 venv
和 python 二进制文件。激活的替代方法是在 Makefile 中使用环境变量。例如:
.PHONY: venv install
VENV=.venv
PYTHON=$(VENV)/bin/python3
venv:
python3 -m venv $(VENV)
install: venv
$(PYTHON) -m pip install -r requirements-dev.txt
isort:
$(PYTHON) -m isort --check-only .
black:
$(PYTHON) -m black --check .
mypy:
$(PYTHON) -m mypy .
flake8:
$(PYTHON) -m flake8 .
bandit:
$(PYTHON) -m bandit -r app
lint: isort black mypy flake8 bandit
test: ## Run tests
$(PYTHON) -m pytest
一种方法:在Makefile
中为
each命令加上
. venv/bin/activate &&
,它必须在venv
下运行。
即使用:
target:
. venv/bin/activate && command
代替
target:
command