|
1 |
| -#! /usr/bin/env python |
| 1 | +#!/usr/bin/env python3 |
2 | 2 | # -*- coding: utf-8 -*-
|
3 | 3 |
|
4 | 4 | #===============================================================================
|
@@ -538,8 +538,8 @@ def DeployBinariesForBundle():
|
538 | 538 | if not DeploymentF and not DeploymentP:
|
539 | 539 | return 1
|
540 | 540 | if DeploymentF and NonOSStdLang:
|
541 |
| - print( "WARNING!!! You chose <-y|--deploy> while using non-OS-standard script language.", file=sys.stderr ) |
542 |
| - print( " Use <-Y|--DEPLOY> instead", file=sys.stderr ) |
| 541 | + print( " WARNING!!! You chose <-y|--deploy> while using non-OS-standard script language.", file=sys.stderr ) |
| 542 | + print( " Consider using <-Y|--DEPLOY> instead", file=sys.stderr ) |
543 | 543 | #return 1
|
544 | 544 | if not os.path.isfile(MacBuildLog):
|
545 | 545 | print( "!!! Build log file <%s> does not present !!!" % MacBuildLog, file=sys.stderr )
|
@@ -756,51 +756,119 @@ def DeployBinariesForBundle():
|
756 | 756 | os.chdir(ProjectDir)
|
757 | 757 | os.chdir(MacPkgDir)
|
758 | 758 | command = "%s %s %s" % ( deploytool, app_bundle, options )
|
759 |
| - print(command) |
760 | 759 | if subprocess.call( command, shell=True ) != 0:
|
761 | 760 | msg = "!!! Failed to deploy applications on OSX !!!"
|
762 | 761 | print( msg, file=sys.stderr )
|
763 | 762 | print("")
|
764 | 763 | os.chdir(ProjectDir)
|
765 | 764 | return 1
|
766 | 765 |
|
767 |
| - deploymentPython = False |
768 |
| - if deploymentPython: |
769 |
| - # TODO Code incomplete! To be finished. |
770 |
| - from macbuild.build4mac_util import WalkFrameworkPaths, PerformChanges, DetectChanges |
771 |
| - |
772 |
| - bundlePath = 'qt5.pkg.macos-HighSierra-release/klayout.app' |
773 |
| - bundleExecPathAbs = os.getcwd() + '/%s/Contents/MacOS/' % bundlePath |
774 |
| - |
775 |
| - # rsync -a --safe-links /usr/local/opt/python/Frameworks/Python.framework/ qt5.pkg.macos-HighSierra-release/klayout.app/Contents/Frameworks/Python.framework |
776 |
| - # cp -RL /usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages qt5.pkg.macos-HighSierra-release/klayout.app/Contents/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ |
777 |
| - # rm -rf qt5.pkg.macos-HighSierra-release/klayout.app/Contents/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/test |
| 766 | + deploymentPython = True |
| 767 | + if deploymentPython and NonOSStdLang: |
| 768 | + from build4mac_util import WalkFrameworkPaths, PerformChanges, DetectChanges |
| 769 | + from pathlib import Path |
778 | 770 |
|
| 771 | + bundlePath = AbsMacPkgDir + '/klayout.app' |
| 772 | + # bundlePath = os.getcwd() + '/qt5.pkg.macos-HighSierra-release/klayout.app' |
| 773 | + bundleExecPathAbs = '%s/Contents/MacOS/' % bundlePath |
| 774 | + pythonOriginalFrameworkPath = '/usr/local/opt/python/Frameworks/Python.framework' |
779 | 775 | pythonFrameworkPath = '%s/Contents/Frameworks/Python.framework' % bundlePath
|
780 |
| - depdict = WalkFrameworkPaths(pythonFrameworkPath) |
781 | 776 |
|
782 |
| - pythonOriginalFrameworkPath = '/usr/local/opt/python/Frameworks/Python.framework' |
| 777 | + print(f" [8.1] Deploying Python from {pythonOriginalFrameworkPath} ..." ) |
| 778 | + print(" [1] Copying Python Framework") |
| 779 | + shell_commands = list() |
| 780 | + shell_commands.append(f"rm -rf {pythonFrameworkPath}") |
| 781 | + shell_commands.append(f"rsync -a --safe-links {pythonOriginalFrameworkPath}/ {pythonFrameworkPath}") |
| 782 | + shell_commands.append(f"mkdir {pythonFrameworkPath}/Versions/3.6/lib/python3.6/site-packages/") |
| 783 | + shell_commands.append(f"cp -RL {pythonOriginalFrameworkPath}/Versions/3.6/lib/python3.6/site-packages/{{pip*,pkg_resources,setuptools*,wheel*}} " + |
| 784 | + f"{pythonFrameworkPath}/Versions/3.6/lib/python3.6/site-packages/") |
| 785 | + shell_commands.append(f"rm -rf {pythonFrameworkPath}/Versions/3.6/lib/python3.6/test") |
| 786 | + shell_commands.append(f"rm -rf {pythonFrameworkPath}/Versions/3.6/Resources") |
| 787 | + shell_commands.append(f"rm -rf {pythonFrameworkPath}/Versions/3.6/bin") |
| 788 | + |
| 789 | + for command in shell_commands: |
| 790 | + if subprocess.call( command, shell=True ) != 0: |
| 791 | + msg = "command failed: %s" |
| 792 | + print( msg % command, file=sys.stderr ) |
| 793 | + exit(1) |
| 794 | + |
| 795 | + shutil.copy2( sourceDir2 + "/start-console.py", targetDirM ) |
| 796 | + shutil.copy2( sourceDir2 + "/klayout_console", targetDirM ) |
| 797 | + os.chmod( targetDirM + "/klayout_console", 0o0755 ) |
| 798 | + |
| 799 | + print(" [2] Relinking dylib dependencies inside Python.framework") |
| 800 | + print(" [2.1] Patching Python Framework") |
| 801 | + depdict = WalkFrameworkPaths(pythonFrameworkPath) |
783 | 802 | appPythonFrameworkPath = '@executable_path/../Frameworks/Python.framework/'
|
784 |
| - PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath)], bundleExecPathAbs) |
785 |
| - |
786 |
| - klayoutPath = bundleExecPathAbs |
787 |
| - depdict = WalkFrameworkPaths(klayoutPath, filter_regex=r'klayout$') |
788 |
| - PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath)], bundleExecPathAbs) |
789 |
| - |
790 |
| - klayoutPath = bundleExecPathAbs + '../Frameworks' |
791 |
| - depdict = WalkFrameworkPaths(klayoutPath, filter_regex=r'libklayout') |
792 |
| - PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath)], bundleExecPathAbs) |
793 |
| - |
| 803 | + PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs) |
794 | 804 |
|
| 805 | + print(" [2.2] Patching /usr/local/opt/ libs") |
795 | 806 | usrLocalPath = '/usr/local/opt/'
|
796 | 807 | appUsrLocalPath = '@executable_path/../Frameworks/'
|
797 |
| - depdict = WalkFrameworkPaths(pythonFrameworkPath) |
798 |
| - PerformChanges(depdict, [(usrLocalPath, appUsrLocalPath)], bundleExecPathAbs) |
| 808 | + replacePairs = [(usrLocalPath, appUsrLocalPath, True)] |
| 809 | + depdict = WalkFrameworkPaths(pythonFrameworkPath, search_path_filter=r'\t+/usr/local/(opt|Cellar)') |
| 810 | + PerformChanges(depdict, replacePairs, bundleExecPathAbs) |
799 | 811 |
|
800 |
| - # usrLocalPath = '/usr/local/lib/' |
801 |
| - # appUsrLocalPath = '@executable_path/../Frameworks/' |
802 |
| - # depdict = WalkFrameworkPaths(pythonFrameworkPath) |
803 |
| - # PerformChanges(depdict, [(usrLocalPath, appUsrLocalPath)], bundleExecPathAbs) |
| 812 | + print(" [2.3] Patching openssl, gdbm, readline, sqlite, tcl-tk, xz") |
| 813 | + usrLocalPath = '/usr/local/opt' |
| 814 | + appUsrLocalPath = '@executable_path/../Frameworks/' |
| 815 | + replacePairs = [(usrLocalPath, appUsrLocalPath, True)] |
| 816 | + replacePairs.extend([(openssl_version, '@executable_path/../Frameworks/openssl', True) |
| 817 | + for openssl_version in list(Path('/usr/local/Cellar/openssl').glob('*'))]) |
| 818 | + depdict = WalkFrameworkPaths([pythonFrameworkPath + '/../openssl', |
| 819 | + pythonFrameworkPath + '/../gdbm', |
| 820 | + pythonFrameworkPath + '/../readline', |
| 821 | + pythonFrameworkPath + '/../sqlite', |
| 822 | + pythonFrameworkPath + '/../tcl-tk', |
| 823 | + pythonFrameworkPath + '/../xz'], search_path_filter=r'\t+/usr/local/(opt|Cellar)') |
| 824 | + |
| 825 | + PerformChanges(depdict, replacePairs, bundleExecPathAbs) |
| 826 | + |
| 827 | + print(" [3] Relinking dylib dependencies for klayout") |
| 828 | + klayoutPath = bundleExecPathAbs |
| 829 | + depdict = WalkFrameworkPaths(klayoutPath, filter_regex=r'klayout$') |
| 830 | + PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs) |
| 831 | + |
| 832 | + libKlayoutPath = bundleExecPathAbs + '../Frameworks' |
| 833 | + depdict = WalkFrameworkPaths(libKlayoutPath, filter_regex=r'libklayout') |
| 834 | + PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs) |
| 835 | + |
| 836 | + print(" [4] Patching site.py, pip/, and distutils/") |
| 837 | + site_module = f"{pythonFrameworkPath}/Versions/3.6/lib/python3.6/site.py" |
| 838 | + with open(site_module, 'r') as site: |
| 839 | + buf = site.readlines() |
| 840 | + with open(site_module, 'w') as site: |
| 841 | + import re |
| 842 | + for line in buf: |
| 843 | + # This will fool pip into thinking it's inside a virtual environment |
| 844 | + # and install new packates to the correct site-packages |
| 845 | + if re.match("^PREFIXES", line) is not None: |
| 846 | + line = line + "sys.real_prefix = sys.prefix\n" |
| 847 | + # do not allow installation in the user folder. |
| 848 | + if re.match("^ENABLE_USER_SITE", line) is not None: |
| 849 | + line = "ENABLE_USER_SITE = False\n" |
| 850 | + site.write(line) |
| 851 | + |
| 852 | + pip_module = f"{pythonFrameworkPath}/Versions/3.6/lib/python3.6/site-packages/pip/__init__.py" |
| 853 | + with open(pip_module, 'r') as pip: |
| 854 | + buf = pip.readlines() |
| 855 | + with open(pip_module, 'w') as pip: |
| 856 | + import re |
| 857 | + for line in buf: |
| 858 | + # this will reject user's configuration of pip, forcing the isolated mode |
| 859 | + line = re.sub("return isolated$", "return isolated or True", line) |
| 860 | + pip.write(line) |
| 861 | + |
| 862 | + distutilsconfig = f"{pythonFrameworkPath}/Versions/3.6/lib/python3.6/distutils/distutils.cfg" |
| 863 | + with open(distutilsconfig, 'r') as file: |
| 864 | + buf = file.readlines() |
| 865 | + with open(distutilsconfig, 'w') as file: |
| 866 | + import re |
| 867 | + for line in buf: |
| 868 | + # This will cause all packages to be installed to sys.prefix |
| 869 | + if re.match('prefix=', line) is not None: |
| 870 | + continue |
| 871 | + file.write(line) |
804 | 872 |
|
805 | 873 | else:
|
806 | 874 | print( " [8] Skipped deploying Qt's Frameworks ..." )
|
|
0 commit comments