Search code examples
powershellmakefilepython-venv

Activate Python virtual environment from Makefile


I have the following Makefile on a folder on Windows 11.

VENV = test
PYTHON = $(VENV)/Scripts/python
PIP = $(VENV)/Scripts/pip
ACTIVATE = $(VENV)/Scripts/activate

run: $(ACTIVATE)
    $(PYTHON) api/app.py

$(ACTIVATE): requirements.txt
    py -m venv $(VENV)
    $(PIP) install -r requirements.txt

deactivate: $(ACTIVATE)
    $(VENV)/deactivate

.PHONY: clean
clean:
    rmdir $(VENV) /s /q
    rmdir api\__pycache__ /s /q

When I execute make run on PowerShell, it suscessfully creates the virtual environment, installs the requirements and runs app.py. However, I have noticed that it is not running in the virtual environment. In other words, it is not activating the environment before running.

The reason why I think it is not running on the virtual environment is because when I stop the app, the command line doesn't show '(test)' on the left, as it would usually do. I have also checked some installed packages to make sure I was not in the virtual environment.

If I did it by hand, I would just type test\Scripts\activate. I have tried adding this inside the run command before executing api/app.py, but it doesn't seem to be activating it either. I have also tried the solution here, i.e. adding test\Scripts\activate && exec bash right before executing the app but exec is not recognized as a command. Replacing test\Scripts\activate by $(ACTIVATE) does not work either because it says that test is not recognized as a command.

What can I do to make sure that api/app.py is running in the virtual environment?


Solution

  • I think I would do something like this:

    VENV = test
    PYTHON = $(VENV)/Scripts/python
    
    .PHONY: run
    run: $(PYTHON)
        $(PYTHON) api/app.py
    
    $(PYTHON):
        py -m venv $(VENV)
        $(PYTHON) -m pip install --requirement requirements.txt
    
    .PHONY: clean
    clean:
        rmdir $(VENV) /s /q
        rmdir api/__pycache__ /s /q
    

    I do not think it makes sense to have activate and deactivate rules in a Makefile and I do not think it would work even, so I skip them. The trick you linked in your question is meant for bash on Linux, I am quite sure it would not work on Windows, and I can not think of a solution that would work on Windows.