Project

General

Profile

Bundle-python » History » Version 44

Adrian Georgescu, 03/04/2018 03:48 PM

1 1 Saúl Ibarra Corretgé
h1. Building a Python Framework to bundle inside Blink
2
3 44 Adrian Georgescu
*These have moved inside blink project _build_scripts folder*
4
5
6 1 Saúl Ibarra Corretgé
In order to avoid using the system Python a custom Framework build is needed. Using a bundled Python version will make the package bigger in size, but all package versions are controlled and not up to the environment. Also, we can use the latest Python version, with latest bugfixes and features, since Apple only updates the system Python version on every major OS release.
7
8 13 Saúl Ibarra Corretgé
The following instructions only apply for 64bit builds, 32bit builds are no longer supported.
9 7 Adrian Georgescu
10 22 Adrian Georgescu
Blink dependencies must be installed under the following directory structure:
11
12
* Distribution/Frameworks/
13
* Distribution/Resources/lib
14 1 Saúl Ibarra Corretgé
 
15 7 Adrian Georgescu
h2. Building the Python Framework itself
16 1 Saúl Ibarra Corretgé
17 18 Saúl Ibarra Corretgé
* Install it using Homebrew
18 1 Saúl Ibarra Corretgé
19
<pre>
20 40 Adrian Georgescu
brew install python (this may install python 3)
21
22
To install 2.7:
23
24 41 Adrian Georgescu
brew install python2
25
26
or
27 40 Adrian Georgescu
https://stackoverflow.com/questions/18671253/how-can-i-use-homebrew-to-install-both-python-2-and-3-on-mac
28
29
brew install pyenv
30
pyenv install 2.7
31 1 Saúl Ibarra Corretgé
</pre>
32
33 18 Saúl Ibarra Corretgé
The framework will be installed and linked with Homebrew supplied OpenSSL and SQLite versions. Those libraries will need to be copied too.
34 1 Saúl Ibarra Corretgé
35 18 Saúl Ibarra Corretgé
*NOTE*: Be careful when copying the framework around, it contains symlinks and if @cp -r@ is used the size will we doubled, use @cp -a@ instead.
36 22 Adrian Georgescu
37
The Python framework is found in
38
39
<pre>
40 27 Adrian Georgescu
cp -a /usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework ~/work/blink/Distribution/Frameworks/
41 22 Adrian Georgescu
</pre>
42
43 2 Saúl Ibarra Corretgé
* Reduce the size of the Python Framework:
44
45 1 Saúl Ibarra Corretgé
There are a number of things that can (and must when submitting a sandbox app to Mac App Store) be removed from the framework directory to make it smaller in size:
46
47
<pre>
48 43 Adrian Georgescu
cd ~/work/blink/Distribution/Frameworks/Python.framework
49 42 Adrian Georgescu
cd Versions/2.7
50
ln -sf Current 2.7
51 43 Adrian Georgescu
cd ~/work/blink/Distribution/Frameworks/Python.framework
52 42 Adrian Georgescu
ln -sf Versions/Current/Headers .
53
ln -sf Versions/Current/Python .
54
ln -sf Versions/Current/Resources .
55 26 Adrian Georgescu
find . -name *.pyc -exec rm -r "{}" \; 
56
find . -name *.pyo -exec rm -r "{}" \; 
57 24 Adrian Georgescu
rm -r Versions/Current/lib/python2.7/config/python.o
58
rm -r Versions/Current/bin
59
rm -r Versions/Current/Resources/*
60
rm -r Versions/Current/lib/python2.7/test
61
rm -r Versions/Current/lib/python2.7/plat-*
62
rm -r Versions/Current/lib/python2.7/idlelib
63
rm -r Versions/Current/lib/python2.7/curses
64
rm -r Versions/Current/lib/python2.7/lib2to3
65
rm -r Versions/Current/lib/python2.7/lib-tk
66
rm -r Versions/Current/lib/python2.7/bsddb
67
rm -r Versions/Current/lib/python2.7/lib-dynload/gdbm.so
68
rm -r Versions/Current/lib/python2.7/lib-dynload/readline.so
69 35 Adrian Georgescu
rm -r Versions/2.7/lib/python2.7/site-packages
70 1 Saúl Ibarra Corretgé
</pre>
71 3 Saúl Ibarra Corretgé
72 1 Saúl Ibarra Corretgé
Replace @Versions/Current/lib/python2.7/site.py@ with an empty file.
73 28 Adrian Georgescu
74
<pre>
75 38 Adrian Georgescu
rm ~/work/blink/Distribution/Frameworks//Python.framework/Versions/Current/lib/python2.7/site.py
76
touch ~/work/blink/Distribution/Frameworks//Python.framework/Versions/Current/lib/python2.7/site.py
77 28 Adrian Georgescu
</pre>
78 5 Saúl Ibarra Corretgé
79 34 Adrian Georgescu
Python Framework needs file a Info.plist file under Resources in order to be compatible with latest OSX bundle structure:
80
81
<pre>
82
cp build_scripts/PythonFramework.plist Distribution/Frameworks/Python.framework/Resources/Info.plist           
83
</pre>
84
85
86 5 Saúl Ibarra Corretgé
h2. Compiling PyObjC
87
88 13 Saúl Ibarra Corretgé
In order to get a PyObjC version that will work with the framework created above (Python 2.7, 64bits) an equivalent Python must be used to compile it. That is, if has to be a Python 2.7 version (it doesn't have to be the exact version) and it has to be a 64bit version. The MACOSX_DEPLOYMENT_TARGET must also be set to the appropriate value.
89 5 Saúl Ibarra Corretgé
90
PyObjcC can be installed with easy_install or pip. We install it in 2 steps to save some compilation time due to a bug in the build system:
91 1 Saúl Ibarra Corretgé
92 5 Saúl Ibarra Corretgé
<pre>
93
pip install pyobjc-core
94
pip install pyobjc
95 23 Adrian Georgescu
pip install pycrypto
96 1 Saúl Ibarra Corretgé
</pre>
97
98 5 Saúl Ibarra Corretgé
When compiling PyObjC a Python package will be created for every system framework, but not all of them are needed (at the moment), so just pick the ones we use:
99
100
<pre>
101
AddressBook
102
AppKit
103 1 Saúl Ibarra Corretgé
Cocoa
104 5 Saúl Ibarra Corretgé
CoreFoundation
105
Foundation
106 13 Saúl Ibarra Corretgé
JavaScriptCore
107 5 Saúl Ibarra Corretgé
LaunchServices
108 1 Saúl Ibarra Corretgé
PyObjCTools
109
Quartz
110 13 Saúl Ibarra Corretgé
ScriptingBridge
111
StoreKit
112 1 Saúl Ibarra Corretgé
WebKit
113 8 Adrian Georgescu
objc
114 6 Saúl Ibarra Corretgé
</pre>
115
116 1 Saúl Ibarra Corretgé
117 21 Adrian Georgescu
For example this is the content of a Resources/lib bundled with Blink Cocoa as of November 3rd, 2016 (including sipsimple dependencies & all):
118 20 Adrian Georgescu
119 1 Saúl Ibarra Corretgé
<pre>
120
AVFoundation
121
AddressBook
122
AppKit
123
Cocoa
124
CoreFoundation
125
Crypto
126
Foundation
127
LaunchServices
128
PyObjCTools
129
Quartz
130
ScriptingBridge
131
WebKit
132
_cffi_backend.so
133
_ldap.so
134
_markerlib
135
application
136
cffi
137
cjson.so
138
cryptography
139
cryptography-1.5.1.dist-info
140
dateutil
141
dns
142
dsml.py
143
enum
144
eventlib
145
formencode
146
gmpy2.so
147
gnutls
148
greenlet.so
149
idna
150
ipaddress.py
151
ldap
152
ldapurl.py
153
ldif.py
154
lxml
155
msrplib
156
objc
157
otr
158
pkg_resources
159
pyasn1
160
pycparser
161
pydispatch
162
pytz
163
service_identity
164
sipsimple
165
six.py
166
sqlobject
167
twisted
168
xcaplib
169 21 Adrian Georgescu
</pre>
170
171
172
*NOTE:* The _objc_ package is located inside a _PyObjC_ directory, just copy it from there, without the parent directory.
173
174
<pre>
175
__import__('pkg_resources').declare_namespace(__name__)
176
</pre>
177
178 25 Adrian Georgescu
h2. Fix library paths
179
180
All libraries must have their relative path change to the Framework path bundled within Blink.app
181
182
<pre>
183
#!/bin/sh
184
185
old_path="local/lib/\|local/Cellar/\|/usr/local/opt/libmpc/lib/\|/usr/local/opt/mpfr/lib/\|Frameworks/Frameworks/\|/Users/adigeo/work/ag-projects/video/local/lib/"
186
new_path="@executable_path/../Frameworks/"
187
188
for library in $@; do
189
  install_name_tool -id $new_path$library $library
190
  dependencies=$(otool -L $library | grep $old_path | awk '{print $1}')
191
  for dependency in $dependencies; do
192
      new_basename=$(basename $dependency)
193
      new_name="$new_path$new_basename"
194
      echo $dependency $new_name $library
195
      install_name_tool -change $dependency $new_name $library
196
  done
197 1 Saúl Ibarra Corretgé
done
198
</pre>
199
200
A script is available in ./build_scripts/ directory
201
202
<pre>
203
./build_scripts/change_lib_names.sh Distribution/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/*.so
204
chmod +w Distribution/Frameworks/Python.framework/Versions/Current/Python
205
./build_scripts/change_lib_names.sh Distribution/Frameworks/Python.framework/Versions/Current/Python
206
</pre>
207
208 33 Adrian Georgescu
*NOTE*: Python.framework as well as all other libraries must be signed using command line tools. Make sure when building Blink that "Code sign on copy" option is disabled for Python.framework. This script can be used to sign all libraries and frameworks
209
210
<pre>
211
sos=`find ./Resources/lib -name *.so`; for s in $sos; do codesign -f -s '3rd Party Mac Developer Application: AG Projects' $s; done
212
sos=`find ./Frameworks -name *.dylib`; for s in $sos; do codesign -f -s '3rd Party Mac Developer Application: AG Projects' $s; done
213
sos=`find ./Frameworks -name *.so`; for s in $sos; do codesign -f -s '3rd Party Mac Developer Application: AG Projects' $s; done
214
sos=`find ./Frameworks -name *.o`; for s in $sos; do codesign -f -s '3rd Party Mac Developer Application: AG Projects' $s; done
215
sos=`find ./Frameworks -name *.a`; for s in $sos; do codesign -f -s '3rd Party Mac Developer Application: AG Projects' $s; done
216
</pre>
217
218
A script is available in ./build_scripts/ directory
219
220
<pre>
221
./build_scripts/codesign.sh 
222
</pre>
223 29 Adrian Georgescu
224 21 Adrian Georgescu
h2. Module exceptions
225
226
When copying built Python modules into the distribution folder, care must be taken with the 2 following packages:
227
228 1 Saúl Ibarra Corretgé
* zope: an empty @__init__.py@ file must be created in the @zope@ directory
229
* cryptography: the @*-dist.info@ must be copied too
230 39 Adrian Georgescu
* _PyObjCTools_ is not a valid Python package, as it lacks a @__init__.py@ file, an empty one needs to be manually created with this content:
231
232 21 Adrian Georgescu
233
h1. Creating a sandbox (Python virtualenv)
234
235
<pre>
236
sudo easy_install pip
237
sudo pip install virtualenv virtualenvwrapper
238
</pre>
239
240
Add to ~.bashrc
241
242
<pre>
243
# Virtualenv
244
export WORKON_HOME=$HOME/.virtualenvs
245
export PIP_VIRTUALENV_BASE=$WORKON_HOME
246
export PIP_RESPECT_VIRTUALENV=true
247
export VIRTUALENVWRAPPER_SCRIPT=/usr/local/bin/virtualenvwrapper.sh
248
[[ -f /usr/local/bin/virtualenvwrapper_lazy.sh ]] && source /usr/local/bin/virtualenvwrapper_lazy.sh
249
</pre>
250
251
Creating a sandbox:
252
253
<pre>
254
mkvirtualenv -p $(which python2.7) sandbox
255
</pre>
256
257
Exiting the sandbox:
258
259
<pre>
260
deactivate
261
</pre>
262
263
Entering the sandbox:
264
265
<pre>
266
workon sandbox
267 19 Adrian Georgescu
</pre>