mirror of https://github.com/KLayout/klayout.git
Made changes to build KLayout 0.28~:
1) Set the CPATH environment variable for including <png.h> required to build the pymod 2) Not to use Python 2.7 on Catalina (nightlybuild) 3) Resolve the library dependency of Python in Homebrew 4) Add a handy tool to setup the standardized directory structures for Homebrew Python 3.x
This commit is contained in:
parent
389f1728bd
commit
2e3bc28a69
|
|
@ -875,9 +875,29 @@ def Build_pymod(parameters):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# [2] Get the new directory names (dictionary) for "dist"
|
# [2] Get the new directory names (dictionary) for "dist" and
|
||||||
|
# set the CPATH environment variable for including <png.h>
|
||||||
|
# required to build the pymod of 0.28 or later
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
PymodDistDir = parameters['pymod_dist']
|
PymodDistDir = parameters['pymod_dist']
|
||||||
|
# Using MacPorts
|
||||||
|
if PymodDistDir[ModulePython] == 'dist-MP3':
|
||||||
|
addIncPath = "/opt/local/include"
|
||||||
|
# Using Homebrew
|
||||||
|
elif PymodDistDir[ModulePython] == 'dist-HB3':
|
||||||
|
addIncPath = "%s/include" % DefaultHomebrewRoot # defined in "build4mac_env.py"
|
||||||
|
# Using Anaconda3
|
||||||
|
elif PymodDistDir[ModulePython] == 'dist-ana3':
|
||||||
|
addIncPath = "/Applications/anaconda3/include"
|
||||||
|
else:
|
||||||
|
addIncPath = ""
|
||||||
|
if not addIncPath == "":
|
||||||
|
try:
|
||||||
|
cpath = os.environ['CPATH']
|
||||||
|
except KeyError:
|
||||||
|
os.environ['CPATH'] = addIncPath
|
||||||
|
else:
|
||||||
|
os.environ['CPATH'] = "%s:%s" % (addIncPath, cpath)
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# [3] Set different command line parameters for building <pymod>
|
# [3] Set different command line parameters for building <pymod>
|
||||||
|
|
@ -1491,6 +1511,36 @@ def Deploy_Binaries_For_Bundle(config, parameters):
|
||||||
# in "/usr/local/opt/python@3.8/lib/"
|
# in "/usr/local/opt/python@3.8/lib/"
|
||||||
# Python.framework -> ../Frameworks/Python.framework/ <=== this symbolic was needed
|
# Python.framework -> ../Frameworks/Python.framework/ <=== this symbolic was needed
|
||||||
# pkgconfig/
|
# pkgconfig/
|
||||||
|
#
|
||||||
|
# Use the "python3HB.py" tool to make different symbolic links [*] including the above one.
|
||||||
|
# Catalina0{kazzz-s} lib (1)% pwd
|
||||||
|
# /usr/local/opt/python@3.8/lib
|
||||||
|
# Catalina0{kazzz-s} lib (2)% ll
|
||||||
|
# total 0
|
||||||
|
# drwxr-xr-x 4 kazzz-s admin 128 12 16 21:40 .
|
||||||
|
# drwxr-xr-x 13 kazzz-s admin 416 12 12 23:08 ..
|
||||||
|
# [*] lrwxr-xr-x 1 kazzz-s admin 31 12 16 21:40 Python.framework -> ../Frameworks/Python.framework/
|
||||||
|
# drwxr-xr-x 4 kazzz-s admin 128 12 12 23:08 pkgconfig
|
||||||
|
#
|
||||||
|
# Catalina0{kazzz-s} Python.framework (3)% pwd
|
||||||
|
# /usr/local/opt/python@3.8/Frameworks/Python.framework/Versions
|
||||||
|
# Catalina0{kazzz-s} Versions (4)% ll
|
||||||
|
# total 0
|
||||||
|
# drwxr-xr-x 4 kazzz-s admin 128 12 16 21:40 .
|
||||||
|
# drwxr-xr-x 6 kazzz-s admin 192 12 16 21:40 ..
|
||||||
|
# drwxr-xr-x 9 kazzz-s admin 288 12 12 23:08 3.8
|
||||||
|
# [*] lrwxr-xr-x 1 kazzz-s admin 4 12 16 21:40 Current -> 3.8/
|
||||||
|
#
|
||||||
|
# Catalina0{kazzz-s} Python.framework (5)% pwd
|
||||||
|
# /usr/local/opt/python@3.8/Frameworks/Python.framework
|
||||||
|
# Catalina0{kazzz-s} Python.framework (6)% ll
|
||||||
|
# total 0
|
||||||
|
# drwxr-xr-x 6 kazzz-s admin 192 12 16 21:40 .
|
||||||
|
# drwxr-xr-x 3 kazzz-s admin 96 12 12 23:07 ..
|
||||||
|
# [*] lrwxr-xr-x 1 kazzz-s admin 25 12 16 21:40 Headers -> Versions/Current/Headers/
|
||||||
|
# [*] lrwxr-xr-x 1 kazzz-s admin 23 12 16 21:40 Python -> Versions/Current/Python
|
||||||
|
# [*] lrwxr-xr-x 1 kazzz-s admin 27 12 16 21:40 Resources -> Versions/Current/Resources/
|
||||||
|
# drwxr-xr-x 4 kazzz-s admin 128 12 16 21:40 Versions
|
||||||
#-----------------------------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------------------------
|
||||||
deploymentPython38HB = (ModulePython == 'Python38Brew')
|
deploymentPython38HB = (ModulePython == 'Python38Brew')
|
||||||
deploymentPythonAutoHB = (ModulePython == 'PythonAutoBrew')
|
deploymentPythonAutoHB = (ModulePython == 'PythonAutoBrew')
|
||||||
|
|
@ -1550,43 +1600,49 @@ def Deploy_Binaries_For_Bundle(config, parameters):
|
||||||
os.chmod( targetDirM + "/start-console.py", 0o0755 )
|
os.chmod( targetDirM + "/start-console.py", 0o0755 )
|
||||||
os.chmod( targetDirM + "/klayout_console", 0o0755 )
|
os.chmod( targetDirM + "/klayout_console", 0o0755 )
|
||||||
|
|
||||||
print(" [9.2] Relinking dylib dependencies inside Python.framework" )
|
print( " [9.2] Relinking dylib dependencies inside Python.framework" )
|
||||||
print(" [9.2.1] Patching Python Framework" )
|
print( " [9.2.1] Patching Python Framework" )
|
||||||
depdict = WalkFrameworkPaths( pythonFrameworkPath )
|
depdict = WalkFrameworkPaths( pythonFrameworkPath )
|
||||||
appPythonFrameworkPath = '@executable_path/../Frameworks/Python.framework/'
|
appPythonFrameworkPath = '@executable_path/../Frameworks/Python.framework/'
|
||||||
PerformChanges(depdict, [(HBPythonFrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs)
|
PerformChanges( depdict, [(HBPythonFrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs )
|
||||||
|
|
||||||
print(" [9.2.2] Patching /usr/local/opt/ libs")
|
print( " [9.2.2] Patching 'Python' itself in Python Framework" )
|
||||||
usrLocalPath = '/usr/local/opt/'
|
filterreg = r'\t+%s/(opt|Cellar)' % DefaultHomebrewRoot
|
||||||
appUsrLocalPath = '@executable_path/../Frameworks/'
|
Patch_Python_In_PythonFramework( pythonFrameworkPath, filter_regex=filterreg )
|
||||||
replacePairs = [(usrLocalPath, appUsrLocalPath, True)]
|
|
||||||
depdict = WalkFrameworkPaths(pythonFrameworkPath, search_path_filter=r'\t+/usr/local/(opt|Cellar)')
|
|
||||||
PerformChanges(depdict, replacePairs, bundleExecPathAbs)
|
|
||||||
|
|
||||||
print(" [9.2.3] Patching openssl@1.1, gdbm, readline, sqlite, xz")
|
print( " [9.2.3] Patching %s/opt/ libs" % DefaultHomebrewRoot ) # eg. DefaultHomebrewRoot == "/usr/local"
|
||||||
usrLocalPath = '/usr/local/opt'
|
usrLocalPath = '%s/opt/' % DefaultHomebrewRoot
|
||||||
appUsrLocalPath = '@executable_path/../Frameworks/'
|
appUsrLocalPath = '@executable_path/../Frameworks/'
|
||||||
replacePairs = [(usrLocalPath, appUsrLocalPath, True)]
|
replacePairs = [ (usrLocalPath, appUsrLocalPath, True) ]
|
||||||
replacePairs.extend([(openssl_version, '@executable_path/../Frameworks/openssl@1.1', True)
|
filterreg = r'\t+%s/(opt|Cellar)' % DefaultHomebrewRoot
|
||||||
for openssl_version in glob.glob('/usr/local/Cellar/openssl@1.1/*')])
|
depdict = WalkFrameworkPaths( pythonFrameworkPath, search_path_filter=filterreg )
|
||||||
depdict = WalkFrameworkPaths([pythonFrameworkPath + '/../openssl@1.1',
|
PerformChanges( depdict, replacePairs, bundleExecPathAbs )
|
||||||
|
|
||||||
|
print( " [9.2.4] Patching openssl@1.1, gdbm, readline, sqlite, xz" )
|
||||||
|
usrLocalPath = '%s/opt/' % DefaultHomebrewRoot
|
||||||
|
appUsrLocalPath = '@executable_path/../Frameworks/'
|
||||||
|
replacePairs = [ (usrLocalPath, appUsrLocalPath, True) ]
|
||||||
|
replacePairs.extend( [ (openssl_version, '@executable_path/../Frameworks/openssl@1.1', True)
|
||||||
|
for openssl_version in glob.glob( '%s/Cellar/openssl@1.1/*' % DefaultHomebrewRoot ) ] )
|
||||||
|
filterreg = r'\t+%s/(opt|Cellar)' % DefaultHomebrewRoot
|
||||||
|
depdict = WalkFrameworkPaths( [pythonFrameworkPath + '/../openssl@1.1',
|
||||||
pythonFrameworkPath + '/../gdbm',
|
pythonFrameworkPath + '/../gdbm',
|
||||||
pythonFrameworkPath + '/../readline',
|
pythonFrameworkPath + '/../readline',
|
||||||
pythonFrameworkPath + '/../sqlite',
|
pythonFrameworkPath + '/../sqlite',
|
||||||
pythonFrameworkPath + '/../xz'], search_path_filter=r'\t+/usr/local/(opt|Cellar)')
|
pythonFrameworkPath + '/../xz'], search_path_filter=filterreg )
|
||||||
|
|
||||||
PerformChanges(depdict, replacePairs, bundleExecPathAbs)
|
PerformChanges( depdict, replacePairs, bundleExecPathAbs )
|
||||||
|
|
||||||
print(" [9.3] Relinking dylib dependencies for klayout")
|
print( " [9.3] Relinking dylib dependencies for klayout" )
|
||||||
klayoutPath = bundleExecPathAbs
|
klayoutPath = bundleExecPathAbs
|
||||||
depdict = WalkFrameworkPaths(klayoutPath, filter_regex=r'klayout$')
|
depdict = WalkFrameworkPaths( klayoutPath, filter_regex=r'klayout$' )
|
||||||
PerformChanges(depdict, [(HBPythonFrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs)
|
PerformChanges( depdict, [(HBPythonFrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs )
|
||||||
|
|
||||||
libKlayoutPath = bundleExecPathAbs + '../Frameworks'
|
libKlayoutPath = bundleExecPathAbs + '../Frameworks'
|
||||||
depdict = WalkFrameworkPaths(libKlayoutPath, filter_regex=r'libklayout')
|
depdict = WalkFrameworkPaths( libKlayoutPath, filter_regex=r'libklayout' )
|
||||||
PerformChanges(depdict, [(HBPythonFrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs)
|
PerformChanges( depdict, [(HBPythonFrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs )
|
||||||
|
|
||||||
print(" [9.4] Patching site.py, pip/, and distutils/")
|
print( " [9.4] Patching site.py, pip/, and distutils/" )
|
||||||
site_module = "%s/Versions/%s/lib/python%s/site.py" % (pythonFrameworkPath, pythonHBVer, pythonHBVer)
|
site_module = "%s/Versions/%s/lib/python%s/site.py" % (pythonFrameworkPath, pythonHBVer, pythonHBVer)
|
||||||
with open(site_module, 'r') as site:
|
with open(site_module, 'r') as site:
|
||||||
buf = site.readlines()
|
buf = site.readlines()
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,8 @@ def DecomposeLibraryDependency( depstr ):
|
||||||
#----------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------
|
||||||
def PrintLibraryDependencyDictionary( depdic, pathdic, namedic ):
|
def PrintLibraryDependencyDictionary( depdic, pathdic, namedic ):
|
||||||
keys = depdic.keys()
|
keys = depdic.keys()
|
||||||
print("")
|
print( "" )
|
||||||
print("##### Contents of <%s> #####:" % namedic )
|
print( "##### Contents of <%s> #####:" % namedic )
|
||||||
for key in keys:
|
for key in keys:
|
||||||
supporters = depdic[key]
|
supporters = depdic[key]
|
||||||
keyName = os.path.basename(key)
|
keyName = os.path.basename(key)
|
||||||
|
|
@ -158,8 +158,9 @@ def SetChangeLibIdentificationName( executable, relativedir ):
|
||||||
for lib in deplibs:
|
for lib in deplibs:
|
||||||
#-----------------------------------------------------------
|
#-----------------------------------------------------------
|
||||||
# [1] Set the identification names for the library
|
# [1] Set the identification names for the library
|
||||||
|
# $ install_name_tool [-id name] input
|
||||||
#-----------------------------------------------------------
|
#-----------------------------------------------------------
|
||||||
nameOld = "klayout.app/Contents/Frameworks/%s" % lib
|
nameOld = "klayout.app/Contents/Frameworks/%s" % lib # input file
|
||||||
nameNew = "@executable_path/%s/%s" % ( relativedir, lib )
|
nameNew = "@executable_path/%s/%s" % ( relativedir, lib )
|
||||||
command = "%s %s %s" % ( cmdNameId, nameNew, nameOld )
|
command = "%s %s %s" % ( cmdNameId, nameNew, nameOld )
|
||||||
if subprocess.call( command, shell=True ) != 0:
|
if subprocess.call( command, shell=True ) != 0:
|
||||||
|
|
@ -169,6 +170,7 @@ def SetChangeLibIdentificationName( executable, relativedir ):
|
||||||
|
|
||||||
#-----------------------------------------------------------
|
#-----------------------------------------------------------
|
||||||
# [2] Make the application aware of the new identification
|
# [2] Make the application aware of the new identification
|
||||||
|
# $ install_name_tool [-change old new] input
|
||||||
#-----------------------------------------------------------
|
#-----------------------------------------------------------
|
||||||
nameOld = "%s" % lib
|
nameOld = "%s" % lib
|
||||||
nameNew = "@executable_path/%s/%s" % ( relativedir, lib )
|
nameNew = "@executable_path/%s/%s" % ( relativedir, lib )
|
||||||
|
|
@ -182,6 +184,8 @@ def SetChangeLibIdentificationName( executable, relativedir ):
|
||||||
|
|
||||||
#----------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------
|
||||||
## To make a library dependency dictionary by recursively walk down the lib hierarchy
|
## To make a library dependency dictionary by recursively walk down the lib hierarchy
|
||||||
|
# DefaultHomebrewRoot = '/opt/homebrew' "arm64" Apple Silicon
|
||||||
|
# DefaultHomebrewRoot = '/usr/local' "x86_64" Intel Mac
|
||||||
#
|
#
|
||||||
# @param[in] dylibPath: dylib path
|
# @param[in] dylibPath: dylib path
|
||||||
# @param[in] depth: hierarchy depth (< 5)
|
# @param[in] depth: hierarchy depth (< 5)
|
||||||
|
|
@ -189,7 +193,7 @@ def SetChangeLibIdentificationName( executable, relativedir ):
|
||||||
#
|
#
|
||||||
# @return a dictionary
|
# @return a dictionary
|
||||||
#----------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------
|
||||||
def WalkLibDependencyTree( dylibPath, depth=0, filter_regex=r'\t+/usr/local/opt' ):
|
def WalkLibDependencyTree( dylibPath, depth=0, filter_regex=r'\t+%s/opt' % DefaultHomebrewRoot ):
|
||||||
otoolCm = 'otool -L %s | grep -E "%s"' % (dylibPath, filter_regex)
|
otoolCm = 'otool -L %s | grep -E "%s"' % (dylibPath, filter_regex)
|
||||||
otoolOut = os.popen( otoolCm ).read()
|
otoolOut = os.popen( otoolCm ).read()
|
||||||
exedepdic = DecomposeLibraryDependency( dylibPath + ":\n" + otoolOut )
|
exedepdic = DecomposeLibraryDependency( dylibPath + ":\n" + otoolOut )
|
||||||
|
|
@ -201,7 +205,7 @@ def WalkLibDependencyTree( dylibPath, depth=0, filter_regex=r'\t+/usr/local/opt'
|
||||||
for idx, lib in enumerate(deplibs):
|
for idx, lib in enumerate(deplibs):
|
||||||
lib = str(lib)
|
lib = str(lib)
|
||||||
if lib != list(keys)[0]:
|
if lib != list(keys)[0]:
|
||||||
deplibs[idx] = WalkLibDependencyTree(lib, depth+1, filter_regex)
|
deplibs[idx] = WalkLibDependencyTree( lib, depth+1, filter_regex )
|
||||||
if depth == 0:
|
if depth == 0:
|
||||||
return deplibs
|
return deplibs
|
||||||
return exedepdic
|
return exedepdic
|
||||||
|
|
@ -210,6 +214,8 @@ def WalkLibDependencyTree( dylibPath, depth=0, filter_regex=r'\t+/usr/local/opt'
|
||||||
|
|
||||||
#----------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------
|
||||||
## To make a library dependency dictionary by recursively walk down the Framework
|
## To make a library dependency dictionary by recursively walk down the Framework
|
||||||
|
# DefaultHomebrewRoot = '/opt/homebrew' "arm64" Apple Silicon
|
||||||
|
# DefaultHomebrewRoot = '/usr/local' "x86_64" Intel Mac
|
||||||
#
|
#
|
||||||
# @param[in] frameworkPaths: Framework path
|
# @param[in] frameworkPaths: Framework path
|
||||||
# @param[in] filter_regex: filter regular expression
|
# @param[in] filter_regex: filter regular expression
|
||||||
|
|
@ -218,9 +224,8 @@ def WalkLibDependencyTree( dylibPath, depth=0, filter_regex=r'\t+/usr/local/opt'
|
||||||
# @return a dictionary
|
# @return a dictionary
|
||||||
#----------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------
|
||||||
def WalkFrameworkPaths( frameworkPaths, filter_regex=r'\.(so|dylib)$',
|
def WalkFrameworkPaths( frameworkPaths, filter_regex=r'\.(so|dylib)$',
|
||||||
search_path_filter=r'\t+/usr/local/opt' ):
|
search_path_filter=r'\t+%s/opt' % DefaultHomebrewRoot ):
|
||||||
|
if isinstance( frameworkPaths, str ):
|
||||||
if isinstance(frameworkPaths, str):
|
|
||||||
frameworkPathsIter = [frameworkPaths]
|
frameworkPathsIter = [frameworkPaths]
|
||||||
else:
|
else:
|
||||||
frameworkPathsIter = frameworkPaths
|
frameworkPathsIter = frameworkPaths
|
||||||
|
|
@ -229,14 +234,12 @@ def WalkFrameworkPaths( frameworkPaths, filter_regex=r'\.(so|dylib)$',
|
||||||
|
|
||||||
for frameworkPath in frameworkPathsIter:
|
for frameworkPath in frameworkPathsIter:
|
||||||
# print("Calling:", 'find %s -type f | grep -E "%s"' % (frameworkPath, filter_regex))
|
# print("Calling:", 'find %s -type f | grep -E "%s"' % (frameworkPath, filter_regex))
|
||||||
find_grep_results = os.popen('find %s -type f | grep -E "%s"' % (frameworkPath, filter_regex)).read().split('\n')
|
find_grep_results = os.popen( 'find %s -type f | grep -E "%s"' % (frameworkPath, filter_regex) ).read().split('\n')
|
||||||
framework_files = filter(lambda x: x != '',
|
framework_files = filter( lambda x: x != '', map(lambda x: x.strip(), find_grep_results) )
|
||||||
map(lambda x: x.strip(),
|
|
||||||
find_grep_results))
|
|
||||||
|
|
||||||
dependency_dict[frameworkPath] = list()
|
dependency_dict[frameworkPath] = list()
|
||||||
for idx, file in enumerate(framework_files):
|
for idx, file in enumerate(framework_files):
|
||||||
dict_file = {file: WalkLibDependencyTree(file, filter_regex=search_path_filter)}
|
dict_file = { file: WalkLibDependencyTree( file, filter_regex=search_path_filter ) }
|
||||||
dependency_dict[frameworkPath].append(dict_file)
|
dependency_dict[frameworkPath].append(dict_file)
|
||||||
return dependency_dict
|
return dependency_dict
|
||||||
|
|
||||||
|
|
@ -262,17 +265,17 @@ def WalkDictTree( dependencyDict, visited_files ):
|
||||||
if deplib not in visited_files:
|
if deplib not in visited_files:
|
||||||
visited_files.append(deplib)
|
visited_files.append(deplib)
|
||||||
elif isinstance(deplib, dict):
|
elif isinstance(deplib, dict):
|
||||||
dependency_list.append(next(iter(deplib)))
|
dependency_list.append( next(iter(deplib)) )
|
||||||
libNameChanges.extend(WalkDictTree(deplib, visited_files))
|
libNameChanges.extend( WalkDictTree(deplib, visited_files) )
|
||||||
else:
|
else:
|
||||||
#raise RuntimeError("Unexpected value: %s" % deplib)
|
#raise RuntimeError("Unexpected value: %s" % deplib)
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise RuntimeError("Unexpected value: %s" % dependencies)
|
raise RuntimeError( "Unexpected value: %s" % dependencies )
|
||||||
if len(dependency_list) > 0:
|
if len(dependency_list) > 0:
|
||||||
libNameChanges.append((lib, dependency_list))
|
libNameChanges.append( (lib, dependency_list) )
|
||||||
else:
|
else:
|
||||||
libNameChanges.append((lib, ))
|
libNameChanges.append( (lib, ) )
|
||||||
visited_files.append(lib)
|
visited_files.append(lib)
|
||||||
return libNameChanges
|
return libNameChanges
|
||||||
|
|
||||||
|
|
@ -300,7 +303,7 @@ def FindFramework( path, root_path ):
|
||||||
#----------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------
|
||||||
def ResolveExecutablePath( path, executable_path ):
|
def ResolveExecutablePath( path, executable_path ):
|
||||||
""" Transforms @executable_path into executable_path"""
|
""" Transforms @executable_path into executable_path"""
|
||||||
p = path.replace("@executable_path", "/%s/" % executable_path)
|
p = path.replace( "@executable_path", "/%s/" % executable_path )
|
||||||
return p
|
return p
|
||||||
|
|
||||||
#----------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------
|
||||||
|
|
@ -318,7 +321,7 @@ def DetectChanges(frameworkDependencyDict):
|
||||||
libNameChanges = list()
|
libNameChanges = list()
|
||||||
for framework, libraries in frameworkDependencyDict.items():
|
for framework, libraries in frameworkDependencyDict.items():
|
||||||
for libraryDict in libraries:
|
for libraryDict in libraries:
|
||||||
libNameChanges.extend(WalkDictTree(libraryDict, visited_files))
|
libNameChanges.extend( WalkDictTree(libraryDict, visited_files) )
|
||||||
return libNameChanges
|
return libNameChanges
|
||||||
|
|
||||||
#----------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------
|
||||||
|
|
@ -458,9 +461,94 @@ def GenerateInfoPlist( keydic, templfile ):
|
||||||
s = t.substitute( EXECUTABLE = val_exe,
|
s = t.substitute( EXECUTABLE = val_exe,
|
||||||
ICONFILE = val_icon,
|
ICONFILE = val_icon,
|
||||||
BUNDLENAME = val_bname,
|
BUNDLENAME = val_bname,
|
||||||
VERSION = val_ver)
|
VERSION = val_ver )
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------------------
|
||||||
|
## To patch 'Python' itself in Python Framework
|
||||||
|
#
|
||||||
|
# A relatively new Python 3.x may depend on other dylib(s) under /usr/local/opt/.
|
||||||
|
# This was first found in:
|
||||||
|
# Catalina0{kazzz-s} klayout (1)% python3
|
||||||
|
# Python 3.8.16 (default, Dec 12 2022, 14:07:09)
|
||||||
|
# [Clang 12.0.0 (clang-1200.0.32.29)] on darwin
|
||||||
|
# Type "help", "copyright", "credits" or "license" for more information.
|
||||||
|
# >>>
|
||||||
|
#
|
||||||
|
# Catalina0{kazzz-s} Current (2)% pwd
|
||||||
|
# /usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/Current
|
||||||
|
#
|
||||||
|
# Catalina0{kazzz-s} Current (3)% ll
|
||||||
|
# total 5024
|
||||||
|
# drwxr-xr-x 7 kazzz-s admin 224 Dec 16 23:02 .
|
||||||
|
# drwxr-xr-x 4 kazzz-s admin 128 Dec 16 21:40 ..
|
||||||
|
# lrwxr-xr-x 1 kazzz-s admin 17 Dec 17 08:46 Headers -> include/python3.8
|
||||||
|
# -rwxr-xr-x 1 kazzz-s admin 2571960 Dec 12 23:08 Python
|
||||||
|
# drwxr-xr-x 3 kazzz-s admin 96 Dec 12 23:08 include
|
||||||
|
# drwxr-xr-x 5 kazzz-s admin 160 Dec 12 23:08 lib
|
||||||
|
# drwxr-xr-x 3 kazzz-s admin 96 Dec 12 23:08 share
|
||||||
|
#
|
||||||
|
# Catalina0{kazzz-s} Current (4)% otool -L Python
|
||||||
|
# Python:
|
||||||
|
# /usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/Python (compatibility version 3.8.0, current version 3.8.0)
|
||||||
|
# /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1675.129.0)
|
||||||
|
# [*] /usr/local/opt/gettext/lib/libintl.8.dylib (compatibility version 12.0.0, current version 12.0.0)
|
||||||
|
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.100.1)
|
||||||
|
#
|
||||||
|
# This library dependency [*] has to be changed as shown below:
|
||||||
|
# Catalina0{kazzz-s} Current (5)% install_name_tool -change \
|
||||||
|
# /usr/local/opt/gettext/lib/libintl.8.dylib \
|
||||||
|
# @executable_path/../Frameworks/libintl.8.dylib \
|
||||||
|
# Python
|
||||||
|
#
|
||||||
|
# Catalina0{kazzz-s} Current (6)% otool -L Python
|
||||||
|
# Python:
|
||||||
|
# /usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/Python (compatibility version 3.8.0, current version 3.8.0)
|
||||||
|
# /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1675.129.0)
|
||||||
|
# [*] @executable_path/../Frameworks/libintl.8.dylib (compatibility version 12.0.0, current version 12.0.0)
|
||||||
|
# /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.100.1)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# @param[in] pythonFrameworkPath: Python Framework path
|
||||||
|
# @param[in] filter_regex: filter regular expression
|
||||||
|
#
|
||||||
|
# @return 0 on succcess; non-zero on failure
|
||||||
|
#----------------------------------------------------------------------------------------
|
||||||
|
def Patch_Python_In_PythonFramework( pythonFrameworkPath, filter_regex=r'\t+%s/opt' % DefaultHomebrewRoot ):
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
# [1] Get Python's dependency
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
target = "%s/Python" % pythonFrameworkPath
|
||||||
|
otoolCm = 'otool -L %s | grep -E "%s"' % (target, filter_regex)
|
||||||
|
otoolOut = os.popen( otoolCm ).read()
|
||||||
|
exedepdic = DecomposeLibraryDependency( target + ":\n" + otoolOut )
|
||||||
|
keys = exedepdic.keys()
|
||||||
|
deplibs = exedepdic[ list(keys)[0] ]
|
||||||
|
# print(deplibs)
|
||||||
|
# [ '/usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/Python',
|
||||||
|
# '/usr/local/opt/gettext/lib/libintl.8.dylib'
|
||||||
|
# ]
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
# [2] Change the library name
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
cmdNameChg = XcodeToolChain['nameCH']
|
||||||
|
|
||||||
|
for lib in deplibs:
|
||||||
|
basename = os.path.basename(lib)
|
||||||
|
if basename == "Python": # self
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
nameOld = "%s" % lib
|
||||||
|
nameNew = "@executable_path/../Frameworks/%s" % basename
|
||||||
|
command = "%s %s %s %s" % ( cmdNameChg, nameOld, nameNew, target )
|
||||||
|
if subprocess.call( command, shell=True ) != 0:
|
||||||
|
msg = "!!! Failed to make 'Python' aware of the new identification name <%s> of supporter <%s> !!!"
|
||||||
|
print( msg % (nameNew, lib), file=sys.stderr )
|
||||||
|
return 1
|
||||||
|
# for-lib
|
||||||
|
return 0
|
||||||
|
|
||||||
#----------------
|
#----------------
|
||||||
# End of File
|
# End of File
|
||||||
#----------------
|
#----------------
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,7 @@ def Parse_CommandLine_Arguments():
|
||||||
if platform in [ "Monterey", "BigSur" ]:
|
if platform in [ "Monterey", "BigSur" ]:
|
||||||
targetopt = "1,2,3,4"
|
targetopt = "1,2,3,4"
|
||||||
elif platform in ["Catalina"]:
|
elif platform in ["Catalina"]:
|
||||||
targetopt = "0,1,2,3,4"
|
targetopt = "1,2,3,4"
|
||||||
else:
|
else:
|
||||||
targetopt = ""
|
targetopt = ""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,174 @@
|
||||||
|
#! /usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
#==============================================================================
|
||||||
|
# File: macbuild/python3HB.py
|
||||||
|
#
|
||||||
|
# Descriptions: A handy tool to setup the standardized directory structures
|
||||||
|
# for Homebrew's Python 3.x
|
||||||
|
#==============================================================================
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import platform
|
||||||
|
import optparse
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Set global variables
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
def SetGlobals():
|
||||||
|
global DefaultHomebrewRoot
|
||||||
|
global Usage
|
||||||
|
|
||||||
|
(System, Node, Release, MacVersion, Machine, Processor) = platform.uname()
|
||||||
|
if Machine == "arm64": # Apple Silicon!
|
||||||
|
DefaultHomebrewRoot = '/opt/homebrew'
|
||||||
|
else:
|
||||||
|
DefaultHomebrewRoot = '/usr/local'
|
||||||
|
del System, Node, Release, MacVersion, Machine, Processor
|
||||||
|
|
||||||
|
Usage = "\n"
|
||||||
|
Usage += "-------------------------------------------------------------------------------------\n"
|
||||||
|
Usage += "<< Usage of 'python3HB.py' >>\n"
|
||||||
|
Usage += " to setup the standardized directory structures for Homebrew's Python 3.x on Mac\n"
|
||||||
|
Usage += "\n"
|
||||||
|
Usage += " option & argument : descriptions | default value\n"
|
||||||
|
Usage += " -----------------------------------------------------------+---------------\n"
|
||||||
|
Usage += " <-v|--version <number>>: in ['3.8', '3.9', '3.10', '3.11'] | ''\n"
|
||||||
|
Usage += " [-u|-unlink] : unlink only | disabled\n"
|
||||||
|
Usage += " [-?|--?] : print this usage and exit | disabled\n"
|
||||||
|
Usage += "--------------------------------------------------------------+----------------------\n"
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Parse the command line arguments
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
def Parse_CLI_Args():
|
||||||
|
global Version
|
||||||
|
global UnlinkOnly
|
||||||
|
|
||||||
|
p = optparse.OptionParser( usage=Usage )
|
||||||
|
|
||||||
|
p.add_option( '-v', '--version',
|
||||||
|
dest='version',
|
||||||
|
help="python3 version=['3.8', '3.9', '3.10', '3.11']" )
|
||||||
|
|
||||||
|
p.add_option( '-u', '--unlink',
|
||||||
|
action='store_true',
|
||||||
|
dest='unlink',
|
||||||
|
default=False,
|
||||||
|
help='unlink only' )
|
||||||
|
|
||||||
|
p.add_option( '-?', '--??',
|
||||||
|
action='store_true',
|
||||||
|
dest='checkusage',
|
||||||
|
default=False,
|
||||||
|
help='check usage' )
|
||||||
|
|
||||||
|
p.set_defaults( version = "",
|
||||||
|
unlink = False,
|
||||||
|
checkusage = False )
|
||||||
|
|
||||||
|
opt, args = p.parse_args()
|
||||||
|
if (opt.checkusage):
|
||||||
|
print(Usage)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
Version = opt.version
|
||||||
|
UnlinkOnly = opt.unlink
|
||||||
|
if not Version in [ '3.8', '3.9', '3.10', '3.11' ]:
|
||||||
|
print( "! Unsupported Python 3 version <%s>" % Version )
|
||||||
|
print(Usage)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# Set the directory structures
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
def SetDirectoryStructures():
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# [1] Check the root directory of python@${Version}
|
||||||
|
#----------------------------------------------------------
|
||||||
|
root = "%s/opt/python@%s" % (DefaultHomebrewRoot, Version)
|
||||||
|
if not os.path.isdir(root):
|
||||||
|
print( "! Found no such a directory <%s>" % root )
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# [2] Go to "lib/" and make
|
||||||
|
# Python.framework -> ../Frameworks/Python.framework/
|
||||||
|
#----------------------------------------------------------
|
||||||
|
os.chdir( root )
|
||||||
|
os.chdir( "lib/" )
|
||||||
|
try:
|
||||||
|
os.remove( "Python.framework" )
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
if not UnlinkOnly:
|
||||||
|
os.symlink( "../Frameworks/Python.framework/", "Python.framework" )
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# [3] Go to "bin/" and make
|
||||||
|
# ./python${version} -> python3
|
||||||
|
# ./pip${version} -> pip3
|
||||||
|
#----------------------------------------------------------
|
||||||
|
os.chdir( root )
|
||||||
|
os.chdir( "bin/" )
|
||||||
|
try:
|
||||||
|
os.remove( "python3" )
|
||||||
|
os.remove( "pip3" )
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
if not UnlinkOnly:
|
||||||
|
os.symlink( "./python%s" % Version, "python3" )
|
||||||
|
os.symlink( "./pip%s" % Version, "pip3" )
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# [4] Go to "Frameworks/Python.framework/" and delete
|
||||||
|
# three symbolic links
|
||||||
|
#----------------------------------------------------------
|
||||||
|
os.chdir( root )
|
||||||
|
os.chdir( "Frameworks/Python.framework/" )
|
||||||
|
try:
|
||||||
|
os.remove( "Headers" )
|
||||||
|
os.remove( "Resources" )
|
||||||
|
os.remove( "Python" )
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# [5] Go to "Versions/" and make
|
||||||
|
# Current -> ${Version}/
|
||||||
|
#----------------------------------------------------------
|
||||||
|
os.chdir( root )
|
||||||
|
os.chdir( "Frameworks/Python.framework/Versions/" )
|
||||||
|
try:
|
||||||
|
os.remove( "Current" )
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
if not UnlinkOnly:
|
||||||
|
os.symlink( "%s/" % Version, "Current" )
|
||||||
|
|
||||||
|
#----------------------------------------------------------
|
||||||
|
# [6] Go to "Frameworks/Python.framework/" and make
|
||||||
|
# three symbolic links
|
||||||
|
#----------------------------------------------------------
|
||||||
|
if not UnlinkOnly:
|
||||||
|
os.chdir( root )
|
||||||
|
os.chdir( "Frameworks/Python.framework/" )
|
||||||
|
os.symlink( "Versions/Current/Headers/", "Headers" )
|
||||||
|
os.symlink( "Versions/Current/Resources/", "Resources" )
|
||||||
|
os.symlink( "Versions/Current/Python", "Python" )
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# The main function
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
def Main():
|
||||||
|
SetGlobals()
|
||||||
|
Parse_CLI_Args()
|
||||||
|
SetDirectoryStructures()
|
||||||
|
|
||||||
|
#===================================================================================
|
||||||
|
if __name__ == "__main__":
|
||||||
|
Main()
|
||||||
|
|
||||||
|
#---------------
|
||||||
|
# End of file
|
||||||
|
#---------------
|
||||||
Loading…
Reference in New Issue