forked from Sigil-Ebook/Sigil
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Building_A_Relocatable_Python_3.9_Framework_on_MacOSX.txt
370 lines (274 loc) · 13.7 KB
/
Building_A_Relocatable_Python_3.9_Framework_on_MacOSX.txt
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
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
# *** IMPORTANT ***
# Build Prerequisite requirements for Python 3.9.9 on macOS 10.12 Sierra and later users:
#
# First make sure you are using the latest XCode for your version of Mac OSX
# Then make sure you have the command line tools (CLT) installed (via xcode-select --install)
#
#
# For Python's pip3 and lzma module, and other Python functionality you will need to
# compile and install the headers and static library versions of liblzma.a (xz),
# libssl.a (libopenssl), and libcrypto.a (libopenssl), along side
# static versions of sqlite, and a specially built internal TclTk library
#
# Create a build folder where all of the work will be done
cd
mkdir devpython
cd devpython
mkdir sources
If you are using XCode 10.X on MacOSX 10.14.X, remember to install the command line tools
and their headers! The headers are now not installed by default. An installer package
for the headers can be found here:
/Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
# First build the main prerequisites
# Download openssl-1.1.1l.tar.gz or later into sources from https://www.openssl.org/source
export MACOSX_DEPLOYMENT_TARGET=10.12
export LDFLAGS="-Wl,-macosx_version_min,10.12"
export CFLAGS="-mmacosx-version-min=10.12 -Werror=partial-availability"
tar -zxvf sources/openssl-1.1.1l.tar.gz
cd openssl-1.1.1l
./config no-shared --prefix=/usr/local
make
sudo make install
# Download xz-5.2.5.tar.gz or later into sources from https://tukaani.org/xz/ (via sourceforge)
export MACOSX_DEPLOYMENT_TARGET=10.12
export LDFLAGS="-Wl,-macosx_version_min,10.12"
export CFLAGS="-mmacosx-version-min=10.12 -Werror=partial-availability"
# Since configure is very stupid in how it tests symbols on macOSX we need
# to apply a patch to prevent it from using something that does not exist
# on our deployment target of 10.12 as below (futimens does not exist on macOS10.12)
cat fix_xz_for_macOS_10.12.patch
--- configure.orig 2019-06-04 11:12:26.000000000 -0400
+++ configure 2019-06-04 11:12:42.000000000 -0400
@@ -18233,7 +18233,7 @@
# Find the best function to set timestamps.
-for ac_func in futimens futimes futimesat utimes _futime utime
+for ac_func in futimes futimesat utimes _futime utime
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-------
tar -zxvf sources/xz-5.2.5.tar.gz
cd xz-5.2.5
patch -p0 < fix_xz_for_macOS_10.12.patch
./configure --disable-shared --prefix=/usr/local
make
sudo make install
# Download sqlite-autoconf-3350500.tar.gz into sources from https://sqlite.org/2021/sqlite-autoconf-3350500.tar.gz"
export MACOSX_DEPLOYMENT_TARGET=10.12
export LDFLAGS="-Wl,-macosx_version_min,10.12"
export CFLAGS="-mmacosx-version-min=10.12 -Werror=partial-availability -Os -DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_JSON1 \
-DSQLITE_ENABLE_RTREE -DSQLITE_TCL=0 "
tar -zxvf sources/sqlite-autoconf-3350500.tar.gz
cd sqlite-autoconf-3350500
./configure --enable-threadsafe --enable-shared=no --enable-static=yes --disable-readline --disable-dependency-tracking
make
sudo make install
# Specify the future home for the Python.framework and interim tcltk pieces
mkdir libraries
cd libraries
export MYLIBS=`pwd`
mkdir Frameworks
cd Frameworks
export MYDEST=`pwd`
cd ../../
# To enable the Tk / tkinter graphical ui for Python we will need to make a special combined build of tcl and tk
# and build it right "in place" for the future Python.framework to install around
# Download tcl8.6.12-src.tar.gz into sources from ftp://ftp.tcl.tk/pub/tcl//tcl8_6/tcl8.6.12-src.tar.gz
# Download tk8.6.12-src.tar.gz into sources from ftp://ftp.tcl.tk/pub/tcl//tcl8_6/tk8.6.12-src.tar.gz
mkdir tcltk
cd tcltk
tar -zxvf ../sources/tcl8.6.12-src.tar.gz
tar -zxvf ../sources/tk8.6.12-src.tar.gz
# Note: TCL_LIBRARY and TK_LIBRARY and libdir are appended to DESTDIR to get actual paths
export MACOSX_DEPLOYMENT_TARGET=10.12
export CFLAGS="-arch x86_64 -mmacosx-version-min=10.12"
cd tcl8.6.12/unix
./configure --enable-shared --enable-threads --libdir=/Frameworks/Python.framework/Versions/3.9/lib
make TCL_LIBRARY=/Frameworks/Python.framework/Versions/3.9/lib/tcl8.6 DESTDIR=${MYLIBS}
make install TCL_LIBRARY=/Frameworks/Python.framework/Versions/3.9/lib/tcl8.6 DESTDIR=${MYLIBS}
cd ../../
cd tk8.6.12/unix
./configure --libdir=/Frameworks/Python.framework/Versions/3.9/lib --enable-aqua --enable-shared --enable-threads
make TCL_LIBRARY=/Frameworks/Python.framework/Versions/3.9/lib/tcl8.6 \
TK_LIBRARY=/Frameworks/Python.framework/Versions/3.9/lib/tk8.6 \
DESTDIR=${MYLIBS}
make install TCL_LIBRARY=/Frameworks/Python.framework/Versions/3.9/lib/tcl8.6 \
TK_LIBRARY=/Frameworks/Python.framework/Versions/3.9/lib/tk8.6 \
DESTDIR=${MYLIBS}
# As a last step fixup the dylib official names to properly reflect their new home
cd ${MYDEST}/Python.framework/Versions/3.9/lib
chmod u+w libtk8.6.dylib
chmod u+w libtcl8.6.dylib
install_name_tool -id ${MYDEST}/Python.framework/Versions/3.9/lib/libtcl8.6.dylib ./libtcl8.6.dylib
install_name_tool -id ${MYDEST}/Python.framework/Versions/3.9/lib/libtk8.6.dylib ./libtk8.6.dylib
# And finally:
# if you are using Qt5, we will be building a required PyQt5 python module, you will need to have built or
# downloaded prebuilt versions of Qt 5.12.X or later first
# So see Building_Qt5_From_Source_on_MacOSX.txt
#
# if you are using Qt6, we will building the required PySide6 module, you will need to have built
# or downloaded prebuilt versions of Qt 6.2.2 or later
# Building Python 3.9.9 to be fully relocatable for macOS 10.12 and later
# Before building remember to rename any /Applications/Python 3.9.app to save it and replace it afterwards
# as the damn python installation from source always overwrites it no matter the configure prefix used
# Download Python-3.9.9.tgz into sources from www.python.org
cd ${MYDEST}
cd ../../
export MACOSX_DEPLOYMENT_TARGET=10.12
# now build Python 3.9.9 as a framework
# Need to patch Python-3.9.9 to allow it to build Mac OS X 10.12 compliant and later
# Note the following calls used in configure are *not* defined on mac OS 10.12
# futimens
# utimensat
# clock_gettime
# clock_getres
# clock_settime
unxz ./sources/Python-3.9.9.tar.xz
tar -xvf ./sources/Python-3.9.9.tar
cd Python-3.9.9
patch -p0 < ../sources/python_3.9.9_fixes.patch
export LDFLAGS="-Wl,-macosx_version_min,10.12"
export CFLAGS="-mmacosx-version-min=10.12 -Werror=partial-availability"
./configure --prefix=${MYDEST} --enable-framework=${MYDEST} --with-ensurepip \
--with-tcltk-includes="-I${MYLIBS}/usr/local/include" \
--with-tcltk-libs="-L${MYDEST}/Python.framework/Versions/3.9/lib -ltcl8.6 -ltk8.6"
make
make frameworkinstall
# next update path in order to use the newly built/installed Python.framework's
# and then use pip3 to install all other required python packages to its site-packages
export PATH=${MYDEST}/Python.framework/Versions/3.9/bin:${PATH}
which pip3
pip3 install six
pip3 install html5lib
pip3 install lxml
pip3 install Pillow
pip3 install regex
pip3 install css-parser
pip3 install cssselect
pip3 install chardet
pip3 install certifi
pip3 install urllib3
pip3 install dulwich
Note: we have replaced cssutils with a drop in replacement with many bugs fixed
called css-parser.
# Now a complete Python.framework has been built in ${MYDEST}
# But we still need to make it a relocatable framework
# To make it relocatable we need to use otool and install_name_tool to change
# the dylib name and path to it from all executables in the Python.framework
# A Quick Guide: On Mac OS X, one may use:
# "otool -D <file>" to view the install name of a dylib
# "otool -L <file>" to view the dependencies
# "otool -l <file> | grep LC_RPATH -A2" to view the RPATHs
# "install_name_tool -id ..." to change an install name
# "install_name_tool -change ..." to change the dependencies
# "install_name_tool -rpath ... -add_rpath ... -delete_rpath ..." to change RPATHs
# Make the framework's main dylib relocatable using rpath
cd ${MYDEST}/Python.framework/Versions/3.9/
chmod u+w Python
otool -D ./Python
install_name_tool -id @rpath/Python ./Python
# Change the dependencies of the executable files in bin to point to the relocatable
# framework in a relative way and add the proper rpath to find the Python (renamed dylib)
cd bin
install_name_tool -change ${MYDEST}/Python.framework/Versions/3.9/Python @rpath/Python python3.9
install_name_tool -add_rpath @executable_path/../ ./python3.9
# so that python3 can find the Qt Frameworks and proper plugins for PyQt5
install_name_tool -add_rpath @executable_path/../../../../ ./python3.9
# now do the same for the Python.app stored inside the Python.framework Resources
# This app is needed to allow gui use by python for plugins
cd ${MYDEST}/Python.framework/Versions/3.9/Resources/Python.app/Contents/MacOS
install_name_tool -change ${MYDEST}/Python.framework/Versions/3.9/Python @rpath/Python ./Python
install_name_tool -add_rpath @executable_path/../../../../ ./Python
# And finally we need to change the name id on the libtk and libtcl to be rpath based
# and fix the _tkinter*.so to have an rpath with a @loader_path back up to the lib dir where they live
cd ${MYDEST}/Python.framework/Versions/3.9/lib
otool -D libtk8.6.dylib
otool -D libtcl8.6.dylib
install_name_tool -id @rpath/libtcl8.6.dylib ./libtcl8.6.dylib
install_name_tool -id @rpath/libtk8.6.dylib ./libtk8.6.dylib
cd ${MYDEST}/Python.framework/Versions/3.9/lib/python3.9/lib-dynload
install_name_tool -add_rpath @loader_path/../.. _tkinter.cpython-39-darwin.so
install_name_tool -change ${MYDEST}/Python.framework/Versions/3.9/lib/libtcl8.6.dylib @rpath/libtcl8.6.dylib _tkinter.cpython-39-darwin.so
install_name_tool -change ${MYDEST}/Python.framework/Versions/3.9/lib/libtk8.6.dylib @rpath/libtk8.6.dylib _tkinter.cpython-39-darwin.so
# We should now have a fully relocatable Python.framework
# We will now use this just-built Python3.9 interpreter to install PyQt5, PyQtWebEngine and sip
# for Qt 5.12.X or PySide6 for Qt 6.2.2
# ***** IF USING QT5 ******
# **** Important: versions of PyQt5 and sip must be selected to match with the Qt version
# **** In these instructions we are using Qt 5.12.X and therefore need:
# **** sip-4.19.18 and PyQt5_gpl-5.12.3 and PyQtWebEngine_gpl-5.12.1
# First Build sip
# Building sip-4.19.18 from source and installing it into your Python Interpreter
# From https://www.riverbankcomputing.com/software/pyqt/download5
# Download sip-4.19.18.tar.gz
# More detailed build instructions can be found here:
# http://pyqt.sourceforge.net/Docs/sip4/installation.html
# Must have the python interpreter you want to install PyQt5 into in the PATH to be found first
export PATH=${MYDEST}/Python.framework/Versions/3.9/bin:${PATH}
which python3
tar -zxvf sources/sip-4.19.18.tar.gz
cd sip-4.19.18
python3 ./configure.py --deployment-target=10.12 --sip-module=PyQt5.sip
make
make install
cd ..
# Next Build PyQt5 for Qt-5.12.9 from source and installing it into your Python Interpreter
# From https://www.riverbankcomputing.com/software/pyqt/download5
# Download PyQt5_gpl-5.12.3.tar.gz
# More detailed build instructions can be found here:
# http://pyqt.sourceforge.net/Docs/PyQt5/installation.html#building-and-installing-from-source
# Must have the python interpreter you want to install PyQt5 into in the path to be found first
export PATH=${MYDEST}/Python.framework/Versions/3.9/bin:${PATH}
which python3
# Must have the Qt5.12.9 bin directory in the path to specify which Qt to use
# See Building_Qt5_From_Source_on_MacOSX.txt
export PATH=/Users/${USER}/Qt5129/bin:${PATH}
which qmake
export MACOSX_DEPLOYMENT_TARGET=10.12
tar -zxvf sources/PyQt5_gpl-5.12.3.tar.gz
cd PyQt5_gpl-5.12.3
python3 ./configure.py --confirm-license --no-docstrings --no-stubs
make -j4
make install
cd ..
# And finally build PyQtWebEngine (again with the destination python and qmake in your path)
# From https://sourceforge.net/projects/pyqtwebengine/
# Download: PyQtWebEngine-5.12.1.tar.gz
export MACOSX_DEPLOYMENT_TARGET=10.12
tar -zxvf sources/PyQtWebEngine-5.12.1.tar.gz
cd PyQtWebEngine_gpl-5.12.1/
python3 ./configure.py --no-docstrings --no-stubs
make -j4
make install
# ***** IF USING QT6 *****
# Download pyside-setup-opensource-src-6.2.2.tar.xz from https://download.qt.io/official_releases/QtForPython/
export MACOSX_DEPLOYMENT_TARGET=10.14
export MYQTHOME=~/Qt622
export PATH=${PATH}:${MYQTHOME}/bin
export PATH=${MYDEST}/Python.framework/Versions/3.9/bin:${PATH}
which qmake
which python3
# Prerequisites
# Your will need to have the packaging module installed on your python3
pip3 install --upgrade --force-reinstall packaging
# As well as a recent version of setuptools
# (some newer versions have broken compatibility)
pip3 install setuptools==59.8.0
# You will need libclang (although macOS has this lib pre-installed, it can *not*
# be found by Qt's cmake. Qt has pre-build binaries ready to be used for each platform.
# I recommend storing it someplace *outside* the normal path such as /opt to help
# prevent future any name clash issues.
# Download libclang-release_130-based-macos-universal.7z from:
# https://download.qt.io/development_releases/prebuilt/libclang/
cd /opt
# and unpack libclang-release_130-based-macos-universal.7z in /opt to create /opt/libclang
# Tell the pyside6 build where to find it
export CLANG_INSTALL_DIR=/opt/libclang
# You should now be ready to build pyside6
unxz ./sources/pyside-setup-opensource-src-6.2.2.tar.xz
tar -xvf ./sources/pyside-setup-opensource-src-6.2.2.tar
cd pyside-setup-opensource-src-6.2.2
python3 setup.py install --parallel=8 --build-tests
# Once complete you will have properly built a Python 3.9 interpreter to be embedded inside
# of Sigil