Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2910a7b

Browse files
committed
Issue #14018: Fix OS X Tcl/Tk framework checking when using OS X SDKs.
Also add tests in the OS X installer build to ensure that the desired dynamic linking with an optional newer Tcl/Tk in /Library actually happens.
1 parent 5d6aeb8 commit 2910a7b

3 files changed

Lines changed: 50 additions & 13 deletions

File tree

Mac/BuildScript/build-installer.py

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,13 @@ def getFullVersion():
161161
--universal-archs=x universal architectures (options: %(UNIVERSALOPTS)r, default: %(UNIVERSALARCHS)r)
162162
""")% globals()
163163

164+
# Dict of object file names with shared library names to check after building.
165+
# This is to ensure that we ended up dynamically linking with the shared
166+
# library paths and versions we expected. For example:
167+
# EXPECTED_SHARED_LIBS['_tkinter.so'] = [
168+
# '/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl',
169+
# '/Library/Frameworks/Tk.framework/Versions/8.5/Tk']
170+
EXPECTED_SHARED_LIBS = {}
164171

165172
# Instructions for building libraries that are necessary for building a
166173
# batteries included python.
@@ -460,27 +467,40 @@ def checkEnvironment():
460467
# Because we only support dynamic load of only one major/minor version of
461468
# Tcl/Tk, ensure:
462469
# 1. there are no user-installed frameworks of Tcl/Tk with version
463-
# higher than the Apple-supplied system version
464-
# 2. there is a user-installed framework in /Library/Frameworks with the
465-
# same version as the system version. This allows users to choose
466-
# to install a newer patch level.
470+
# higher than the Apple-supplied system version in
471+
# SDKROOT/System/Library/Frameworks
472+
# 2. there is a user-installed framework (usually ActiveTcl) in (or linked
473+
# in) SDKROOT/Library/Frameworks with the same version as the system
474+
# version. This allows users to choose to install a newer patch level.
467475

476+
frameworks = {}
468477
for framework in ['Tcl', 'Tk']:
469-
#fw = dict(lower=framework.lower(),
470-
# upper=framework.upper(),
471-
# cap=framework.capitalize())
472-
#fwpth = "Library/Frameworks/%(cap)s.framework/%(lower)sConfig.sh" % fw
473-
fwpth = 'Library/Frameworks/Tcl.framework/Versions/Current'
478+
fwpth = 'Library/Frameworks/%s.framework/Versions/Current' % framework
474479
sysfw = os.path.join(SDKPATH, 'System', fwpth)
475-
libfw = os.path.join('/', fwpth)
480+
libfw = os.path.join(SDKPATH, fwpth)
476481
usrfw = os.path.join(os.getenv('HOME'), fwpth)
477-
#version = "%(upper)s_VERSION" % fw
482+
frameworks[framework] = os.readlink(sysfw)
483+
if not os.path.exists(libfw):
484+
fatal("Please install a link to a current %s %s as %s so "
485+
"the user can override the system framework."
486+
% (framework, frameworks[framework], libfw))
478487
if os.readlink(libfw) != os.readlink(sysfw):
479488
fatal("Version of %s must match %s" % (libfw, sysfw) )
480489
if os.path.exists(usrfw):
481490
fatal("Please rename %s to avoid possible dynamic load issues."
482491
% usrfw)
483492

493+
if frameworks['Tcl'] != frameworks['Tk']:
494+
fatal("The Tcl and Tk frameworks are not the same version.")
495+
496+
# add files to check after build
497+
EXPECTED_SHARED_LIBS['_tkinter.so'] = [
498+
"/Library/Frameworks/Tcl.framework/Versions/%s/Tcl"
499+
% frameworks['Tcl'],
500+
"/Library/Frameworks/Tk.framework/Versions/%s/Tk"
501+
% frameworks['Tk'],
502+
]
503+
484504
# Remove inherited environment variables which might influence build
485505
environ_var_prefixes = ['CPATH', 'C_INCLUDE_', 'DYLD_', 'LANG', 'LC_',
486506
'LD_', 'LIBRARY_', 'PATH', 'PYTHON']
@@ -861,12 +881,12 @@ def buildPython():
861881
frmDir = os.path.join(rootDir, 'Library', 'Frameworks', 'Python.framework')
862882
gid = grp.getgrnam('admin').gr_gid
863883

884+
shared_lib_error = False
864885
for dirpath, dirnames, filenames in os.walk(frmDir):
865886
for dn in dirnames:
866887
os.chmod(os.path.join(dirpath, dn), STAT_0o775)
867888
os.chown(os.path.join(dirpath, dn), -1, gid)
868889

869-
870890
for fn in filenames:
871891
if os.path.islink(fn):
872892
continue
@@ -877,6 +897,19 @@ def buildPython():
877897
os.chmod(p, stat.S_IMODE(st.st_mode) | stat.S_IWGRP)
878898
os.chown(p, -1, gid)
879899

900+
if fn in EXPECTED_SHARED_LIBS:
901+
# check to see that this file was linked with the
902+
# expected library path and version
903+
data = captureCommand("otool -L %s" % shellQuote(p))
904+
for sl in EXPECTED_SHARED_LIBS[fn]:
905+
if ("\t%s " % sl) not in data:
906+
print("Expected shared lib %s was not linked with %s"
907+
% (sl, p))
908+
shared_lib_error = True
909+
910+
if shared_lib_error:
911+
fatal("Unexpected shared library errors.")
912+
880913
if PYTHON_3:
881914
LDVERSION=None
882915
VERSION=None

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ Tests
264264
Build
265265
-----
266266

267+
- Issue #14018: Fix OS X Tcl/Tk framework checking when using OS X SDKs.
268+
267269
- Issue #15431: Add _freeze_importlib project to regenerate importlib.h
268270
on Windows. Patch by Kristján Valur Jónsson.
269271

setup.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ def is_macosx_sdk_path(path):
6969
"""
7070
Returns True if 'path' can be located in an OSX SDK
7171
"""
72-
return (path.startswith('/usr/') and not path.startswith('/usr/local')) or path.startswith('/System/')
72+
return ( (path.startswith('/usr/') and not path.startswith('/usr/local'))
73+
or path.startswith('/System/')
74+
or path.startswith('/Library/') )
7375

7476
def find_file(filename, std_dirs, paths):
7577
"""Searches for the directory where a given file is located,

0 commit comments

Comments
 (0)