diff --git a/macbuild/ReadMe.md b/macbuild/ReadMe.md
index cfd8fe3c4f..4a8da914d7 100644
--- a/macbuild/ReadMe.md
+++ b/macbuild/ReadMe.md
@@ -1,9 +1,9 @@
-Relevant KLayout version: 0.28.17
+Relevant KLayout version: 0.29.0
Author: Kazzz-S
-Last modified: 2024-02-16
+Last modified: 2024-03-27
# 1. Introduction
-This directory **`macbuild`** contains various files required for building KLayout (http://www.klayout.de/) version 0.28.17 or later for different 64-bit macOS, including:
+This directory **`macbuild`** contains various files required for building KLayout (http://www.klayout.de/) version 0.29.0 or later for different 64-bit macOS, including:
* Monterey (12.x) : the primary development environment
* Ventura (13.x) : experimental
* Sonoma (14.x) : -- ditto --
@@ -22,14 +22,14 @@ All Apple (M1|M2|M3) chips are still untested, as the author does not own an (M1
# 2. Qt Frameworks
-The default Qt framework is "Qt5" from Homebrew (https://brew.sh/), which is usually located under:
+The default Qt framework is "Qt5" from **MacPorts** (https://www.macports.org/), which is usually located under:
```
-/usr/local/opt/qt@5/
+/opt/local/libexec/qt5/
```
-If you prefer **MacPorts** (https://www.macports.org/), "Qt5" is usually located under:
+If you prefer "Qt6" from **Homebrew** (https://brew.sh/), which is usually located under:
```
-/opt/local/libexec/qt5/
+/usr/local/opt/qt@6/
```
You can also choose "Qt5" from Anaconda3 (https://www.anaconda.com/), which is usually located under:
@@ -41,11 +41,12 @@ If you have installed Anaconda3 under $HOME/opt/anaconda3/, make a symbolic link
/Applications/anaconda3/ ---> $HOME/opt/anaconda3/
```
-The migration work to "Qt6" is ongoing. You can try to use it; however, you will encounter some build and runtime errors.
+The migration work to "Qt6" is ongoing. You can try to use it; however, you will encounter some build and runtime errors.
+If you use **Homebrew** to build KLayout >= 0.29.0, you need "Qt6" to address [the compilation issue](https://github.com/KLayout/klayout/issues/1599).
# 3. Script language support: Ruby and Python
-The build script **`build4mac.py`** provides several possible combinations of Qt5, Ruby, and Python modules to suit the user's needs and preferences.
+The build script **`build4mac.py`** provides several possible combinations of Qt, Ruby, and Python modules to suit the user's needs and preferences.
Some typical use cases are described in Section 6.
# 4. Prerequisites
@@ -53,8 +54,8 @@ You need to have the followings:
* The latest Xcode and command-line tool kit compliant with each OS
* https://developer.apple.com/xcode/resources/
* https://mac.install.guide/commandlinetools/4
-* Qt5 package from Homebrew, MacPorts, or Anaconda3
-* Optionally, Ruby and Python packages from Homebrew, MacPorts, or Anaconda3
+* Qt5 package from MacPorts or Anaconda3. Qt6, from Homebrew.
+* Optionally, Ruby and Python packages from MacPorts, Homebrew, or Anaconda3
#### For matching versions of Ruby and Python, please also refer to `build4mac_env.py`.
# 5. Command-line options of **`build4mac.py`**
@@ -65,7 +66,7 @@ The operating system type is detected automatically.
```
---------------------------------------------------------------------------------------------------------
<< Usage of 'build4mac.py' >>
- for building KLayout 0.28.17 or later on different Apple macOS platforms.
+ for building KLayout 0.29.0 or later on different Apple macOS platforms.
$ [python] ./build4mac.py
option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value
@@ -121,7 +122,7 @@ $ [python] ./build4mac.py
In this section, the actual file and directory names are those obtained on macOS Monterey.
On different OS, those names differ accordingly.
-### 6A. Standard build using the OS-bundled Ruby and Python with MacPorts Qt
+### 6A. Standard build using the OS-bundled Ruby and Python with MacPorts Qt5
0. Install MacPorts, then install Qt5 and libgit2 by
```
$ sudo port install coreutils
@@ -155,41 +156,45 @@ $ ./build4mac.py -q qt5macports -r sys -p sys -y
* "RsysPsys" means that Ruby is 2.6 provided by OS; Python is 3.9 provided by OS.
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
-### 6B. Fully Homebrew-flavored build with Homebrew Ruby 3.3 and Homebrew Python 3.11
-0. Install Homebrew, then install Qt5, Ruby 3.3, Python 3.11, and libgit2 by
+### 6B. Fully MacPorts-flavored build with MacPorts Ruby 3.3 and MacPorts Python 3.11
+0. Install MacPorts, then install Qt5, Ruby 3.3, Python 3.11, and libgit2 by
```
-$ brew install qt@5
-$ brew install ruby@3.3
-$ brew install python@3.11
-$ brew install libgit2
-$ cd /where/'build.sh'/exists
-$ cd macbuild
-$ ./python3HB.py -v 3.11
+$ sudo port install coreutils
+$ sudo port install findutils
+$ sudo port install qt5
+$ sudo port install ruby33
+$ sudo port install python311
+$ sudo port install py311-pip
+$ sudo port install libgit2
```
1. Invoke **`build4mac.py`** with the following options:
```
$ cd /where/'build.sh'/exists
-$ ./build4mac.py -q qt5brew -r hb33 -p hb311
+$ ./build4mac.py -q qt5macports -r mp33 -p mp311
```
2. Confirm successful build (it will take about one hour, depending on your machine spec).
3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.
The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.
- If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Python Module (\*.whl) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
+ If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Standalone Python Package (\*.whl) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
```
-$ ./build4mac.py -q qt5brew -r hb33 -p hb311 -Y
+$ ./build4mac.py -q qt5macports -r mp33 -p mp311 -Y
```
The application bundle **`klayout.app`** is located under:
- **`LW-qt5Brew.pkg.macos-Monterey-release-Rhb33Phb311`** directory, where
+ **`LW-qt5MP.pkg.macos-Monterey-release-Rmp33Pmp311`** directory, where
* "LW-" means this is a lightweight package.
-* "qt5Brew" means that Qt5 from Homebrew is used.
-* "Rhb33Phb311" means that Ruby is 3.3 from Homebrew; Python is 3.11 from Homebrew.
+* "qt5MP" means that Qt5 from MacPorts is used.
+* "Rmp33Pmp311" means that Ruby is 3.3 from MacPorts; Python is 3.11 from MacPorts.
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
-### 6C. Partially Homebrew-flavored build with System Ruby and Homebrew Python 3.11
-0. Install Homebrew, then install Qt5, Python 3.11, and libgit2 by
+### 6C. Fully Homebrew-flavored build with Homebrew Ruby 3.3 and Homebrew Python 3.11
+> [!IMPORTANT]
+> To build KLayout >= 0.29.0, you need "Qt6" to address [the compilation issue](https://github.com/KLayout/klayout/issues/1599).
+
+0. Install Homebrew, then install Qt6, Ruby 3.3, Python 3.11, and libgit2 by
```
-$ brew install qt@5
+$ brew install qt@6
+$ brew install ruby@3.3
$ brew install python@3.11
$ brew install libgit2
$ cd /where/'build.sh'/exists
@@ -199,55 +204,62 @@ $ ./python3HB.py -v 3.11
1. Invoke **`build4mac.py`** with the following options:
```
$ cd /where/'build.sh'/exists
-$ ./build4mac.py -q qt5brew -r sys -p hb311
+$ ./build4mac.py -q qt6brew -r hb33 -p hb311
```
2. Confirm successful build (it will take about one hour, depending on your machine spec).
-3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-y" to deploy executables and libraries (including Qt and Python frameworks) under the **`klayout.app`** bundle.
- The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.
+3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.
+ The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.
+ If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Standalone Python Package (\*.whl) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
```
-$ ./build4mac.py -q qt5brew -r sys -p hb311 -y
+$ ./build4mac.py -q qt6brew -r hb33 -p hb311 -Y
```
The application bundle **`klayout.app`** is located under:
- **`HW-qt5Brew.pkg.macos-Monterey-release-RsysPhb311`** directory, where
-* "HW-" means this is a heavyweight package because both Qt5 and Python Frameworks are deployed.
-* "qt5Brew" means that Qt5 from Homebrew is used.
-* "RsysPhb311" means that Ruby is OS-bundled; Python is 3.11 from Homebrew.
+ **`LW-qt6Brew.pkg.macos-Monterey-release-Rhb33Phb311`** directory, where
+* "LW-" means this is a lightweight package.
+* "qt6Brew" means that Qt6 from Homebrew is used.
+* "Rhb33Phb311" means that Ruby is 3.3 from Homebrew; Python is 3.11 from Homebrew.
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
-### Important
-So far, the deployment of Homebrew Ruby is not supported.
-Therefore, if you intend to use the "-y" option for deployment, you need to use the "-r sys" option for building.
-### 6D. Fully MacPorts-flavored build with MacPorts Ruby 3.3 and MacPorts Python 3.11
-0. Install MacPorts, then install Qt5, Ruby 3.3, Python 3.11, and libgit2 by
+### 6D. Partially Homebrew-flavored build with System Ruby and Homebrew Python 3.11
+> [!IMPORTANT]
+> To build KLayout >= 0.29.0, you need "Qt6" to address [the compilation issue](https://github.com/KLayout/klayout/issues/1599).
+
+> [!CAUTION]
+> Homebrew Qt6.6.2 seems buggy. More precisely, it does not perfectly deploy the required Qt frameworks.
+> If you plan to distribute an HW*.dmg package, consider using Qt6.4.x from MacPorts.
+> That is, substitute `qt6brew` with `qt6macports` in the following command lines.
+
+0. Install Homebrew, then install Qt6, Python 3.11, and libgit2 by
```
-$ sudo port install coreutils
-$ sudo port install findutils
-$ sudo port install qt5
-$ sudo port install ruby33
-$ sudo port install python311
-$ sudo port install py311-pip
-$ sudo port install libgit2
+$ brew install qt@6
+$ brew install python@3.11
+$ brew install libgit2
+$ cd /where/'build.sh'/exists
+$ cd macbuild
+$ ./python3HB.py -v 3.11
```
1. Invoke **`build4mac.py`** with the following options:
```
$ cd /where/'build.sh'/exists
-$ ./build4mac.py -q qt5macports -r mp33 -p mp311
+$ ./build4mac.py -q qt6brew -r sys -p hb311
```
2. Confirm successful build (it will take about one hour, depending on your machine spec).
-3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.
- The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.
- If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Python Module (\*.whl) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
+3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-y" to deploy executables and libraries (including Qt and Python frameworks) under the **`klayout.app`** bundle.
+ The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.
```
-$ ./build4mac.py -q qt5macports -r mp33 -p mp311 -Y
+$ ./build4mac.py -q qt6brew -r sys -p hb311 -y
```
The application bundle **`klayout.app`** is located under:
- **`LW-qt5MP.pkg.macos-Monterey-release-Rmp33Pmp311`** directory, where
-* "LW-" means this is a lightweight package.
-* "qt5MP" means that Qt5 from MacPorts is used.
-* "Rmp33Pmp311" means that Ruby is 3.3 from MacPorts; Python is 3.11 from MacPorts.
+ **`HW-qt6Brew.pkg.macos-Monterey-release-RsysPhb311`** directory, where
+* "HW-" means this is a heavyweight package because both Qt6 and Python Frameworks are deployed.
+* "qt6Brew" means that Qt6 from Homebrew is used.
+* "RsysPhb311" means that Ruby is OS-bundled; Python is 3.11 from Homebrew.
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
+> [!IMPORTANT]
+> So far, the deployment of Homebrew Ruby is not supported.
+> Therefore, if you intend to use the "-y" option for deployment, you need to use the "-r sys" option for building.
### 6E. Fully Anaconda3-flavored build with Anaconda3 Ruby 3.2 and Anaconda3 Python 3.11
0. Install Anaconda3 (Anaconda3-2023.09-0-MacOSX-x86_64.pkg), then install Ruby 3.2 and libgit2 by
@@ -264,7 +276,7 @@ $ ./build4mac.py -q qt5ana3 -r ana3 -p ana3
2. Confirm successful build (it will take about one hour, depending on your machine spec).
3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.
The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.
- If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Python Module (\*.whl) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
+ If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Standalone Python Package (\*.whl) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
```
$ ./build4mac.py -q qt5ana3 -r ana3 -p ana3 -Y
@@ -292,7 +304,7 @@ $ export KLAYOUT_GIT_HTTP_PROXY="http://111.222.333.444:5678"
Ask your system administrator for the actual IP address and port number of your proxy server.
It is highly recommended that this setting is included in a launching service script bundle.
-A sample content (`*.app.Bash`) of the script bundle can be found in `Resources/script-bundle-[A|B|H|P].zip`.
+A sample content (`*.app.Bash`) of the script bundle can be found in `Resources/script-bundle-[A|B|H|P|S].zip`.
----
@@ -310,8 +322,8 @@ $ cd /where/'build.sh'/exists
$ ./makeDMG4mac.py -p LW-qt5MP.pkg.macos-Monterey-release-Rmp33Pmp311 -m
```
This command will generate the two files below:
-* **`LW-klayout-0.28.17-macOS-Monterey-1-qt5MP-Rmp33Pmp311.dmg`** ---(1) the main DMG file
-* **`LW-klayout-0.28.17-macOS-Monterey-1-qt5MP-Rmp33Pmp311.dmg.md5`** ---(2) MD5-value text file
+* **`LW-klayout-0.29.0-macOS-Monterey-1-qt5MP-Rmp33Pmp311.dmg`** ---(1) the main DMG file
+* **`LW-klayout-0.29.0-macOS-Monterey-1-qt5MP-Rmp33Pmp311.dmg.md5`** ---(2) MD5-value text file
# Known issues
Because we assume some specific versions of non-OS-standard Ruby and Python, updating Homebrew, MacPorts, or Anaconda3 may cause build- and link errors.
diff --git a/macbuild/Resources/script-bundle-A.zip b/macbuild/Resources/script-bundle-A.zip
index 3f7e538fca..89409aa7f2 100644
Binary files a/macbuild/Resources/script-bundle-A.zip and b/macbuild/Resources/script-bundle-A.zip differ
diff --git a/macbuild/Resources/script-bundle-B.zip b/macbuild/Resources/script-bundle-B.zip
index 9855a5f57c..95870471e1 100644
Binary files a/macbuild/Resources/script-bundle-B.zip and b/macbuild/Resources/script-bundle-B.zip differ
diff --git a/macbuild/Resources/script-bundle-H.zip b/macbuild/Resources/script-bundle-H.zip
index f3d73ffb41..4db6f545d2 100644
Binary files a/macbuild/Resources/script-bundle-H.zip and b/macbuild/Resources/script-bundle-H.zip differ
diff --git a/macbuild/Resources/script-bundle-P.zip b/macbuild/Resources/script-bundle-P.zip
index d8df82a293..626efae4ee 100644
Binary files a/macbuild/Resources/script-bundle-P.zip and b/macbuild/Resources/script-bundle-P.zip differ
diff --git a/macbuild/Resources/script-bundle-S.zip b/macbuild/Resources/script-bundle-S.zip
index 164a970ba2..ad3ac4b177 100644
Binary files a/macbuild/Resources/script-bundle-S.zip and b/macbuild/Resources/script-bundle-S.zip differ
diff --git a/macbuild/build4mac.py b/macbuild/build4mac.py
index de2204b040..b5a5129476 100755
--- a/macbuild/build4mac.py
+++ b/macbuild/build4mac.py
@@ -5,7 +5,7 @@
# File: "macbuild/build4mac.py"
#
# The top Python script for building KLayout (http://www.klayout.de/index.php)
-# version 0.28.17 or later on different Apple Mac OSX platforms.
+# version 0.29.0 or later on different Apple Mac OSX platforms.
#===============================================================================
import sys
import os
@@ -45,7 +45,7 @@ def GenerateUsage(platform):
usage = "\n"
usage += "---------------------------------------------------------------------------------------------------------\n"
usage += "<< Usage of 'build4mac.py' >>\n"
- usage += " for building KLayout 0.28.17 or later on different Apple macOS platforms.\n"
+ usage += " for building KLayout 0.29.0 or later on different Apple macOS platforms.\n"
usage += "\n"
usage += "$ [python] ./build4mac.py\n"
usage += " option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value\n"
@@ -100,7 +100,7 @@ def GenerateUsage(platform):
#-------------------------------------------------------------------------------
## To get the default configurations
#
-# @return a dictionary containing the default configuration for the macOS build
+# @return a dictionary containing the default configurations for the macOS build
#-------------------------------------------------------------------------------
def Get_Default_Config():
ProjectDir = os.getcwd()
@@ -166,7 +166,7 @@ def Get_Default_Config():
ModuleRuby = "nil"
ModulePython = "nil"
- BuildPymod = False
+ BuildPymodWhl = False
NonOSStdLang = False
NoQtBindings = False
NoQtUiTools = False
@@ -181,6 +181,8 @@ def Get_Default_Config():
Version = GetKLayoutVersionFrom( "./version.sh" )
HBPythonIs39 = False # because ModulePython == "Python311Brew" by default
OSPython3FW = None # system Python3 frameworks in [ None, MontereyPy3FW, VenturaPy3FW, SonomaPy3FW ]
+ EmbedQt = False
+ EmbedPython3 = False
config = dict()
config['ProjectDir'] = ProjectDir # project directory where "build.sh" exists
@@ -190,7 +192,7 @@ def Get_Default_Config():
config['ModuleQt'] = ModuleQt # Qt module to be used
config['ModuleRuby'] = ModuleRuby # Ruby module to be used
config['ModulePython'] = ModulePython # Python module to be used
- config['BuildPymod'] = BuildPymod # True to build and deploy "Pymod"
+ config['BuildPymodWhl'] = BuildPymodWhl # True to build and deploy "Pymod (*.whl)"
config['NonOSStdLang'] = NonOSStdLang # True if non-OS-standard language is chosen
config['NoQtBindings'] = NoQtBindings # True if not creating Qt bindings for Ruby scripts
config['NoQtUiTools'] = NoQtUiTools # True if not to include QtUiTools in Qt binding
@@ -207,6 +209,8 @@ def Get_Default_Config():
config['ToolDebug'] = ToolDebug # debug level list for this tool
config['HBPythonIs39'] = HBPythonIs39 # True if the Homebrew Python version <= 3.9
config['OSPython3FW'] = OSPython3FW # system Python3 frameworks in [ None, MontereyPy3FW, VenturaPy3FW, SonomaPy3FW ]
+ config['EmbedQt'] = EmbedQt # True if Qt is embedded
+ config['EmbedPython3'] = EmbedPython3 # True if Python3 is embedded
# auxiliary variables on platform
config['System'] = System # 6-tuple from platform.uname()
config['Node'] = Node # - do -
@@ -234,7 +238,7 @@ def Parse_CLI_Args(config):
ModuleQt = config['ModuleQt']
ModuleRuby = config['ModuleRuby']
ModulePython = config['ModulePython']
- BuildPymod = config['BuildPymod']
+ BuildPymodWhl = config['BuildPymodWhl']
NonOSStdLang = config['NonOSStdLang']
NoQtBindings = config['NoQtBindings']
NoQtUiTools = config['NoQtUiTools']
@@ -250,6 +254,8 @@ def Parse_CLI_Args(config):
ToolDebug = config['ToolDebug']
HBPythonIs39 = config['HBPythonIs39']
OSPython3FW = config['OSPython3FW']
+ EmbedQt = config['EmbedQt']
+ EmbedPython3 = config['EmbedPython3']
#-----------------------------------------------------
# [2] Parse the CLI arguments
@@ -269,9 +275,9 @@ def Parse_CLI_Args(config):
p.add_option( '-P', '--buildPymod',
action='store_true',
- dest='build_pymod',
+ dest='build_pymod_whl',
default=False,
- help="build and deploy (disabled)" )
+ help="build and deploy Pymod (*.whl) (disabled)" )
p.add_option( '-n', '--noqtbinding',
action='store_true',
@@ -335,21 +341,21 @@ def Parse_CLI_Args(config):
help='check usage' )
if Platform.upper() in [ "SONOMA", "VENTURA", "MONTEREY" ]: # with Xcode [13.1 .. ]
- p.set_defaults( type_qt = "qt5macports",
- type_ruby = "sys",
- type_python = "sys",
- build_pymod = False,
- no_qt_binding = False,
- no_qt_uitools = False,
- no_libgit2 = False,
- make_option = "--jobs=4",
- debug_build = False,
- check_command = False,
- deploy_full = False,
- deploy_partial = False,
- deploy_verbose = "1",
- tool_debug = [],
- checkusage = False )
+ p.set_defaults( type_qt = "qt5macports",
+ type_ruby = "sys",
+ type_python = "sys",
+ build_pymod_whl = False,
+ no_qt_binding = False,
+ no_qt_uitools = False,
+ no_libgit2 = False,
+ make_option = "--jobs=4",
+ debug_build = False,
+ check_command = False,
+ deploy_full = False,
+ deploy_partial = False,
+ deploy_verbose = "1",
+ tool_debug = [],
+ checkusage = False )
else:
raise Exception( "! Too obsolete platform <%s>" % Platform )
@@ -504,16 +510,16 @@ def Parse_CLI_Args(config):
ModuleSet = ( choiceQt56, choiceRuby, choicePython )
# (E) Set other parameters
- BuildPymod = opt.build_pymod
- NoQtBindings = opt.no_qt_binding
- NoQtUiTools = opt.no_qt_uitools
- NoLibGit2 = opt.no_libgit2
- MakeOptions = opt.make_option
- DebugMode = opt.debug_build
- CheckComOnly = opt.check_command
- DeploymentF = opt.deploy_full
- DeploymentP = opt.deploy_partial
- ToolDebug = sorted( set([ int(val) for val in opt.tool_debug ]) )
+ BuildPymodWhl = opt.build_pymod_whl
+ NoQtBindings = opt.no_qt_binding
+ NoQtUiTools = opt.no_qt_uitools
+ NoLibGit2 = opt.no_libgit2
+ MakeOptions = opt.make_option
+ DebugMode = opt.debug_build
+ CheckComOnly = opt.check_command
+ DeploymentF = opt.deploy_full
+ DeploymentP = opt.deploy_partial
+ ToolDebug = sorted( set([ int(val) for val in opt.tool_debug ]) )
if DeploymentF and DeploymentP:
print("")
@@ -528,31 +534,42 @@ def Parse_CLI_Args(config):
print(Usage)
sys.exit(1)
+ # (F) Build mode
if not DeploymentF and not DeploymentP:
target = "%s %s %s" % (Platform, Release, Machine)
modules = "Qt=%s, Ruby=%s, Python=%s" % (ModuleQt, ModuleRuby, ModulePython)
- if BuildPymod:
- pymodbuild = "enabled"
+ if BuildPymodWhl:
+ pymodWhlbuild = "enabled"
else:
- pymodbuild = "disabled"
+ pymodWhlbuild = "disabled"
message = "### You are going to build KLayout\n for <%s>\n with <%s>\n with Pymod <%s>...\n"
print("")
- print( message % (target, modules, pymodbuild) )
+ print( message % (target, modules, pymodWhlbuild) )
+ # (G) Deploy mode
else:
- okHWdmg = True
- message = "### You are going to make "
+ EmbedQt = False
+ EmbedPython3 = False
+ okHWdmg = True
+ message = "### You are going to make "
if DeploymentP:
PackagePrefix = "LW-"
- if not BuildPymod:
- message += "a lightweight (LW-) package excluding Qt5, Ruby, and Python..."
+ if not BuildPymodWhl:
+ message += "a lightweight (LW-) package excluding Qt[5|6], Ruby, and Python..."
else:
- message += "a lightweight (LW-) package with Pymod excluding Qt5, Ruby, and Python..."
+ message += "a lightweight (LW-) package with Pymod (*.whl) excluding Qt[5|6], Ruby, and Python..."
elif DeploymentF:
- if (ModuleRuby in RubySys) and (ModulePython in PythonSys):
+ if ModuleQt == "Qt5Ana3":
+ EmbedQt = False
+ message += "Qt5 from Anaconda3 embedded, which is not allowed!"
+ okHWdmg = False
+ elif (ModuleRuby in RubySys) and (ModulePython in PythonSys):
PackagePrefix = "ST-"
+ EmbedQt = True
message += "a standard (ST-) package including Qt[5|6] and using OS-bundled Ruby and Python..."
elif ModulePython in ['Python311Brew', 'Python39Brew', 'PythonAutoBrew']:
PackagePrefix = "HW-"
+ EmbedQt = True
+ EmbedPython3 = True
message += "a heavyweight (HW-) package including Qt[5|6] and Python3.[11|9] from Homebrew..."
okHWdmg = (ModulePython == 'Python311Brew') or \
(ModulePython == 'Python39Brew') or \
@@ -564,7 +581,9 @@ def Parse_CLI_Args(config):
print( message )
print( "" )
if not okHWdmg:
- print( "!!! HW-dmg package assumes either python@3.11 or python@3.9" )
+ print( "!!! HW-dmg package assumes the two conditions:" )
+ print( " (1) either Qt5 or Qt6 from MacPorts or Homebrew (Anaconda3 is not a candidate)" )
+ print( " (2) either python@3.11 or python@3.9 from Homebrew" )
sys.exit(1)
if CheckComOnly:
sys.exit(0)
@@ -577,7 +596,7 @@ def Parse_CLI_Args(config):
config['ModuleQt'] = ModuleQt
config['ModuleRuby'] = ModuleRuby
config['ModulePython'] = ModulePython
- config['BuildPymod'] = BuildPymod
+ config['BuildPymodWhl'] = BuildPymodWhl
config['NonOSStdLang'] = NonOSStdLang
config['NoQtBindings'] = NoQtBindings
config['NoQtUiTools'] = NoQtUiTools
@@ -593,11 +612,13 @@ def Parse_CLI_Args(config):
config['ToolDebug'] = ToolDebug
config['HBPythonIs39'] = HBPythonIs39
config['OSPython3FW'] = OSPython3FW
+ config['EmbedQt'] = EmbedQt
+ config['EmbedPython3'] = EmbedPython3
if CheckComOnly:
pp = pprint.PrettyPrinter( indent=4, width=140 )
parameters = Get_Build_Parameters(config)
- Build_pymod(parameters)
+ Build_pymod_wheel(parameters)
pp.pprint(parameters)
sys.exit(0)
else:
@@ -620,7 +641,7 @@ def Get_Build_Parameters(config):
ModuleQt = config['ModuleQt']
ModuleRuby = config['ModuleRuby']
ModulePython = config['ModulePython']
- BuildPymod = config['BuildPymod']
+ BuildPymodWhl = config['BuildPymodWhl']
ModuleSet = config['ModuleSet']
NoQtBindings = config['NoQtBindings']
NoQtUiTools = config['NoQtUiTools']
@@ -657,39 +678,28 @@ def Get_Build_Parameters(config):
MacBuildDir = "%s.build.macos-%s-%s-%s" % ( qt, Platform, mode, ruby_python)
MacBuildLog = "%s.build.macos-%s-%s-%s.log" % ( qt, Platform, mode, ruby_python)
MacBuildDirQAT = MacBuildDir + ".macQAT"
+ parameters['bin'] = MacBinDir
+ parameters['build'] = MacBuildDir
parameters['logfile'] = MacBuildLog
- # (D) Qt5|6
- if ModuleQt == 'Qt5MacPorts':
- parameters['qmake'] = Qt5MacPorts['qmake']
- parameters['deploy_tool'] = Qt5MacPorts['deploy']
- elif ModuleQt == 'Qt5Brew':
- parameters['qmake'] = Qt5Brew['qmake']
- parameters['deploy_tool'] = Qt5Brew['deploy']
- elif ModuleQt == 'Qt5Ana3':
- parameters['qmake'] = Qt5Ana3['qmake']
- parameters['deploy_tool'] = Qt5Ana3['deploy']
- elif ModuleQt == 'Qt6MacPorts':
- parameters['qmake'] = Qt6MacPorts['qmake']
- parameters['deploy_tool'] = Qt6MacPorts['deploy']
- elif ModuleQt == 'Qt6Brew':
- parameters['qmake'] = Qt6Brew['qmake']
- parameters['deploy_tool'] = Qt6Brew['deploy']
-
- parameters['bin'] = MacBinDir
- parameters['build'] = MacBuildDir
+ # (D) about Qt[5|6]
+ parameters['qmake'] = Qt56Dictionary[ModuleQt]['qmake']
+ parameters['deploy_tool'] = Qt56Dictionary[ModuleQt]['deploy']
+ parameters['qt_lib_root'] = Qt56Dictionary[ModuleQt]['libdir']
+
+ # (E) rpath
if OSPython3FW in [ MontereyPy3FW, VenturaPy3FW, SonomaPy3FW ]:
parameters['rpath'] = OSPython3FW
else:
parameters['rpath'] = "@executable_path/../Frameworks"
- # (E) want Qt bindings with Ruby scripts?
+ # (F) want Qt bindings with Ruby scripts?
parameters['no_qt_bindings'] = NoQtBindings
- # (F) want QtUiTools?
+ # (G) want QtUiTools?
parameters['no_qt_uitools'] = NoQtUiTools
- # (G) options to `make` tool
+ # (H) options to `make` tool
if not MakeOptions == "":
parameters['make_options'] = MakeOptions
try:
@@ -700,7 +710,7 @@ def Get_Build_Parameters(config):
else:
parameters['num_parallel'] = pnum
- # (H) about Ruby
+ # (I) about Ruby
if ModuleRuby != "nil":
parameters['ruby'] = RubyDictionary[ModuleRuby]['exe']
parameters['rbinc'] = RubyDictionary[ModuleRuby]['inc']
@@ -708,7 +718,7 @@ def Get_Build_Parameters(config):
if 'inc2' in RubyDictionary[ModuleRuby]:
parameters['rbinc2'] = RubyDictionary[ModuleRuby]['inc2']
- # (I) about Python
+ # (J) about Python
if ModulePython != "nil":
parameters['python'] = PythonDictionary[ModulePython]['exe']
parameters['pyinc'] = PythonDictionary[ModulePython]['inc']
@@ -720,21 +730,21 @@ def Get_Build_Parameters(config):
config['MacBuildDirQAT'] = MacBuildDirQAT # relative path to build directory for QATest
config['MacBuildLog'] = MacBuildLog # relative path to build log file
- # (J) Extra parameters needed for deployment
+ # (K) Extra parameters needed for deployment
parameters['project_dir'] = ProjectDir
- # (K) Extra parameters needed for
+ # (L) Extra parameters needed for
# will be built if:
- # BuildPymod = True
- # Platform = [ 'Sonoma', 'Ventura', 'Monterey']
- # ModuleRuby = [ 'Ruby33MacPorts', 'Ruby33Brew', 'RubyAnaconda3' ]
- # ModulePython = [ 'Python311MacPorts', 'Python39MacPorts',
- # 'Python311Brew', Python39Brew', 'PythonAutoBrew',
- # 'PythonAnaconda3' ]
- parameters['BuildPymod'] = BuildPymod
- parameters['Platform'] = Platform
- parameters['ModuleRuby'] = ModuleRuby
- parameters['ModulePython'] = ModulePython
+ # BuildPymodWhl = True
+ # Platform = [ 'Sonoma', 'Ventura', 'Monterey']
+ # ModuleRuby = [ 'Ruby33MacPorts', 'Ruby33Brew', 'RubyAnaconda3' ]
+ # ModulePython = [ 'Python311MacPorts', 'Python39MacPorts',
+ # 'Python311Brew', Python39Brew', 'PythonAutoBrew',
+ # 'PythonAnaconda3' ]
+ parameters['BuildPymodWhl'] = BuildPymodWhl
+ parameters['Platform'] = Platform
+ parameters['ModuleRuby'] = ModuleRuby
+ parameters['ModulePython'] = ModulePython
PymodDistDir = dict()
if Platform in [ 'Sonoma', 'Ventura', 'Monterey' ]:
@@ -750,27 +760,27 @@ def Get_Build_Parameters(config):
#------------------------------------------------------------------------------
## To run the "setup.py" script with appropriate options for building
-# the klayout Python Module "pymod".
+# the klayout Python Module "pymod (*.whl)".
#
# @param[in] parameters dictionary containing the build parameters
#
# @return 0 on success; non-zero (1), otherwise
#------------------------------------------------------------------------------
-def Build_pymod(parameters):
+def Build_pymod_wheel(parameters):
#-----------------------------------------------------------------------------------------------------------
# [1] will be built if:
- # BuildPymod = True
- # Platform = [ 'Sonoma', 'Ventura', 'Monterey']
- # ModuleRuby = [ 'Ruby33MacPorts', 'Ruby33Brew', 'RubyAnaconda3' ]
- # ModulePython = [ 'Python311MacPorts', 'Python39MacPorts',
- # 'Python311Brew', Python39Brew', 'PythonAutoBrew',
- # 'PythonAnaconda3' ]
+ # BuildPymodWhl = True
+ # Platform = [ 'Sonoma', 'Ventura', 'Monterey']
+ # ModuleRuby = [ 'Ruby33MacPorts', 'Ruby33Brew', 'RubyAnaconda3' ]
+ # ModulePython = [ 'Python311MacPorts', 'Python39MacPorts',
+ # 'Python311Brew', Python39Brew', 'PythonAutoBrew',
+ # 'PythonAnaconda3' ]
#-----------------------------------------------------------------------------------------------------------
- BuildPymod = parameters['BuildPymod']
- Platform = parameters['Platform']
- ModuleRuby = parameters['ModuleRuby']
- ModulePython = parameters['ModulePython']
- if not BuildPymod:
+ BuildPymodWhl = parameters['BuildPymodWhl']
+ Platform = parameters['Platform']
+ ModuleRuby = parameters['ModuleRuby']
+ ModulePython = parameters['ModulePython']
+ if not BuildPymodWhl:
return 0
if not Platform in [ 'Sonoma', 'Ventura', 'Monterey' ]:
return 0
@@ -791,20 +801,24 @@ def Build_pymod(parameters):
addBinPath = "/opt/local/bin"
addIncPath = "/opt/local/include"
addLibPath = "/opt/local/lib"
+ whlTarget = "MP3"
# Using Homebrew
elif PymodDistDir[ModulePython].find('dist-HB3') >= 0:
addBinPath = "%s/bin" % DefaultHomebrewRoot # defined in "build4mac_env.py"
addIncPath = "%s/include" % DefaultHomebrewRoot # -- ditto --
addLibPath = "%s/lib" % DefaultHomebrewRoot # -- ditto --
+ whlTarget = "HB3"
# Using Anaconda3
elif PymodDistDir[ModulePython].find('dist-ana3') >= 0:
addBinPath = "/Applications/anaconda3/bin"
addIncPath = "/Applications/anaconda3/include"
addLibPath = "/Applications/anaconda3/lib"
+ whlTarget = "ana3"
else:
addBinPath = ""
addIncPath = ""
addLibPath = ""
+ whlTarget = ""
if not addBinPath == "":
try:
@@ -888,7 +902,7 @@ def Build_pymod(parameters):
return 0
#-----------------------------------------------------
- # [5] Invoke the main Python scripts; takes time:-)
+ # [5-A] Invoke the main Python scripts; takes time:-)
#-----------------------------------------------------
myscript = os.path.basename(__file__)
ret = subprocess.call( command1, shell=True )
@@ -910,12 +924,12 @@ def Build_pymod(parameters):
return 1
#---------------------------------------------------------------------------------------------------------
- # Copy and relink library dependencies for wheel.
- # In this step, the "delocate-wheel" command using the desired Python must be found in the PATH.
- # Refer to: https://github.com/Kazzz-S/klayout/issues/49#issuecomment-1432154118
- # https://pypi.org/project/delocate/
+ # [5-B] Copy and relink library dependencies for wheel.
+ # In this step, the "delocate-wheel" command using the desired Python must be found in the PATH.
+ # Refer to: https://github.com/Kazzz-S/klayout/issues/49#issuecomment-1432154118
+ # https://pypi.org/project/delocate/
#---------------------------------------------------------------------------------------------------------
- cmd3_args = glob.glob( "dist/*.whl" ) # like ['dist/klayout-0.28.6-cp39-cp39-macosx_12_0_x86_64.whl']
+ cmd3_args = glob.glob( "dist/*.whl" ) # like ['dist/klayout-0.29.0-cp311-cp311-macosx_12_0_x86_64.whl']
if len(cmd3_args) == 1:
command3 = "time"
command3 += " \\\n %s \\\n" % deloc_cmd
@@ -942,6 +956,42 @@ def Build_pymod(parameters):
print( "", file=sys.stderr )
return 1
+ #------------------------------------------------------------------------
+ # [5-C] Forcibly change the wheel file name for anaconda3
+ # Ref. https://github.com/Kazzz-S/klayout/issues/53
+ # original: klayout-0.29.0-cp311-cp311-macosx_12_0_x86_64.whl
+ # |
+ # V
+ # new: klayout-0.29.0-cp311-cp311-macosx_10_9_x86_64.whl
+ #------------------------------------------------------------------------
+ if whlTarget == "ana3":
+ wheels = glob.glob( "dist/*.whl" ) # like ['dist/klayout-0.29.0-cp311-cp311-macosx_12_0_x86_64.whl']
+ if not len(wheels) == 1:
+ print( "", file=sys.stderr )
+ print( "-------------------------------------------------------------", file=sys.stderr )
+ print( "!!! <%s>: failed to " % myscript, file=sys.stderr )
+ print( "-------------------------------------------------------------", file=sys.stderr )
+ print( "", file=sys.stderr )
+ return 1
+ else:
+ pass
+
+ original = wheels[0]
+ # 0 1 2 3 4 5 6 *7 8 9
+ patwhl = r"(^dist/klayout-)([0-9.]+)(-)(cp[0-9]+)(-)(cp[0-9]+)(-macosx_)([0-9]+_[0-9]+)([a-z0-9_]+)(\.whl)"
+ regwhl = re.compile(patwhl)
+ if not regwhl.match(original):
+ print( "", file=sys.stderr )
+ print( "-------------------------------------------------------------", file=sys.stderr )
+ print( "!!! <%s>: failed to " % myscript, file=sys.stderr )
+ print( "-------------------------------------------------------------", file=sys.stderr )
+ print( "", file=sys.stderr )
+ return 1
+ else:
+ ver = regwhl.match(original).groups()[7]
+ new = original.replace( ver, "10_9" )
+ os.rename( original, new )
+
#-----------------------------------------------------
# [6] Rename the "dist/" directory
#-----------------------------------------------------
@@ -961,9 +1011,9 @@ def Run_Build_Command(config, parameters):
NoLibGit2 = config['NoLibGit2']
ToolDebug = config['ToolDebug']
if 100 not in ToolDebug: # default
- jump2pymod = False
+ jump2pymod_wheel = False
else:
- jump2pymod = True
+ jump2pymod_wheel = True
#-----------------------------------------------------
# [1] Set two environment variables to use libgit2
@@ -996,7 +1046,7 @@ def Run_Build_Command(config, parameters):
else:
os.environ['MAC_LIBGIT2_LIB'] = "_invalid_MAC_LIBGIT2_LIB_" # link should fail
- if not jump2pymod:
+ if not jump2pymod_wheel:
#-----------------------------------------------------
# [2] Set parameters passed to the main Bash script
#-----------------------------------------------------
@@ -1013,8 +1063,7 @@ def Run_Build_Command(config, parameters):
# (C) Target directories and files
MacBuildDirQAT = parameters['build'] + ".macQAT"
- # (D) Qt5 | Qt6 (Homebrew)
- #cmd_args += " \\\n -qt5" # make 'build.sh' detect the Qt type automatically
+ # (D) Qt5 (MacPorts, Homebrew, Anaconda3) | Qt6 (MacPorts, Homebrew)
cmd_args += " \\\n -qmake %s" % parameters['qmake']
cmd_args += " \\\n -bin %s" % parameters['bin']
cmd_args += " \\\n -build %s" % parameters['build']
@@ -1130,9 +1179,9 @@ def Run_Build_Command(config, parameters):
#------------------------------------------------------------------------
# [6] Build for some predetermined environments on demand
#------------------------------------------------------------------------
- BuildPymod = parameters['BuildPymod']
- if BuildPymod:
- ret = Build_pymod(parameters)
+ BuildPymodWhl = parameters['BuildPymodWhl']
+ if BuildPymodWhl:
+ ret = Build_pymod_wheel(parameters)
return ret
else:
return 0
@@ -1162,20 +1211,23 @@ def Deploy_Binaries_For_Bundle(config, parameters):
ModulePython = config['ModulePython']
ToolDebug = config['ToolDebug']
HBPythonIs39 = config['HBPythonIs39']
+ EmbedQt = config['EmbedQt']
+ EmbedPython3 = config['EmbedPython3']
- BuildPymod = parameters['BuildPymod']
+ BuildPymodWhl = parameters['BuildPymodWhl']
ProjectDir = parameters['project_dir']
MacBinDir = parameters['bin']
MacBuildDir = parameters['build']
MacBuildLog = parameters['logfile']
Platform = parameters['Platform']
+ QtLibRoot = parameters['qt_lib_root']
AbsMacPkgDir = "%s/%s" % (ProjectDir, MacPkgDir)
AbsMacBinDir = "%s/%s" % (ProjectDir, MacBinDir)
AbsMacBuildDir = "%s/%s" % (ProjectDir, MacBuildDir)
AbsMacBuildLog = "%s/%s" % (ProjectDir, MacBuildLog)
- if BuildPymod:
+ if BuildPymodWhl:
try:
PymodDistDir = parameters['pymod_dist']
pymodDistDir = PymodDistDir[ModulePython] # [ 'dist-MP3-${ModuleQt}', 'dist-HB3-${ModuleQt}', 'dist-ana3-${ModuleQt}' ]
@@ -1224,8 +1276,7 @@ def Deploy_Binaries_For_Bundle(config, parameters):
print( " [3] Creating the standard directory structure for 'klayout.app' bundle ..." )
#--------------------------------------------------------------------------------------------------------------
- # [3] Create the directory skeleton for "klayout.app" bundle
- # and command line buddy tools such as "strm2cif".
+ # [3] Create the directory skeleton for "klayout.app" bundle and command line buddy tools such as "strm2cif".
# They are stored in the directory structure below.
#
# klayout.app/+
@@ -1237,12 +1288,15 @@ def Deploy_Binaries_For_Bundle(config, parameters):
# +-- Frameworks/+
# | +-- '*.framework'
# | +-- '*.dylib'
- # | +-- 'db_plugins' --sym.link--> ../MacOS/db_plugins/
+ # | +-- 'db_plugins' --sym.link--> ../MacOS/db_plugins/
+ # | +-- 'lay_plugins' --sym.link--> ../MacOS/lay_plugins/
+ # | +-- 'pymod' --sym.link--> ../MacOS/pymod/
# +-- MacOS/+
# | +-- 'klayout'
# | +-- db_plugins/
# | +-- lay_plugins/
# | +-- pymod/
+ # |
# +-- Buddy/+
# | +-- 'strm2cif'
# | +-- 'strm2dxf'
@@ -1264,15 +1318,14 @@ def Deploy_Binaries_For_Bundle(config, parameters):
os.makedirs(targetDirF)
os.makedirs(targetDirM)
os.makedirs(targetDirB)
- if BuildPymod and not pymodDistDir == "":
+ if BuildPymodWhl and not pymodDistDir == "":
os.makedirs(targetDirP)
- print( " [4] Copying KLayout's dynamic link libraries to 'Frameworks' ..." )
- #---------------------------------------------------------------------------------------
- # [4] Copy KLayout's dynamic link libraries to "Frameworks/" and create
- # the library dependency dictionary.
- # <<< Do this job in "Frameworks/" >>>
+ print( " [4-1] Copying KLayout's dynamic link libraries to 'Frameworks' ..." )
+ #--------------------------------------------------------------------------------------------------------------
+ # [4-1] Copy KLayout's dynamic link libraries to "Frameworks/" and create the library dependency dictionary.
+ # <<< Do this job in "Frameworks/" >>>
#
# Note:
# KLayout's dynamic link library is built as below:
@@ -1299,11 +1352,11 @@ def Deploy_Binaries_For_Bundle(config, parameters):
# 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)
# :
- #---------------------------------------------------------------------------------------
- os.chdir( targetDirF )
- dynamicLinkLibs = glob.glob( os.path.join( AbsMacBinDir, "*.dylib" ) )
- depDicOrdinary = {} # inter-library dependency dictionary
- pathDic = {} # paths to insert for each library
+ #--------------------------------------------------------------------------------------------------------------
+ os.chdir(targetDirF)
+ dynamicLinkLibs = glob.glob( os.path.join( AbsMacBinDir, "*.dylib" ) )
+ dependencyDic_1 = dict() # inter-library dependency dictionary
+ pathDic_1 = dict() # paths to insert for each library
for item in dynamicLinkLibs:
if os.path.isfile(item) and not os.path.islink(item):
#-------------------------------------------------------------------
@@ -1323,88 +1376,364 @@ def Deploy_Binaries_For_Bundle(config, parameters):
otoolCm = "otool -L %s | grep dylib" % nameStyle3
otoolOut = os.popen( otoolCm ).read()
dependDic = DecomposeLibraryDependency(otoolOut)
- depDicOrdinary.update(dependDic)
+ dependencyDic_1.update(dependDic)
#-------------------------------------------------------------------
# (C) This library goes into Frameworks, hence record it's path there
#-------------------------------------------------------------------
- pathDic[nameStyle3] = "@executable_path/../Frameworks/" + nameStyle3
+ pathDic_1[nameStyle3] = "@executable_path/../Frameworks/" + nameStyle3
+
+ if 410 in ToolDebug:
+ DumpDependencyDicPair( "In [4-1 410]:", dependencyDic_1, pathDic_1 )
+ print( " [4-2] Copying the contents of the plugins to the place next to the application..." )
os.chdir(ProjectDir)
- #-------------------------------------------------------------------
- # Copy the contents of the plugin directories to a place next to
- # the application binary
- #-------------------------------------------------------------------
- for piDir in [ "db_plugins", "lay_plugins", "pymod" ]:
- os.makedirs( os.path.join( targetDirM, piDir ))
+ #-------------------------------------------------------------------------------
+ # (A) Copy the contents of the plugin directories to a place next to
+ # the application binary
+ #-------------------------------------------------------------------------------
+ for piDir in [ "db_plugins", "lay_plugins" ]:
+ os.makedirs( os.path.join( targetDirM, piDir ) )
dynamicLinkLibs = glob.glob( os.path.join( MacBinDir, piDir, "*.dylib" ) )
for item in dynamicLinkLibs:
if os.path.isfile(item) and not os.path.islink(item):
#-------------------------------------------------------------------
- # (A) Copy an ordinary *.dylib file here by changing the name
+ # (B) Copy an ordinary *.dylib file here by changing the name
# to style (3) and set its mode to 0755 (sanity check).
#-------------------------------------------------------------------
fullName = os.path.basename(item).split('.')
# e.g. [ 'libklayout_lay', '0', '26', '1', 'dylib' ]
nameStyle3 = fullName[0] + "." + fullName[1] + ".dylib"
- destPath = os.path.join( targetDirM, piDir, nameStyle3 )
+ destPath = os.path.join( targetDirM, piDir, nameStyle3 )
shutil.copy2( item, destPath )
os.chmod( destPath, 0o0755 )
#-------------------------------------------------------------------
- # (B) Then get inter-library dependencies
+ # (C) Then get inter-library dependencies
# Note that will pull all dependencies and sort them out later
# dropping those which don't have a path entry
#-------------------------------------------------------------------
otoolCm = "otool -L %s | grep 'dylib'" % destPath
otoolOut = os.popen( otoolCm ).read()
dependDic = DecomposeLibraryDependency(otoolOut)
- depDicOrdinary.update(dependDic)
+ dependencyDic_1.update(dependDic)
#-------------------------------------------------------------------
- # (C) This library goes into the plugin dir
+ # (D) This library goes into the plugin directory
#-------------------------------------------------------------------
- pathDic[nameStyle3] = "@executable_path/" + piDir + "/" + nameStyle3
+ pathDic_1[nameStyle3] = "@executable_path/" + piDir + "/" + nameStyle3
- '''
- PrintLibraryDependencyDictionary( depDicOrdinary, pathDic, "Style (3)" )
- exit()
- '''
+ if 420 in ToolDebug:
+ DumpDependencyDicPair( "In [4-2 420]:", dependencyDic_1, pathDic_1 )
- #----------------------------------------------------------------------------------
- # (D) Make a symbolic link
- # 'db_plugins' --slink--> ../MacOS/db_plugins/
- # under Frameworks/, which is required for the command line Buddy tools.
+ print( " [4-3] Making symbolic links from 'Frameworks' to '../MacOS/[db_plugins | lay_plugins | pymod]'..." )
+ #--------------------------------------------------------------------------------------------------------------
+ # [4-3] Make symbolic links
+ # 'db_plugins' --slink--> ../MacOS/db_plugins/
+ # 'lay_plugins' --slink--> ../MacOS/lay_plugins/
+ # 'pymod' --slink--> ../MacOS/pymod/
+ # under Frameworks/.
#
- # Ref. https://github.com/KLayout/klayout/issues/460#issuecomment-571803458
+ # 'db_plugins' is required for the command line Buddy tools.
+ # Ref. https://github.com/KLayout/klayout/issues/460#issuecomment-571803458
#
# :
# +-- Frameworks/+
# | +-- '*.framework'
# | +-- '*.dylib'
- # | +-- 'db_plugins' --sym.link--> ../MacOS/db_plugins/
+ # | +-- 'db_plugins' --sym.link--> ../MacOS/db_plugins/
+ # | +-- 'lay_plugins' --sym.link--> ../MacOS/lay_plugins/
+ # | +-- 'pymod' --sym.link--> ../MacOS/pymod/
# +-- MacOS/+
# | +-- 'klayout'
# | +-- db_plugins/
# | +-- lay_plugins/
# | +-- pymod/
# :
- #----------------------------------------------------------------------------------
- os.chdir( targetDirF )
- os.symlink( "../MacOS/db_plugins/", "./db_plugins" )
+ #--------------------------------------------------------------------------------------------------------------
+ os.chdir(targetDirF)
+ os.symlink( "../MacOS/db_plugins/", "./db_plugins" )
+ os.symlink( "../MacOS/lay_plugins/", "./lay_plugins" )
+ os.symlink( "../MacOS/pymod/", "./pymod" )
+ print( " [4-4] Deeply copying 'pymod/*' to 'MacOS/pymod/*'..." )
+ #--------------------------------------------------------------------------------------------------------------
+ # [4-4] Deeply copy the 'pymod' directory's contents, if any
+ # :
+ # +-- Frameworks/+
+ # | +-- '*.framework'
+ # | +-- '*.dylib'
+ # | +-- 'db_plugins' --sym.link--> ../MacOS/db_plugins/
+ # | +-- 'lay_plugins' --sym.link--> ../MacOS/lay_plugins/
+ # | +-- 'pymod' --sym.link--> ../MacOS/pymod/
+ # +-- MacOS/+
+ # | +-- 'klayout'
+ # | +-- db_plugins/
+ # | +-- lay_plugins/
+ # | +-- pymod/+
+ # | +-- klayout/+
+ # | +-- (*)
+ # | +-- pya/+
+ # | +-- __init__.py
+ # :
+ # (*) Example
+ # -rwxr-xr-x ... QtCore.cpython-311-darwin.so --- (+)
+ # -rwxr-xr-x ... QtDesigner.cpython-311-darwin.so
+ # -rwxr-xr-x ... QtGui.cpython-311-darwin.so
+ # -rwxr-xr-x ... QtMultimedia.cpython-311-darwin.so
+ # -rwxr-xr-x ... QtNetwork.cpython-311-darwin.so
+ # -rwxr-xr-x ... QtPrintSupport.cpython-311-darwin.so
+ # -rwxr-xr-x ... QtSql.cpython-311-darwin.so
+ # -rwxr-xr-x ... QtSvg.cpython-311-darwin.so
+ # -rwxr-xr-x ... QtUiTools.cpython-311-darwin.so
+ # -rwxr-xr-x ... QtWidgets.cpython-311-darwin.so
+ # -rwxr-xr-x ... QtXml.cpython-311-darwin.so
+ # -rwxr-xr-x ... QtXmlPatterns.cpython-311-darwin.so
+ # -rwxr-xr-x ... __init__.py
+ # drwxr-xr-x ... __pycache__
+ # drwxr-xr-x ... db
+ # -rwxr-xr-x ... dbcore.cpython-311-darwin.so
+ # drwxr-xr-x ... lay
+ # -rwxr-xr-x ... laycore.cpython-311-darwin.so
+ # drwxr-xr-x ... lib
+ # -rwxr-xr-x ... libcore.cpython-311-darwin.so
+ # drwxr-xr-x ... pya
+ # -rwxr-xr-x ... pyacore.cpython-311-darwin.so
+ # drwxr-xr-x ... rdb
+ # -rwxr-xr-x ... rdbcore.cpython-311-darwin.so
+ # drwxr-xr-x ... tl
+ # -rwxr-xr-x ... tlcore.cpython-311-darwin.so
+ #
+ #--------------------------------------------------------------------------------------------------------------
+ # (+) Example of the inter-library dependency of pymod's library
+ #
+ # % otool -L QtCore.cpython-311-darwin.so
+ #
+ # QtCore.cpython-311-darwin.so:
+ # libQtCore.0.dylib (compatibility version 0.28.0, current version 0.28.17)
+ # /opt/local/lib/libgit2.1.7.dylib (compatibility version 1.7.0, current version 1.7.2)
+ # /opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.3.1)
+ # /usr/local/opt/python@3.11/Frameworks/Python.framework/Versions/3.11/Python (compatibility...)
+ # libklayout_tl.0.dylib (compatibility version 0.28.0, current version 0.28.17)
+ # libklayout_gsi.0.dylib (compatibility version 0.28.0, current version 0.28.17)
+ # libklayout_pya.0.dylib (compatibility version 0.28.0, current version 0.28.17)
+ # libklayout_QtCore.0.dylib (compatibility version 0.28.0, current version 0.28.17)
+ # libklayout_QtGui.0.dylib (compatibility version 0.28.0, current version 0.28.17)
+ # libklayout_QtWidgets.0.dylib (compatibility version 0.28.0, current version 0.28.17)
+ # /opt/local/libexec/qt5/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport (compatibility...)
+ # /opt/local/libexec/qt5/lib/QtDesigner.framework/Versions/5/QtDesigner (compatibility...)
+ # /opt/local/libexec/qt5/lib/QtMultimediaWidgets.framework/Versions/5/QtMultimediaWidgets (compatibility...)
+ # /opt/local/libexec/qt5/lib/QtSvg.framework/Versions/5/QtSvg (compatibility...)
+ # /opt/local/libexec/qt5/lib/QtWidgets.framework/Versions/5/QtWidgets (compatibility...)
+ # /opt/local/libexec/qt5/lib/QtMultimedia.framework/Versions/5/QtMultimedia (compatibility...)
+ # /opt/local/libexec/qt5/lib/QtGui.framework/Versions/5/QtGui (compatibility...)
+ # /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility...)
+ # /System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility...)
+ # /opt/local/libexec/qt5/lib/QtXml.framework/Versions/5/QtXml (compatibility...)
+ # /opt/local/libexec/qt5/lib/QtXmlPatterns.framework/Versions/5/QtXmlPatterns (compatibility...)
+ # /opt/local/libexec/qt5/lib/QtNetwork.framework/Versions/5/QtNetwork (compatibility...)
+ # /opt/local/libexec/qt5/lib/QtSql.framework/Versions/5/QtSql (compatibility...)
+ # /opt/local/libexec/qt5/lib/QtCore.framework/Versions/5/QtCore (compatibility...)
+ # /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility...)
+ # /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility...)
+ # /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility...)
+ # /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility...)
+ # /usr/lib/libc++.1.dylib (compatibility...)
+ # /usr/lib/libSystem.B.dylib (compatibility...)
+ #--------------------------------------------------------------------------------------------------------------
+ os.chdir(AbsMacBinDir)
+ sourceDirKly = "pymod/klayout"
+ sourdeDirPya = "pymod/pya"
+ pymodDirInBin = os.path.isdir(sourceDirKly) and os.path.isdir(sourdeDirPya)
+ dependencyDic_2 = dict() # inter-library dependency dictionary
+ pathDic_2 = dict() # paths to insert for each library
+ dependencyDic_3 = dict() # inter-library dependency dictionary
+ pathDic_3 = dict() # paths to insert for each library
+ dependencyDic_4 = dict() # inter-library dependency dictionary
+ pathDic_4 = dict() # paths to insert for each library
+
+ if pymodDirInBin:
+ targetDirKly = os.path.join(targetDirM, sourceDirKly)
+ targetDirPya = os.path.join(targetDirM, sourdeDirPya)
+
+ retK = Deeply_Copy_Dir( sourceDirKly, targetDirKly, excl_pat_list=["__pycache__"] )
+ retP = Deeply_Copy_Dir( sourdeDirPya, targetDirPya, excl_pat_list=["__pycache__"] )
+ if not (retK and retP):
+ msg = "!!! Failed to deeply copy the 'pymod' directory's contents !!!"
+ print(msg)
+ return 1
+
+ # <<< Do the remaining job in "MacOS/pymod/klayout/" >>>
+ os.chdir(targetDirKly)
+ #-------------------------------------------------------------------
+ # (A) Prepare regular expressions for the library name-matching
+ #-------------------------------------------------------------------
+ # (1) KLayout's self libraries
+ patSelf = r'^(lib.+[.]dylib)'
+ regSelf = re.compile(patSelf)
+
+ # (2) Auxiliary libraries such as 'libgit2.1.7.dylib'
+ libAux_1 = "/opt/local/lib/"
+ libAux_2 = "/usr/local/lib/"
+ libAux_3 = "/opt/homebrew/lib/"
+ libAux_4 = "/Applications/anaconda3/lib/"
+ patAux = r'^(%s|%s|%s|%s)(lib.+[.]dylib)' % (libAux_1, libAux_2, libAux_3, libAux_4)
+ regAux = re.compile(patAux)
+
+ # (3) Qt frameworks
+ # QtLibRoot:
+ # MacPorts ===> '/opt/local/libexec/qt5/lib'
+ # Homebrew ===> '/usr/local/opt/qt@5/lib'
+ # Anaconda3 ===> '/Applications/anaconda3/lib' (not frameworks and won't be embedded)
+ patQt = r'(%s/)(Qt.+[.]framework.+)' % QtLibRoot
+ regQt = re.compile(patQt)
+
+ # (4) Python frameworks (only for Homebrew) # in the case of Intel Mac...
+ libPy3_1 = "%s/" % HBPython311FrameworkPath # /usr/local/opt/python@3.11/Frameworks/Python.framework/
+ libPy3_2 = "%s/" % HBPython39FrameworkPath # /usr/local/opt/python@3.9/Frameworks/Python.framework/
+ patPy3 = r'^(%s|%s)(.+)' % (libPy3_1, libPy3_2)
+ regPy3 = re.compile(patPy3)
+
+ #-------------------------------------------------------------------------------
+ # (B) Copy the contents of the pymod/klayout/ directory to the place next to
+ # the main application executable
+ #-------------------------------------------------------------------------------
+ dynamicLinkLibs = glob.glob( os.path.join( targetDirM, sourceDirKly, "*.so" ) )
+ for item in dynamicLinkLibs:
+ if os.path.isfile(item) and not os.path.islink(item):
+ #-------------------------------------------------------------------
+ # (C) Copy an ordinary *.dylib file here by changing the name
+ # to style (3) and set its mode to 0755 (sanity check).
+ #-------------------------------------------------------------------
+ baseName = os.path.basename(item) # 'QtCore.cpython-311-darwin.so'
+ fullName = os.path.basename(item).split('.') # [ 'QtCore', 'cpython-311-darwin', 'so' ]
+ nameStyle3 = fullName[0] + "." + fullName[1] + ".so" # == fullName; no need to change!
+ destPath = os.path.join( targetDirM, sourceDirKly, nameStyle3 )
+ # shutil.copy2( item, destPath ) # already deeply copied!
+ os.chmod( destPath, 0o0755 ) # just for confirmation
+
+ #-------------------------------------------------------------------
+ # (D) Then get inter-library dependencies
+ #-------------------------------------------------------------------
+ otoolCm = "otool -L %s" % destPath
+ otoolOut = os.popen( otoolCm ).read()
+ dependDic = DecomposeLibraryDependency(otoolOut)
+ dicKey = list(dependDic.keys())[0]
+ dicVal = dependDic[dicKey]
+ dicValIdx = list( range(0, len(dicVal)) )
+
+ #-------------------------------------------------------------------
+ # (E) Dependencies on KLayout's self libraries (always)
+ # Populate 'dependencyDic_2' and 'pathDic_2'
+ #-------------------------------------------------------------------
+ if True:
+ dependLib_2 = dict()
+ for idx in dicValIdx:
+ fname = dicVal[idx]
+ if regSelf.match(fname):
+ if idx == 0:
+ dependLib_2[baseName] = baseName
+ else:
+ dependLib_2[fname] = fname
+
+ dependencyDic_2.update( {dicKey: dependLib_2} )
+ pathDic_2[nameStyle3] = "@executable_path/" + sourceDirKly + "/" + nameStyle3
+
+ for libname in dependLib_2.keys():
+ if libname == baseName:
+ continue
+ else:
+ pathDic_2[libname] = "@executable_path/../Frameworks/" + dependLib_2[libname]
- print( " [5] Setting and changing the identification names among KLayout's libraries ..." )
+ #-------------------------------------------------------------------
+ # (F) Dependencies on Qt and auxiliary libraries (optional)
+ # Populate 'dependencyDic_3' and 'pathDic_3'
+ #-------------------------------------------------------------------
+ if EmbedQt:
+ dependLib_3 = dict()
+ for idx in dicValIdx:
+ fname = dicVal[idx]
+ if regAux.match(fname):
+ dependLib_3[fname] = regAux.match(fname).groups()[1]
+ elif regQt.match(fname):
+ dependLib_3[fname] = regQt.match(fname).groups()[1]
+
+ dependencyDic_3.update( {dicKey: dependLib_3} )
+ pathDic_3[nameStyle3] = "@executable_path/" + sourceDirKly + "/" + nameStyle3
+
+ for libname in dependLib_3.keys():
+ if libname == baseName:
+ continue
+ else:
+ pathDic_3[libname] = "@executable_path/../Frameworks/" + dependLib_3[libname]
+
+ #-------------------------------------------------------------------
+ # (G) Dependencies on Python framework (optional)
+ # Populate 'dependencyDic_4' and 'pathDic_4'
+ #-------------------------------------------------------------------
+ if EmbedPython3:
+ dependLib_4 = dict()
+ for idx in dicValIdx:
+ fname = dicVal[idx]
+ if regPy3.match(fname):
+ dependLib_4[fname] = "Python.framework/%s" % regPy3.match(fname).groups()[1]
+
+ dependencyDic_4.update( {dicKey: dependLib_4} )
+ pathDic_4[nameStyle3] = "@executable_path/" + sourceDirKly + "/" + nameStyle3
+
+ for libname in dependLib_4.keys():
+ if libname == baseName:
+ continue
+ else:
+ pathDic_4[libname] = "@executable_path/../Frameworks/" + dependLib_4[libname]
+
+ if 441 in ToolDebug:
+ DumpDependencyDicPair( "In [4-4 441]:", dependencyDic_2, pathDic_2 )
+
+ if 442 in ToolDebug:
+ DumpDependencyDicPair( "In [4-4 442]:", dependencyDic_3, pathDic_3 )
+
+ if 443 in ToolDebug:
+ DumpDependencyDicPair( "In [4-4 443]:", dependencyDic_4, pathDic_4 )
+
+ print( " [5-1] Setting and changing the identification names among KLayout's libraries ..." )
#-------------------------------------------------------------
- # [5] Set the identification names for KLayout's libraries
+ # [5-1] Set the identification names for KLayout's libraries
# and make the library aware of the locations of libraries
# on which it depends; that is, inter-library dependency
#-------------------------------------------------------------
- ret = SetChangeIdentificationNameOfDyLib( depDicOrdinary, pathDic )
+ os.chdir(targetDirF)
+ ret = SetChangeIdentificationNameOfDyLib( dependencyDic_1, pathDic_1 )
if not ret == 0:
- msg = "!!! Failed to set and change to new identification names !!!"
+ msg = "!!! Failed to set and change to new identification names with (dependencyDic_1, pathDic_1) !!!"
print(msg)
return 1
+ print( " [5-2] Setting and changing the identification names among pymod's libraries ..." )
+ #-------------------------------------------------------------
+ # [5-2] Similarly for the pymod's libraries...
+ #-------------------------------------------------------------
+ if not targetDirKly == None:
+ os.chdir(targetDirKly)
+ if len(dependencyDic_2) > 0 and len(pathDic_2) > 0:
+ ret = SetChangeIdentificationNameOfDyLib( dependencyDic_2, pathDic_2 )
+ if not ret == 0:
+ msg = "!!! Failed to set and change to new identification names with (dependencyDic_2, pathDic_2) !!!"
+ print(msg)
+ return 1
+
+ if len(dependencyDic_3) > 0 and len(pathDic_3) > 0:
+ ret = SetChangeIdentificationNameOfDyLib( dependencyDic_3, pathDic_3 )
+ if not ret == 0:
+ msg = "!!! Failed to set and change to new identification names with (dependencyDic_3, pathDic_3) !!!"
+ print(msg)
+ return 1
+
+ if len(dependencyDic_4) > 0 and len(pathDic_4) > 0:
+ ret = SetChangeIdentificationNameOfDyLib( dependencyDic_4, pathDic_4 )
+ if not ret == 0:
+ msg = "!!! Failed to set and change to new identification names with (dependencyDic_4, pathDic_4) !!!"
+ print(msg)
+ return 1
- print( " [6] Copying built executables and resource files ..." )
+ print( " [6] Copying the built executables and resource files ..." )
#-------------------------------------------------------------
# [6] Copy some known files in source directories to
# relevant target directories
@@ -1414,15 +1743,13 @@ def Deploy_Binaries_For_Bundle(config, parameters):
sourceDir1 = sourceDir0 + "/MacOS"
sourceDir2 = "%s/macbuild/Resources" % ProjectDir
sourceDir3 = "%s" % MacBinDir
- sourceDir4 = "%s/pymod" % MacBinDir
# (A) the main components
tmpfileM = ProjectDir + "/macbuild/Resources/Info.plist.template"
keydicM = { 'exe': 'klayout', 'icon': 'klayout.icns', 'bname': 'klayout', 'ver': Version }
plistM = GenerateInfoPlist( keydicM, tmpfileM )
- file = open( targetDir0 + "/Info.plist", "w" )
- file.write(plistM)
- file.close()
+ with open( targetDir0 + "/Info.plist", "w" ) as file:
+ file.write(plistM)
shutil.copy2( sourceDir0 + "/PkgInfo", targetDir0 ) # this file is not mandatory
shutil.copy2( sourceDir1 + "/klayout", targetDirM )
@@ -1441,7 +1768,7 @@ def Deploy_Binaries_For_Bundle(config, parameters):
os.chmod( targetDirB + "/" + buddy, 0o0755 )
# (C) the Pymod
- if BuildPymod and not pymodDistDir == "":
+ if BuildPymodWhl and not pymodDistDir == "":
for item in glob.glob( pymodDistDir + "/*.whl" ):
shutil.copy2( item, targetDirP )
@@ -1471,7 +1798,7 @@ def Deploy_Binaries_For_Bundle(config, parameters):
return 1
if DeploymentF:
- print( " [8] Finally, deploying Qt's Frameworks ..." )
+ print( " [8] Finally, deploying Qt's Frameworks and auxiliary libraries ..." )
#-------------------------------------------------------------
# [8] Deploy Qt Frameworks
#-------------------------------------------------------------
@@ -1831,8 +2158,8 @@ def Deploy_Binaries_For_Bundle(config, parameters):
#-------------------------------------------------------------
# [10] Special deployment of Ruby3.3 from Homebrew?
#-------------------------------------------------------------
- deploymentRuby32HB = (ModuleRuby == 'Ruby33Brew')
- if deploymentRuby32HB and NonOSStdLang:
+ deploymentRuby33HB = (ModuleRuby == 'Ruby33Brew')
+ if deploymentRuby33HB and NonOSStdLang:
print( "" )
print( " [10] You have reached optional deployment of Ruby from %s ..." % HBRuby33Path )
@@ -1848,7 +2175,7 @@ def Deploy_Binaries_For_Bundle(config, parameters):
else:
print( " [8] Skipped deploying Qt's Frameworks and optional Python/Ruby Frameworks..." )
- print( "##### Finished deploying libraries and executables for #####" )
+ print( "##### Finished deploying the libraries and executables for #####" )
print("")
os.chdir(ProjectDir)
return 0
diff --git a/macbuild/build4mac_env.py b/macbuild/build4mac_env.py
index feb04bad89..c7d6f2e1f2 100755
--- a/macbuild/build4mac_env.py
+++ b/macbuild/build4mac_env.py
@@ -6,7 +6,7 @@
#
# Here are dictionaries of ...
# different modules for building KLayout (http://www.klayout.de/index.php)
-# version 0.28.17 or later on different Apple Mac OSX platforms.
+# version 0.29.0 or later on different Apple Mac OSX platforms.
#
# This file is imported by 'build4mac.py' script.
#===============================================================================
@@ -72,14 +72,16 @@
# install with 'sudo port install [qt5|qt5-qttools]'
# [Key Type Name] = 'Qt5MacPorts'
Qt5MacPorts = { 'qmake' : '/opt/local/libexec/qt5/bin/qmake',
- 'deploy': '/opt/local/libexec/qt5/bin/macdeployqt'
+ 'deploy': '/opt/local/libexec/qt5/bin/macdeployqt',
+ 'libdir': '/opt/local/libexec/qt5/lib'
}
# Qt5 from Homebrew (https://brew.sh/)
# install with 'brew install qt5'
# [Key Type Name] = 'Qt5Brew'
Qt5Brew = { 'qmake' : '%s/opt/qt@5/bin/qmake' % DefaultHomebrewRoot,
- 'deploy': '%s/opt/qt@5/bin/macdeployqt' % DefaultHomebrewRoot
+ 'deploy': '%s/opt/qt@5/bin/macdeployqt' % DefaultHomebrewRoot,
+ 'libdir': '%s/opt/qt@5/lib' % DefaultHomebrewRoot
}
# Qt5 bundled with anaconda3 installed under /Applications/anaconda3/
@@ -87,7 +89,8 @@
# If so, you need to make a symbolic link: /Applications/anaconda3 ---> $HOME/opt/anaconda3/
# [Key Type Name] = 'Qt5Ana3'
Qt5Ana3 = { 'qmake' : '/Applications/anaconda3/bin/qmake',
- 'deploy': '/Applications/anaconda3/bin/macdeployqt'
+ 'deploy': '/Applications/anaconda3/bin/macdeployqt',
+ 'libdir': '/Applications/anaconda3/lib'
}
#-------------------------------------------------------------------------
@@ -97,16 +100,26 @@
# install with 'sudo port install [qt6|qt6-qttools]'
# [Key Type Name] = 'Qt6MacPorts'
Qt6MacPorts = { 'qmake' : '/opt/local/libexec/qt6/bin/qmake',
- 'deploy': '/opt/local/libexec/qt6/bin/macdeployqt'
+ 'deploy': '/opt/local/libexec/qt6/bin/macdeployqt',
+ 'libdir': '/opt/local/libexec/qt6/lib'
}
# Qt6 from Homebrew (https://brew.sh/)
# install with 'brew install qt6'
# [Key Type Name] = 'Qt6Brew'
Qt6Brew = { 'qmake' : '%s/opt/qt@6/bin/qmake' % DefaultHomebrewRoot,
- 'deploy': '%s/opt/qt@6/bin/macdeployqt' % DefaultHomebrewRoot
+ 'deploy': '%s/opt/qt@6/bin/macdeployqt' % DefaultHomebrewRoot,
+ 'libdir': '%s/opt/qt@6/lib' % DefaultHomebrewRoot
}
+# Consolidated dictionary kit for Qt[5|6]
+Qt56Dictionary = { 'Qt5MacPorts': Qt5MacPorts,
+ 'Qt5Brew' : Qt5Brew,
+ 'Qt5Ana3' : Qt5Ana3,
+ 'Qt6MacPorts': Qt6MacPorts,
+ 'Qt6Brew' : Qt6Brew
+ }
+
#-----------------------------------------------------
# [2] Ruby
# * Dropped the followings (2023-10-24).
@@ -123,31 +136,46 @@
#-----------------------------------------------------
# Whereabouts of different components of Ruby
#-----------------------------------------------------
+# % which ruby
+# /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
+#
+# % ruby -v
+# ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.x86_64-darwin21]
+#
+# Where is the 'ruby.h' used to build the 'ruby' executable?
+#
+# % ruby -e "puts File.expand_path('ruby.h', RbConfig::CONFIG['rubyhdrdir'])"
+# ===> /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk \
+# /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/include/ruby-2.6.0/ruby.h
+#
# Bundled with Monterey (12.x)
# [Key Type Name] = 'Sys'
-MontereySDK = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
+MontereyXcSDK = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
+MontereyCLTSDK = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
RubyMonterey = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby',
- 'inc': '%s/System/Library/Frameworks/Ruby.framework/Headers' % MontereySDK,
- 'inc2': '%s/System/Library/Frameworks/Ruby.framework/Headers/ruby' % MontereySDK,
- 'lib': '%s/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.tbd' % MontereySDK
+ 'inc': '%s/System/Library/Frameworks/Ruby.framework/Headers' % MontereyXcSDK,
+ 'inc2': '%s/System/Library/Frameworks/Ruby.framework/Headers/ruby' % MontereyXcSDK,
+ 'lib': '%s/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.tbd' % MontereyXcSDK
}
# Bundled with Ventura (13.x)
# [Key Type Name] = 'Sys'
-VenturaSDK = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
+VenturaXcSDK = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
+VenturaCLTSDK = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
RubyVentura = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby',
- 'inc': '%s/System/Library/Frameworks/Ruby.framework/Headers' % VenturaSDK,
- 'inc2': '%s/System/Library/Frameworks/Ruby.framework/Headers/ruby' % VenturaSDK,
- 'lib': '%s/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.tbd' % VenturaSDK
+ 'inc': '%s/System/Library/Frameworks/Ruby.framework/Headers' % VenturaXcSDK,
+ 'inc2': '%s/System/Library/Frameworks/Ruby.framework/Headers/ruby' % VenturaXcSDK,
+ 'lib': '%s/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.tbd' % VenturaXcSDK
}
# Bundled with Sonoma (14.x)
# [Key Type Name] = 'Sys'
-SonomaSDK = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
+SonomaXcSDK = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
+SonomaCLTSDK = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
RubySonoma = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby',
- 'inc': '%s/System/Library/Frameworks/Ruby.framework/Headers' % SonomaSDK,
- 'inc2': '%s/System/Library/Frameworks/Ruby.framework/Headers/ruby' % SonomaSDK,
- 'lib': '%s/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.tbd' % SonomaSDK
+ 'inc': '%s/System/Library/Frameworks/Ruby.framework/Headers' % SonomaXcSDK,
+ 'inc2': '%s/System/Library/Frameworks/Ruby.framework/Headers/ruby' % SonomaXcSDK,
+ 'lib': '%s/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.tbd' % SonomaXcSDK
}
# Ruby 3.3 from MacPorts (https://www.macports.org/)
diff --git a/macbuild/build4mac_util.py b/macbuild/build4mac_util.py
index 8241aebf7c..87980982b7 100755
--- a/macbuild/build4mac_util.py
+++ b/macbuild/build4mac_util.py
@@ -6,7 +6,7 @@
#
# Here are utility functions and classes ...
# for building KLayout (http://www.klayout.de/index.php)
-# version 0.28.17 or later on different Apple Mac OSX platforms.
+# version 0.29.0 or later on different Apple Mac OSX platforms.
#
# This file is imported by 'build4mac.py' script.
#========================================================================================
@@ -16,6 +16,7 @@
import string
import subprocess
import shutil
+import fnmatch
#----------------------------------------------------------------------------------------
## To import global dictionaries of different modules
@@ -80,6 +81,9 @@ def PrintLibraryDependencyDictionary( depdic, pathdic, namedic ):
# @return 0 on success; non-zero on failure
#----------------------------------------------------------------------------------------
def SetChangeIdentificationNameOfDyLib( libdic, pathDic ):
+ if len(libdic) == 0 or len(pathDic) == 0:
+ return 0
+
cmdNameId = XcodeToolChain['nameID']
cmdNameChg = XcodeToolChain['nameCH']
dependentLibs = libdic.keys()
@@ -101,10 +105,9 @@ def SetChangeIdentificationNameOfDyLib( libdic, pathDic ):
# [2] Make the library aware of the new identifications of all supporters
#-------------------------------------------------------------------------
supporters = libdic[lib]
- for sup in supporters:
- supName = os.path.basename(sup)
- if libName != supName and (supName in pathDic):
- nameOld = "%s" % sup
+ for supName in supporters:
+ if (libName != supName) and (supName in pathDic):
+ nameOld = "%s" % supName
nameNew = pathDic[supName]
command = "%s %s %s %s" % ( cmdNameChg, nameOld, nameNew, lib )
if subprocess.call( command, shell=True ) != 0:
@@ -133,11 +136,15 @@ def SetChangeIdentificationNameOfDyLib( libdic, pathDic ):
# +-- Frameworks/+
# | +-- '*.framework'
# | +-- '*.dylib'
-# | +-- 'db_plugins' --slink--> ../MacOS/db_plugins/
+# | +-- 'db_plugins' --sym.link--> ../MacOS/db_plugins/
+# | +-- 'lay_plugins' --sym.link--> ../MacOS/lay_plugins/
+# | +-- 'pymod' --sym.link--> ../MacOS/pymod/
# +-- MacOS/+
# | +-- 'klayout'
# | +-- db_plugins/
# | +-- lay_plugins/
+# | +-- pymod/
+# |
# +-- Buddy/+
# +-- 'strm2cif'
# +-- 'strm2dxf'
@@ -790,6 +797,79 @@ def Generate_Start_Console_Py( template, pythonver, target ):
else:
return True
+#----------------------------------------------------------------------------------------
+## To deeply copy directory contents
+#
+# @param[in] src_dir : source directory
+# @param[in] dest_dir : destination directory
+# @param[in] excl_pat_list: exclude pattern list (default=[]])
+#
+# @return True on success, False on failure
+#----------------------------------------------------------------------------------------
+def Deeply_Copy_Dir( src_dir, dest_dir, excl_pat_list=[] ):
+
+ def FnameMatch(item):
+ for excl_pat in excl_pat_list:
+ if fnmatch.fnmatch( item, excl_pat ):
+ return True
+ return False
+
+ if os.path.isfile(dest_dir):
+ print( "! Destination <%s> is an existing file" % dest_dir, file=sys.stderr )
+ return False
+
+ if not os.path.exists(dest_dir):
+ os.makedirs(dest_dir)
+
+ for item in os.listdir(src_dir):
+ src_item = os.path.join(src_dir, item)
+ dest_item = os.path.join(dest_dir, item)
+
+ if os.path.isdir(src_item):
+ if FnameMatch(item):
+ continue # skip copying if directory name matches the exclusion pattern
+ Deeply_Copy_Dir( src_item, dest_item, excl_pat_list )
+ else:
+ if FnameMatch(item):
+ continue # skip copying if the file matches the exclusion pattern
+ shutil.copy2( src_item, dest_item )
+
+ return True
+
+#----------------------------------------------------------------------------------------
+## To dump the contents of a dependency dictionary
+#
+# @param[in] title: title
+# @param[in] depDic: dependency dictionary to dump
+# @param[in] pathDic: path dictionary to dump
+#
+# @return void
+#----------------------------------------------------------------------------------------
+def DumpDependencyDicPair( title, depDic, pathDic ):
+
+ print( "### Dependency Dictionary Pair <%s> ###" % title )
+
+ # depDic
+ count1 = 0
+ for key1 in sorted(depDic.keys()):
+ count1 += 1
+ diclist = depDic[key1]
+ print( " %3d:%s" % (count1, key1) )
+
+ count2 = 0
+ for dict_file in diclist:
+ count2 += 1
+ print( " %3d:%s" % (count2, dict_file) )
+
+ # pathDic
+ print( " ==========" )
+ count3 = 0
+ for key3 in sorted(pathDic.keys()):
+ count3 += 1
+ print( " %3d:%s: %s" % (count3, key3, pathDic[key3]) )
+
+ return
+
#----------------
# End of File
#----------------
diff --git a/macbuild/macQAT.py b/macbuild/macQAT.py
index f62ffce162..bd73ddcc1d 100755
--- a/macbuild/macQAT.py
+++ b/macbuild/macQAT.py
@@ -5,7 +5,7 @@
# File: "macbuild/macQAT.py"
#
# The top Python script to run "ut_runner" after building KLayout
-# (http://www.klayout.de/index.php) version 0.28.17 or later on different Apple
+# (http://www.klayout.de/index.php) version 0.29.0 or later on different Apple
# ßMac OSX platforms.
#
# This script must be copied to a "*.macQAT/" directory to run.
@@ -25,6 +25,7 @@
def SetGlobals():
global ProjectDir # project directory where "ut_runner" exists
global RunnerUsage # True to print the usage of 'ut_runner'
+ global StartKLayout # True to start the KLayout main GUI window
global Run # True to run this script
global ContinueOnError # True to continue after an error
global TestsExcluded # list of tests to exclude
@@ -54,6 +55,7 @@ def SetGlobals():
Usage += " -----------------------------------------------------------------+---------------\n"
Usage += " [-u|--usage] : print usage of 'ut_runner'and exit | disabled\n"
Usage += " |\n"
+ Usage += " [-k|--klayout] : just start the KLayout main GUI window | disabled\n"
Usage += " <-r|--run> : run this script | disabled\n"
Usage += " [-s|--stop] : stop on error | disabled\n"
Usage += " [-x|--exclude ] : exclude test(s) such as 'pymod,pya' | ''\n"
@@ -66,6 +68,7 @@ def SetGlobals():
ProjectDir = os.getcwd()
RunnerUsage = False
+ StartKLayout = False
Run = False
ContinueOnError = True
TestsExcluded = list()
@@ -104,6 +107,7 @@ def GetTimeStamp():
def ParseCommandLineArguments():
global Usage
global RunnerUsage
+ global StartKLayout
global Run
global ContinueOnError
global TestsExcluded
@@ -117,6 +121,12 @@ def ParseCommandLineArguments():
default=False,
help="print usage of 'ut_runner' and exit (false)" )
+ p.add_option( '-k', '--klayout',
+ action='store_true',
+ dest='start_KLayout',
+ default=False,
+ help='just start the KLayout main GUI window (false)' )
+
p.add_option( '-r', '--run',
action='store_true',
dest='runme',
@@ -152,6 +162,7 @@ def ParseCommandLineArguments():
help='check usage (false)' )
p.set_defaults( runner_usage = False,
+ start_KLayout = False,
runme = False,
stop_on_error = False,
exclude_tests = list(),
@@ -165,6 +176,7 @@ def ParseCommandLineArguments():
quit()
RunnerUsage = opt.runner_usage
+ StartKLayout = opt.start_KLayout
Run = opt.runme
ContinueOnError = not opt.stop_on_error
if not len(opt.exclude_tests) == 0:
@@ -211,6 +223,18 @@ def ExportEnvVariables():
for env in [ 'TESTSRC', 'TESTTMP', 'LD_LIBRARY_PATH' ]:
os.environ[env] = MyEnviron[env]
+#-------------------------------------------------------------------------------
+## Start the KLayout main GUI window
+#
+#-------------------------------------------------------------------------------
+def StartKLatyouGUIWindow():
+ if System == "Darwin":
+ command = "./klayout.app/Contents/MacOS/klayout"
+ else:
+ command = "./klayout"
+
+ subprocess.call( command, shell=False )
+
#-------------------------------------------------------------------------------
## Run the tester
#
@@ -255,35 +279,43 @@ def Main():
quit()
#-------------------------------------------------------
- # [3] Run the unit tester
+ # [3] Start the KLayout main GUI window
+ #-------------------------------------------------------
+ if StartKLayout:
+ StartKLatyouGUIWindow()
+
#-------------------------------------------------------
- if not Run:
- print( "! pass <-r|--run> option to run" )
+ # [4] Run the unit tester
+ #-------------------------------------------------------
+ if not Run and not StartKLayout:
+ print( "! pass <-r|--run> option to run the QA tests" )
+ print( "! pass <-k|--klayout> option to start the KLayout main GUI window" )
print(Usage)
quit()
- command = './ut_runner'
- if ContinueOnError:
- command += " -c"
- for item in TestsExcluded:
- command += ' -x %s' % item
- if not len(Arguments) == 0:
- for arg in Arguments:
- command += " %s" % arg
-
- print( "" )
- print( "### Dumping the log to <%s>" % LogFile )
- print( "------------------------------------------------------------------------" )
- print( " Git SHA1 = %s" % GitSHA1 )
- print( " Time stamp = %s" % TimeStamp )
- print( " Command line = %s" % command )
- print( "------------------------------------------------------------------------" )
- if DryRun:
- quit()
- sleep(1.0)
- HidePrivateDir()
- RunTester( command, logfile=LogFile )
- ShowPrivateDir()
+ if Run:
+ command = './ut_runner'
+ if ContinueOnError:
+ command += " -c"
+ for item in TestsExcluded:
+ command += ' -x %s' % item
+ if not len(Arguments) == 0:
+ for arg in Arguments:
+ command += " %s" % arg
+
+ print( "" )
+ print( "### Dumping the log to <%s>" % LogFile )
+ print( "------------------------------------------------------------------------" )
+ print( " Git SHA1 = %s" % GitSHA1 )
+ print( " Time stamp = %s" % TimeStamp )
+ print( " Command line = %s" % command )
+ print( "------------------------------------------------------------------------" )
+ if DryRun:
+ quit()
+ sleep(1.0)
+ HidePrivateDir()
+ RunTester( command, logfile=LogFile )
+ ShowPrivateDir()
#===================================================================================
if __name__ == "__main__":
diff --git a/macbuild/makeDMG4mac.py b/macbuild/makeDMG4mac.py
index 1b2ae16835..1cdd03cde6 100755
--- a/macbuild/makeDMG4mac.py
+++ b/macbuild/makeDMG4mac.py
@@ -77,7 +77,7 @@ def SetGlobals():
Usage = "\n"
Usage += "---------------------------------------------------------------------------------------------------------\n"
Usage += "<< Usage of 'makeDMG4mac.py' >>\n"
- Usage += " for making a DMG file of KLayout 0.28.17 or later on different Apple macOS platforms.\n"
+ Usage += " for making a DMG file of KLayout 0.29.0 or later on different Apple macOS platforms.\n"
Usage += "\n"
Usage += "$ [python] ./makeDMG4mac.py\n"
Usage += " option & argument : descriptions | default value\n"
@@ -162,36 +162,50 @@ def SetGlobals():
Item3AppleScript = ""
# Populate DicStdLightHeavyW
- DicStdLightHeavyW[ "std" ] = dict() # ST-*
- DicStdLightHeavyW[ "ports" ] = dict() # LW-*
- DicStdLightHeavyW[ "brew" ] = dict() # LW-*
- DicStdLightHeavyW[ "ana3" ] = dict() # LW-*
- DicStdLightHeavyW[ "brewH" ] = dict() # HW-*
-
- DicStdLightHeavyW[ "std" ]["zip"] = "macbuild/Resources/script-bundle-S.zip"
- DicStdLightHeavyW[ "std" ]["src"] = "script-bundle-S"
- DicStdLightHeavyW[ "std" ]["des"] = "MacStdUser-ReadMeFirst"
- DicStdLightHeavyW[ "std" ]["item3"] = 'set position of item "MacStdUser-ReadMeFirst" to {700, 400}'
-
- DicStdLightHeavyW[ "ports" ]["zip"] = "macbuild/Resources/script-bundle-P.zip"
- DicStdLightHeavyW[ "ports" ]["src"] = "script-bundle-P"
- DicStdLightHeavyW[ "ports" ]["des"] = "MacPortsUser-ReadMeFirst"
- DicStdLightHeavyW[ "ports" ]["item3"] = 'set position of item "MacPortsUser-ReadMeFirst" to {700, 400}'
-
- DicStdLightHeavyW[ "brew" ]["zip"] = "macbuild/Resources/script-bundle-B.zip"
- DicStdLightHeavyW[ "brew" ]["src"] = "script-bundle-B"
- DicStdLightHeavyW[ "brew" ]["des"] = "HomebrewUser-ReadMeFirst"
- DicStdLightHeavyW[ "brew" ]["item3"] = 'set position of item "HomebrewUser-ReadMeFirst" to {700, 400}'
-
- DicStdLightHeavyW[ "ana3" ]["zip"] = "macbuild/Resources/script-bundle-A.zip"
- DicStdLightHeavyW[ "ana3" ]["src"] = "script-bundle-A"
- DicStdLightHeavyW[ "ana3" ]["des"] = "Anaconda3User-ReadMeFirst"
- DicStdLightHeavyW[ "ana3" ]["item3"] = 'set position of item "Anaconda3User-ReadMeFirst" to {700, 400}'
-
- DicStdLightHeavyW[ "brewH" ]["zip"] = "macbuild/Resources/script-bundle-H.zip"
- DicStdLightHeavyW[ "brewH" ]["src"] = "script-bundle-H"
- DicStdLightHeavyW[ "brewH" ]["des"] = "Homebrew-HUser-ReadMeFirst"
- DicStdLightHeavyW[ "brewH" ]["item3"] = 'set position of item "Homebrew-HUser-ReadMeFirst" to {700, 400}'
+ DicStdLightHeavyW[ "std" ] = dict() # ST-*
+ DicStdLightHeavyW[ "ports" ] = dict() # LW-*
+ DicStdLightHeavyW[ "brew" ] = dict() # LW-*
+ DicStdLightHeavyW[ "ana3" ] = dict() # LW-*
+ DicStdLightHeavyW[ "brewH" ] = dict() # HW-*
+ # "pbrew" is the alternative of "brew" using MacPorts' Qt and Homebrew's (Ruby, Python)
+ # "pbrewHW" is the alternative of "brewH" using MacPorts' Qt and Homebrew's Python
+ DicStdLightHeavyW[ "pbrew" ] = dict() # LW-*
+ DicStdLightHeavyW[ "pbrewHW" ] = dict() # HW-*
+
+ DicStdLightHeavyW[ "std" ]["zip"] = "macbuild/Resources/script-bundle-S.zip"
+ DicStdLightHeavyW[ "std" ]["src"] = "script-bundle-S"
+ DicStdLightHeavyW[ "std" ]["des"] = "MacStdUser-ReadMeFirst"
+ DicStdLightHeavyW[ "std" ]["item3"] = 'set position of item "MacStdUser-ReadMeFirst" to {700, 400}'
+
+ DicStdLightHeavyW[ "ports" ]["zip"] = "macbuild/Resources/script-bundle-P.zip"
+ DicStdLightHeavyW[ "ports" ]["src"] = "script-bundle-P"
+ DicStdLightHeavyW[ "ports" ]["des"] = "MacPortsUser-ReadMeFirst"
+ DicStdLightHeavyW[ "ports" ]["item3"] = 'set position of item "MacPortsUser-ReadMeFirst" to {700, 400}'
+
+ DicStdLightHeavyW[ "brew" ]["zip"] = "macbuild/Resources/script-bundle-B.zip"
+ DicStdLightHeavyW[ "brew" ]["src"] = "script-bundle-B"
+ DicStdLightHeavyW[ "brew" ]["des"] = "HomebrewUser-ReadMeFirst"
+ DicStdLightHeavyW[ "brew" ]["item3"] = 'set position of item "HomebrewUser-ReadMeFirst" to {700, 400}'
+
+ DicStdLightHeavyW[ "ana3" ]["zip"] = "macbuild/Resources/script-bundle-A.zip"
+ DicStdLightHeavyW[ "ana3" ]["src"] = "script-bundle-A"
+ DicStdLightHeavyW[ "ana3" ]["des"] = "Anaconda3User-ReadMeFirst"
+ DicStdLightHeavyW[ "ana3" ]["item3"] = 'set position of item "Anaconda3User-ReadMeFirst" to {700, 400}'
+
+ DicStdLightHeavyW[ "brewH" ]["zip"] = "macbuild/Resources/script-bundle-H.zip"
+ DicStdLightHeavyW[ "brewH" ]["src"] = "script-bundle-H"
+ DicStdLightHeavyW[ "brewH" ]["des"] = "Homebrew-HUser-ReadMeFirst"
+ DicStdLightHeavyW[ "brewH" ]["item3"] = 'set position of item "Homebrew-HUser-ReadMeFirst" to {700, 400}'
+
+ DicStdLightHeavyW[ "pbrew" ]["zip"] = "macbuild/Resources/script-bundle-B.zip"
+ DicStdLightHeavyW[ "pbrew" ]["src"] = "script-bundle-B"
+ DicStdLightHeavyW[ "pbrew" ]["des"] = "HomebrewUser-ReadMeFirst"
+ DicStdLightHeavyW[ "pbrew" ]["item3"] = 'set position of item "HomebrewUser-ReadMeFirst" to {700, 400}'
+
+ DicStdLightHeavyW[ "pbrewHW" ]["zip"] = "macbuild/Resources/script-bundle-H.zip"
+ DicStdLightHeavyW[ "pbrewHW" ]["src"] = "script-bundle-H"
+ DicStdLightHeavyW[ "pbrewHW" ]["des"] = "Homebrew-HUser-ReadMeFirst"
+ DicStdLightHeavyW[ "pbrewHW" ]["item3"] = 'set position of item "Homebrew-HUser-ReadMeFirst" to {700, 400}'
#------------------------------------------------------------------------------
## To check the contents of the package directory
@@ -199,18 +213,15 @@ def SetGlobals():
# The package directory name should look like:
# * ST-qt5MP.pkg.macos-Monterey-release-RsysPsys
# * LW-qt5Ana3.pkg.macos-Monterey-release-Rana3Pana3
-# * LW-qt5Brew.pkg.macos-Monterey-release-Rhb33Phb311 --- (1)
+# * LW-qt6Brew.pkg.macos-Monterey-release-Rhb33Phb311 --- (1)
# * LW-qt5MP.pkg.macos-Monterey-release-Rmp33Pmp311
-# * HW-qt5Brew.pkg.macos-Monterey-release-RsysPhb311
+# * HW-qt6Brew.pkg.macos-Monterey-release-RsysPhb311
#
# * ST-qt6MP.pkg.macos-Monterey-release-RsysPsys
-# * LW-qt6Ana3.pkg.macos-Monterey-release-Rana3Pana3
-# * LW-qt6Brew.pkg.macos-Monterey-release-Rhb33Phb311
# * LW-qt6MP.pkg.macos-Monterey-release-Rmp33Pmp311
-# * HW-qt6Brew.pkg.macos-Monterey-release-RsysPhb311
#
# Generated DMG will be, for example,
-# (1) ---> LW-klayout-0.28.17-macOS-Monterey-1-qt5Brew-Rhb33Phb311.dmg
+# (1) ---> LW-klayout-0.29.0-macOS-Monterey-1-qt6Brew-Rhb33Phb311.dmg
#
# @return on success, positive integer in [MB] that tells approx. occupied disc space;
# on failure, -1
@@ -251,16 +262,13 @@ def CheckPkgDirectory():
# [2] Identify (Qt, Ruby, Python) from PkgDir
# * ST-qt5MP.pkg.macos-Monterey-release-RsysPsys
# * LW-qt5Ana3.pkg.macos-Monterey-release-Rana3Pana3
- # * LW-qt5Brew.pkg.macos-Monterey-release-Rhb33Phb311
+ # * LW-qt6Brew.pkg.macos-Monterey-release-Rhb33Phb311
# * LW-qt5MP.pkg.macos-Monterey-release-Rmp33Pmp311
- # * HW-qt5Brew.pkg.macos-Monterey-release-RsysPhb311
+ # * HW-qt6Brew.pkg.macos-Monterey-release-RsysPhb311
# * EX-qt5MP.pkg.macos-Monterey-release-Rhb33Pmp311
#
# * ST-qt6MP.pkg.macos-Monterey-release-RsysPsys
- # * LW-qt6Ana3.pkg.macos-Monterey-release-Rana3Pana3
- # * LW-qt6Brew.pkg.macos-Monterey-release-Rhb33Phb311
# * LW-qt6MP.pkg.macos-Monterey-release-Rmp33Pmp311
- # * HW-qt6Brew.pkg.macos-Monterey-release-RsysPhb311
#-----------------------------------------------------------------------------------------------
patQRP = u'(ST|LW|HW|EX)([-])([qt5|qt6][0-9A-Za-z]+)([.]pkg[.])([A-Za-z]+[-][A-Za-z]+[-]release[-])([0-9A-Za-z]+)'
regQRP = re.compile(patQRP)
@@ -299,7 +307,7 @@ def CheckPkgDirectory():
LatestOSHomebrew = Platform == LatestOS
LatestOSHomebrew &= PackagePrefix == "LW"
- LatestOSHomebrew &= QtIdentification in [ "qt5Brew", "qt6Brew" ]
+ LatestOSHomebrew &= QtIdentification in [ "qt5Brew", "qt6Brew", "qt5MP", "qt6MP" ] # "qt[5|6]MP" are the alternatives
LatestOSHomebrew &= RubyPythonID in [ "Rhb33Phb311", "Rhb33Phb39", "Rhb33Phbauto" ]
LatestOSAnaconda3 = Platform == LatestOS
@@ -309,8 +317,8 @@ def CheckPkgDirectory():
LatestOSHomebrewH = Platform == LatestOS
LatestOSHomebrewH &= PackagePrefix == "HW"
- LatestOSHomebrewH &= QtIdentification in [ "qt5Brew", "qt6Brew" ]
- LatestOSHomebrewH &= RubyPythonID in [ "RsysPhb311", "RsysPhb39", "RsysPhbauto" ] # Sys-Homebre hybrid
+ LatestOSHomebrewH &= QtIdentification in [ "qt5Brew", "qt6Brew", "qt5MP", "qt6MP" ] # "qt[5|6]MP" are the alternatives
+ LatestOSHomebrewH &= RubyPythonID in [ "RsysPhb311", "RsysPhb39", "RsysPhbauto" ] # Sys-Homebrew hybrid
if LatestOSSys:
mydic = DicStdLightHeavyW["std"]
diff --git a/macbuild/nightlyBuild.py b/macbuild/nightlyBuild.py
index 7ffb3d4160..3d6100b309 100755
--- a/macbuild/nightlyBuild.py
+++ b/macbuild/nightlyBuild.py
@@ -57,15 +57,18 @@ def Test_My_Platform( platforms=[ 'Monterey', 'Ventura', 'Sonoma' ] ):
# @return a dictionary; key=integer, value=mnemonic
#------------------------------------------------------------------------------
def Get_Build_Target_Dict():
- buildTargetDic = dict()
- buildTargetDic[0] = 'std'
- buildTargetDic[1] = 'ports'
- buildTargetDic[2] = 'brew'
- buildTargetDic[3] = 'brewHW'
- buildTargetDic[4] = 'ana3'
-
- buildTargetDic[5] = 'brewA'
- buildTargetDic[6] = 'brewAHW'
+ buildTargetDic = dict()
+ buildTargetDic[0] = 'std'
+ buildTargetDic[1] = 'ports'
+ buildTargetDic[2] = 'brew'
+ buildTargetDic[3] = 'brewHW'
+ buildTargetDic[4] = 'ana3'
+
+ buildTargetDic[5] = 'brewA'
+ buildTargetDic[6] = 'brewAHW'
+
+ buildTargetDic[12] = 'pbrew' # use MacPorts' Qt and Homebrew's (Ruby, Python)
+ buildTargetDic[13] = 'pbrewHW' # use MacPorts' Qt and Homebrew's Python
return buildTargetDic
#------------------------------------------------------------------------------
@@ -97,25 +100,32 @@ def Get_Build_Options( targetDic, platform ):
buildOp[(qtVer, "ports")] = [ '-q', '%sMacPorts' % qtType, '-r', 'MP33', '-p', 'MP311' ]
logfile[(qtVer, "ports")] = "%sMP.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rmp33Pmp311")
elif target == "brew":
- buildOp[(qtVer, "brew")] = [ '-q', '%sBrew' % qtType, '-r', 'HB33', '-p', 'HB311' ]
+ buildOp[(qtVer, "brew")] = [ '-q', '%sBrew' % qtType, '-r', 'HB33', '-p', 'HB311' ]
logfile[(qtVer, "brew")] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rhb33Phb311")
elif target == "brewHW":
- buildOp[(qtVer, "brewHW")] = [ '-q', '%sBrew' % qtType, '-r', 'sys', '-p', 'HB311' ]
+ buildOp[(qtVer, "brewHW")] = [ '-q', '%sBrew' % qtType, '-r', 'sys', '-p', 'HB311' ]
logfile[(qtVer, "brewHW")] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "RsysPhb311")
elif target == "ana3":
- buildOp[(qtVer, "ana3")] = [ '-q', '%sAna3' % qtType, '-r', 'Ana3', '-p', 'Ana3' ]
+ buildOp[(qtVer, "ana3")] = [ '-q', '%sAna3' % qtType, '-r', 'Ana3', '-p', 'Ana3' ]
logfile[(qtVer, "ana3")] = "%sAna3.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rana3Pana3")
elif target == "brewA":
- buildOp[(qtVer, "brewA")] = [ '-q', '%sBrew' % qtType, '-r', 'HB33', '-p', 'HBAuto' ]
+ buildOp[(qtVer, "brewA")] = [ '-q', '%sBrew' % qtType, '-r', 'HB33', '-p', 'HBAuto' ]
logfile[(qtVer, "brewA")] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rhb33Phbauto")
elif target == "brewAHW":
- buildOp[(qtVer, "brewAHW")] = [ '-q', '%sBrew' % qtType, '-r', 'sys', '-p', 'HBAuto' ]
+ buildOp[(qtVer, "brewAHW")] = [ '-q', '%sBrew' % qtType, '-r', 'sys', '-p', 'HBAuto' ]
logfile[(qtVer, "brewAHW")] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "RsysPhbauto")
+ elif target == "pbrew":
+ buildOp[(qtVer, "pbrew")] = [ '-q', '%sMacPorts' % qtType, '-r', 'HB33', '-p', 'HB311' ]
+ logfile[(qtVer, "pbrew")] = "%sMP.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rhb33Phb311")
+ elif target == "pbrewHW":
+ buildOp[(qtVer, "pbrewHW")] = [ '-q', '%sMacPorts' % qtType, '-r', 'sys', '-p', 'HB311' ]
+ logfile[(qtVer, "pbrewHW")] = "%sMP.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "RsysPhb311")
if WithPymod:
buildOp[(qtVer,"ports")] = buildOp[(qtVer,"ports")] + ['--buildPymod']
buildOp[(qtVer,"brew")] = buildOp[(qtVer,"brew")] + ['--buildPymod']
buildOp[(qtVer,"ana3")] = buildOp[(qtVer,"ana3")] + ['--buildPymod']
+ buildOp[(qtVer,"pbrew")] = buildOp[(qtVer,"pbrew")] + ['--buildPymod']
return (buildOp, logfile)
@@ -152,6 +162,10 @@ def Get_QAT_Directory( targetDic, platform ):
dirQAT[(qtVer, "brewA")] = '%sBrew.build.macos-%s-release-Rhb33Phbauto.macQAT' % (qtType.lower(), platform)
elif target == "brewAHW":
dirQAT[(qtVer, "brewAHW")] = '%sBrew.build.macos-%s-release-RsysPhbauto.macQAT' % (qtType.lower(), platform)
+ elif target == "pbrew":
+ dirQAT[(qtVer, "pbrew")] = '%sMP.build.macos-%s-release-Rhb33Phb311.macQAT' % (qtType.lower(), platform)
+ elif target == "pbrewHW":
+ dirQAT[(qtVer, "pbrewHW")] = '%sMP.build.macos-%s-release-RsysPhb311.macQAT' % (qtType.lower(), platform)
return dirQAT
@@ -182,19 +196,19 @@ def Get_Package_Options( targetDic, platform, srlDMG, makeflag ):
for key in targetDic.keys():
target = targetDic[key]
if target == "std":
- packOp[(qtVer, "std")] = [ '-p', 'ST-%sMP.pkg.macos-%s-release-RsysPsys' % (qtType.lower(), platform),
+ packOp[(qtVer, "std")] = [ '-p', 'ST-%sMP.pkg.macos-%s-release-RsysPsys' % (qtType.lower(), platform),
'-s', '%d' % srlDMG, '%s' % flag ]
elif target == "ports":
- packOp[(qtVer, "ports")] = [ '-p', 'LW-%sMP.pkg.macos-%s-release-Rmp33Pmp311' % (qtType.lower(), platform),
+ packOp[(qtVer, "ports")] = [ '-p', 'LW-%sMP.pkg.macos-%s-release-Rmp33Pmp311' % (qtType.lower(), platform),
'-s', '%d' % srlDMG, '%s' % flag ]
elif target == "brew":
- packOp[(qtVer, "brew")] = [ '-p', 'LW-%sBrew.pkg.macos-%s-release-Rhb33Phb311' % (qtType.lower(), platform),
+ packOp[(qtVer, "brew")] = [ '-p', 'LW-%sBrew.pkg.macos-%s-release-Rhb33Phb311' % (qtType.lower(), platform),
'-s', '%d' % srlDMG, '%s' % flag ]
elif target == "brewHW":
- packOp[(qtVer, "brewHW")] = [ '-p', 'HW-%sBrew.pkg.macos-%s-release-RsysPhb311' % (qtType.lower(), platform),
+ packOp[(qtVer, "brewHW")] = [ '-p', 'HW-%sBrew.pkg.macos-%s-release-RsysPhb311' % (qtType.lower(), platform),
'-s', '%d' % srlDMG, '%s' % flag ]
elif target == "ana3":
- packOp[(qtVer, "ana3")] = [ '-p', 'LW-%sAna3.pkg.macos-%s-release-Rana3Pana3' % (qtType.lower(), platform),
+ packOp[(qtVer, "ana3")] = [ '-p', 'LW-%sAna3.pkg.macos-%s-release-Rana3Pana3' % (qtType.lower(), platform),
'-s', '%d' % srlDMG, '%s' % flag ]
elif target == "brewA":
packOp[(qtVer, "brewA")] = [ '-p', 'LW-%sBrew.pkg.macos-%s-release-Rhb33Phbauto' % (qtType.lower(), platform),
@@ -202,6 +216,12 @@ def Get_Package_Options( targetDic, platform, srlDMG, makeflag ):
elif target == "brewAHW":
packOp[(qtVer, "brewAHW")] = [ '-p', 'HW-%sBrew.pkg.macos-%s-release-RsysPhbauto' % (qtType.lower(), platform),
'-s', '%d' % srlDMG, '%s' % flag ]
+ elif target == "pbrew":
+ packOp[(qtVer, "pbrew")] = [ '-p', 'LW-%sMP.pkg.macos-%s-release-Rhb33Phb311' % (qtType.lower(), platform),
+ '-s', '%d' % srlDMG, '%s' % flag ]
+ elif target == "pbrewHW":
+ packOp[(qtVer, "pbrewHW")] = [ '-p', 'HW-%sMP.pkg.macos-%s-release-RsysPhb311' % (qtType.lower(), platform),
+ '-s', '%d' % srlDMG, '%s' % flag ]
return packOp
#------------------------------------------------------------------------------
@@ -227,7 +247,7 @@ def Parse_CommandLine_Arguments():
if platform in [ "Sonoma", "Ventura", "Monterey" ]:
targetopt = "0,1,2,3,4"
else:
- targetopt = None
+ targetopt = ""
Usage = "\n"
Usage += "----------------------------------------------------------------------------------------------------------\n"
@@ -240,7 +260,7 @@ def Parse_CommandLine_Arguments():
Usage += " --------------------------------------------------------------------------+--------------\n"
Usage += " [--qt ] : 5='qt5', 6='qt6' (migration to Qt6 is ongoing) | 5\n"
Usage += " [--target ] : 0='std', 1='ports', 2='brew', 3='brewHW', 4='ana3', | '%s'\n" % targetopt
- Usage += " 5='brewA', 6='brewAHW' |\n"
+ Usage += " 5='brewA', 6='brewAHW', 12='pbrew', 13='pbrewHW' |\n"
Usage += " * with --qt=6, use --target='0,1,2,3' (4 is ignored) |\n"
Usage += " [--qttarget ] : ex. '5,1' for qt=5, target=1 | disabled\n"
Usage += " + This option supersedes, if used, the --qt and --target combination. |\n"
@@ -266,7 +286,7 @@ def Parse_CommandLine_Arguments():
Usage += " (3) $ ./nightlyBuild.py --test |\n"
Usage += " (4) $ ./nightlyBuild.py --check (confirm the QA Test results) |\n"
Usage += " (5) $ ./nightlyBuild.py --makedmg 1 |\n"
- Usage += " (6) $ ./nightlyBuild.py --upload '0.28.17' |\n"
+ Usage += " (6) $ ./nightlyBuild.py --upload '0.29.0' |\n"
Usage += " (7) $ ./nightlyBuild.py --cleandmg 1 |\n"
Usage += "-----------------------------------------------------------------------------+----------------------------\n"
@@ -370,7 +390,7 @@ def Parse_CommandLine_Arguments():
targetDic = Get_Build_Target_Dict()
Target = list()
for idx in targetIdx:
- if idx in range(0, 7):
+ if idx in [0,1,2,3,4,5,6,12,13]:
Target.append( targetDic[idx] )
# Populate QtTarget
@@ -393,7 +413,7 @@ def Parse_CommandLine_Arguments():
for i in range(0, len(df)):
qt = df.iloc[i,0]
idx = df.iloc[i,1]
- if (qt == 5 and idx in range(0, 7)) or (qt == 6 and idx in [0,1,2,3, 5,6]):
+ if (qt == 5 and idx in [0,1,2,3,4,5,6,12,13]) or (qt == 6 and idx in [0,1,2,3, 5,6,12,13]):
QtTarget.append( (qt, targetDic[idx]) )
elif len(opt.qt_target) > 0:
QtTarget = list()
@@ -401,7 +421,7 @@ def Parse_CommandLine_Arguments():
for item in opt.qt_target:
qt = int(item.split(",")[0])
idx = int(item.split(",")[1])
- if (qt == 5 and idx in range(0, 7)) or (qt == 6 and idx in [0,1,2,3, 5,6]):
+ if (qt == 5 and idx in [0,1,2,3,4,5,6,12,13]) or (qt == 6 and idx in [0,1,2,3, 5,6,12,13]):
QtTarget.append( (qt, targetDic[idx]) )
else:
withqttarget = False
@@ -462,7 +482,7 @@ def Build_Deploy():
command1 = [ pyBuilder ] + buildOp[(qttype, key)]
- if key in [ "std", "brewHW", "brewAHW" ] :
+ if key in [ "std", "brewHW", "brewAHW", "pbrewHW" ] :
command2 = "time"
command2 += " \\\n %s" % pyBuilder
for option in buildOp[(qttype, key)]:
diff --git a/macbuild/nightlyBuild.sample.csv b/macbuild/nightlyBuild.sample.csv
index edc13bc0a7..ed0f996c95 100644
--- a/macbuild/nightlyBuild.sample.csv
+++ b/macbuild/nightlyBuild.sample.csv
@@ -8,18 +8,21 @@
# qtVer,target
# where
# qtVer = 5 or 6
-# target = [0='std', 1='ports', 2='brew', 3='brewHW', 4='ana3']
+# target = [0='std', 1='ports', 2='brew', 3='brewHW', 4='ana3',
+# 12='pbrew', 13='pbrewHW']
# note that
# (qtVer,target)=(6,4) will be omitted
#-------------------------------------------------------------------------------
qtVer,target
5,0
5,1
-5,2
-5,3
+6,2
+6,13
5,4
#6,0
#6,1
#6,2
#6,3
#6,4
+#6,12
+#6,13
diff --git a/macbuild/python3HB.py b/macbuild/python3HB.py
index a04f0e64ad..82046c09b9 100755
--- a/macbuild/python3HB.py
+++ b/macbuild/python3HB.py
@@ -27,17 +27,17 @@ def SetGlobals():
del System, Node, Release, MacVersion, Machine, Processor
Usage = "\n"
- 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 += " -------------------------------------------------------------------+---------------\n"
Usage += " <-v|--version >: in ['3.8', '3.9', '3.10', '3.11', '3.12', | ''\n"
- Usage += " '3.13'] | ''\n"
+ Usage += " '3.13'] |\n"
Usage += " [-u|-unlink] : unlink only | disabled\n"
Usage += " [-?|--?] : print this usage and exit | disabled\n"
- Usage += "----------------------------------------------------------------------+--------------\n"
+ Usage += "----------------------------------------------------------------------+-----------------\n"
#------------------------------------------------------------------------------
# Parse the command line arguments