Project

General

Profile

Bundle-python » History » Version 34

Adrian Georgescu, 11/08/2016 03:20 PM

1 1 Saúl Ibarra Corretgé
h1. Building a Python Framework to bundle inside Blink
2
3
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.
4
5 13 Saúl Ibarra Corretgé
The following instructions only apply for 64bit builds, 32bit builds are no longer supported.
6 7 Adrian Georgescu
7 22 Adrian Georgescu
Blink dependencies must be installed under the following directory structure:
8
9
* Distribution/Frameworks/
10
* Distribution/Resources/lib
11 1 Saúl Ibarra Corretgé
 
12 7 Adrian Georgescu
h2. Building the Python Framework itself
13 1 Saúl Ibarra Corretgé
14 18 Saúl Ibarra Corretgé
* Install it using Homebrew
15 1 Saúl Ibarra Corretgé
16
<pre>
17 18 Saúl Ibarra Corretgé
brew install python
18 1 Saúl Ibarra Corretgé
</pre>
19
20 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.
21 1 Saúl Ibarra Corretgé
22 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.
23 22 Adrian Georgescu
24
The Python framework is found in
25
26
<pre>
27 27 Adrian Georgescu
cp -a /usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework ~/work/blink/Distribution/Frameworks/
28 22 Adrian Georgescu
</pre>
29
30 2 Saúl Ibarra Corretgé
* Reduce the size of the Python Framework:
31
32 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:
33
34
<pre>
35 27 Adrian Georgescu
cd ~/work/blink/Distribution/Frameworks//Python.framework
36 26 Adrian Georgescu
find . -name *.pyc -exec rm -r "{}" \; 
37
find . -name *.pyo -exec rm -r "{}" \; 
38 24 Adrian Georgescu
rm -r Versions/Current/lib/python2.7/config/python.o
39
rm -r Versions/Current/Mac
40
rm -r Versions/Current/bin
41
rm -r Versions/Current/share
42
rm -r Versions/Current/Resources/*
43
rm -r Versions/Current/Resources/*.app
44
rm -r Versions/Current/lib/python2.7/test
45
rm -r Versions/Current/lib/python2.7/plat-*
46
rm -r Versions/Current/lib/python2.7/idlelib
47
rm -r Versions/Current/lib/python2.7/curses
48
rm -r Versions/Current/lib/python2.7/lib2to3
49
rm -r Versions/Current/lib/python2.7/lib-tk
50
rm -r Versions/Current/lib/python2.7/bsddb
51
rm -r Versions/Current/lib/python2.7/lib-dynload/gdbm.so
52
rm -r Versions/Current/lib/python2.7/lib-dynload/readline.so
53 1 Saúl Ibarra Corretgé
</pre>
54 3 Saúl Ibarra Corretgé
55 1 Saúl Ibarra Corretgé
Replace @Versions/Current/lib/python2.7/site.py@ with an empty file.
56 28 Adrian Georgescu
57
<pre>
58
rm Versions/Current/lib/python2.7/site.py
59
touch Versions/Current/lib/python2.7/site.py
60
</pre>
61 5 Saúl Ibarra Corretgé
62 34 Adrian Georgescu
Python Framework needs file a Info.plist file under Resources in order to be compatible with latest OSX bundle structure:
63
64
<pre>
65
cp build_scripts/PythonFramework.plist Distribution/Frameworks/Python.framework/Resources/Info.plist           
66
</pre>
67
68
69 5 Saúl Ibarra Corretgé
h2. Compiling PyObjC
70
71 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.
72 5 Saúl Ibarra Corretgé
73
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:
74 1 Saúl Ibarra Corretgé
75 5 Saúl Ibarra Corretgé
<pre>
76
pip install pyobjc-core
77
pip install pyobjc
78 23 Adrian Georgescu
pip install pycrypto
79 1 Saúl Ibarra Corretgé
</pre>
80
81 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:
82
83
<pre>
84
AddressBook
85
AppKit
86 1 Saúl Ibarra Corretgé
Cocoa
87 5 Saúl Ibarra Corretgé
CoreFoundation
88
Foundation
89 13 Saúl Ibarra Corretgé
JavaScriptCore
90 5 Saúl Ibarra Corretgé
LaunchServices
91 1 Saúl Ibarra Corretgé
PyObjCTools
92
Quartz
93 13 Saúl Ibarra Corretgé
ScriptingBridge
94
StoreKit
95 1 Saúl Ibarra Corretgé
WebKit
96 8 Adrian Georgescu
objc
97 6 Saúl Ibarra Corretgé
</pre>
98
99 1 Saúl Ibarra Corretgé
100 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):
101 20 Adrian Georgescu
102 1 Saúl Ibarra Corretgé
<pre>
103
AVFoundation
104
AddressBook
105
AppKit
106
Cocoa
107
CoreFoundation
108
Crypto
109
Foundation
110
LaunchServices
111
PyObjCTools
112
Quartz
113
ScriptingBridge
114
WebKit
115
_cffi_backend.so
116
_ldap.so
117
_markerlib
118
application
119
cffi
120
cjson.so
121
cryptography
122
cryptography-1.5.1.dist-info
123
dateutil
124
dns
125
dsml.py
126
enum
127
eventlib
128
formencode
129
gmpy2.so
130
gnutls
131
greenlet.so
132
idna
133
ipaddress.py
134
ldap
135
ldapurl.py
136
ldif.py
137
lxml
138
msrplib
139
objc
140
otr
141
pkg_resources
142
pyasn1
143
pycparser
144
pydispatch
145
pytz
146
service_identity
147
sipsimple
148
six.py
149
sqlobject
150
twisted
151
xcaplib
152 21 Adrian Georgescu
</pre>
153
154
155
*NOTE:* The _objc_ package is located inside a _PyObjC_ directory, just copy it from there, without the parent directory.
156
157
*NOTE:* _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:
158
159
<pre>
160
__import__('pkg_resources').declare_namespace(__name__)
161
</pre>
162
163 25 Adrian Georgescu
h2. Fix library paths
164
165
All libraries must have their relative path change to the Framework path bundled within Blink.app
166
167
<pre>
168
#!/bin/sh
169
170
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/"
171
new_path="@executable_path/../Frameworks/"
172
173
for library in $@; do
174
  install_name_tool -id $new_path$library $library
175
  dependencies=$(otool -L $library | grep $old_path | awk '{print $1}')
176
  for dependency in $dependencies; do
177
      new_basename=$(basename $dependency)
178
      new_name="$new_path$new_basename"
179
      echo $dependency $new_name $library
180
      install_name_tool -change $dependency $new_name $library
181
  done
182 1 Saúl Ibarra Corretgé
done
183
</pre>
184
185
A script is available in ./build_scripts/ directory
186
187
<pre>
188
./build_scripts/change_lib_names.sh Distribution/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/*.so
189
chmod +w Distribution/Frameworks/Python.framework/Versions/Current/Python
190
./build_scripts/change_lib_names.sh Distribution/Frameworks/Python.framework/Versions/Current/Python
191
</pre>
192
193 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
194
195
<pre>
196
sos=`find ./Resources/lib -name *.so`; for s in $sos; do codesign -f -s '3rd Party Mac Developer Application: AG Projects' $s; done
197
sos=`find ./Frameworks -name *.dylib`; for s in $sos; do codesign -f -s '3rd Party Mac Developer Application: AG Projects' $s; done
198
sos=`find ./Frameworks -name *.so`; for s in $sos; do codesign -f -s '3rd Party Mac Developer Application: AG Projects' $s; done
199
sos=`find ./Frameworks -name *.o`; for s in $sos; do codesign -f -s '3rd Party Mac Developer Application: AG Projects' $s; done
200
sos=`find ./Frameworks -name *.a`; for s in $sos; do codesign -f -s '3rd Party Mac Developer Application: AG Projects' $s; done
201
</pre>
202
203
A script is available in ./build_scripts/ directory
204
205
<pre>
206
./build_scripts/codesign.sh 
207
</pre>
208 29 Adrian Georgescu
209 21 Adrian Georgescu
h2. Module exceptions
210
211
When copying built Python modules into the distribution folder, care must be taken with the 2 following packages:
212
213
* zope: an empty @__init__.py@ file must be created in the @zope@ directory
214
* cryptography: the @*-dist.info@ must be copied too
215
216
h1. Creating a sandbox (Python virtualenv)
217
218
<pre>
219
sudo easy_install pip
220
sudo pip install virtualenv virtualenvwrapper
221
</pre>
222
223
Add to ~.bashrc
224
225
<pre>
226
# Virtualenv
227
export WORKON_HOME=$HOME/.virtualenvs
228
export PIP_VIRTUALENV_BASE=$WORKON_HOME
229
export PIP_RESPECT_VIRTUALENV=true
230
export VIRTUALENVWRAPPER_SCRIPT=/usr/local/bin/virtualenvwrapper.sh
231
[[ -f /usr/local/bin/virtualenvwrapper_lazy.sh ]] && source /usr/local/bin/virtualenvwrapper_lazy.sh
232
</pre>
233
234
Creating a sandbox:
235
236
<pre>
237
mkvirtualenv -p $(which python2.7) sandbox
238
</pre>
239
240
Exiting the sandbox:
241
242
<pre>
243
deactivate
244
</pre>
245
246
Entering the sandbox:
247
248
<pre>
249
workon sandbox
250 19 Adrian Georgescu
</pre>