Created
November 11, 2022 19:15
-
-
Save DaelonSuzuka/502ce9bd735e5043666c26b931b62e62 to your computer and use it in GitHub Desktop.
Python Makefile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# **************************************************************************** # | |
# General Make configuration | |
# This suppresses make's command echoing. This suppression produces a cleaner output. | |
# If you need to see the full commands being issued by make, comment this out. | |
MAKEFLAGS += -s | |
# **************************************************************************** # | |
APP_FOLDER = app | |
APP_MAIN = $(APP_FOLDER)/main.py | |
APP_INFO = $(APP_FOLDER)/app_info.py | |
# load the project variables | |
ifneq (,$(wildcard $(APP_INFO))) | |
include $(APP_INFO) | |
# remove extra quotes | |
AppName := $(patsubst "%",%,$(AppName)) | |
AppVersion := $(patsubst "%",%,$(AppVersion)) | |
AppPublisher := $(patsubst "%",%,$(AppPublisher)) | |
AppExeName := $(patsubst "%",%,$(AppExeName)) | |
AppIconName := $(patsubst "%",%,$(AppIconName)) | |
AppId := $(patsubst "%",%,$(AppId)) | |
# export them for InnoSetup | |
export | |
endif | |
# **************************************************************************** # | |
# Development Targets | |
# run the application | |
run: venv | |
$(VENV_PYTHON) $(APP_MAIN) | |
# run the application in pdb | |
debug: venv | |
$(VENV_PYTHON) -m pdb $(APP_MAIN) | |
# run the test suite | |
test: venv | |
$(VENV_PYTHON) -m pytest | |
# **************************************************************************** # | |
# Build Targets | |
# build a one folder bundle | |
bundle: venv | |
$(VENV_PYINSTALLER) -y bundle.spec | |
# run the bundled executable | |
run_bundle: | |
ifeq ($(OS),Windows_NT) | |
dist/$(AppName)/$(AppName).exe | |
else | |
dist/$(AppName)/$(AppName) | |
endif | |
# **************************************************************************** # | |
# Release Targets | |
# wrap the bundle into a zip file | |
zip: | |
echo > dist/$(AppName)/.portable | |
$(PYTHON) -m zipfile -c dist/$(AppName)-$(AppVersion)-portable.zip dist/$(AppName)/ | |
ifeq ($(OS),Windows_NT) | |
del dist\$(AppName)\.portable | |
else | |
-@ $(RM) dist/$(AppName)/.portable | |
endif | |
# build an installer with InnoSetup | |
installer: | |
iscc "installer.iss" | |
# remove the various build outputs | |
clean: | |
-@ $(RM) build | |
-@ $(RM) dist | |
# **************************************************************************** # | |
include venv.mk |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# **************************************************************************** # | |
# python venv settings | |
VENV_NAME := .venv | |
REQUIREMENTS := requirements.txt | |
ifeq ($(OS),Windows_NT) | |
VENV_DIR := $(VENV_NAME) | |
VENV_CANARY_DIR := $(VENV_DIR)\canary | |
VENV_CANARY_FILE := $(VENV_CANARY_DIR)\$(REQUIREMENTS) | |
VENV_TMP_DIR := $(VENV_DIR)\tmp | |
VENV_TMP_FREEZE := $(VENV_TMP_DIR)\freeze.txt | |
VENV := $(VENV_DIR)\Scripts | |
PYTHON := python | |
VENV_PYTHON := $(VENV)\$(PYTHON) | |
VENV_PYINSTALLER := $(VENV)\pyinstaller | |
RM := -rd /s /q | |
CP := copy | |
else | |
VENV_DIR := $(VENV_NAME) | |
VENV_CANARY_DIR := $(VENV_DIR)/canary | |
VENV_CANARY_FILE := $(VENV_CANARY_DIR)/$(REQUIREMENTS) | |
VENV_TMP_DIR $(VENV_DIR)/tmp | |
VENV_TMP_FREEZE := $(VENV_TMP_DIR)/freeze.txt | |
VENV := $(VENV_DIR)/bin | |
PYTHON := python3 | |
VENV_PYTHON := $(VENV)/$(PYTHON) | |
VENV_PYINSTALLER := $(VENV)/pyinstaller | |
RM := rm -rf | |
CP := cp | |
endif | |
# **************************************************************************** # | |
# Add this as a requirement to any make target that relies on the venv | |
.PHONY: venv | |
venv: $(VENV_DIR) $(VENV_CANARY_FILE) | |
# Create the venv if it doesn't exist | |
$(VENV_DIR): | |
$(PYTHON) -m venv $(VENV_DIR) | |
# Update the venv if the canary is out of date | |
$(VENV_CANARY_FILE): $(REQUIREMENTS) | |
$(VENV_PYTHON) -m pip install --upgrade pip | |
$(VENV_PYTHON) -m pip install -r $(REQUIREMENTS) | |
mkdir $(VENV_CANARY_DIR) | |
$(CP) $(REQUIREMENTS) $(VENV_CANARY_FILE) | |
# forcibly update the canary file | |
canary: $(VENV_CANARY_DIR) | |
$(CP) $(REQUIREMENTS) $(VENV_CANARY_FILE) | |
# update requirements.txt to match the state of the venv | |
freeze_reqs: venv | |
$(VENV_PYTHON) -m pip freeze > $(REQUIREMENTS) | |
# try to update the venv - expirimental feature, don't rely on it | |
update_venv: venv | |
$(VENV_PYTHON) -m pip install --upgrade pip | |
$(VENV_PYTHON) -m pip install --upgrade -r $(REQUIREMENTS) | |
# remove all packages from the venv | |
clean_venv: | |
$(RM) $(VENV_CANARY_DIR) | |
mkdir $(VENV_TMP_DIR) | |
$(VENV_PYTHON) -m pip freeze > $(VENV_TMP_FREEZE) | |
$(VENV_PYTHON) -m pip uninstall -y -r $(VENV_TMP_FREEZE) | |
$(RM) $(VENV_TMP_DIR) | |
# clean the venv and rebuild it | |
reset_venv: clean_venv update_venv | |
# **************************************************************************** # | |
# expirimental, probably not reliable | |
# If the first argument is "pip"... | |
ifeq (pip,$(firstword $(MAKECMDGOALS))) | |
# use the rest as arguments for "pip" | |
RUN_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)) | |
# ...and turn them into do-nothing targets | |
$(eval $(RUN_ARGS):;@:) | |
endif | |
# forward pip commands to the venv | |
pip: venv | |
$(VENV_PYTHON) -m pip $(RUN_ARGS) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment