How to use virtualenv in makefile
I like using something that runs only when requirements.txt
changes:
This assumes that source files are under project
in your project's root directory and that tests are under project/test
. (You should change project
to match your actually project name.)
venv: venv/touchfile
venv/touchfile: requirements.txt
test -d venv || virtualenv venv
. venv/bin/activate; pip install -Ur requirements.txt
touch venv/touchfile
test: venv
. venv/bin/activate; nosetests project/test
clean:
rm -rf venv
find -iname "*.pyc" -delete
- Run
make
to install packages inrequirements.txt
. - Run
make test
to run your tests (you can update this command if your tests are somewhere else). - run
make clean
to delete all artifacts.
Normally make
runs every command in a recipe in a different subshell. However, setting .ONESHELL:
will run all the commands in a recipe in the same subshell, allowing you to activate a virtualenv and then run commands inside it.
Note that .ONESHELL:
applies to the whole Makefile, not just a single recipe. It may change behaviour of existing commands, details of possible errors in the full documentation. This will not let you activate a virtualenv for use outside the Makefile, since the commands are still run inside a subshell.
Reference documentation: https://www.gnu.org/software/make/manual/html_node/One-Shell.html
Example:
.ONESHELL:
.PHONY: install
install:
source path/to/virtualenv/bin/activate
pip install -r requirements.txt
In make you can run a shell as command. In this shell you can do everything you can do in a shell you started from comandline. Example:
install:
( \
source path/to/virtualenv/bin/activate; \
pip install -r requirements.txt; \
)
Attention must be paid to the ;
and the \
.
Everything between the open and close brace will be done in a single instance of a shell.