-
Notifications
You must be signed in to change notification settings - Fork 5
/
cx_freeze_setup.py
241 lines (212 loc) · 8.25 KB
/
cx_freeze_setup.py
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#!/usr/bin/env python
r'''
Make stand-alone version of ncvue with cx_Freeze.
On macOS, use minimal virtual environment
if [[ "$(uname -m)" == "arm64" ]] ; then
export OPENBLAS="$(brew --prefix openblas)"
export HDF5_DIR="$(brew --prefix hdf5)"
export GEOS_DIR="$(brew --prefix geos)"
export GEOS_CONFIG="$(brew --prefix geos)/bin/geos-config"
fi
pyenv virtualenv 3.12.8 ncvue-install
pyenv local ncvue-install
# or:
# pyenv virtualenv 3.12.8 ncvue-install-ctkinter
# pyenv local ncvue-install-ctkinter
pyenv rehash
python -m pip install -r requirements.txt
# if ncvue-install-ctkinter
# python -m pip install customtkinter
python -m pip install -ve ./
python -m pip install cx_freeze
On Windows, use conda-forge for everything because more up-to-date
# Do not use mkl for smaller executable with PyInstaller/cx_Freeze
conda install -c conda-forge nomkl cartopy
conda install -c conda-forge scipy cython pykdtree cftime netcdf4
conda install -c conda-forge cx_Freeze
# pip install ncvue
Have to install ncvue, e.g. in ncvue directory
python -m pip install -ve .
Check in Windows Powershell
$env:PYTHONPATH = "C:/Users/mcuntz/prog/github/ncvue"
python.exe bin/ncvue
Executable for testing
python cx_freeze_setup.py build
macOS app
python cx_freeze_setup.py bdist_mac
macOS dmg
python cx_freeze_setup.py bdist_dmg
Windows installer
python.exe cx_freeze_setup.py bdist_msi
'''
import os
import codecs
import re
import sys
# import platform
import glob
import shutil
from cx_Freeze import setup, Executable
# from cx_Freeze.dist import build as _build
# find __version__
def _iread(*fparts):
''' Read file data. '''
here = os.path.abspath(os.path.dirname(__file__))
with codecs.open(os.path.join(here, *fparts), 'r') as fp:
return fp.read()
def _find_version(*file_paths):
'''Find version without importing module.'''
version_file = _iread(*file_paths)
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
version_file, re.M)
if version_match:
return version_match.group(1)
raise RuntimeError('Unable to find version string.')
# special build hook for macOS - remove redundant dylibs
def _post_build_mac(exedir):
adir = glob.glob(exedir + '/lib/*/.dylibs')
for aa in adir:
print('rm -r', aa)
shutil.rmtree(aa)
# special build hook for Windows - add all .dll also to base path
def _post_build_win(exedir):
adir = glob.glob(exedir + '/lib/**/*.dll', recursive=True)
for aa in adir:
if not os.path.exists(exedir + '/' + os.path.basename(aa)):
print('cp ', aa, exedir)
shutil.copy2(aa, exedir)
# special build hook for macOS on Apple Silicon (M1) - add all .dylib
# also to base path
def _post_build_m1(exedir):
adir = glob.glob(exedir + '/lib/**/*.dylib', recursive=True)
for aa in adir:
if not os.path.exists(exedir + '/' + os.path.basename(aa)):
print('cp ', aa, exedir)
shutil.copy2(aa, exedir)
# # post build hook
# # https://stackoverflow.com/questions/17806485/execute-a-python-script-post-install-using-distutils-setuptools
# class build(_build):
# def run(self):
# _build.run(self)
# if sys.platform == 'win32':
# self.execute(_post_build_win, (self.build_exe,),
# msg='Post-build on Windows')
# elif sys.platform == 'darwin':
# if platform.machine() == 'arm64':
# # self.execute(_post_build_m1, (self.build_exe,),
# # msg='Post-build on macOS Apple Silicon (M1)')
# pass
# else:
# self.execute(_post_build_mac, (self.build_exe,),
# msg='Post-build on macOS')
# else:
# pass
package = 'ncvue'
doclines1 = 'A minimal GUI for a quick view of netcdf files'
doclines = doclines1 + ', aiming to be a drop-in replacement'
doclines += ' for ncview and panoply.'
author = 'Matthias Cuntz'
copyright = 'Copyright (c) 2020-2024 Matthias Cuntz - mc (at) macu (dot) de'
version = _find_version('src/' + package, '_version.py')
script = 'src/ncvue/__main__.py'
# script = 'bin.save/ncvue'
packages = ['scipy', 'cftime', 'netCDF4'] # others detected automatically
excludes = ['pyflakes', 'mccabe', 'pycodestyle', 'flake8', # flake8
'gtk', 'PyQt4', 'PyQt5', 'wx'] # matplotlib
includes = []
# no need to include images and themes because ncvue gets installed as module
# include_files = [('ncvue/images', 'images'), ('ncvue/themes', 'themes')]
include_files = []
if sys.platform == 'win32':
base = 'Win32GUI'
exe = 'ncvue.exe'
icon = 'src/ncvue/images/ncvue_icon.ico'
msvcr = True
shortcutname = 'ncvue'
shortcutdir = 'ProgramMenuFolder'
elif sys.platform == 'darwin':
base = None
exe = 'ncvue'
icon = 'docs/images/ncvue_icon.icns'
msvcr = False
shortcutname = 'ncvue'
shortcutdir = None
else:
base = None
exe = 'ncvue'
icon = 'src/ncvue/images/ncvue_icon.ico'
msvcr = False
shortcutname = 'ncvue'
shortcutdir = None
build_exe_options = {'packages': packages,
'excludes': excludes,
'includes': includes,
'include_files': include_files,
'include_msvcr': msvcr}
executables = [Executable(script,
target_name=exe,
copyright=copyright,
base=base,
icon=icon,
shortcut_name=shortcutname,
shortcut_dir=shortcutdir)]
# Check codesign
# spctl -a -t exec -vvv build/ncvue.app
bdist_mac_options = {
'iconfile': icon,
'bundle_name': package,
# Create certificate
# https://developer.apple.com/help/account/create-certificates/create-developer-id-certificates
# Check ID (Team ID is in parenthesis)
# security find-identity -p codesigning -v
'codesign_identity': 'MATTHIAS OSKAR CUNTZ (R5T7LWQ224)',
'codesign_options': 'runtime', # Ensure codesign uses 'hardened runtime'
'codesign_verify': True, # Get more verbose logging for codesign
'spctl_assess': False, # rejects codesign because not notarized yet
'plist_items': [('NSPrincipalClass', 'NSApplication'),
('NSHighResolutionCapable', True)]
}
# Install intermediate certificates as in answer of FrostyBagg on
# https://forums.developer.apple.com/forums/thread/86161
# Do not change the trust settings.
# xcrun notarytool submit ncvue-5.1.dev1.dmg --keychain-profile "notarytool-password" --wait
# Check codesign
# spctl -a -t open -vvv --context context:primary-signature build/ncvue-5.1.dev1.dmg
bdist_dmg_options = {
'applications_shortcut': True
}
bdist_msi_options = {
'add_to_path': True,
'all_users': True,
'data': {'ProgId': [('Prog.Id', None, None, doclines1,
'IconId', None)]},
'summary_data': {'author': author,
'comments': doclines1,
'keywords': 'netcdf maps view GUI cartopy'},
'install_icon': icon}
# 'extensions': [{'extension': 'nc', # open / view netcdf files (.nc)
# 'verb': 'open',
# 'executable': exe,
# 'context': 'Open with ncvue'},
# {'extension': 'nc',
# 'verb': 'view',
# 'executable': exe,
# 'context': 'View with ncvue'},
# {'extension': 'nc4', # open / view netcdf files (.nc4)
# 'verb': 'open',
# 'executable': exe,
# 'context': 'Open with ncvue'},
# {'extension': 'nc4',
# 'verb': 'view',
# 'executable': exe,
# 'context': 'View with ncvue'}]
setup(name=package,
version=version,
description=doclines,
# cmdclass={'build': build},
options={'build_exe': build_exe_options,
'bdist_mac': bdist_mac_options,
'bdist_dmg': bdist_dmg_options,
'bdist_msi': bdist_msi_options},
executables=executables,
)