-
Notifications
You must be signed in to change notification settings - Fork 579
/
Building_A_Relocatable_Python_3.11_Framework_on_MacOSX.txt
270 lines (202 loc) · 9.83 KB
/
Building_A_Relocatable_Python_3.11_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
# *** IMPORTANT ***
# Build Prerequisite requirements for Python 3.11.9 on macOS 11.0 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 ndevpython
cd ndevpython
# 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-3.0.14.tar.gz or later into sources from https://www.openssl.org/source
export MACOSX_DEPLOYMENT_TARGET=11.0
export LDFLAGS="-Wl,-macosx_version_min,11.0"
tar -zxvf support/openssl-3.0.14.tar.gz
cd openssl-3.0.14
./config no-shared --prefix=/usr/local
make -j4
sudo make install
unset LDFLAGS
cd ..
# Download xz-5.2.3.tar.gz or later into sources from https://tukaani.org/xz/ (via sourceforge)
export MACOSX_DEPLOYMENT_TARGET=11.0
export LDFLAGS="-Wl,-macosx_version_min,11.0"
export CFLAGS="-mmacosx-version-min=11.0 -Werror=partial-availability"
tar -zxvf support/xz-5.2.3.tar.gz
cd xz-5.2.3
./configure --disable-shared --prefix=/usr/local
make -j4
sudo make install
unset CFLAGS
unset LDFLAGS
cd ..
# Download sqlite-autoconf-3450300.tar.gz into sources from
# https://sqlite.org/2021/sqlite-autoconf-3450300.tar.gz"
export MACOSX_DEPLOYMENT_TARGET=11.0
export LDFLAGS="-Wl,-macosx_version_min,11.0"
export CFLAGS="-mmacosx-version-min=11.0 -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 support/sqlite-autoconf-3450300.tar.gz
cd sqlite-autoconf-3450300
./configure --prefix=/usr/local --enable-threadsafe --enable-shared=no --enable-static=yes --disable-readline --disable-dependency-tracking
make -j4
sudo make install
unset LDFLAGS
unset CFLAGS
cd ..
# Download mpdecimal-4.0.0.tar.gz from:
# https://www.bytereef.org/software/mpdecimal/releases/mpdecimal-4.0.0.tar.gz
export MACOSX_DEPLOYMENT_TARGET=11.0
tar -zxvf support/mpdecimal-4.0.0.tar.gz
cd mpdecimal-4.0.0
./configure --prefix=/usr/local --disable-cxx MACHINE=universal
make -j4
sudo make install
cd ..
# 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.14-src.tar.gz into sources from ftp://ftp.tcl.tk/pub/tcl//tcl8_6/tcl8.6.14-src.tar.gz
# Download tk8.6.14-src.tar.gz into sources from ftp://ftp.tcl.tk/pub/tcl//tcl8_6/tk8.6.14-src.tar.gz
mkdir tcltk
cd tcltk
tar -zxvf ../support/tcl8.6.14-src.tar.gz
tar -zxvf ../support/tk8.6.14-src.tar.gz
For this version - no backport patches are needed.
# Note: TCL_LIBRARY and TK_LIBRARY and libdir are appended to DESTDIR to get actual paths
export MACOSX_DEPLOYMENT_TARGET=11.0
export CFLAGS="-arch x86_64 -mmacosx-version-min=11.0"
cd tcl8.6.14/unix
./configure --enable-shared --enable-threads --libdir=/Frameworks/Python.framework/Versions/3.11/lib
make TCL_LIBRARY=/Frameworks/Python.framework/Versions/3.11/lib/tcl8.6 DESTDIR=${MYLIBS}
make install TCL_LIBRARY=/Frameworks/Python.framework/Versions/3.11/lib/tcl8.6 DESTDIR=${MYLIBS}
cd ../../
cd tk8.6.14/unix
./configure --libdir=/Frameworks/Python.framework/Versions/3.11/lib --enable-aqua --enable-shared --enable-threads
make TCL_LIBRARY=/Frameworks/Python.framework/Versions/3.11/lib/tcl8.6 \
TK_LIBRARY=/Frameworks/Python.framework/Versions/3.11/lib/tk8.6 \
DESTDIR=${MYLIBS}
make install TCL_LIBRARY=/Frameworks/Python.framework/Versions/3.11/lib/tcl8.6 \
TK_LIBRARY=/Frameworks/Python.framework/Versions/3.11/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.11/lib
chmod u+w libtk8.6.dylib
chmod u+w libtcl8.6.dylib
install_name_tool -id ${MYDEST}/Python.framework/Versions/3.11/lib/libtcl8.6.dylib ./libtcl8.6.dylib
install_name_tool -id ${MYDEST}/Python.framework/Versions/3.11/lib/libtk8.6.dylib ./libtk8.6.dylib
# Building Python 3.11.9 to be fully relocatable for macOS 11.0 and later
# Before building remember to rename any /Applications/Python 3.11.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.11.9.tgz into support from www.python.org
cd ${MYDEST}
cd ../../
export MACOSX_DEPLOYMENT_TARGET=11.0
# now build Python 3.11.9 as a framework
# no need to worry about what symbols exist in what version of
# macOS any longer, since Python 3.9.1 and later use and test for weak symbols
tar -jxvf support/Python-3.11.9.tar.xz
cd Python-3.11.9
export LDFLAGS="-Wl,-macosx_version_min,11.0"
export CFLAGS="-mmacosx-version-min=11.0"
./configure --prefix=${MYDEST} --enable-framework=${MYDEST} --with-ensurepip \
TCLTK_CFLAGS="-I${MYLIBS}/usr/local/include" \
TCLTK_LIBS="-L${MYDEST}/Python.framework/Versions/3.11/lib -ltcl8.6 -ltk8.6"
make -j4
make frameworkinstall
# Now due to changes in Python3 since 3.9, the places it looks for the tcl8.6 and
# tk8.6 folders moves if Python3 is NOT installed in the standard framework
# location (not in /Library/Framework/Python.framework).
# So Python3 can not find its platform independent tcltk (tkinter) libraries
# on macOS if moved. Because an "app" is needed for gui activity, these libraries
# must be found relative to the internal Python.app
# To allow our Python to fully moveable we must move these tcltk platform
# independent files to a new lib folder placed in Python.app/Contents/
# so that they can always be found as follows:
cd ${MYDEST}/Python.framework/Versions/3.11/Resources/Python.app/Contents
mkdir lib
cd lib
mv ${MYDEST}/Python.framework/Versions/3.11/lib/tcl8.6 ./
mv ${MYDEST}/Python.framework/Versions/3.11/lib/tk8.6 ./
cd ${MYDEST}
cd ../../
# 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.11/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
# 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.11/
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.11/Python @rpath/Python python3.11
install_name_tool -add_rpath @executable_path/../ ./python3.11
# so that python3 can find the Qt Frameworks and proper plugins for PyQt5
install_name_tool -add_rpath @executable_path/../../../../ ./python3.11
# 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.11/Resources/Python.app/Contents/MacOS
install_name_tool -change ${MYDEST}/Python.framework/Versions/3.11/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.11/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.11/lib/python3.11/lib-dynload
install_name_tool -add_rpath @loader_path/../.. _tkinter.cpython-311-darwin.so
install_name_tool -change ${MYDEST}/Python.framework/Versions/3.11/lib/libtcl8.6.dylib @rpath/libtcl8.6.dylib _tkinter.cpython-311-darwin.so
install_name_tool -change ${MYDEST}/Python.framework/Versions/3.11/lib/libtk8.6.dylib @rpath/libtk8.6.dylib _tkinter.cpython-311-darwin.so
# We should now have a fully relocatable Python.framework
# We will now use this just-built Python3.11 interpreter to install PySide6 for Qt 6.X
See Building_PySide6_for_Qt6_on_MacOSX.txt