Updated the build system for Mac (#1073)

* WIP: add "pymod"

* To fix the issue reported by GitHub ticket No.1040

* WIP: To build "pymod"

* Updated the build system for Mac.

* Updated the build system for Mac.
This commit is contained in:
Kazunari Sekigawa 2022-05-06 05:01:40 +09:00 committed by Matthias Koefferlein
parent 66c0eaccab
commit 1464ede707
5 changed files with 368 additions and 155 deletions

View File

@ -1,9 +1,9 @@
Relevant KLayout version: 0.27.4<br> Relevant KLayout version: 0.27.9<br>
Author: Kazzz-S<br> Author: Kazzz-S<br>
Last modified: 2021-11-07<br> Last modified: 2022-04-30<br>
# 1. Introduction # 1. Introduction
This directory **`macbuild`** contains different files required for building KLayout (http://www.klayout.de/) version 0.27.4 or later for different 64-bit macOS, including: This directory **`macbuild`** contains different files required for building KLayout (http://www.klayout.de/) version 0.27.9 or later for different 64-bit macOS, including:
* Catalina (10.15.7) : the primary development environment * Catalina (10.15.7) : the primary development environment
* Big Sur (11.x) : experimental; Apple M1 chip is not tested since the author does not own an M1 Mac * Big Sur (11.x) : experimental; Apple M1 chip is not tested since the author does not own an M1 Mac
* Monterey (12.x) : -- ditto -- * Monterey (12.x) : -- ditto --
@ -53,8 +53,9 @@ $ /usr/bin/python --version
Python 2.7.16 Python 2.7.16
``` ```
Big Sur (11.x) and Monterey (12.x) still provide the Python 2.7 binaries to run various legacy applications.<br> Big Sur (11.x) and Monterey (< 12.3) still provide the Python 2.7 binaries to run various legacy applications.<br>
However, the latest Xcode 13.1 does not allow us to link the legacy Python 2.7 library with the newly compiled KLayout binaries.<br> However, the latest Xcode 13.1 does not allow us to link the legacy Python 2.7 library with the newly compiled KLayout binaries.<br>
Moreover, Monterey (12.3.1) finally eliminated the Python 2.7 binaries.<br>
Therefore, Homebrew is adopted as the default environment for Big Sur and Monterey. Therefore, Homebrew is adopted as the default environment for Big Sur and Monterey.
The build script **`build4mac.py`** provides several possible combinations of Qt5, Ruy, and Python modules to accommodate such a slightly complex environment.<br> The build script **`build4mac.py`** provides several possible combinations of Qt5, Ruy, and Python modules to accommodate such a slightly complex environment.<br>
@ -72,7 +73,7 @@ You need to have:
``` ```
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
<< Usage of 'build4mac.py' >> << Usage of 'build4mac.py' >>
for building KLayout 0.27.4 or later on different Apple macOS / Mac OSX platforms. for building KLayout 0.27.9 or later on different Apple macOS / Mac OSX platforms.
$ [python] ./build4mac.py $ [python] ./build4mac.py
option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value
@ -95,6 +96,7 @@ $ [python] ./build4mac.py
: HB38: use Python 3.8 from Homebrew | : HB38: use Python 3.8 from Homebrew |
: Ana3: use Python 3.8 from Anaconda3 | : Ana3: use Python 3.8 from Anaconda3 |
: HBAuto: use the latest Python 3.x auto-detected from Homebrew | : HBAuto: use the latest Python 3.x auto-detected from Homebrew |
[-j|--jump2pymod] : jump into <pymod> build (developer's use only) | disabled
[-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled
[-u|--noqtuitools] : don't include uitools in Qt binding | disabled [-u|--noqtuitools] : don't include uitools in Qt binding | disabled
[-m|--make <option>] : option passed to 'make' | '--jobs=4' [-m|--make <option>] : option passed to 'make' | '--jobs=4'
@ -119,7 +121,7 @@ $ [python] ./build4mac.py
``` ```
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
<< Usage of 'build4mac.py' >> << Usage of 'build4mac.py' >>
for building KLayout 0.27.4 or later on different Apple macOS / Mac OSX platforms. for building KLayout 0.27.9 or later on different Apple macOS / Mac OSX platforms.
$ [python] ./build4mac.py $ [python] ./build4mac.py
option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value
@ -142,6 +144,7 @@ $ [python] ./build4mac.py
: HB38: use Python 3.8 from Homebrew | : HB38: use Python 3.8 from Homebrew |
: Ana3: use Python 3.8 from Anaconda3 | : Ana3: use Python 3.8 from Anaconda3 |
: HBAuto: use the latest Python 3.x auto-detected from Homebrew | : HBAuto: use the latest Python 3.x auto-detected from Homebrew |
[-j|--jump2pymod] : jump into <pymod> build (developer's use only) | disabled
[-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled
[-u|--noqtuitools] : don't include uitools in Qt binding | disabled [-u|--noqtuitools] : don't include uitools in Qt binding | disabled
[-m|--make <option>] : option passed to 'make' | '--jobs=4' [-m|--make <option>] : option passed to 'make' | '--jobs=4'
@ -214,7 +217,9 @@ $ ./build4mac.py -q qt5macports -r mp27 -p mp38
``` ```
2. Confirm successful build (it will take about one hour depending on your machine spec). 2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br> 3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step. The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.<br>
The KLayout Python Module (\*.whl, \*.egg) will be deployed under **klayout.app/Contents/pymod-dist/**.
``` ```
$ ./build4mac.py -q qt5macports -r mp27 -p mp38 -Y $ ./build4mac.py -q qt5macports -r mp27 -p mp38 -Y
``` ```
@ -239,7 +244,9 @@ $ ./build4mac.py -q qt5brew -r hb27 -p hb38
``` ```
2. Confirm successful build (it will take about one hour depending on your machine spec). 2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br> 3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step. The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.<br>
The KLayout Python Module (\*.whl, \*.egg) will be deployed under **klayout.app/Contents/pymod-dist/**.
``` ```
$ ./build4mac.py -q qt5brew -r hb27 -p hb38 -Y $ ./build4mac.py -q qt5brew -r hb27 -p hb38 -Y
``` ```
@ -263,7 +270,8 @@ $ ./build4mac.py -q qt5brew -r sys -p hb38
``` ```
2. Confirm successful build (it will take about one hour depending on your machine spec). 2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-y" to deploy executables and libraries (including Qt's framework and Python framework) under **`klayout.app`** bundle.<br> 3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-y" to deploy executables and libraries (including Qt's framework and Python framework) under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step. The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.
``` ```
$ ./build4mac.py -q qt5brew -r sys -p hb38 -y $ ./build4mac.py -q qt5brew -r sys -p hb38 -y
``` ```
@ -289,7 +297,9 @@ $ ./build4mac.py -q qt5ana3 -r ana3 -p ana3
``` ```
2. Confirm successful build (it will take about one hour depending on your machine spec). 2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br> 3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step. The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.<br>
The KLayout Python Module (\*.whl, \*.egg) will be deployed under **klayout.app/Contents/pymod-dist/**.
``` ```
$ ./build4mac.py -q qt5ana3 -r ana3 -p ana3 -Y $ ./build4mac.py -q qt5ana3 -r ana3 -p ana3 -Y
``` ```
@ -324,8 +334,8 @@ $ cd /where/'build.sh'/exists
$ ./makeDMG4mac.py -p ST-qt5MP.pkg.macos-Catalina-release-RsysPsys -m $ ./makeDMG4mac.py -p ST-qt5MP.pkg.macos-Catalina-release-RsysPsys -m
``` ```
This command will generate the two files below:<br> This command will generate the two files below:<br>
* **`ST-klayout-0.27.4-macOS-Catalina-1-qt5MP-RsysPsys.dmg`** ---(1) the main DMG file * **`ST-klayout-0.27.9-macOS-Catalina-1-qt5MP-RsysPsys.dmg`** ---(1) the main DMG file
* **`ST-klayout-0.27.4-macOS-Catalina-1-qt5MP-RsysPsys.dmg.md5`** ---(2) MD5-value text file * **`ST-klayout-0.27.9-macOS-Catalina-1-qt5MP-RsysPsys.dmg.md5`** ---(2) MD5-value text file
# Known issues # Known issues
Because we assume some specific versions of non-OS-standard Ruby and Python, updating MacPorts, Homebrew, or Anaconda3 may cause build- and link errors.<br> Because we assume some specific versions of non-OS-standard Ruby and Python, updating MacPorts, Homebrew, or Anaconda3 may cause build- and link errors.<br>

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#=============================================================================== #===============================================================================
@ -47,7 +47,7 @@ def GenerateUsage(platform):
usage = "\n" usage = "\n"
usage += "---------------------------------------------------------------------------------------------------------\n" usage += "---------------------------------------------------------------------------------------------------------\n"
usage += "<< Usage of 'build4mac.py' >>\n" usage += "<< Usage of 'build4mac.py' >>\n"
usage += " for building KLayout 0.27.4 or later on different Apple macOS / Mac OSX platforms.\n" usage += " for building KLayout 0.27.9 or later on different Apple macOS / Mac OSX platforms.\n"
usage += "\n" usage += "\n"
usage += "$ [python] ./build4mac.py\n" usage += "$ [python] ./build4mac.py\n"
usage += " option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value\n" usage += " option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value\n"
@ -70,6 +70,7 @@ def GenerateUsage(platform):
usage += " : HB38: use Python 3.8 from Homebrew | \n" usage += " : HB38: use Python 3.8 from Homebrew | \n"
usage += " : Ana3: use Python 3.8 from Anaconda3 | \n" usage += " : Ana3: use Python 3.8 from Anaconda3 | \n"
usage += " : HBAuto: use the latest Python 3.x auto-detected from Homebrew | \n" usage += " : HBAuto: use the latest Python 3.x auto-detected from Homebrew | \n"
usage += " [-j|--jump2pymod] : jump into <pymod> build (developer's use only) | disabled\n"
usage += " [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled\n" usage += " [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled\n"
usage += " [-u|--noqtuitools] : don't include uitools in Qt binding | disabled\n" usage += " [-u|--noqtuitools] : don't include uitools in Qt binding | disabled\n"
usage += " [-m|--make <option>] : option passed to 'make' | '--jobs=4'\n" usage += " [-m|--make <option>] : option passed to 'make' | '--jobs=4'\n"
@ -176,6 +177,7 @@ def Get_Default_Config():
ModuleRuby = "nil" ModuleRuby = "nil"
ModulePython = "nil" ModulePython = "nil"
Jump2Pymod = False
NonOSStdLang = False NonOSStdLang = False
NoQtBindings = False NoQtBindings = False
NoQtUiTools = False NoQtUiTools = False
@ -196,6 +198,7 @@ def Get_Default_Config():
config['ModuleQt'] = ModuleQt # Qt module to be used config['ModuleQt'] = ModuleQt # Qt module to be used
config['ModuleRuby'] = ModuleRuby # Ruby module to be used config['ModuleRuby'] = ModuleRuby # Ruby module to be used
config['ModulePython'] = ModulePython # Python module to be used config['ModulePython'] = ModulePython # Python module to be used
config['Jump2Pymod'] = Jump2Pymod # True to jump into <pymod> build
config['NonOSStdLang'] = NonOSStdLang # True if non-OS-standard language is chosen config['NonOSStdLang'] = NonOSStdLang # True if non-OS-standard language is chosen
config['NoQtBindings'] = NoQtBindings # True if not creating Qt bindings for Ruby scripts config['NoQtBindings'] = NoQtBindings # True if not creating Qt bindings for Ruby scripts
config['NoQtUiTools'] = NoQtUiTools # True if not to include QtUiTools in Qt binding config['NoQtUiTools'] = NoQtUiTools # True if not to include QtUiTools in Qt binding
@ -235,6 +238,7 @@ def Parse_CLI_Args(config):
ModuleQt = config['ModuleQt'] ModuleQt = config['ModuleQt']
ModuleRuby = config['ModuleRuby'] ModuleRuby = config['ModuleRuby']
ModulePython = config['ModulePython'] ModulePython = config['ModulePython']
Jump2Pymod = config['Jump2Pymod']
NonOSStdLang = config['NonOSStdLang'] NonOSStdLang = config['NonOSStdLang']
NoQtBindings = config['NoQtBindings'] NoQtBindings = config['NoQtBindings']
NoQtUiTools = config['NoQtUiTools'] NoQtUiTools = config['NoQtUiTools']
@ -263,6 +267,12 @@ def Parse_CLI_Args(config):
dest='type_python', dest='type_python',
help="Python type=['nil', 'Sys', 'MP38', 'HB38', 'Ana3', 'HBAuto']" ) help="Python type=['nil', 'Sys', 'MP38', 'HB38', 'Ana3', 'HBAuto']" )
p.add_option( '-j', '--jump2pymod',
action='store_true',
dest='jump_to_pymod',
default=False,
help="jump into <pymod> build (developer's use only)" )
p.add_option( '-n', '--noqtbinding', p.add_option( '-n', '--noqtbinding',
action='store_true', action='store_true',
dest='no_qt_binding', dest='no_qt_binding',
@ -317,6 +327,7 @@ def Parse_CLI_Args(config):
p.set_defaults( type_qt = "qt5brew", p.set_defaults( type_qt = "qt5brew",
type_ruby = "hb27", type_ruby = "hb27",
type_python = "hb38", type_python = "hb38",
jump_to_pymod = False,
no_qt_binding = False, no_qt_binding = False,
no_qt_uitools = False, no_qt_uitools = False,
make_option = "--jobs=4", make_option = "--jobs=4",
@ -330,6 +341,7 @@ def Parse_CLI_Args(config):
p.set_defaults( type_qt = "qt5macports", p.set_defaults( type_qt = "qt5macports",
type_ruby = "sys", type_ruby = "sys",
type_python = "sys", type_python = "sys",
jump_to_pymod = False,
no_qt_binding = False, no_qt_binding = False,
no_qt_uitools = False, no_qt_uitools = False,
make_option = "--jobs=4", make_option = "--jobs=4",
@ -473,6 +485,8 @@ def Parse_CLI_Args(config):
# (D) Set of modules chosen # (D) Set of modules chosen
ModuleSet = ( choiceQt5, choiceRuby, choicePython ) ModuleSet = ( choiceQt5, choiceRuby, choicePython )
# (E) Set other parameters
Jump2Pymod = opt.jump_to_pymod
NoQtBindings = opt.no_qt_binding NoQtBindings = opt.no_qt_binding
NoQtUiTools = opt.no_qt_uitools NoQtUiTools = opt.no_qt_uitools
MakeOptions = opt.make_option MakeOptions = opt.make_option
@ -518,7 +532,7 @@ def Parse_CLI_Args(config):
print( "" ) print( "" )
print( message ) print( message )
print( "" ) print( "" )
if CheckComOnly: if CheckComOnly and not Jump2Pymod:
sys.exit(0) sys.exit(0)
#----------------------------------------------------- #-----------------------------------------------------
@ -529,6 +543,7 @@ def Parse_CLI_Args(config):
config['ModuleQt'] = ModuleQt config['ModuleQt'] = ModuleQt
config['ModuleRuby'] = ModuleRuby config['ModuleRuby'] = ModuleRuby
config['ModulePython'] = ModulePython config['ModulePython'] = ModulePython
config['Jump2Pymod'] = Jump2Pymod
config['NonOSStdLang'] = NonOSStdLang config['NonOSStdLang'] = NonOSStdLang
config['NoQtBindings'] = NoQtBindings config['NoQtBindings'] = NoQtBindings
config['NoQtUiTools'] = NoQtUiTools config['NoQtUiTools'] = NoQtUiTools
@ -539,7 +554,7 @@ def Parse_CLI_Args(config):
config['DeploymentP'] = DeploymentP config['DeploymentP'] = DeploymentP
config['PackagePrefix'] = PackagePrefix config['PackagePrefix'] = PackagePrefix
config['DeployVerbose'] = DeployVerbose config['DeployVerbose'] = DeployVerbose
config['ModuleSet'] = ModuleSet # config['ModuleSet'] = ModuleSet
return config return config
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@ -559,6 +574,7 @@ def Get_Build_Parameters(config):
ModuleQt = config['ModuleQt'] ModuleQt = config['ModuleQt']
ModuleRuby = config['ModuleRuby'] ModuleRuby = config['ModuleRuby']
ModulePython = config['ModulePython'] ModulePython = config['ModulePython']
Jump2Pymod = config['Jump2Pymod']
ModuleSet = config['ModuleSet'] ModuleSet = config['ModuleSet']
NoQtBindings = config['NoQtBindings'] NoQtBindings = config['NoQtBindings']
NoQtUiTools = config['NoQtUiTools'] NoQtUiTools = config['NoQtUiTools']
@ -642,8 +658,162 @@ def Get_Build_Parameters(config):
# (J) Extra parameters needed for deployment # (J) Extra parameters needed for deployment
parameters['project_dir'] = ProjectDir parameters['project_dir'] = ProjectDir
# (K) Extra parameters needed for <pymod>
# <pymod> will be built for:
# Platform = [ 'Monterey', 'BigSur', 'Catalina' ]
# ModuleRuby = [ 'Ruby27MacPorts', 'Ruby27Brew', 'RubyAnaconda3' ]
# ModulePython = [ 'Python38MacPorts', 'Python38Brew',
# 'PythonAnaconda3', 'PythonAutoBrew' ]
parameters['Jump2Pymod'] = Jump2Pymod
parameters['Platform'] = Platform
parameters['ModuleRuby'] = ModuleRuby
parameters['ModulePython'] = ModulePython
PymodDistDir = dict()
if Platform in [ 'Monterey', 'BigSur', 'Catalina' ]:
if ModuleRuby in [ 'Ruby27MacPorts', 'Ruby27Brew', 'RubyAnaconda3' ]:
if ModulePython in ['Python38MacPorts']:
PymodDistDir[ModulePython] = 'dist-MP3'
elif ModulePython in [ 'Python38Brew', 'PythonAutoBrew' ]:
PymodDistDir[ModulePython] = 'dist-HB3'
elif ModulePython in [ 'PythonAnaconda3' ]:
PymodDistDir[ModulePython] = 'dist-ana3'
parameters['pymod_dist'] = PymodDistDir
return parameters return parameters
#------------------------------------------------------------------------------
## To run the "setup.py" script with appropriate options for building
# the klayout Python Module "pymod".
#
# @param[in] parameters dictionary containing the build parameters
#
# @return 0 on success; non-zero (1), otherwise
#------------------------------------------------------------------------------
def Build_pymod(parameters):
#---------------------------------------------------------------------------
# [1] <pymod> will be built for:
# Platform = [ 'Monterey', 'BigSur', 'Catalina' ]
# ModuleRuby = [ 'Ruby27MacPorts', 'Ruby27Brew', 'RubyAnaconda3' ]
# ModulePython = [ 'Python38MacPorts', 'Python38Brew',
# 'PythonAnaconda3', 'PythonAutoBrew' ]
#---------------------------------------------------------------------------
Platform = parameters['Platform']
ModuleRuby = parameters['ModuleRuby']
ModulePython = parameters['ModulePython']
if not Platform in [ 'Monterey', 'BigSur', 'Catalina' ]:
return 0
elif not ModuleRuby in [ 'Ruby27MacPorts', 'Ruby27Brew', 'RubyAnaconda3' ]:
return 0
elif not ModulePython in [ 'Python38MacPorts', 'Python38Brew', 'PythonAnaconda3', 'PythonAutoBrew' ]:
return 0
#--------------------------------------------------------------------
# [2] Get the new directory names (dictionary) for "dist"
#--------------------------------------------------------------------
PymodDistDir = parameters['pymod_dist']
#--------------------------------------------------------------------
# [3] Set different command line parameters for building <pymod>
#--------------------------------------------------------------------
cmd1_args = " setup.py build \\\n"
cmd2_args = " setup.py bdist_wheel \\\n"
cmd3_args = " setup.py bdist_egg \\\n"
cmd4_args = " setup.py clean --all \\\n"
#--------------------------------------------------------------------
# [4] Make the consolidated command lines
#--------------------------------------------------------------------
command1 = "time"
command1 += " \\\n %s \\\n" % parameters['python']
command1 += cmd1_args
command1 += " 2>&1 | tee -a %s; \\\n" % parameters['logfile']
command1 += " test ${PIPESTATUS[0]} -eq 0" # tee always exits with 0
command2 = "time"
command2 += " \\\n %s \\\n" % parameters['python']
command2 += cmd2_args
command2 += " 2>&1 | tee -a %s; \\\n" % parameters['logfile']
command2 += " test ${PIPESTATUS[0]} -eq 0" # tee always exits with 0
command3 = "time"
command3 += " \\\n %s \\\n" % parameters['python']
command3 += cmd3_args
command3 += " 2>&1 | tee -a %s; \\\n" % parameters['logfile']
command3 += " test ${PIPESTATUS[0]} -eq 0" # tee always exits with 0
command4 = "time"
command4 += " \\\n %s \\\n" % parameters['python']
command4 += cmd4_args
command4 += " 2>&1 | tee -a %s; \\\n" % parameters['logfile']
command4 += " test ${PIPESTATUS[0]} -eq 0" # tee always exits with 0
print( "" )
print( "### You are going to build <pymod> with the following four stages." )
print( "<Stage-1>")
print( " ", command1 )
print( "" )
print( "<Stage-2>")
print( " ", command2 )
print( "" )
print( "<Stage-3>")
print( " ", command3 )
print( "" )
print( "<Stage-4>")
print( " ", command4 )
print( "" )
if parameters['check_cmd_only']:
sys.exit(0)
#-----------------------------------------------------
# [5] Invoke the main Python scripts; takes time:-)
#-----------------------------------------------------
myscript = os.path.basename(__file__)
ret = subprocess.call( command1, shell=True )
if ret != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to build <pymod>" % myscript, file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
ret = subprocess.call( command2, shell=True )
if ret != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to build <pymod-wheel>" % myscript, file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
ret = subprocess.call( command3, shell=True )
if ret != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to build <pymod-egg>" % myscript, file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
ret = subprocess.call( command4, shell=True )
if ret != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to clean <pymod>" % myscript, file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
#-----------------------------------------------------
# [6] Rename the "dist/" directory
#-----------------------------------------------------
os.rename( "dist", PymodDistDir[ModulePython] )
return 0
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
## To run the main Bash script "build.sh" with appropriate options ## To run the main Bash script "build.sh" with appropriate options
# #
@ -652,6 +822,9 @@ def Get_Build_Parameters(config):
# @return 0 on success; non-zero (1), otherwise # @return 0 on success; non-zero (1), otherwise
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
def Run_Build_Command(parameters): def Run_Build_Command(parameters):
jump2pymod = parameters['Jump2Pymod']
if not jump2pymod:
#----------------------------------------------------- #-----------------------------------------------------
# [1] Set parameters passed to the main Bash script # [1] Set parameters passed to the main Bash script
#----------------------------------------------------- #-----------------------------------------------------
@ -778,7 +951,12 @@ def Run_Build_Command(parameters):
print( "### <%s>: prepared the initial *.macQAT/" % myscript, file=sys.stderr ) print( "### <%s>: prepared the initial *.macQAT/" % myscript, file=sys.stderr )
print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", file=sys.stderr ) print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", file=sys.stderr )
print( "", file=sys.stderr ) print( "", file=sys.stderr )
return 0
#------------------------------------------------------------------------
# [5] Build <pymod> for some predetermined environments
#------------------------------------------------------------------------
ret = Build_pymod(parameters)
return ret
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
## For making a bundle (klayout.app), deploy built binaries and libraries ## For making a bundle (klayout.app), deploy built binaries and libraries
@ -814,6 +992,13 @@ def Deploy_Binaries_For_Bundle(config, parameters):
AbsMacBuildDir = "%s/%s" % (ProjectDir, MacBuildDir) AbsMacBuildDir = "%s/%s" % (ProjectDir, MacBuildDir)
AbsMacBuildLog = "%s/%s" % (ProjectDir, MacBuildLog) AbsMacBuildLog = "%s/%s" % (ProjectDir, MacBuildLog)
try:
PymodDistDir = parameters['pymod_dist']
pymodDistDir = PymodDistDir[ModulePython] # [ 'dist-MP3', 'dist-HB3', 'dist-ana3' ]
except KeyError:
pymodDistDir = ""
else:
pass
print("") print("")
print( "##### Started deploying libraries and executables for <klayout.app> #####" ) print( "##### Started deploying libraries and executables for <klayout.app> #####" )
@ -852,7 +1037,7 @@ def Deploy_Binaries_For_Bundle(config, parameters):
print( " [3] Creating the standard directory structure for 'klayout.app' bundle ..." ) print( " [3] Creating the standard directory structure for 'klayout.app' bundle ..." )
#----------------------------------------------------------------- #--------------------------------------------------------------------------------------------------------------
# [3] Create the directory skeleton for "klayout.app" bundle # [3] Create the directory skeleton for "klayout.app" bundle
# and command line buddy tools such as "strm2cif". # and command line buddy tools such as "strm2cif".
# They are stored in the directory structure below. # They are stored in the directory structure below.
@ -872,24 +1057,34 @@ def Deploy_Binaries_For_Bundle(config, parameters):
# | +-- db_plugins/ # | +-- db_plugins/
# | +-- lay_plugins/ # | +-- lay_plugins/
# +-- Buddy/+ # +-- Buddy/+
# +-- 'strm2cif' # | +-- 'strm2cif'
# +-- 'strm2dxf' # | +-- 'strm2dxf'
# : # | :
# +-- 'strmxor' # | +-- 'strmxor'
#----------------------------------------------------------------- # |
# +-- pymod-dist/+ (created only if *.whl and *.egg are available)
# +-- klayout-0.27.8-cp38-cp38-macosx_10_9_x86_64.whl (example)(1)
# +-- klayout-0.27.8-py3.8-macosx-10.9-x86_64.egg (example)(2)
#
# (1) *.whl is recommended to install with 'pip3'
# (2) *.egg is for 'easy_install' users
#--------------------------------------------------------------------------------------------------------------
targetDir0 = "%s/klayout.app/Contents" % AbsMacPkgDir targetDir0 = "%s/klayout.app/Contents" % AbsMacPkgDir
targetDirR = targetDir0 + "/Resources" targetDirR = targetDir0 + "/Resources"
targetDirF = targetDir0 + "/Frameworks" targetDirF = targetDir0 + "/Frameworks"
targetDirM = targetDir0 + "/MacOS" targetDirM = targetDir0 + "/MacOS"
targetDirB = targetDir0 + "/Buddy" targetDirB = targetDir0 + "/Buddy"
targetDirP = targetDir0 + "/pymod-dist"
os.makedirs(targetDirR) os.makedirs(targetDirR)
os.makedirs(targetDirF) os.makedirs(targetDirF)
os.makedirs(targetDirM) os.makedirs(targetDirM)
os.makedirs(targetDirB) os.makedirs(targetDirB)
if not pymodDistDir == "":
os.makedirs(targetDirP)
print( " [4] Copying KLayout's dynamic link libraries to 'Frameworks' ..." ) print( " [4] Copying KLayout's dynamic link libraries to 'Frameworks' ..." )
#------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------
# [4] Copy KLayout's dynamic link libraries to "Frameworks/" and create # [4] Copy KLayout's dynamic link libraries to "Frameworks/" and create
# the library dependency dictionary. # the library dependency dictionary.
# <<< Do this job in "Frameworks/" >>> # <<< Do this job in "Frameworks/" >>>
@ -919,7 +1114,7 @@ def Deploy_Binaries_For_Bundle(config, parameters):
# libklayout_gsi.0.dylib (compatibility version 0.26.0, current version 0.26.1) # libklayout_gsi.0.dylib (compatibility version 0.26.0, current version 0.26.1)
# libklayout_db.0.dylib (compatibility version 0.26.0, current version 0.26.1) # libklayout_db.0.dylib (compatibility version 0.26.0, current version 0.26.1)
# : # :
#------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------
os.chdir( targetDirF ) os.chdir( targetDirF )
dynamicLinkLibs = glob.glob( os.path.join( AbsMacBinDir, "*.dylib" ) ) dynamicLinkLibs = glob.glob( os.path.join( AbsMacBinDir, "*.dylib" ) )
depDicOrdinary = {} # inter-library dependency dictionary depDicOrdinary = {} # inter-library dependency dictionary
@ -1033,7 +1228,9 @@ def Deploy_Binaries_For_Bundle(config, parameters):
sourceDir1 = sourceDir0 + "/MacOS" sourceDir1 = sourceDir0 + "/MacOS"
sourceDir2 = "%s/macbuild/Resources" % ProjectDir sourceDir2 = "%s/macbuild/Resources" % ProjectDir
sourceDir3 = "%s" % MacBinDir sourceDir3 = "%s" % MacBinDir
sourceDir4 = "%s/pymod" % MacBinDir
# (A) the main components
tmpfileM = ProjectDir + "/macbuild/Resources/Info.plist.template" tmpfileM = ProjectDir + "/macbuild/Resources/Info.plist.template"
keydicM = { 'exe': 'klayout', 'icon': 'klayout.icns', 'bname': 'klayout', 'ver': Version } keydicM = { 'exe': 'klayout', 'icon': 'klayout.icns', 'bname': 'klayout', 'ver': Version }
plistM = GenerateInfoPlist( keydicM, tmpfileM ) plistM = GenerateInfoPlist( keydicM, tmpfileM )
@ -1045,18 +1242,24 @@ def Deploy_Binaries_For_Bundle(config, parameters):
shutil.copy2( sourceDir1 + "/klayout", targetDirM ) shutil.copy2( sourceDir1 + "/klayout", targetDirM )
shutil.copy2( sourceDir2 + "/klayout.icns", targetDirR ) shutil.copy2( sourceDir2 + "/klayout.icns", targetDirR )
os.chmod( targetDir0 + "/PkgInfo", 0o0644 ) os.chmod( targetDir0 + "/PkgInfo", 0o0644 )
os.chmod( targetDir0 + "/Info.plist", 0o0644 ) os.chmod( targetDir0 + "/Info.plist", 0o0644 )
os.chmod( targetDirM + "/klayout", 0o0755 ) os.chmod( targetDirM + "/klayout", 0o0755 )
os.chmod( targetDirR + "/klayout.icns", 0o0644 ) os.chmod( targetDirR + "/klayout.icns", 0o0644 )
# (B) the buddy command line tools
buddies = glob.glob( sourceDir3 + "/strm*" ) buddies = glob.glob( sourceDir3 + "/strm*" )
for item in buddies: for item in buddies:
shutil.copy2( item, targetDirB ) shutil.copy2( item, targetDirB )
buddy = os.path.basename(item) buddy = os.path.basename(item)
os.chmod( targetDirB + "/" + buddy, 0o0755 ) os.chmod( targetDirB + "/" + buddy, 0o0755 )
# (C) the pymod
if not pymodDistDir == "":
for item in glob.glob( pymodDistDir + "/*.whl" ):
shutil.copy2( item, targetDirP )
for item in glob.glob( pymodDistDir + "/*.egg" ):
shutil.copy2( item, targetDirP )
print( " [7] Setting and changing the identification names of KLayout's libraries in each executable ..." ) print( " [7] Setting and changing the identification names of KLayout's libraries in each executable ..." )
#------------------------------------------------------------- #-------------------------------------------------------------