【问题标题】:Makefile to create and "activate" Python virtual environmentMakefile 创建和“激活”Python 虚拟环境
【发布时间】:2020-04-08 11:23:44
【问题描述】:

我正在尝试使用 Makefile 创建一个 Python 虚拟环境,并在 make 命令完成后激活它以简化用户操作。显然,这是not possible,因为“子进程不能改变父进程的环境”。我想知道是否有任何解决方法。到目前为止,这是我的 Makefile 的一部分: .PHONY:创建-venv venv .DEFAULT_GOAL := 全部 SHELL=/bin/bash

CPUTYPE = $(shell uname -m | sed "s/\\ /_/g")
SYSTYPE = $(shell uname -s)
BUILDDIR = build/$(SYSTYPE)-$(CPUTYPE)
VENV_NAME?=venv
VENV_DIR=$(BUILDDIR)/${VENV_NAME}
VENV_BIN=$(shell pwd)/${VENV_DIR}/bin
VENV_ACTIVATE=. ${VENV_BIN}/activate

PYTHON=${VENV_BIN}/python3

create-venv:
    test -d $(BUILDDIR) || mkdir -p $(BUILDDIR)
    which python3 || apt install -y python3 python3-pip
    test -d $(VENV_DIR) || python3 -m venv $(VENV_DIR)

venv: ${VENV_BIN}/activate
${VENV_BIN}/activate: setup.py
    test -d $(VENV_DIR) || make create-venv
    ${PYTHON} -m pip install -r requirements.txt
    touch $(VENV_BIN)/activate
    source ${VENV_BIN}/activate # <- doesn't work
    . ${VENV_BIN}/activate # <- doesn't work either

【问题讨论】:

  • 不可能只通过makefile来做到这一点。你引用的答案解释了它,没有什么可说的。这是自 1970 年代发明以来所有 UNIX/POSIX 系统的基本安全特性。如果你想在你的 shell 中设置一个 venv,那么你必须在你的 shell 中设置它:直接设置,或者通过别名或 shell 函数。没有任何程序(包括启动另一个脚本、运行 make 或其他任何程序)可以解决这个问题。
  • @MadScientist 下面的答案正是我想要的。
  • 它可能会做你想做的事,但不会做你要求的事。您要求使用 Makefile 创建一个 Python 虚拟环境,并在 make 命令完成后激活它,这不是下面给出的答案。它在 makefile 配方的上下文中为您提供了一个新的 shell(因此 make 命令尚未完成)。您将无法访问任何父 shell 的本地数据(shell 历史记录等)。我还应该指出,您不能将该解决方案与 make -j 一起使用。但是,如果它对你有用,那就太好了!
  • 是的,我明白了。从用户角度来看,虚拟环境似乎是在 Makefile 中激活的。愚弄用户的错觉是对我有用的错觉......
  • 当然。请注意,用户将能够分辨。例如,如果他们使用向上箭头检索他们调用的最后一个命令......它不会在那里......

标签: makefile virtualenv gnu-make


【解决方案1】:

您可以激活环境并在激活的环境中运行shell:

. ${VENV_BIN}/activate && exec bash

(请注意它必须在一行中才能在一个shell中运行;exec用于将shell替换为新的。)

当您完成对环境的处理时,您会退出,然后 Makefile 就完成了。

【讨论】:

  • 成功了!我收到了The default interactive shell is now zsh. 的消息,因为我在 Mac 上并且他们更改为 zsh,但我想这不是问题。谢谢!
  • @aaragon 也许可以固定调用exec $$SHELL 而不是固定的bash; double $ 将单个 $ 传递给 shell — Makefiles 中的语法技巧。
  • 这似乎解决了 zsh 问题,但现在用户不知道他/她在虚拟环境中,因为前缀不再显示。在它显示(venv) 之前。此外,在 Ubuntu Linux 中,这两种方法都不显示 (venv) 前缀。
  • bash 中为我工作;无法帮助zsh,对不起。
  • Linux Shell 是 bash,没有一种方法显示 (vent)。你在 Linux 上吗?它对你有用吗?
【解决方案2】:

你可以这样做。

它依赖于您查看activate 脚本并查看它设置的环境变量,所以它非常丑陋。

$(eval $(shell source $(PYTHON3_VENV)/bin/activate && echo "export PATH := $$PATH; export PYTHONHOME := $$PYTHONHOME; export VIRTUAL_ENV := $$VIRTUAL_ENV" ))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    • 2020-10-17
    相关资源
    最近更新 更多