Skip to content

Commit b800dda

Browse files
committed
Build a working v14.0.2 .app and .pkg installer
1 parent 171a6f9 commit b800dda

File tree

8 files changed

+122
-70
lines changed

8 files changed

+122
-70
lines changed

Makefile

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ APPID ?= 1608360813
2424
#DEVID ?= 3rd Party Mac Developer Application: Perry Kundert ($(TEAMID))
2525
#DEVID ?= A5DE932A0649AE3B6F06A8134F3E19D2E19A8196
2626
# Developer ID Application (not for Mac App Store) (exp. Friday, November 10, 2028 at 14:19:34 Mountain Standard Time)
27-
#DEVID ?= EAA134BE299C43D27E33E2B8645FF4CF55DE8A92
27+
DEVID ?= EAA134BE299C43D27E33E2B8645FF4CF55DE8A92
2828
# 3rd Party Mac Developer Application; for signing for Mac App Store
29-
DEVID ?= AAEEBB68998F340D00A05926C67D77980D562856
29+
#DEVID ?= AAEEBB68998F340D00A05926C67D77980D562856
3030

3131
PKGID ?= Developer ID Installer: Perry Kundert ($(TEAMID))
3232
#PKGID ?= CC8AA39695DCC81F0DD56063EBCF033DC2529CC7
@@ -82,7 +82,7 @@ GHUB_NAME = python-slip39
8282
VENV_DIR = $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/.. )
8383
VENV_NAME = $(GHUB_NAME)-$(VERSION)-$(PYTHON_V)
8484
VENV = $(VENV_DIR)/$(VENV_NAME)
85-
VENV_OPTS = # --copies # Doesn't help; still references some system libs.
85+
VENV_OPTS = --system-site-packages --copies # make available references some system libs, eg. _tkinter
8686

8787

8888
.PHONY: all help test doctest analyze pylint build install upload clean FORCE
@@ -127,6 +127,20 @@ signing-check:
127127

128128
build: clean wheel
129129

130+
clean:
131+
@echo "Cleaning Python artifacts..."
132+
rm -rf build/ dist/ *.egg-info .eggs/
133+
find . -type d -name '__pycache__' -exec rm -rf {} +
134+
find . -type d -name '.pytest_cache' -exec rm -rf {} +
135+
find . -type d -name '.mypy_cache' -exec rm -rf {} +
136+
find . -type d -name '*.egg-info' -exec rm -rf {} +
137+
find . -type f -name '*.pyc' -delete
138+
find . -type f -name '*.pyo' -delete
139+
find . -type f -name '*.egg' -delete
140+
find . -type f -name '.coverage' -delete
141+
find . -type f -name '*.log' -delete
142+
143+
130144
nix-%:
131145
@if [ -r flake.nix ]; then \
132146
nix develop $(NIX_OPTS) --command make $*; \
@@ -420,19 +434,35 @@ install: $(WHEEL) FORCE
420434
$(PYTHON) -m pip install --no-user --force-reinstall $<[$(ALL)]
421435

422436
install-%: # ...-dev, -tests, -gui, -serial, -wallet, -invoice
423-
$(PYTHON) -m pip install --no-user --upgrade -e .[$*]
437+
$(PYTHON) -m pip install --no-user --upgrade .[$*]
424438

425439

440+
#
426441
# Building / Signing / Notarizing and Uploading the macOS or win32 App
427442
# o TODO: no signed and notarized package yet accepted for upload by macOS App Store
428443
#
429-
# Mac: To build the .dmg installer, run:
430-
# nix develop
431-
# PYTHON=python3.12 make venv
432-
# - In the venv:
433-
# make clean
434-
# make installer # continue running every couple of minutes 'til the App is notarized
435-
# - Once .pkg is successfully notarized, upload it:
444+
# Building, signing and deploying a .app / .pkg currently requires the official python.org
445+
# Python 3.13; the Nix supplied python doesn't work with PyInstaller to yield a working .app
446+
#
447+
# Mac: To build the .pkg (default) installer:
448+
#
449+
# 1) Download the macOS 3.13 aarch64 installer from python.org: https://www.python.org/downloads/latest/python3.13/
450+
#
451+
# 2) Install it; should put it in /usr/local/bin/python
452+
#
453+
# 3) Create the venv using the just-installed python:
454+
# $ PATH=/usr/local/bin make venv
455+
# ...
456+
# python-slip39-14.0.2-Library-darwin-cpython-313) [perry@Perrys-MBP python-slip39 (master *%=)]$
457+
#
458+
# 4) Build the app and installer:
459+
#
460+
# $ make clean
461+
# $ make installer
462+
#
463+
# 5) Test the dist/SLIP-39-14.0.2.pkg and the installed /Applications/SLIP-39.app
464+
#
465+
# 6) Once .pkg is successfully notarized, upload it: (TODO)
436466
# make app-pkg-upload
437467
#
438468
installer: $(INSTALLER)
@@ -487,12 +517,13 @@ dist/slip39-$(VERSION)-win64.msi: build/exe.$(CXFREEZE_EXT)/SLIP-39.exe # signin
487517
# o Uses https://github.com/sindresorhus/create-dmg
488518
# - npm install --global create-dmg
489519
# - Renames the resultant file from "SLIP-39 1.2.3.dmg" to "SLIP-39-1.2.3.dmg"
490-
# - It automatically finds the correct signing key (unkown)
520+
# - It automatically finds the correct signing key (unknown)
491521
#
492522
dist/SLIP-39-$(VERSION).dmg: dist/SLIP-39.app
493523
@echo -e "\n\n*** Creating and signing DMG $@..."
494-
npx create-dmg -v --overwrite --identity "$(PKGID)" $< dist/
495-
mv "SLIP-39 $(VERSION).dmg" "$@"
524+
#npx create-dmg -v --overwrite --identity "$(PKGID)" $< dist/
525+
npx create-dmg -v --overwrite --identity "$(DEVID)" $< dist/
526+
mv "dist/SLIP-39 $(VERSION).dmg" "$@"
496527
@echo "Checking signature..."; ./SLIP-39.metadata/check-signature $@
497528

498529
.PHONY: dist/SLIP-39-$(VERSION).dmg-verify
@@ -672,7 +703,6 @@ dist/SLIP-39-$(VERSION).pkg.upload-package: dist/SLIP-39-$(VERSION).pkg dist/SLI
672703
)
673704

674705

675-
676706
#
677707
# Build the macOS App, and Package the macOS App as a Zip file for Notarization
678708
#
@@ -800,6 +830,10 @@ dist/SLIP-39.app-checkids: SLIP-39.spec
800830
# https://github.com/txoof/codesign
801831
# https://github.com/The-Nicholas-R-Barrow-Company-LLC/PyMacApp
802832

833+
# .../src/python-slip39-14.0.2-nix-darwin-cpython-313/lib/python3.13/site-packages/PyInstaller/utils/hooks/tcl_tk.py
834+
# TK_LIBRARY environment variable must be set to the location of the tkinter installation directory. If supplied by Nix,
835+
# this can be deduced.
836+
803837
# * In order for code signing to succeed, your code signing key(s) MUST have all of their dependent
804838
# (issuer) keys downloaded to your Keychain, from https://www.apple.com/certificateauthority.
805839
# - Use Keychain Access, right-click on your signing key and click Evaluate "...".
@@ -821,8 +855,13 @@ dist/SLIP-39.app: SLIP-39-macOS.spec \
821855
@echo -e "\n\n*** Rebuilding $@, version $(VERSION)..."
822856
rm -rf build $@*
823857
sed -i"" -E "s/version=.*/version='$(VERSION)',/" $<
824-
sed -i"" -E "s/'CFBundleVersion':.*/'CFBundleVersion':'$(VERSION)',/" $<
858+
sed -i"" -E "s/'CFBundleVersion':.*/'CFBundleVersion': '$(VERSION)',/" $<
825859
sed -i"" -E "s/codesign_identity=.*/codesign_identity='$(DEVID)',/" $<
860+
@echo "Finding Tcl/Tk libraries from Nix environment..."
861+
export TCL_LIBRARY=$$($(PYTHON) -c "import tkinter; print(tkinter.Tcl().eval('info library'))") && \
862+
export TK_LIBRARY=$$($(PYTHON) -c "import tkinter; tk = tkinter.Tk(); tk.withdraw(); print(tk.eval('set ::tk_library')); tk.destroy()") && \
863+
echo " TCL_LIBRARY=$$TCL_LIBRARY" && \
864+
echo " TK_LIBRARY=$$TK_LIBRARY" && \
826865
pyinstaller --noconfirm $<
827866
#echo "Copying Provisioning Profile..."; rsync -va $(PROVISION) $@/Contents/embedded.provisionprofile
828867
echo "Checking signature (pyinstaller signed)..."; ./SLIP-39.metadata/check-signature $@ || true
@@ -833,11 +872,13 @@ dist/SLIP-39.app: SLIP-39-macOS.spec \
833872
# $@
834873
# echo "Checking signature (app code signed)..."; ./SLIP-39.metadata/check-signature $@ || true
835874
# codesign --verify $@
875+
#
876+
echo "Not valid; codesign-ing..."
836877
codesign --deep --force --timestamp --verbose --options runtime \
837-
--all-architectures \
838-
--entitlements ./SLIP-39.metadata/entitlements.plist \
839-
--sign "$(DEVID)" \
840-
$@
878+
--all-architectures \
879+
--entitlements ./SLIP-39.metadata/entitlements.plist \
880+
--sign "$(DEVID)" \
881+
$@
841882
echo "Checking signature (app code + entitlements signed w/ $(DEVID))..."; ./SLIP-39.metadata/check-signature $@ || true
842883
codesign --verify --verbose $@
843884
touch $@ # try to avoid unnecessary rebuilding
@@ -865,15 +906,21 @@ app-assess: dist/SLIP-39.app
865906
# + })
866907
# +
867908
# bundle_identifier='ca.kundert.perry.SLIP39')
868-
909+
#
910+
#
911+
# The --onefile approach is incompatible with macOS Apps; use --onedir
869912
SLIP-39-macOS.spec: SLIP-39.py
870913
@echo -e "\n\n!!! Rebuilding $@; Must be manually edited..."
871-
pyinstaller --noconfirm --windowed --onefile \
914+
pyinstaller --noconfirm --windowed --onedir \
872915
--codesign-identity "$(DEVID)" \
873916
--osx-bundle-identifier "$(BUNDLEID)" \
874917
--collect-data shamir_mnemonic \
918+
--collect-all tzdata \
919+
--collect-all zoneinfo \
875920
--hidden-import slip39 \
876921
--collect-data slip39 \
922+
--osx-entitlements-file SLIP-39.metadata/entitlements.plist \
923+
--icon images/SLIP-39.icns \
877924
$<
878925
mv SLIP-39.spec $@
879926
@echo "!!! Regenerated $@: must be manually corrected!"
@@ -888,6 +935,7 @@ SLIP-39-win32.spec: SLIP-39.py
888935
@echo -e "\n\n!!! Rebuilding $@; Must be manually edited..."
889936
pyinstaller --noconfirm --windowed --onefile \
890937
--collect-data shamir_mnemonic \
938+
--collect-data tzdata \
891939
--hidden-import slip39 \
892940
--collect-data slip39 \
893941
$<

SLIP-39-macOS.spec

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,73 @@
11
# -*- mode: python ; coding: utf-8 -*-
22
from PyInstaller.utils.hooks import collect_data_files
3+
from PyInstaller.utils.hooks import collect_all
34

45
datas = []
6+
binaries = []
7+
hiddenimports = ['slip39', 'tzdata']
58
datas += collect_data_files('shamir_mnemonic')
69
datas += collect_data_files('slip39')
10+
tmp_ret = collect_all('tzdata')
11+
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
12+
tmp_ret = collect_all('zoneinfo')
13+
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
714

8-
block_cipher = None
915

1016
a = Analysis(
1117
['SLIP-39.py'],
1218
pathex=[],
13-
binaries=[],
19+
binaries=binaries,
1420
datas=datas,
15-
hiddenimports=['slip39'],
21+
hiddenimports=hiddenimports,
1622
hookspath=[],
1723
hooksconfig={},
1824
runtime_hooks=[],
1925
excludes=[],
20-
win_no_prefer_redirects=False,
21-
win_private_assemblies=False,
22-
cipher=block_cipher,
2326
noarchive=False,
27+
optimize=0,
2428
)
25-
26-
pyz = PYZ(
27-
a.pure,
28-
a.zipped_data,
29-
cipher=block_cipher,
30-
)
29+
pyz = PYZ(a.pure)
3130

3231
exe = EXE(
3332
pyz,
3433
a.scripts,
35-
a.binaries,
36-
a.datas,
3734
[],
35+
exclude_binaries=True,
3836
name='SLIP-39',
3937
debug=False,
4038
bootloader_ignore_signals=False,
4139
strip=False,
4240
upx=True,
43-
upx_exclude=[],
44-
runtime_tmpdir=None,
4541
console=False,
4642
disable_windowed_traceback=False,
4743
argv_emulation=False,
48-
#target_arch='universal2', # Requires Python fat binary
4944
target_arch=None,
50-
codesign_identity='AAEEBB68998F340D00A05926C67D77980D562856',
45+
codesign_identity='EAA134BE299C43D27E33E2B8645FF4CF55DE8A92',
5146
entitlements_file='SLIP-39.metadata/entitlements.plist',
52-
icon='images/SLIP-39.icns',
47+
icon=['images/SLIP-39.icns'],
5348
)
54-
55-
app = BUNDLE(
49+
coll = COLLECT(
5650
exe,
51+
a.binaries,
52+
a.datas,
53+
strip=False,
54+
upx=True,
55+
upx_exclude=[],
56+
name='SLIP-39',
57+
)
58+
app = BUNDLE(
59+
coll,
5760
name='SLIP-39.app',
5861
icon='images/SLIP-39.icns',
59-
version='14.0.0',
62+
version='14.0.2',
6063
info_plist={
6164
'NSPrincipalClass': 'NSApplication',
6265
'NSAppleScriptEnabled': False,
6366
'LSBackgroundOnly': False,
6467
'NSRequiresAquaSystemAppearance': 'No',
6568
'CFBundleSupportedPlatforms': ['MacOSX'],
6669
'CFBundleIdentifier': 'ca.kundert.perry.SLIP39',
67-
'CFBundleVersion':'14.0.0',
70+
'CFBundleVersion': '14.0.2',
6871
'CFBundlePackageType':'APPL',
6972
'LSApplicationCategoryType':'public.app-category.utilities',
7073
'LSMinimumSystemVersion':'10.15',

SLIP-39.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#! /usr/bin/env python3
2-
2+
from tkinter import Tk, font # noqa: F401
33
import sys
44

55
from slip39.gui.main import main

flake.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
description = "Python HD Wallet development environment with multiple Python versions";
2+
description = "Python slip39 development environment with multiple Python versions";
33

44
inputs = {
5-
nixpkgs.url = "github:NixOS/nixpkgs/25.05";
5+
nixpkgs.url = "github:NixOS/nixpkgs/16c7794d0a28b5a37904d55bcca36003b9109aaa";
66
flake-utils.url = "github:numtide/flake-utils";
77
};
88

@@ -13,18 +13,19 @@
1313

1414
# Create Python environments with required packages
1515
mkPythonEnv = pythonPkg: pythonPkg.withPackages (ps: with ps; [
16+
tkinter
1617
pytest
17-
coincurve
18-
scikit-learn
19-
pycryptodome
20-
pynacl
18+
#coincurve scikit-learn scikit-build cmake
19+
#pycryptodome
20+
#pynacl
2121
]);
2222

2323
python310Env = mkPythonEnv pkgs.python310;
2424
python311Env = mkPythonEnv pkgs.python311;
2525
python312Env = mkPythonEnv pkgs.python312;
2626
python313Env = mkPythonEnv pkgs.python313;
2727
python314Env = mkPythonEnv pkgs.python314;
28+
python3Env = mkPythonEnv pkgs.python3;
2829

2930
in {
3031
# Single development shell with all Python versions
@@ -38,25 +39,33 @@
3839
bash
3940
bash-completion
4041

42+
# coincurve + skikit-learn requires this to build:
43+
#cmake clang ninja pkg-config
44+
4145
# All Python versions with packages
4246
#python310Env
4347
#python311Env
44-
python312Env
45-
#python313Env
48+
#python312Env
49+
python313Env
4650
#python314Env
51+
#python3Env
52+
53+
# Utilities for creating MacOS .dmg
54+
nodejs_20 # Not a bleeding-edge version
4755
];
4856

4957
shellHook = ''
5058
echo "Welcome to the multi-Python development environment!"
5159
echo "Available Python interpreters:"
5260
echo " python (default): $(python --version 2>/dev/null || echo 'not available')"
61+
echo " python3: $(python3 --version 2>/dev/null || echo 'not available')"
5362
echo " python3.10: $(python3.10 --version 2>/dev/null || echo 'not available')"
5463
echo " python3.11: $(python3.11 --version 2>/dev/null || echo 'not available')"
5564
echo " python3.12: $(python3.12 --version 2>/dev/null || echo 'not available')"
5665
echo " python3.13: $(python3.13 --version 2>/dev/null || echo 'not available')"
5766
echo " python3.14: $(python3.14 --version 2>/dev/null || echo 'not available')"
5867
echo ""
59-
echo "All versions have pytest, coincurve, scikit-learn, pycryptodome, and pynacl installed."
68+
echo "All versions have pytest, coincurve, pycryptodome, and pynacl installed."
6069
'';
6170
};
6271
});

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ dev = [
7373
"build",
7474
"setuptools",
7575
"wheel",
76+
"pyinstaller >=6.17",
77+
"tzdata",
7678
]
7779

7880
[project.urls]

0 commit comments

Comments
 (0)