# Makefile for hdwalletpy workflow # - Build reusable Docker image (Python 3.12) # - Vendor multi-platform wheels for offline air-gapped use # - Compile wheels in container (wheelhouse) # - Create host venv and install from wheelhouse or vendor/ # - Optionally run inside a warm container # ---------- Platform Detection ---------- UNAME_S := $(shell uname -s) UNAME_M := $(shell uname -m) ifeq ($(UNAME_S),Darwin) PLATFORM := macos ifeq ($(UNAME_M),arm64) ARCH := arm64 else $(error Unsupported macOS architecture: $(UNAME_M)) endif else ifeq ($(UNAME_S),Linux) PLATFORM := linux ARCH := x86_64 else $(error Unsupported OS: $(UNAME_S)) endif VENDOR_DIR := vendor/$(PLATFORM)-$(ARCH) # ---------- Config ---------- IMAGE := hdwallet-build:3.12 CONTAINER := hdwallet-dev WORKDIR := /app VENV_HOST := .venv VENV_CONTAINER := /opt/venv WHEELHOUSE := wheelhouse # Vendor directories for air-gapped deployment VENDOR_MACOS := vendor/macos-arm64 VENDOR_LINUX := vendor/linux-x86_64 # ---------- Help ---------- .PHONY: help help: @echo "pyhdwallet build system (macOS + Linux compatible)" @echo "" @echo "๐Ÿ“ฆ Vendoring (for offline/air-gapped use):" @echo " make vendor-macos - Build macOS ARM64 wheels (requires macOS native)" @echo " make vendor-linux - Build Linux x86_64 wheels (Docker - any OS)" @echo " make vendor-all - Build wheels for both platforms (macOS native + Docker)" @echo " make verify-vendor - Test offline installation from vendor/" @echo "" @echo "๐Ÿ”จ Binary Distribution:" @echo " make binary - Build standalone binary for current platform" @echo " make binary-linux - Build Linux binary via Docker (any OS)" @echo " make binary-all - Build binaries for all platforms" @echo "" @echo "๐Ÿš€ Release Management:" @echo " make release - Build complete release (binaries + vendors + checksums)" @echo " make release-binaries - Copy binaries to releases/vX.Y.Z/" @echo " make release-checksums - Generate SHA256SUMS for binaries" @echo " make release-test - Test release binaries" @echo " make clean-release - Remove all release artifacts" @echo "" @echo "๐Ÿ› ๏ธ Development workflow (works on macOS + Linux):" @echo " make build-image - Build Docker image (Python 3.12)" @echo " make wheels - Build wheels into ./$(WHEELHOUSE)" @echo " make install - Create venv and install dependencies" @echo " make test - Run test suite" @echo " make up - Start warm dev container" @echo " make shell - Open shell in warm container" @echo " make down - Stop and remove dev container" @echo "" @echo "๐Ÿงน Cleanup:" @echo " make clean - Remove venv, wheelhouse, vendor/" @echo " make clean-vendor - Remove vendor/ only" @echo " make clean-release - Remove releases/ only" @echo "" @echo "โ„น๏ธ Platform Info:" @echo " make info - Show platform detection info" @echo "" @echo "Platform notes:" @echo " โ€ข vendor-macos requires native macOS (uses .venv312 with ARM64 Python)" @echo " โ€ข vendor-linux works on any platform with Docker" @echo " โ€ข binary-linux works on any platform with Docker" @echo " โ€ข All other targets work on macOS and Linux" # ---------- Build reusable image ---------- .PHONY: build-image build-image: docker build -t $(IMAGE) . # ---------- Vendoring for Air-Gapped Use ---------- .PHONY: vendor-macos vendor-macos: requirements.txt @echo "Building macOS ARM64 wheels (native)..." @if [ ! -f ".venv312/bin/pip" ]; then \ echo "ERROR: .venv312 not found. Create it first:"; \ echo " python3.12 -m venv .venv312 && source .venv312/bin/activate"; \ exit 1; \ fi mkdir -p $(VENDOR_MACOS) .venv312/bin/pip download --dest $(VENDOR_MACOS) -r requirements.txt cd $(VENDOR_MACOS) && shasum -a 256 *.whl > SHA256SUMS @echo "โœ“ macOS ARM64 wheels: $(VENDOR_MACOS)/" .PHONY: vendor-linux vendor-linux: requirements.txt build-image @echo "Building Linux x86_64 wheels (Docker)..." mkdir -p $(VENDOR_LINUX) docker run --rm \ -v "$$PWD":$(WORKDIR) \ -w $(WORKDIR) \ $(IMAGE) \ bash -c " \ pip install --upgrade pip && \ pip download --dest $(VENDOR_LINUX) -r requirements.txt && \ pip wheel --wheel-dir $(VENDOR_LINUX) --no-deps $(VENDOR_LINUX)/*.tar.gz 2>/dev/null || true && \ rm -f $(VENDOR_LINUX)/*.tar.gz && \ cd $(VENDOR_LINUX) && sha256sum *.whl > SHA256SUMS \ " @echo "โœ“ Linux x86_64 wheels: $(VENDOR_LINUX)/" .PHONY: vendor-all vendor-all: vendor-macos vendor-linux @echo "" @echo "โœ“ All platforms vendored:" @echo " macOS ARM64: $(VENDOR_MACOS)/ ($$(ls $(VENDOR_MACOS)/*.whl 2>/dev/null | wc -l | xargs) wheels)" @echo " Linux x86_64: $(VENDOR_LINUX)/ ($$(ls $(VENDOR_LINUX)/*.whl 2>/dev/null | wc -l | xargs) wheels)" @echo "" @echo "Commit with: git add vendor/ && git commit -m 'vendor: update wheels'" .PHONY: verify-vendor verify-vendor: @echo "Testing offline installation from vendor/..." @bash -c ' \ if [[ "$$OSTYPE" == "darwin"* ]]; then \ PLATFORM="macos-arm64"; \ else \ PLATFORM="linux-x86_64"; \ fi; \ echo "Platform: $$PLATFORM"; \ python3.12 -m venv .venv-verify && \ source .venv-verify/bin/activate && \ pip install --no-index --find-links=vendor/$$PLATFORM -r requirements.txt && \ pytest -v tests/test_vectors.py && \ python src/pyhdwallet.py test && \ echo "" && \ echo "โœ… Vendor installation verified!" && \ deactivate && \ rm -rf .venv-verify \ ' # ---------- Binary Building ---------- .PHONY: binary binary: @echo "๐Ÿ”จ Building binary for current platform: $(PLATFORM)-$(ARCH)..." ifeq ($(PLATFORM),macos) @if [ ! -f "build_binary.sh" ]; then \ echo "โŒ build_binary.sh not found!"; \ exit 1; \ fi @bash build_binary.sh else @echo "โš ๏ธ For Linux native builds, use build_binary.sh directly" @echo " Or use: make binary-linux (builds via Docker)" endif .PHONY: binary-linux binary-linux: @./build_binary_linux.sh .PHONY: binary-all binary-all: @echo "๐Ÿ—๏ธ Building binaries for all platforms..." @echo "" @echo "1๏ธโƒฃ Building native binary..." @$(MAKE) binary @echo "" @echo "2๏ธโƒฃ Building Linux binary via Docker..." @$(MAKE) binary-linux @echo "" @echo "โœ… All binaries built:" @ls -lh dist/pyhdwallet* 2>/dev/null | awk '{print " " $$9 " (" $$5 ")"}' || echo " No binaries found" # ---------- Development Workflow ---------- .PHONY: wheels wheels: requirements.txt build-image docker run --rm \ -v "$$PWD":$(WORKDIR) \ -w $(WORKDIR) \ $(IMAGE) \ bash -c " \ pip install --upgrade pip setuptools wheel && \ mkdir -p $(WHEELHOUSE) && \ pip wheel -r requirements.txt -w $(WHEELHOUSE) \ " .PHONY: install install: requirements.txt @if [ ! -d "$(VENV_HOST)" ]; then \ echo "Creating venv: $(VENV_HOST)"; \ python3.12 -m venv $(VENV_HOST); \ fi . $(VENV_HOST)/bin/activate && \ pip install --upgrade pip && \ pip install -r requirements.txt && \ echo "โœ“ Virtual environment ready: $(VENV_HOST)" .PHONY: test test: @if [ ! -d "$(VENV_HOST)" ]; then \ echo "ERROR: Run 'make install' first"; \ exit 1; \ fi . $(VENV_HOST)/bin/activate && \ pytest -v tests/test_vectors.py && \ python src/pyhdwallet.py test # ---------- Warm container lifecycle ---------- .PHONY: up up: build-image docker run -dit \ -v "$$PWD":$(WORKDIR) \ -w $(WORKDIR) \ --name $(CONTAINER) \ $(IMAGE) \ bash .PHONY: shell shell: docker exec -it $(CONTAINER) bash .PHONY: down down: - docker rm -f $(CONTAINER) # ---------- Cleanup ---------- .PHONY: clean-vendor clean-vendor: rm -rf vendor/ .PHONY: clean clean: down rm -rf $(VENV_HOST) $(WHEELHOUSE) .venv-verify .venv-offline-test rm -rf dist/ build/ *.spec src/pyhdwallet_frozen.py find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true find . -type d -name "*.egg-info" -exec rm -rf {} + 2>/dev/null || true # NOTE: vendor/ is kept (use 'make clean-vendor' to remove) # ---------- Platform-Aware Operations ---------- .PHONY: info info: @echo "Platform Information:" @echo " OS: $(PLATFORM)" @echo " Architecture: $(ARCH)" @echo " Vendor dir: $(VENDOR_DIR)" @echo " Python: $(shell python3 --version 2>/dev/null || echo 'not found')" @echo " Docker: $(shell docker --version 2>/dev/null || echo 'not found')" # ---------- Release Management ---------- VERSION := $(shell grep 'VERSION = ' src/pyhdwallet.py | head -1 | sed 's/.*"\(.*\)".*/\1/' || echo "v1.1.0") RELEASE_DIR := releases/$(VERSION) .PHONY: release-prep release-prep: @echo "๐Ÿ“ฆ Preparing release $(VERSION)..." @mkdir -p $(RELEASE_DIR) .PHONY: release-binaries release-binaries: release-prep binary binary-linux @echo "๐Ÿ“ฆ Copying binaries to $(RELEASE_DIR)..." @cp dist/pyhdwallet $(RELEASE_DIR)/pyhdwallet-macos-arm64 @cp dist/pyhdwallet-linux $(RELEASE_DIR)/pyhdwallet-linux-x86_64 @echo "โœ… Binaries copied" .PHONY: release-checksums release-checksums: release-binaries @echo "๐Ÿ” Generating checksums..." @cd $(RELEASE_DIR) && shasum -a 256 pyhdwallet-* > SHA256SUMS @echo "โœ… Checksums generated:" @cat $(RELEASE_DIR)/SHA256SUMS .PHONY: release-vendors release-vendors: release-prep vendor-all @echo "๐Ÿ“ฆ Copying vendor wheels to $(RELEASE_DIR)..." @mkdir -p $(RELEASE_DIR)/vendor @cp -r vendor/macos-arm64 $(RELEASE_DIR)/vendor/ @cp -r vendor/linux-x86_64 $(RELEASE_DIR)/vendor/ @echo "โœ… Vendor wheels copied" .PHONY: release release: release-checksums @echo "" @echo "๐ŸŽ‰ Release $(VERSION) binaries ready!" @echo "" @if [ -d ".venv312" ]; then \ echo "๐Ÿ“ฆ Building vendor wheels..."; \ $(MAKE) release-vendors; \ else \ echo "โš ๏ธ Skipping vendor wheels (.venv312 not found)"; \ echo " To include vendors: python3.12 -m venv .venv312 && make release-vendors"; \ fi @echo "" @echo "Contents:" @ls -lh $(RELEASE_DIR)/ | tail -n +2 @echo "" @cat $(RELEASE_DIR)/SHA256SUMS @echo "" @echo "Next steps:" @echo " 1. Test: make release-test" @echo " 2. Tag: git tag -a $(VERSION) -m 'Release $(VERSION)'" @echo " 3. Push: git push origin $(VERSION)" .PHONY: release-test release-test: @echo "๐Ÿงช Testing release binaries..." @echo "" @echo "Testing macOS binary:" @$(RELEASE_DIR)/pyhdwallet-macos-arm64 test || echo "โš ๏ธ macOS binary test skipped (wrong platform)" @echo "" @echo "Testing Linux binary (via Docker):" @docker run --rm --platform linux/amd64 \ -v "$$PWD/$(RELEASE_DIR)":/binaries \ ubuntu:22.04 \ /binaries/pyhdwallet-linux-x86_64 test .PHONY: clean-release clean-release: @echo "๐Ÿงน Cleaning release artifacts..." @rm -rf releases/ @echo "โœ… Release artifacts cleaned"