Issue #15663: OS X installer builtin Tcl/Tk support
Make it easier for users to make use of the backup _tkinter linked with the third-party Tcl and Tk frameworks in /Library/Frameworks. The two tkinter variants are now installed in separate directories under a new lib-tkinter. This allows per-user selection by manipulating sys.path, directly or with PYTHONPATH. If this proves useful, we can supply a more convenient user interface to supply the paths. For now, this remains somewhat experimental.
This commit is contained in:
parent
2ff68dd526
commit
050fcd51cc
|
@ -68,28 +68,28 @@ for each release.
|
||||||
- requires ActiveState Tcl/Tk 8.5.14 (or later) to be installed for building
|
- requires ActiveState Tcl/Tk 8.5.14 (or later) to be installed for building
|
||||||
|
|
||||||
* Beginning with Python 3.3.3, this installer now includes its own
|
* Beginning with Python 3.3.3, this installer now includes its own
|
||||||
private copy of Tcl and Tk 8.5.15 libraries and thus is no longer
|
builtin copy of Tcl and Tk 8.5.15 libraries and thus is no longer
|
||||||
dependent on the buggy releases of Aqua Cocoa Tk 8.5 shipped with
|
dependent on the buggy releases of Aqua Cocoa Tk 8.5 shipped with
|
||||||
OS X 10.6 or on installing a newer third-party version of Tcl/Tk
|
OS X 10.6 or on installing a newer third-party version of Tcl/Tk
|
||||||
in /Library/Frameworks, such as from ActiveState. If it is
|
in /Library/Frameworks, such as from ActiveState. If it is
|
||||||
necessary to fallback to using a third-party Tcl/Tk because of
|
necessary to fallback to using a third-party Tcl/Tk because of
|
||||||
a problem with the private Tcl/Tk, there is a backup version of
|
a problem with the builtin Tcl/Tk, there is a backup version of
|
||||||
the _tkinter extension included which will dynamically link to
|
the _tkinter extension included which will dynamically link to
|
||||||
Tcl and Tk frameworks in /Library/Frameworks as in previous releases.
|
Tcl and Tk frameworks in /Library/Frameworks as in previous releases.
|
||||||
To enable (for all users of this Python 3.3)::
|
To enable (for all users of this Python 3.3)::
|
||||||
|
|
||||||
sudo bash
|
sudo bash
|
||||||
cd /Library/Frameworks/Python.framework/Versions/3.3
|
cd /Library/Frameworks/Python.framework/Versions/3.3
|
||||||
cd ./lib/python3.3/lib-dynload
|
cd ./lib/python3.3
|
||||||
cp -p _tkinter.so.framework _tkinter.so
|
cp -p ./lib-tkinter/library/_tkinter.so ./lib-dynload
|
||||||
exit
|
exit
|
||||||
|
|
||||||
To restore using Python's private versions of Tcl and Tk::
|
To restore using Python's builtin versions of Tcl and Tk::
|
||||||
|
|
||||||
sudo bash
|
sudo bash
|
||||||
cd /Library/Frameworks/Python.framework/Versions/3.3
|
cd /Library/Frameworks/Python.framework/Versions/3.3
|
||||||
cd ./lib/python3.3/lib-dynload
|
cd ./lib/python3.3
|
||||||
cp -p _tkinter.so.private _tkinter.so
|
cp -p ./lib-tkinter/builtin/_tkinter.so ./lib-dynload
|
||||||
exit
|
exit
|
||||||
|
|
||||||
- recommended build environment:
|
- recommended build environment:
|
||||||
|
|
|
@ -565,11 +565,11 @@ def checkEnvironment():
|
||||||
]
|
]
|
||||||
|
|
||||||
# For 10.6+ builds, we build two versions of _tkinter:
|
# For 10.6+ builds, we build two versions of _tkinter:
|
||||||
# - the traditional version (renamed to _tkinter.so.framework) linked
|
# - the traditional version (renamed to _tkinter_library.so) linked
|
||||||
# with /Library/Frameworks/{Tcl,Tk}.framework
|
# with /Library/Frameworks/{Tcl,Tk}.framework
|
||||||
# - the default version linked with our private copies of Tcl and Tk
|
# - the default version linked with our builtin copies of Tcl and Tk
|
||||||
if DEPTARGET > '10.5':
|
if DEPTARGET > '10.5':
|
||||||
EXPECTED_SHARED_LIBS['_tkinter.so.framework'] = \
|
EXPECTED_SHARED_LIBS['_tkinter_library.so'] = \
|
||||||
EXPECTED_SHARED_LIBS['_tkinter.so']
|
EXPECTED_SHARED_LIBS['_tkinter.so']
|
||||||
EXPECTED_SHARED_LIBS['_tkinter.so'] = [
|
EXPECTED_SHARED_LIBS['_tkinter.so'] = [
|
||||||
"/Library/Frameworks/Python.framework/Versions/%s/lib/libtcl%s.dylib"
|
"/Library/Frameworks/Python.framework/Versions/%s/lib/libtcl%s.dylib"
|
||||||
|
@ -966,18 +966,18 @@ def buildPython():
|
||||||
# of Tcl and Cocoa Aqua Tk libs because the Apple-supplied Tk 8.5 is
|
# of Tcl and Cocoa Aqua Tk libs because the Apple-supplied Tk 8.5 is
|
||||||
# out-of-date and has critical bugs. Save the _tkinter.so that was
|
# out-of-date and has critical bugs. Save the _tkinter.so that was
|
||||||
# linked with /Library/Frameworks/{Tck,Tk}.framework and build
|
# linked with /Library/Frameworks/{Tck,Tk}.framework and build
|
||||||
# another _tkinter.so linked with our private Tcl and Tk libs.
|
# another _tkinter.so linked with our builtin Tcl and Tk libs.
|
||||||
if DEPTARGET > '10.5':
|
if DEPTARGET > '10.5':
|
||||||
runCommand("find build -name '_tkinter.so' "
|
runCommand("find build -name '_tkinter.so' "
|
||||||
" -execdir mv '{}' '{}'.framework \;")
|
" -execdir mv '{}' _tkinter_library.so \;")
|
||||||
print("Running make to rebuild _tkinter")
|
print("Running make to build builtin _tkinter")
|
||||||
runCommand("make TCLTK_INCLUDES='-I%s/libraries/usr/local/include' "
|
runCommand("make TCLTK_INCLUDES='-I%s/libraries/usr/local/include' "
|
||||||
"TCLTK_LIBS='-L%s/libraries/usr/local/lib -ltcl8.5 -ltk8.5'"%(
|
"TCLTK_LIBS='-L%s/libraries/usr/local/lib -ltcl8.5 -ltk8.5'"%(
|
||||||
shellQuote(WORKDIR)[1:-1],
|
shellQuote(WORKDIR)[1:-1],
|
||||||
shellQuote(WORKDIR)[1:-1]))
|
shellQuote(WORKDIR)[1:-1]))
|
||||||
# make a backup copy, just in case
|
# make a copy which will be moved to lib-tkinter later
|
||||||
runCommand("find build -name '_tkinter.so' "
|
runCommand("find build -name '_tkinter.so' "
|
||||||
" -execdir cp -p '{}' '{}'.private \;")
|
" -execdir cp -p '{}' _tkinter_builtin.so \;")
|
||||||
|
|
||||||
print("Running make install")
|
print("Running make install")
|
||||||
runCommand("make install DESTDIR=%s"%(
|
runCommand("make install DESTDIR=%s"%(
|
||||||
|
@ -999,11 +999,31 @@ def buildPython():
|
||||||
'Python.framework', 'Versions', getVersion(),
|
'Python.framework', 'Versions', getVersion(),
|
||||||
'lib'))))
|
'lib'))))
|
||||||
|
|
||||||
|
path_to_lib = os.path.join(rootDir, 'Library', 'Frameworks',
|
||||||
|
'Python.framework', 'Versions',
|
||||||
|
version, 'lib', 'python%s'%(version,))
|
||||||
|
|
||||||
|
# If we made multiple versions of _tkinter, move them to
|
||||||
|
# their own directories under python lib. This allows
|
||||||
|
# users to select which to import by manipulating sys.path
|
||||||
|
# directly or with PYTHONPATH.
|
||||||
|
|
||||||
|
if DEPTARGET > '10.5':
|
||||||
|
TKINTERS = ['builtin', 'library']
|
||||||
|
tkinter_moves = [('_tkinter_' + tkn + '.so',
|
||||||
|
os.path.join(path_to_lib, 'lib-tkinter', tkn))
|
||||||
|
for tkn in TKINTERS]
|
||||||
|
# Create the destination directories under lib-tkinter.
|
||||||
|
# The permissions and uid/gid will be fixed up next.
|
||||||
|
for tkm in tkinter_moves:
|
||||||
|
os.makedirs(tkm[1])
|
||||||
|
|
||||||
print("Fix file modes")
|
print("Fix file modes")
|
||||||
frmDir = os.path.join(rootDir, 'Library', 'Frameworks', 'Python.framework')
|
frmDir = os.path.join(rootDir, 'Library', 'Frameworks', 'Python.framework')
|
||||||
gid = grp.getgrnam('admin').gr_gid
|
gid = grp.getgrnam('admin').gr_gid
|
||||||
|
|
||||||
shared_lib_error = False
|
shared_lib_error = False
|
||||||
|
moves_list = []
|
||||||
for dirpath, dirnames, filenames in os.walk(frmDir):
|
for dirpath, dirnames, filenames in os.walk(frmDir):
|
||||||
for dn in dirnames:
|
for dn in dirnames:
|
||||||
os.chmod(os.path.join(dirpath, dn), STAT_0o775)
|
os.chmod(os.path.join(dirpath, dn), STAT_0o775)
|
||||||
|
@ -1029,9 +1049,25 @@ def buildPython():
|
||||||
% (sl, p))
|
% (sl, p))
|
||||||
shared_lib_error = True
|
shared_lib_error = True
|
||||||
|
|
||||||
|
# If this is a _tkinter variant, move it to its own directory
|
||||||
|
# now that we have fixed its permissions and checked that it
|
||||||
|
# was linked properly. The directory was created earlier.
|
||||||
|
# The files are moved after the entire tree has been walked
|
||||||
|
# since the shared library checking depends on the files
|
||||||
|
# having unique names.
|
||||||
|
if DEPTARGET > '10.5':
|
||||||
|
for tkm in tkinter_moves:
|
||||||
|
if fn == tkm[0]:
|
||||||
|
moves_list.append(
|
||||||
|
(p, os.path.join(tkm[1], '_tkinter.so')))
|
||||||
|
|
||||||
if shared_lib_error:
|
if shared_lib_error:
|
||||||
fatal("Unexpected shared library errors.")
|
fatal("Unexpected shared library errors.")
|
||||||
|
|
||||||
|
# Now do the moves.
|
||||||
|
for ml in moves_list:
|
||||||
|
shutil.move(ml[0], ml[1])
|
||||||
|
|
||||||
if PYTHON_3:
|
if PYTHON_3:
|
||||||
LDVERSION=None
|
LDVERSION=None
|
||||||
VERSION=None
|
VERSION=None
|
||||||
|
@ -1061,10 +1097,6 @@ def buildPython():
|
||||||
include_path = '-I%s/libraries/usr/local/include' % (WORKDIR,)
|
include_path = '-I%s/libraries/usr/local/include' % (WORKDIR,)
|
||||||
lib_path = '-L%s/libraries/usr/local/lib' % (WORKDIR,)
|
lib_path = '-L%s/libraries/usr/local/lib' % (WORKDIR,)
|
||||||
|
|
||||||
path_to_lib = os.path.join(rootDir, 'Library', 'Frameworks',
|
|
||||||
'Python.framework', 'Versions',
|
|
||||||
version, 'lib', 'python%s'%(version,))
|
|
||||||
|
|
||||||
# fix Makefile
|
# fix Makefile
|
||||||
path = os.path.join(path_to_lib, 'config' + config_suffix, 'Makefile')
|
path = os.path.join(path_to_lib, 'config' + config_suffix, 'Makefile')
|
||||||
fp = open(path, 'r')
|
fp = open(path, 'r')
|
||||||
|
|
Loading…
Reference in New Issue