-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathlnp.spec
140 lines (126 loc) · 5.6 KB
/
lnp.spec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# -*- mode: python -*-
# If PIL or similar is available on this system, it will be available for the
# generated executable. Since this is the only factor in whether or not we
# will be able to use non-GIF images, we only include the appropriate version.
import sys
if sys.platform == 'win32':
try:
from PyInstaller.utils.winmanifest import Manifest
except ImportError:
# Newer PyInstaller versions
from PyInstaller.utils.win32.winmanifest import Manifest
Manifest.old_toprettyxml = Manifest.toprettyxml
def new_toprettyxml(self, indent=" ", newl=os.linesep, encoding="UTF-8"): # noqa: F821
s = self.old_toprettyxml(indent, newl, encoding)
# Make sure we only modify our own manifest
if 'name="lnp"' in s:
d = (indent
+ '<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">'
'<windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">'
'<dpiAware>false</dpiAware></windowsSettings></asmv3:application>'
+ newl)
s = s.replace('</assembly>', d + '</assembly>')
return s
Manifest.toprettyxml = new_toprettyxml
try:
from PIL import Image, ImageTk
has_PIL = True
except ImportError: # Some PIL installations live outside of the PIL package
try:
import Image # noqa: F401
import ImageTk # noqa: F401
has_PIL = True
except ImportError: # No PIL compatible library
has_PIL = False
from tkinter import * # noqa: F403
if has_PIL or TkVersion >= 8.6:
logo = 'LNPSMALL.png'
icon = 'LNP.png'
else:
logo = 'LNPSMALL.gif'
icon = 'LNP.gif'
extension = ''
script = 'launch.py'
if sys.platform == 'win32':
icon = 'LNP.ico'
extension = '.exe'
hiddenimports = []
if sys.platform.startswith('linux'):
hiddenimports = ['PIL', 'PIL._imagingtk', 'PIL._tkinter_finder']
needs_tcl_copy = False
if sys.platform == 'darwin' and sys.hexversion >= 0x3070000:
needs_tcl_copy = True
try:
# HACK: PyInstaller is not handling the bundled Tcl and Tk in Python 3.7 from python.org
# properly.
#
# This patch intercepts the value that causes PyInstaller to attempt to use the wrong Tcl/Tk
# version and triggers a fallback to treat Tcl/Tk as a Unix-style build.
#
# See https://github.com/pyinstaller/pyinstaller/issues/3753 for the relevant bug report for
# PyInstaller
from PyInstaller.depend import bindepend
old_selectImports = bindepend.selectImports
def patched_selectImports(pth, xtrapath=None):
rv = old_selectImports(pth, xtrapath)
if '_tkinter' in pth:
import inspect
caller = inspect.stack()[1]
if ('hook-_tkinter.py' in caller.filename and 'Library/Frameworks' in rv[0][1]
and 'Python' in rv[0][1]):
return [('libtcl8.6.dylib', ''), ('libtk8.6.dylib', '')]
return rv
bindepend.selectImports = patched_selectImports
except ImportError:
pass
a = Analysis(
[script], pathex=['.'], hiddenimports=hiddenimports, hookspath=None, runtime_hooks=None)
a.datas += [(logo, logo, 'DATA'), (icon, icon, 'DATA')]
if sys.platform == 'win32':
# Importing pkg_resources fails with Pillow on Windows due to
# un-normalized case; this works around the problem
a.datas = list({tuple(map(str.upper, t)) for t in a.datas})
pyz = PYZ(a.pure)
if sys.platform != 'darwin':
exe = EXE(
pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name='PyLNP' + extension,
debug=False, strip=None, upx=False, console=False, icon='LNP.ico')
else:
info = {'NSHighResolutionCapable': 'True'}
exe = EXE(
pyz, a.scripts, exclude_binaries=True, name='PyLNP' + extension,
debug=False, strip=None, upx=True, console=False)
coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=None, upx=True, name='PyLNP')
app = BUNDLE(coll, name='PyLNP.app', icon='LNP.icns', info_plist=info)
if needs_tcl_copy:
import shutil
import os
def copytree(src, dst, symlinks=False, ignore=None):
if not os.path.exists(dst):
os.makedirs(dst)
for item in os.listdir(src):
s = os.path.join(src, item)
d = os.path.join(dst, item)
if os.path.isdir(s):
copytree(s, d, symlinks, ignore)
else:
if not os.path.exists(d) or os.stat(s).st_mtime - os.stat(d).st_mtime > 1:
shutil.copy2(s, d)
# Manually copy tcl/tk files into .app - based on copy commands mentioned here:
# https://github.com/pyinstaller/pyinstaller/issues/3753#issuecomment-432464838
# https://stackoverflow.com/questions/56092383/how-to-fix-msgcatmc-error-after-running-app-from-pyinstaller-on-macos-mojave
basepath = os.path.normpath(os.path.join(os.path.dirname(sys.executable), '..', 'lib'))
for e in os.listdir(basepath):
p = os.path.join(basepath, e)
if not os.path.isdir(p):
continue
if e == 'tcl8':
dst = os.path.abspath(os.path.join(app.name, 'Contents', 'MacOS', 'tcl8'))
elif e.startswith('tcl'):
dst = os.path.abspath(os.path.join(app.name, 'Contents', 'MacOS', 'tcl'))
elif e.startswith('tk') or e.startswith('Tk'):
dst = os.path.abspath(os.path.join(app.name, 'Contents', 'MacOS', 'tk'))
else:
continue
copytree(p, dst)
# vim:expandtab