Merge pull request #461 from Kazzz-S/0.26.2-mac1

Update of the build environment for macOS: KLayout 0.26.1 or later
This commit is contained in:
Matthias Köfferlein 2020-01-02 22:03:42 +01:00 committed by GitHub
commit e83269d60f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 820 additions and 816 deletions

View File

@ -1,13 +1,15 @@
Relevant KLayout version: 0.25.2
Relevant KLayout version: 0.26.1
# 1. Introduction
This directory "macbuild" contains different files required for building KLayout (http://www.klayout.de/) version 0.25 or later for different 64-bit Mac OSXs including:
* Yosemite (10.10)
This directory **`macbuild`** contains different files required for building KLayout (http://www.klayout.de/) version 0.26.1 or later for different 64-bit Mac OSXs including:
* El Capitan (10.11)
* Sierra (10.12)
* High Sierra (10.13)
* Mojave (10.14)
* Catalina (10.15)
By default, Qt framework is "Qt5" from MacPorts (https://www.macports.org/) which is usually located under:
# 2. Qt5 Frameworks
By default, Qt frameworks are "Qt5" from MacPorts (https://www.macports.org/) which is usually located under:
```
/opt/local/libexec/qt5/
```
@ -16,102 +18,218 @@ Alternatively, you can use "Qt5" from Homebrew (https://brew.sh/) which is usual
```
/usr/local/opt/qt/
```
Please refer to Section # 5. of this document regarding use of Homebrew.
KLayout 0.25.2 was successfully built with "Qt 5.10.0" from MacPorts and "Qt 5.10.1" from Homebrew.
OR
### IMPORTANT
"Qt5" from Anaconda3 (https://www.anaconda.com/) which is usually located under:
```
* Please DO NOT USE "Qt 4.x" which is problematic in compilation.
$HOME/opt/anaconda3/pkgs/qt-{version}
```
Also by default, supported script languages, i.e, Ruby and Python, are those standard ones bundled with the OS.
# 3. Script language support: Ruby and Python
By default, supported script languages, i.e., Ruby and Python, are those standard ones bundled with the OS.<br>
As for Catalina (10.15),
```
$ /usr/bin/ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin19]
# 2. Non-OS-standard script language support
You may want to use a non-OS-standard script language such as Python 3.6 from Anaconda2 (https://www.anaconda.com/download/#macos) in combination with KLayout.
$ /usr/bin/python --version
Python 2.7.16
```
Even in the latest OS as of today (December 2019), Python 3.x is not bundled with the OS, and this is the main reason why users want non-OS-standard script language support.
Since Anaconda2 is a popular Python development environment, this is worth trying. Unfortunately, however, some dynamic linkage problems are observed as of today.
On the other hand, Python 3.7 provided by MacPorts or Homebrew is usable.
Please try this (refer to 3B below or Section #5) if you feel it's useful.
To meet such a requirement, the build script **`build4mac.py`** provides several possible combinations of Qt5, Ruy and Python module.<br>
Some typical use cases are described in Section 6.
# 3. Use-cases
### 3A. Debug build using the OS-standard script languages
1. Make a symbolic link (if it does not exist) from the parent directory (where 'build.sh' exists) to 'build4mac.py', that is,
```
build4mac.py -> macbuild/build4mac.py
```
2. Invoke 'build4mac.py' with appropriate options ("-d" for debug build):
```
$ cd /where/'build.sh'/exists
$ ./build4mac.py -d
```
3. Confirm successful build (it will take about one hour).
4. Run 'build4mac.py' again with the same options used in 2. PLUS "-y" to deploy executables and libraries (including Qt's frameworks) under "klayout.app" bundle. The buddy command line tools (strm*) will also be deployed in this step.
```
$ ./build4mac.py -d -y
```
5. Copy/move generated bundles ("klayout.app" and "klayout.scripts/") to your "/Applications" directory for installation.
# 4. Prerequisites
You need to have:
* the latest Xcode and command-line tool kit compliant with each OS
* Qt5 package from MacPorts, Homebrew, or Anaconda3
* optionally Ruby and Python packages from MacPorts, Homebrew, or Anaconda3
#### For matching versions of Ruby and Python, please also refer to `build4mac_env.py`. ####
### 3B. Release build using the non-OS-standard Ruby 2.4 and Python 3.6 both from MacPorts
1. Make a symbolic link (if it does not exist) from the parent directory (where 'build.sh' exists) to 'build4mac.py', that is,
# 5. Command-line options of **`build4mac.py`** are as shown below.
```
build4mac.py -> macbuild/build4mac.py
---------------------------------------------------------------------------------------------------------
<< Usage of **`build4mac.py`** >>
for building KLayout 0.26.1 or later on different Apple Mac OSX platforms.
$ [python] ./build4mac.py
option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value
--------------------------------------------------------------------------------------+---------------
[-q|--qt <type>] : case-insensitive type=['Qt5MacPorts', 'Qt5Brew', 'Qt5Ana3'] | qt5macports
: Qt5MacPorts: use Qt5 from MacPorts |
: Qt5Brew: use Qt5 from Homebrew |
: Qt5Ana3: use Qt5 from Anaconda3 |
[-r|--ruby <type>] : case-insensitive type=['nil', 'Sys', 'MP26', 'HB26', 'Ana3'] | sys
: nil: don't bind Ruby |
: Sys: use OS-bundled Ruby [2.0 - 2.6] depending on OS |
: MP26: use Ruby 2.6 from MacPorts |
: HB26: use Ruby 2.6 from Homebrew |
: Ana3: use Ruby 2.5 from Anaconda3 |
[-p|--python <type>] : case-insensitive type=['nil', 'Sys', 'MP37', 'HB37', 'Ana3'] | sys
: nil: don't bind Python |
: Sys: use OS-bundled Python 2.7 [ElCapitan -- Catalina] |
: MP37: use Python 3.7 from MacPorts |
: HB37: use Python 3.7 from Homebrew |
: Ana3: use Python 3.7 from Anaconda3 |
[-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled
[-m|--make <option>] : option passed to 'make' | '-j4'
[-d|--debug] : enable debug mode build | disabled
[-c|--checkcom] : check command-line and exit without building | disabled
[-y|--deploy] : deploy executables and dylibs including Qt's Frameworks | disabled
[-Y|--DEPLOY] : deploy executables and dylibs for those who built KLayout | disabled
: from the source code and use the tools in the same machine |
: ! After confirmation of successful build of 'klayout.app', |
: rerun this script with BOTH: |
: 1) the same options used for building AND |
: 2) <-y|--deploy> OR <-Y|--DEPLOY> |
: optionally with [-v|--verbose <0-3>] |
[-v|--verbose <0-3>] : verbose level of `macdeployqt' (effective with -y only) | 1
: 0 = no output, 1 = error/warning (default), |
: 2 = normal, 3 = debug |
[-?|--?] : print this usage and exit | disabled
-----------------------------------------------------------------------------------------+---------------
```
2. Invoke 'build4mac.py' with appropriate options:
# 6. Use-cases
In this section, the actual file- and directory names are those obtained on macOS Catalina.<br>
On different OS, those names differ accordingly.
### 6A. Standard build using the OS-bundled Ruby and Python
1. Invoke **`build4mac.py`** with the default options:
```
$ cd /where/'build.sh'/exists
$ ./build4mac.py -r mp24 -p mp36
$ ./build4mac.py
```
3. Confirm successful build (it will take about one hour).
4. Run 'build4mac.py' again with the same options used in 2. PLUS "-Y" to deploy executables and libraries under "klayout.app" bundle. The buddy command line tools (strm*) will also be deployed in this step.
2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-y" to deploy executables and libraries (including Qt's frameworks) under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step.
```
$ ./build4mac.py -r mp24 -p mp36 -Y
$ ./build4mac.py -y
```
* [-Y|--DEPLOY] option deploys KLayout's dylibs and executables only.
That is, paths to other modules (Ruby, Python, and Qt5 Frameworks) remain unchanged (absolute paths in your development environment).
The application bundle **`klayout.app`** is located under:<br>
**`ST-qt5MP.pkg.macos-Catalina-release-RsysPsys`** directory, where the three parts below are important.
* "ST-" means that this is a standard package (LW-, HW-, and EX- are other possibilities explained below).
* "qt5MP" means that Qt5 from MacPorts is used.
* "RsysPsys" means that Ruby is OS-bundled; Python is OS-bundled.
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
5. Copy/move generated bundles ("klayout.app" and "klayout.scripts/") to your "/Applications" directory for installation.
If you use "-Y" option instead of "-y" in Step-3, Qt5 frameworks is NOT deployed in the application bundle.<br>
Then the directory name will be **`LW-qt5MP.pkg.macos-Catalina-release-RsysPsys`**, where
* "LW-" means that this is a lightweight package.
#### If you build KLayout from the source code AND use it on the same machine, "-Y" option is highly recommended. ####
### 6B. Fully MacPorts-flavored build with MacPorts Ruby 2.6 and MacPorts Python 3.7
```
$ cd /where/'build.sh'/exists
$ ./build4mac.py -q qt5macports -r mp26 -p mp37
```
2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step.
```
$ ./build4mac.py -q qt5macports -r mp26 -p mp37 -Y
```
The application bundle **`klayout.app`** is located under:<br>
**`LW-qt5MP.pkg.macos-Catalina-release-Rmp26Pmp37`** directory, where
* "LW-" means that this is a lightweight package.
* "qt5MP" means that Qt5 from MacPorts is used.
* "Rmp26Pmp37" means that Ruby is 2.6 from MacPorts; Python is 3.7 from MacPorts.
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
### 6C. Fully Homebrew-flavored build with Homebrew Ruby 2.6 and Homebrew Python 3.7
```
$ cd /where/'build.sh'/exists
$ ./build4mac.py -q qt5brew -r hb26 -p hb37
```
2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step.
```
$ ./build4mac.py -q qt5brew -r hb26 -p hb37 -Y
```
The application bundle **`klayout.app`** is located under:<br>
**`LW-qt5Brew.pkg.macos-Catalina-release-Rhb26Phb37`** directory, where
* "LW-" means that this is a lightweight package.
* "qt5Brew" means that Qt5 from Homebrew is used.
* "Rhb26Phb37" means that Ruby is 2.6 from Homebrew; Python is 3.7 from Homebrew.
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
### 6D. Partially Homebrew-flavored build with System Ruby and Homebrew Python 3.7
```
$ cd /where/'build.sh'/exists
$ ./build4mac.py -q qt5brew -r sys -p hb37
```
2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-y" to deploy executables and libraries (including Qt's frameworks and Python frameworks) under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step.
```
$ ./build4mac.py -q qt5brew -r sys -p hb37 -y
```
The application bundle **`klayout.app`** is located under:<br>
**`HW-qt5Brew.pkg.macos-Catalina-release-RsysPhb37`** directory, where
* "HW-" means that this is a heavyweight package because both Qt5 and Python are deployed.
* "qt5Brew" means that Qt5 from Homebrew is used.
* "RsysPhb37" means that Ruby is OS-bundled; Python is 3.7 from Homebrew.
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
### Important ###
So far, deployment of Homebrew Ruby is not supported. <br>
Therefore, if you intend to use "-y" option, you need to use "-r sys" for building.
### 6E. Fully Anaconda3-flavored build with Anaconda3 Ruby 2.5 and Anaconda3 Python 3.7
```
$ cd /where/'build.sh'/exists
$ ./build4mac.py -q qt5ana3 -r ana3 -p ana3
```
2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step.
```
$ ./build4mac.py -q qt5ana3 -r ana3 -p ana3 -Y
```
The application bundle **`klayout.app`** is located under:<br>
**`LW-qt5Ana3.pkg.macos-Catalina-release-Rana3Pana3`** directory, where
* "LW-" means that this is a lightweight package.
* "qt5Ana3" means that Qt5 from Anaconda3 is used.
* "Rana3Pana3" means that Ruby (2.5) is from Anaconda3; Python (3.7) is from Anaconda3.
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
5. You may have to set `PYTHONHOME` environment variable like:
```
export PYTHONHOME=$HOME/opt/anaconda3
```
### 6F. Other combinations
Logically, several different module combinations other than 6A. through 6E. are possible, including `nil` choice.<br>
If you choose such a combination, the resultant package directory name will begin with **`EX-`** (exceptional).
----
# 4. Making a DMG installer
You can make a DMG installer using another Python script 'makeDMG4mac.py'.
This script requires a directory generated by 'build4mac.py' with [-y|-Y] option (refer to 3A.4 & 3B.4)
# 7. Making a DMG installer
You can make a DMG installer using another Python script **`makeDMG4mac.py`**.
This script requires a directory generated by **`build4mac.py`** with [-y|-Y] option (refer to 6A through 6E).
1. Make a symbolic link (if it does not exist) from the parent directory (where 'build.sh' exists) to 'makeDMG4mac.py', that is,
1. Make a symbolic link (if it does not exist) from the parent directory (where **`build.sh`** exists) to **`makeDMG4mac.py`**, that is,
```
makeDMG4mac.py -> macbuild/makeDMG4mac.py
```
2. Invoke 'makeDMG4mac.py' with -p and -m options, for example,
2. Invoke **`makeDMG4mac.py`** with -p and -m options, for example,
```
$ cd /where/'build.sh'/exists
$ ./makeDMG4mac.py -p qt5.pkg.macos-HighSierra-release -m
$ ./makeDMG4mac.py -p ST-qt5MP.pkg.macos-Catalina-release-RsysPsys -m
```
This command will generate the two files below:<br>
* **`ST-klayout-0.26.1-macOS-Catalina-1-qt5MP-RsysPsys.dmg`** ---(1) the main DMG file
* **`ST-klayout-0.26.1-macOS-Catalina-1-qt5MP-RsysPsys.dmg.md5`** ---(2) MD5-value text file
# Known issues
Because we assume some specific versions of non-OS-standard Ruby and Python, updating MacPorts, Homebrew, or Anaconda3 may cause build- and link errors.<br>
In such cases, you need to update the dictionary contents of **`build4mac_env.py`**.
# 5. Alternative building options
### 5.1 Python 3.7 from Homebrew, Qt 5.10.1 from Homebrew
# Final comments
No need to say, KLayout is a great tool! <br>
With the object-oriented script language (both Ruby and Python) support, our error-prone jobs can be simplified and speed-up.<br>
Building KLayout from its source code is not difficult. Try it with your favorite environment!
Homebrew's installation of python3 (`brew install python3`) places a `Python.framework` in `/usr/local/opt/python/Frameworks/Python.framework/`, which you can use to build KLayout from. Qt can also be downloaded from brew with `brew install qt`.
```
# Build step
./build4mac.py -p B37 -q Qt5Brew
# build with log
./build4mac.py -p B37 -q Qt5Brew 2>&1 | tee qt5.build.macos-HighSierra-release-version.log
# Deploy step
./build4mac.py -p B37 -q Qt5Brew -y # normal deploy
./build4mac.py -p B37 -q Qt5Brew -y -v 3 2>&1 | tee qt5.pkg.macos-HighSierra-release.log # deploy with debug options
# Packaging step
./makeDMG4mac.py -p qt5.pkg.macos-HighSierra-release -m -q Qt5101
```
#### Known issues
Because we link python to `/usr/local/opt/python/Frameworks/Python.framework/`, updating python from brew might break KLayout if the new version is incompatible. To fix this, it is better to link python directly to `/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework`, but that might complicate release builds, because that assumes users have the exact version of python installed by brew.
[End of File]
[End of File]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 304 KiB

After

Width:  |  Height:  |  Size: 202 KiB

View File

@ -1,116 +0,0 @@
-------------------------------------------------------------------------------------------------
(*
* Template File:
* macbuild/Resources/template-KLayoutDMG.applescript
*
* Actual AppleScrip File to be generated:
* macbuild/Resources/KLayoutDMG.applescript
*
* Description:
* A template AppleScript to make a fancy DMG installer of KLayout
* (http://www.klayout.de/index.php) bundles.
* "makeDMG4mac.py" will read this template and generate the actual AppleScript to execute.
* Values to be found and replaced by "makeDMG4mac.py" are marked by ${KEYWORD}.
*
* The background image was designed using Logoist2 (http://www.syniumsoftware.com/en/logoist)
* and exported to a PNG file of 1000 x 700 pix size.
*-----------------------------------------------------------------------------------------------
* This is a derivative work of Ref. 2) below. Refer to "macbuild/LICENSE" file.
* Ref.
* 1) https://el-tramo.be/guides/fancy-dmg/
* 2) https://github.com/andreyvit/create-dmg.git
*)
-------------------------------------------------------------------------------------------------
on run (volumeName) -- most likely, the volume name is "KLayout"
tell application "Finder"
tell disk (volumeName as string)
-- [1] Open the volume
open
-- [2] Set the key coordinates and windows size
-- The size of given background PNG image is 1000 x 700 pix
-- ORGX = [50] pix
-- ORGY = [100] pix
-- WIN_WIDTH = [1000] pix
-- WIN_HEIGHT = [700] pix
set posMargin to 50
set negMargin to 10
set theTopLeftX to 50
set theTopLeftY to 100
set theWidth to 1000
set theHeight to 700
set theBottomRightX to (theTopLeftX + theWidth + posMargin)
set theBottomRightY to (theTopLeftY + theHeight + posMargin)
-- [3] Set the full path to .DS_Store file
set dotDSStore to "/Volumes/KLayout/.DS_Store"
-- [4] Set global view options
tell container window
set current view to icon view
set toolbar visible to false
set statusbar visible to false
set statusbar visible to false
set bounds to {theTopLeftX, theTopLeftY, theBottomRightX, theBottomRightY}
set position of every item to {theTopLeftX + 150, theTopLeftY + 350}
end tell
-- [5] Set icon view options
set opts to the icon view options of container window
tell opts
set icon size to 80
set text size to 16
set arrangement to not arranged
end tell
-- [6] Set the background PNG image (1000 x 700 pix) file name stored
set background picture of opts to file ".background:KLayoutDMG-Back.png"
-- [7] Set positions of each icon
-- ITEM_1 = klayout.app {960, 140}
-- ITEM_2 = klayout.scripts {610, 140}
-- ITEM_3 = Applications {790, 140}
set position of item "klayout.app" to {960, 140}
set position of item "klayout.scripts" to {610, 140}
set position of item "Applications" to {790, 140}
-- [8] Update the contents of container
close
open
update without registering applications
-- [9] Force save the negatively resized window size
delay 2
tell container window
set statusbar visible to false
set bounds to {theTopLeftX, theTopLeftY, theBottomRightX - negMargin, theBottomRightY - negMargin}
end tell
update without registering applications
end tell
-- [10] Restore back the original window size
delay 2
tell disk (volumeName as string)
tell container window
set statusbar visible to false
set bounds to {theTopLeftX, theTopLeftY, theBottomRightX, theBottomRightY}
end tell
update without registering applications
end tell
-- [11] Wait for some time so that "Finder" can complete writing to .DS_Store file
delay 3
set elapsedTime to 0
set ejected to false
repeat while ejected is false
delay 1
set elapsedTime to elapsedTime + 1
if (do shell script "[ -f " & dotDSStore & " ]; echo $?") = "0" then set ejected to true
end repeat
log "### Elapsed <" & elapsedTime & "> [sec] for writing .DS_Store file."
end tell
end run
--
-- End of file
--

View File

@ -1,36 +0,0 @@
#!/bin/bash
#-------------------------------------------------------------------------------------
# File: KLayoutEditor.sh
#
# Descriptions:
# This is to invoke "klayout" with Qt5 distributed as a binary package for Mac
# in "editor" mode.
#
# You may specify style and other options as you like by setting
# "opt_style" and "opt_others" variable in this script.
#-------------------------------------------------------------------------------------
#---------------------------------------------------------
# With "-n" option, multiple instances can be invoked
#---------------------------------------------------------
myKLayout="open -n -a /Applications/klayout.app --args "
#===================================================
# Pass command line parameters to klayout
# vvvvvvvvvv You may edit the block below vvvvvvvvvv
opt_mode="-e"
opt_style="-style=fusion"
opt_others=""
# ^^^^^^^^^^ You may edit the block above ^^^^^^^^^^
#===================================================
options="$opt_mode $opt_style $opt_others"
targetfiles=$@
echo "### Starting KLayout in Editor mode..."
$myKLayout $options $targetfiles &
exit 0
#-------------------
# End of file
#-------------------

View File

@ -1,36 +0,0 @@
#!/bin/bash
#-------------------------------------------------------------------------------------
# File: KLayoutViewer.sh
#
# Descriptions:
# This is to invoke "klayout" with Qt5 distributed as a binary package for Mac
# in "viewer" mode.
#
# You may specify style and other options as you like by setting
# "opt_style" and "opt_others" variable in this script.
#-------------------------------------------------------------------------------------
#---------------------------------------------------------
# With "-n" option, multiple instances can be invoked
#---------------------------------------------------------
myKLayout="open -n -a /Applications/klayout.app --args "
#===================================================
# Pass command line parameters to klayout
# vvvvvvvvvv You may edit the block below vvvvvvvvvv
opt_mode="-ne"
opt_style="-style=windows"
opt_others=""
# ^^^^^^^^^^ You may edit the block above ^^^^^^^^^^
#===================================================
options="$opt_mode $opt_style $opt_others"
targetfiles=$@
echo "### Starting KLayout in Viewer mode..."
$myKLayout $options $targetfiles &
exit 0
#-------------------
# End of file
#-------------------

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

View File

@ -3,8 +3,10 @@
* Template File:
* macbuild/Resources/template-KLayoutDMG.applescript
*
* Actual AppleScrip File to be generated:
* macbuild/Resources/KLayoutDMG.applescript
* On the runtime, "makeDMG4mac.py" will generate the actual AppleScrip File:
* "macbuild/Resources/KLayoutDMG.applescript"
* from this template. Hence, the generated actual scrip file does not need
* to be version controlled by Git.
*
* Description:
* A template AppleScript to make a fancy DMG installer of KLayout
@ -12,8 +14,8 @@
* "makeDMG4mac.py" will read this template and generate the actual AppleScript to execute.
* Values to be found and replaced by "makeDMG4mac.py" are marked by ${KEYWORD}.
*
* The background image was designed using Logoist2 (http://www.syniumsoftware.com/en/logoist)
* and exported to a PNG file of 1000 x 700 pix size.
* The background image was designed using Logoist3 (http://www.syniumsoftware.com/en/logoist)
* and exported to a PNG file of 1000 x 500 pix size.
*-----------------------------------------------------------------------------------------------
* This is a derivative work of Ref. 2) below. Refer to "macbuild/LICENSE" file.
* Ref.
@ -28,11 +30,11 @@ on run (volumeName) -- most likely, the volume name is "KLayout"
open
-- [2] Set the key coordinates and windows size
-- The size of given background PNG image is 1000 x 700 pix
-- The size of given background PNG image is 1000 x 500 pix
-- ORGX = [50] pix
-- ORGY = [100] pix
-- WIN_WIDTH = [1000] pix
-- WIN_HEIGHT = [700] pix
-- WIN_HEIGHT = [500] pix
set posMargin to 50
set negMargin to 10
set theTopLeftX to ${ORGX}
@ -67,12 +69,10 @@ on run (volumeName) -- most likely, the volume name is "KLayout"
set background picture of opts to file ".background:${BACKGROUND_PNG_FILE}"
-- [7] Set positions of each icon
-- ITEM_1 = klayout.app {960, 140}
-- ITEM_2 = klayout.scripts {610, 140}
-- ITEM_3 = Applications {790, 140}
-- ITEM_1 = klayout.app {860, 165}
-- ITEM_2 = Applications {860, 345}
set position of item "${ITEM_1}" to {${X1}, ${Y1}}
set position of item "${ITEM_2}" to {${X2}, ${Y2}}
set position of item "${ITEM_3}" to {${X3}, ${Y3}}
-- [8] Update the contents of container
close
@ -105,7 +105,7 @@ on run (volumeName) -- most likely, the volume name is "KLayout"
repeat while ejected is false
delay 1
set elapsedTime to elapsedTime + 1
if (do shell script "${CHECK_BASH}") = "0" then set ejected to true
if (do shell script "[ -f " & dotDSStore & " ]; echo $?") = "0" then set ejected to true
end repeat
log "### Elapsed <" & elapsedTime & "> [sec] for writing .DS_Store file."
end tell

View File

@ -5,7 +5,7 @@
# File: "macbuild/build4mac.py"
#
# The top Python script for building KLayout (http://www.klayout.de/index.php)
# version 0.25 or later on different Apple Mac OSX platforms.
# version 0.26.1 or later on different Apple Mac OSX platforms.
#===============================================================================
from __future__ import print_function # to use print() of Python 3 in Python >= 2.7
import sys
@ -42,8 +42,10 @@ def SetGlobals():
global CheckComOnly # True if only for checking the command line parameters to "build.sh"
global DeploymentF # True if fully (including Qt's Frameworks) deploy the binaries for bundles
global DeploymentP # True if partially deploy the binaries excluding Qt's Frameworks
global PackagePrefix # the package prefix: 'ST-', 'LW-', 'HW-', or 'EX-'
global DeployVerbose # -verbose=<0-3> level passed to 'macdeployqt' tool
global Version # KLayout's version
global ModuleSet # (Qt, Ruby, Python)-tuple
# auxiliary variables on platform
global System # 6-tuple from platform.uname()
global Node # - do -
@ -54,37 +56,46 @@ def SetGlobals():
global Bit # machine bit-size
Usage = "\n"
Usage += "--------------------------------------------------------------------------------------------------------\n"
Usage += "---------------------------------------------------------------------------------------------------------\n"
Usage += "<< Usage of 'build4mac.py' >>\n"
Usage += " for building KLayout 0.25 or later on different Apple Mac OSX platforms.\n"
Usage += " for building KLayout 0.26.1 or later on different Apple Mac OSX platforms.\n"
Usage += "\n"
Usage += "$ [python] ./build4mac.py \n"
Usage += " option & argument : descriptions | default value\n"
Usage += " ----------------------------------------------------------------------------------+---------------\n"
Usage += " : * key type names below are case insensitive * | \n"
Usage += " : 'nil' = not to support the script language | \n"
Usage += " : 'Sys' = using the OS standard script language | \n"
Usage += " : Refer to 'macbuild/build4mac_env.py' for details | \n"
Usage += " [-q|--qt <type>] : type=['Qt4MacPorts', 'Qt5MacPorts', 'Qt5Brew'] | qt5macports \n"
Usage += " [-r|--ruby <type>] : type=['nil', 'Sys', 'Src24', 'MP24', 'B25'] | sys \n"
Usage += " [-p|--python <type>] : type=['nil', 'Sys', 'Ana27', 'Ana36', 'MP36', 'B37'] | sys \n"
Usage += " [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled \n"
Usage += " [-m|--make <option>] : option passed to 'make' | -j4 \n"
Usage += " [-d|--debug] : enable debug mode build | disabled \n"
Usage += " [-c|--checkcom] : check command line and exit without building | disabled \n"
Usage += " [-y|--deploy] : deploy executables and dylibs including Qt's Frameworks | disabled \n"
Usage += " [-Y|--DEPLOY] : deploy executables and dylibs for those who built KLayout | disabled \n"
Usage += " : from the source code and use the tools in the same machine | \n"
Usage += " : ! After confirmation of successful build of | \n"
Usage += " : KLayout, rerun this script with BOTH: | \n"
Usage += " : 1) the same options used for building AND | \n"
Usage += " : 2) <-y|--deploy> OR <-Y|--DEPLOY> | \n"
Usage += " : optionally with [-v|--verbose <0-3>] | \n"
Usage += " [-v|--verbose <0-3>] : verbose level of `macdeployqt' (effective with -y only) | 1 \n"
Usage += " : 0 = no output, 1 = error/warning (default), | \n"
Usage += " : 2 = normal, 3 = debug | \n"
Usage += " [-?|--?] : print this usage and exit | disabled \n"
Usage += "--------------------------------------------------------------------------------------------------------\n"
Usage += " option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value\n"
Usage += " --------------------------------------------------------------------------------------+---------------\n"
Usage += " [-q|--qt <type>] : case-insensitive type=['Qt5MacPorts', 'Qt5Brew', 'Qt5Ana3'] | qt5macports \n"
Usage += " : Qt5MacPorts: use Qt5 from MacPorts | \n"
Usage += " : Qt5Brew: use Qt5 from Homebrew | \n"
Usage += " : Qt5Ana3: use Qt5 from Anaconda3 | \n"
Usage += " [-r|--ruby <type>] : case-insensitive type=['nil', 'Sys', 'MP26', 'HB26', 'Ana3'] | sys \n"
Usage += " : nil: don't bind Ruby | \n"
Usage += " : Sys: use OS-bundled Ruby [2.0 - 2.6] depending on OS | \n"
Usage += " : MP26: use Ruby 2.6 from MacPorts | \n"
Usage += " : HB26: use Ruby 2.6 from Homebrew | \n"
Usage += " : Ana3: use Ruby 2.5 from Anaconda3 | \n"
Usage += " [-p|--python <type>] : case-insensitive type=['nil', 'Sys', 'MP37', 'HB37', 'Ana3'] | sys \n"
Usage += " : nil: don't bind Python | \n"
Usage += " : Sys: use OS-bundled Python 2.7 [ElCapitan -- Catalina] | \n"
Usage += " : MP37: use Python 3.7 from MacPorts | \n"
Usage += " : HB37: use Python 3.7 from Homebrew | \n"
Usage += " : Ana3: use Python 3.7 from Anaconda3 | \n"
Usage += " [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled \n"
Usage += " [-m|--make <option>] : option passed to 'make' | '-j4' \n"
Usage += " [-d|--debug] : enable debug mode build | disabled \n"
Usage += " [-c|--checkcom] : check command line and exit without building | disabled \n"
Usage += " [-y|--deploy] : deploy executables and dylibs including Qt's Frameworks | disabled \n"
Usage += " [-Y|--DEPLOY] : deploy executables and dylibs for those who built KLayout | disabled \n"
Usage += " : from the source code and use the tools in the same machine | \n"
Usage += " : ! After confirmation of successful build of 'klayout.app', | \n"
Usage += " : rerun this script with BOTH: | \n"
Usage += " : 1) the same options used for building AND | \n"
Usage += " : 2) <-y|--deploy> OR <-Y|--DEPLOY> | \n"
Usage += " : optionally with [-v|--verbose <0-3>] | \n"
Usage += " [-v|--verbose <0-3>] : verbose level of `macdeployqt' (effective with -y only) | 1 \n"
Usage += " : 0 = no output, 1 = error/warning (default), | \n"
Usage += " : 2 = normal, 3 = debug | \n"
Usage += " [-?|--?] : print this usage and exit | disabled \n"
Usage += "-----------------------------------------------------------------------------------------+---------------\n"
ProjectDir = os.getcwd()
BuildBash = "./build.sh"
@ -94,44 +105,49 @@ def SetGlobals():
print("")
print( "!!! Sorry. Your system <%s> looks like non-Mac" % System, file=sys.stderr )
print(Usage)
exit()
sys.exit(1)
release = int( Release.split(".")[0] ) # take the first of ['14', '5', '0']
if release == 14:
Platform = "Yosemite"
elif release == 15:
Platform = "ElCapitan"
elif release == 16:
Platform = "Sierra"
release = int( Release.split(".")[0] ) # take the first of ['19', '0', '0']
if release == 19:
Platform = "Catalina"
elif release == 18:
Platform = "Mojave"
elif release == 17:
Platform = "HighSierra"
elif release == 16:
Platform = "Sierra"
elif release == 15:
Platform = "ElCapitan"
else:
Platform = ""
print("")
print( "!!! Sorry. Unsupported major OS release <%d>" % release, file=sys.stderr )
print(Usage)
exit()
sys.exit(1)
if not Machine == "x86_64":
print("")
print( "!!! Sorry. Only x86_64 architecture machine is supported but found <%s>" % Machine, file=sys.stderr )
print(Usage)
exit()
sys.exit(1)
# default modules
# Set the default modules
ModuleQt = "Qt5MacPorts"
if Platform == "Yosemite":
ModuleRuby = "RubyYosemite"
ModulePython = "PythonYosemite"
elif Platform == "ElCapitan":
ModuleRuby = "RubyElCapitan"
ModulePython = "PythonElCapitan"
elif Platform == "Sierra":
ModuleRuby = "RubySierra"
ModulePython = "PythonSierra"
if Platform == "Catalina":
ModuleRuby = "RubyCatalina"
ModulePython = "PythonCatalina"
elif Platform == "Mojave":
ModuleRuby = "RubyMojave"
ModulePython = "PythonMojave"
elif Platform == "HighSierra":
ModuleRuby = "RubyHighSierra"
ModulePython = "PythonHighSierra"
elif Platform == "Sierra":
ModuleRuby = "RubySierra"
ModulePython = "PythonSierra"
elif Platform == "ElCapitan":
ModuleRuby = "RubyElCapitan"
ModulePython = "PythonElCapitan"
else:
ModuleRuby = "nil"
ModulePython = "nil"
@ -143,8 +159,10 @@ def SetGlobals():
CheckComOnly = False
DeploymentF = False
DeploymentP = False
PackagePrefix = ""
DeployVerbose = 1
Version = GetKLayoutVersionFrom( "./version.sh" )
ModuleSet = ( 'qt5MP', 'Sys', 'Sys' )
#------------------------------------------------------------------------------
## To get command line parameters
@ -162,20 +180,22 @@ def ParseCommandLineArguments():
global CheckComOnly
global DeploymentF
global DeploymentP
global PackagePrefix
global DeployVerbose
global ModuleSet
p = optparse.OptionParser( usage=Usage )
p.add_option( '-q', '--qt',
dest='type_qt',
help="Qt type=['Qt4MacPorts', 'Qt5MacPorts']" )
help="Qt type=['Qt5MacPorts', 'Qt5Brew', 'Qt5Ana3']" )
p.add_option( '-r', '--ruby',
dest='type_ruby',
help="Ruby type=['nil', 'Sys', 'Src24', 'MP24']" )
help="Ruby type=['nil', 'Sys', 'MP26', 'HB26', 'Ana3']" )
p.add_option( '-p', '--python',
dest='type_python',
help="Python type=['nil', 'Sys', 'Ana27', 'Ana36', 'MP36', 'B37']" )
help="Python type=['nil', 'Sys', 'MP37', 'HB37', 'Ana3']" )
p.add_option( '-n', '--noqtbinding',
action='store_true',
@ -236,103 +256,123 @@ def ParseCommandLineArguments():
opt, args = p.parse_args()
if (opt.checkusage):
print(Usage)
exit()
sys.exit(0)
# Determine Qt type
candidates = ['Qt4MacPorts', 'Qt5MacPorts', 'Qt5Brew']
candidates_upper = [ i.upper() for i in candidates ]
ModuleQt = ""
index = 0
if opt.type_qt.upper() in candidates_upper:
idx = candidates_upper.index(opt.type_qt.upper())
ModuleQt = candidates[idx]
else:
# Determine the Qt type
candidates = dict()
candidates['QT5MACPORTS'] = 'Qt5MacPorts'
candidates['QT5BREW'] = 'Qt5Brew'
candidates['QT5ANA3'] = 'Qt5Ana3'
try:
ModuleQt = candidates[ opt.type_qt.upper() ]
except KeyError:
ModuleQt = ''
pass
if ModuleQt == '':
print("")
print( "!!! Unknown Qt type %s. Candidates: %s" % (opt.type_qt, candidates), file=sys.stderr )
print( "!!! Unknown Qt type <%s>. Case-insensitive candidates: %s" % \
(opt.type_qt, list(candidates.keys())), file=sys.stderr )
print(Usage)
exit(1)
sys.exit(1)
elif ModuleQt == "Qt5MacPorts":
choiceQt5 = 'qt5MP'
elif ModuleQt == "Qt5Brew":
choiceQt5 = 'qt5Brew'
elif ModuleQt == "Qt5Ana3":
choiceQt5 = 'qt5Ana3'
# By default, OS-standard script languages (Ruby and Python) are used
# By default, OS-standard (-bundled) script languages (Ruby and Python) are used
NonOSStdLang = False
# Determine Ruby type
candidates = [ i.upper() for i in ['nil', 'Sys', 'Src24', 'MP24', 'B25'] ]
ModuleRuby = ""
index = 0
for item in candidates:
if opt.type_ruby.upper() == item:
if index == 0:
ModuleRuby = 'nil'
break
elif index == 1:
if Platform == "Yosemite":
ModuleRuby = 'RubyYosemite'
elif Platform == "ElCapitan":
ModuleRuby = 'RubyElCapitan'
elif Platform == "Sierra":
ModuleRuby = 'RubySierra'
elif Platform == "HighSierra":
ModuleRuby = 'RubyHighSierra'
else:
ModuleRuby = ''
break
elif index == 2:
ModuleRuby = 'Ruby24SrcBuild'
NonOSStdLang = True
elif index == 3:
ModuleRuby = 'Ruby24MacPorts'
NonOSStdLang = True
elif index == 4:
ModuleRuby = 'Ruby25Brew'
NonOSStdLang = True
else:
index += 1
if ModuleRuby == "":
# Determine the Ruby type
candidates = dict()
candidates['NIL'] = 'nil'
candidates['SYS'] = 'Sys'
candidates['MP26'] = 'MP26'
candidates['HB26'] = 'HB26'
candidates['ANA3'] = 'Ana3'
try:
choiceRuby = candidates[ opt.type_ruby.upper() ]
except KeyError:
ModuleRuby = ''
pass
else:
ModuleRuby = ''
if choiceRuby == "nil":
ModuleRuby = 'nil'
elif choiceRuby == "Sys":
choiceRuby = "Sys"
if Platform == "Catalina":
ModuleRuby = 'RubyCatalina'
elif Platform == "Mojave":
ModuleRuby = 'RubyMojave'
elif Platform == "HighSierra":
ModuleRuby = 'RubyHighSierra'
elif Platform == "Sierra":
ModuleRuby = 'RubySierra'
elif Platform == "ElCapitan":
ModuleRuby = 'RubyElCapitan'
elif choiceRuby == "MP26":
ModuleRuby = 'Ruby26MacPorts'
NonOSStdLang = True
elif choiceRuby == "HB26":
ModuleRuby = 'Ruby26Brew'
NonOSStdLang = True
elif choiceRuby == "Ana3":
ModuleRuby = 'RubyAnaconda3'
NonOSStdLang = True
if ModuleRuby == '':
print("")
print( "!!! Unknown Ruby type", file=sys.stderr )
print( "!!! Unknown Ruby type <%s>. Case-insensitive candidates: %s" % \
(opt.type_ruby, list(candidates.keys())), file=sys.stderr )
print(Usage)
exit()
sys.exit(1)
# Determine Python type
candidates = [ i.upper() for i in ['nil', 'Sys', 'Ana27', 'Ana36', 'MP36', 'B37'] ]
ModulePython = ""
index = 0
for item in candidates:
if opt.type_python.upper() == item:
if index == 0:
ModulePython = 'nil'
break
elif index == 1:
if Platform == "Yosemite":
ModulePython = 'PythonYosemite'
elif Platform == "ElCapitan":
ModulePython = 'PythonElCapitan'
elif Platform == "Sierra":
ModulePython = 'PythonSierra'
elif Platform == "HighSierra":
ModulePython = 'PythonHighSierra'
else:
ModulePython = ''
break
elif index == 2:
ModulePython = 'Anaconda27'
NonOSStdLang = True
elif index == 3:
ModulePython = 'Anaconda36'
NonOSStdLang = True
elif index == 4:
ModulePython = 'Python36MacPorts'
NonOSStdLang = True
elif index == 5:
ModulePython = 'Python37Brew'
NonOSStdLang = True
else:
index += 1
if ModulePython == "":
# Determine the Python type
candidates = dict()
candidates['NIL'] = 'nil'
candidates['SYS'] = 'Sys'
candidates['MP37'] = 'MP37'
candidates['HB37'] = 'HB37'
candidates['ANA3'] = 'Ana3'
try:
choicePython = candidates[ opt.type_python.upper() ]
except KeyError:
ModulePython = ''
pass
else:
ModulePython = ''
if choicePython == "nil":
ModulePython = 'nil'
elif choicePython == "Sys":
if Platform == "Catalina":
ModulePython = 'PythonCatalina'
elif Platform == "Mojave":
ModulePython = 'PythonMojave'
elif Platform == "HighSierra":
ModulePython = 'PythonHighSierra'
elif Platform == "Sierra":
ModulePython = 'PythonSierra'
elif Platform == "ElCapitan":
ModulePython = 'PythonElCapitan'
elif choicePython == "MP37":
ModulePython = 'Python37MacPorts'
NonOSStdLang = True
elif choicePython == "HB37":
ModulePython = 'Python37Brew'
NonOSStdLang = True
elif choicePython == "Ana3":
ModulePython = 'PythonAnaconda3'
NonOSStdLang = True
if ModulePython == '':
print("")
print( "!!! Unknown Python type", file=sys.stderr )
print( "!!! Unknown Python type <%s>. Case-insensitive candidates: %s" % \
(opt.type_python, list(candidates.keys())), file=sys.stderr )
print(Usage)
exit()
sys.exit(1)
# Set of modules chosen
ModuleSet = ( choiceQt5, choiceRuby, choicePython )
NoQtBindings = opt.no_qt_binding
MakeOptions = opt.make_option
@ -345,14 +385,14 @@ def ParseCommandLineArguments():
print("")
print( "!!! Choose either [-y|--deploy] or [-Y|--DEPLOY]", file=sys.stderr )
print(Usage)
exit()
sys.exit(1)
DeployVerbose = int(opt.deploy_verbose)
if not DeployVerbose in [0, 1, 2, 3]:
print("")
print( "!!! Unsupported verbose level passed to `macdeployqt` tool", file=sys.stderr )
print(Usage)
exit()
sys.exit(1)
if not DeploymentF and not DeploymentP:
target = "%s %s %s" % (Platform, Release, Machine)
@ -360,6 +400,26 @@ def ParseCommandLineArguments():
message = "### You are going to build KLayout\n for <%s>\n with <%s>...\n"
print("")
print( message % (target, modules) )
else:
message = "### You are going to make "
if DeploymentP:
PackagePrefix = "LW-"
message += "a llightweight (LW-) package excluding Qt5, Ruby, and Python..."
elif DeploymentF:
if (ModuleRuby in RubySys) and (ModulePython in PythonSys):
PackagePrefix = "ST-"
message += "a standard (ST-) package including Qt5 and using OS-bundled Ruby and Python..."
elif ModulePython == 'Python37Brew':
PackagePrefix = "HW-"
message += "a heavyweight (HW-) package including Qt5 and Python3.7 from Homebrew..."
else:
PackagePrefix = "EX-"
message += "a package with exceptional (EX-) combinations of different modules..."
print( "" )
print( message )
print( "" )
if CheckComOnly:
sys.exit(0)
#------------------------------------------------------------------------------
## To run the main Bash script "build.sh" with appropriate options
@ -373,11 +433,14 @@ def RunMainBuildBash():
global ModuleQt
global ModuleRuby
global ModulePython
global ModuleSet
global NoQtBindings
global MakeOptions
global DebugMode
global CheckComOnly
global DeploymentF
global DeploymentP
global PackagePrefix
global MacPkgDir # relative path to package directory
global MacBinDir # relative path to binary directory
global MacBuildDir # relative path to build directory
@ -400,59 +463,49 @@ def RunMainBuildBash():
mode = "release"
parameters += " -release"
# (B) Qt4 or Qt5
if ModuleQt == 'Qt4MacPorts':
parameters += " \\\n -qt4"
parameters += " \\\n -qmake %s" % Qt4MacPorts['qmake']
MacPkgDir = "./qt4.pkg.macos-%s-%s" % (Platform, mode)
MacBinDir = "./qt4.bin.macos-%s-%s" % (Platform, mode)
MacBuildDir = "./qt4.build.macos-%s-%s" % (Platform, mode)
MacBuildLog = "./qt4.build.macos-%s-%s.log" % (Platform, mode)
AbsMacPkgDir = "%s/qt4.pkg.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBinDir = "%s/qt4.bin.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBuildDir = "%s/qt4.build.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBuildLog = "%s/qt4.build.macos-%s-%s.log" % (ProjectDir, Platform, mode)
parameters += " \\\n -bin %s" % MacBinDir
parameters += " \\\n -build %s" % MacBuildDir
elif ModuleQt == 'Qt5MacPorts':
# (B) Modules
(qt, ruby, python) = ModuleSet # ( 'qt5MP', 'Sys', 'Sys' )
ruby_python = "R%sP%s" % ( ruby.lower(), python.lower() )
# (C) Target directories and files
MacPkgDir = "./%s%s.pkg.macos-%s-%s-%s" % (PackagePrefix, qt, Platform, mode, ruby_python)
MacBinDir = "./%s.bin.macos-%s-%s-%s" % ( qt, Platform, mode, ruby_python)
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)
AbsMacPkgDir = "%s/%s%s.pkg.macos-%s-%s-%s" % (ProjectDir, PackagePrefix, qt, Platform, mode, ruby_python)
AbsMacBinDir = "%s/%s.bin.macos-%s-%s-%s" % (ProjectDir, qt, Platform, mode, ruby_python)
AbsMacBuildDir = "%s/%s.build.macos-%s-%s-%s" % (ProjectDir, qt, Platform, mode, ruby_python)
AbsMacBuildLog = "%s/%s.build.macos-%s-%s-%s.log" % (ProjectDir, qt, Platform, mode, ruby_python)
# (D) Qt5
if ModuleQt == 'Qt5MacPorts':
parameters += " \\\n -qt5"
parameters += " \\\n -qmake %s" % Qt5MacPorts['qmake']
MacPkgDir = "./qt5.pkg.macos-%s-%s" % (Platform, mode)
MacBinDir = "./qt5.bin.macos-%s-%s" % (Platform, mode)
MacBuildDir = "./qt5.build.macos-%s-%s" % (Platform, mode)
MacBuildLog = "./qt5.build.macos-%s-%s.log" % (Platform, mode)
AbsMacPkgDir = "%s/qt5.pkg.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBinDir = "%s/qt5.bin.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBuildDir = "%s/qt5.build.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBuildLog = "%s/qt5.build.macos-%s-%s.log" % (ProjectDir, Platform, mode)
parameters += " \\\n -bin %s" % MacBinDir
parameters += " \\\n -build %s" % MacBuildDir
elif ModuleQt == 'Qt5Brew':
parameters += " \\\n -qt5"
parameters += " \\\n -qmake %s" % Qt5Brew['qmake']
MacPkgDir = "./qt5.pkg.macos-%s-%s" % (Platform, mode)
MacBinDir = "./qt5.bin.macos-%s-%s" % (Platform, mode)
MacBuildDir = "./qt5.build.macos-%s-%s" % (Platform, mode)
MacBuildLog = "./qt5.build.macos-%s-%s.log" % (Platform, mode)
AbsMacPkgDir = "%s/qt5.pkg.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBinDir = "%s/qt5.bin.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBuildDir = "%s/qt5.build.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBuildLog = "%s/qt5.build.macos-%s-%s.log" % (ProjectDir, Platform, mode)
parameters += " \\\n -bin %s" % MacBinDir
parameters += " \\\n -build %s" % MacBuildDir
parameters += " \\\n -rpath %s" % "@executable_path/../Frameworks"
elif ModuleQt == 'Qt5Ana3':
parameters += " \\\n -qt5"
parameters += " \\\n -qmake %s" % Qt5Ana3['qmake']
parameters += " \\\n -bin %s" % MacBinDir
parameters += " \\\n -build %s" % MacBuildDir
parameters += " \\\n -rpath %s" % "@executable_path/../Frameworks"
# (C) want Qt bindings with Ruby scripts?
# (E) want Qt bindings with Ruby scripts?
if NoQtBindings:
parameters += " \\\n -without-qtbinding"
else:
parameters += " \\\n -with-qtbinding"
# (D) options to `make` tool
# (F) options to `make` tool
if not MakeOptions == "":
parameters += " \\\n -option %s" % MakeOptions
# (E) about Ruby
# (G) about Ruby
if ModuleRuby == "nil":
parameters += " \\\n -noruby"
else:
@ -460,7 +513,7 @@ def RunMainBuildBash():
parameters += " \\\n -rbinc %s" % RubyDictionary[ModuleRuby]['inc']
parameters += " \\\n -rblib %s" % RubyDictionary[ModuleRuby]['lib']
# (F) about Python
# (H) about Python
if ModulePython == "nil":
parameters += " \\\n -nopython"
else:
@ -477,7 +530,7 @@ def RunMainBuildBash():
command += " 2>&1 | tee %s" % MacBuildLog
if CheckComOnly:
print(command)
exit()
sys.exit(0)
#-----------------------------------------------------
# [3] Invoke the main Bash script; takes time:-)
@ -581,10 +634,6 @@ def DeployBinariesForBundle():
# | +-- '*.dylib'
# +-- MacOS/+
# | +-- 'klayout'
# | +-- 'db_plugins'/+
# | +-- '*.dylib'
# | +-- 'lay_plugins'/+
# | +-- '*.dylib'
# +-- Buddy/+
# +-- 'strm2cif'
# +-- 'strm2dxf'
@ -610,10 +659,10 @@ def DeployBinariesForBundle():
#
# Note:
# KLayout's dynamic link library is built as below:
# (1) libklayout_lay.0.25.0.dylib
# (2) libklayout_lay.0.25.dylib -> libklayout_lay.0.25.0.dylib
# (3) libklayout_lay.0.dylib -> libklayout_lay.0.25.0.dylib
# (4) libklayout_lay.dylib -> libklayout_lay.0.25.0.dylib
# (1) libklayout_lay.0.26.1.dylib
# (2) libklayout_lay.0.26.dylib -> libklayout_lay.0.26.1.dylib
# (3) libklayout_lay.0.dylib -> libklayout_lay.0.26.1.dylib
# (4) libklayout_lay.dylib -> libklayout_lay.0.26.1.dylib
# where,
# (1) is an ordinary file with full version number 'major.minor.teeny'
# between "library_name."='libklayout_lay.' and '.dylib'
@ -625,13 +674,13 @@ def DeployBinariesForBundle():
# in the example below.
#
# Example:
# MacBookPro(1)$ otool -L klayout
# MacBookPro2(1)$ otool -L klayout
# klayout:
# :
# :
# libklayout_tl.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_gsi.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_db.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_tl.0.dylib (compatibility version 0.26.0, current version 0.26.1)
# libklayout_gsi.0.dylib (compatibility version 0.26.0, current version 0.26.1)
# libklayout_db.0.dylib (compatibility version 0.26.0, current version 0.26.1)
# :
#-------------------------------------------------------------------------------
os.chdir( targetDirF )
@ -645,7 +694,7 @@ def DeployBinariesForBundle():
# to style (3) and set its mode to 0755 (sanity check).
#-------------------------------------------------------------------
fullName = os.path.basename(item).split('.')
# e.g. [ 'libklayout_lay', '0', '25', '0', 'dylib' ]
# e.g. [ 'libklayout_lay', '0', '26', '1', 'dylib' ]
nameStyle3 = fullName[0] + "." + fullName[1] + ".dylib"
shutil.copy2( item, nameStyle3 )
os.chmod( nameStyle3, 0o0755 )
@ -678,7 +727,7 @@ def DeployBinariesForBundle():
# to style (3) and set its mode to 0755 (sanity check).
#-------------------------------------------------------------------
fullName = os.path.basename(item).split('.')
# e.g. [ 'libklayout_lay', '0', '25', '0', 'dylib' ]
# e.g. [ 'libklayout_lay', '0', '26', '1', 'dylib' ]
nameStyle3 = fullName[0] + "." + fullName[1] + ".dylib"
destPath = os.path.join( targetDirM, piDir, nameStyle3 )
shutil.copy2( item, destPath )
@ -738,6 +787,7 @@ def DeployBinariesForBundle():
shutil.copy2( sourceDir1 + "/klayout", targetDirM )
shutil.copy2( sourceDir2 + "/klayout.icns", targetDirR )
os.chmod( targetDir0 + "/PkgInfo", 0o0644 )
os.chmod( targetDir0 + "/Info.plist", 0o0644 )
os.chmod( targetDirM + "/klayout", 0o0755 )
@ -782,18 +832,22 @@ def DeployBinariesForBundle():
# [8] Deploy Qt Frameworks
#-------------------------------------------------------------
verbose = " -verbose=%d" % DeployVerbose
if ModuleQt == 'Qt4MacPorts':
deploytool = Qt4MacPorts['deploy']
app_bundle = "klayout.app"
options = macdepQtOpt + verbose
elif ModuleQt == 'Qt5MacPorts':
if ModuleQt == 'Qt5MacPorts':
deploytool = Qt5MacPorts['deploy']
app_bundle = "klayout.app"
options = macdepQtOpt + verbose
# To use Qt5 from Homebrew on Catalina...
# in "/usr/local/opt/python/lib/"
# Python.framework -> ../Frameworks/Python.framework/ <=== this symbolic was needed
# pkgconfig/
elif ModuleQt == 'Qt5Brew':
deploytool = Qt5Brew['deploy']
app_bundle = "klayout.app"
options = macdepQtOpt + verbose
elif ModuleQt == 'Qt5Ana3':
deploytool = Qt5Ana3['deploy']
app_bundle = "klayout.app"
options = macdepQtOpt + verbose
# Without the following, the plugin cocoa would not be found properly.
shutil.copy2( sourceDir2 + "/qt.conf", targetDirM )
@ -803,58 +857,70 @@ def DeployBinariesForBundle():
os.chdir(MacPkgDir)
command = "%s %s %s" % ( deploytool, app_bundle, options )
if subprocess.call( command, shell=True ) != 0:
msg = "!!! Failed to deploy applications on OSX !!!"
msg = "!!! Failed to deploy applications on OSX/macOS !!!"
print( msg, file=sys.stderr )
print("")
os.chdir(ProjectDir)
return 1
deploymentPython = True
if deploymentPython and NonOSStdLang:
#-------------------------------------------------------------
# [9] Special deployment of Python3.7 from Homebrew
#-------------------------------------------------------------
deploymentPython37HB = (ModulePython == 'Python37Brew')
if deploymentPython37HB and NonOSStdLang:
from build4mac_util import WalkFrameworkPaths, PerformChanges
bundlePath = AbsMacPkgDir + '/klayout.app'
# bundlePath = os.getcwd() + '/qt5.pkg.macos-HighSierra-release/klayout.app'
bundleExecPathAbs = '%s/Contents/MacOS/' % bundlePath
pythonOriginalFrameworkPath = '/usr/local/opt/python/Frameworks/Python.framework'
pythonFrameworkPath = '%s/Contents/Frameworks/Python.framework' % bundlePath
print(" [8.1] Deploying Python from %s ..." % pythonOriginalFrameworkPath)
print(" [1] Copying Python Framework")
print( "" )
print( " [9] Optional deployment of Python from %s ..." % HBPython37FrameworkPath )
print( " [9.1] Copying Python Framework" )
cmd1 = "rm -rf %s" % pythonFrameworkPath
cmd2 = "rsync -a --safe-links %s/ %s" % (HBPython37FrameworkPath, pythonFrameworkPath)
cmd3 = "mkdir %s/Versions/3.7/lib/python3.7/site-packages/" % pythonFrameworkPath
cmd4 = "cp -RL %s/Versions/3.7/lib/python3.7/site-packages/{pip*,pkg_resources,setuptools*,wheel*} " % \
HBPython37FrameworkPath
cmd4 += "%s/Versions/3.7/lib/python3.7/site-packages/" % pythonFrameworkPath
cmd5 = "rm -rf %s/Versions/3.7/lib/python3.7/test" % pythonFrameworkPath
cmd6 = "rm -rf %s/Versions/3.7/Resources" % pythonFrameworkPath
cmd7 = "rm -rf %s/Versions/3.7/bin" % pythonFrameworkPath
shell_commands = list()
shell_commands.append("rm -rf %s" % pythonFrameworkPath)
shell_commands.append("rsync -a --safe-links %s/ %s" % (pythonOriginalFrameworkPath, pythonFrameworkPath))
shell_commands.append("mkdir %s/Versions/3.7/lib/python3.7/site-packages/" % pythonFrameworkPath)
shell_commands.append("cp -RL %s/Versions/3.7/lib/python3.7/site-packages/{pip*,pkg_resources,setuptools*,wheel*} " % pythonOriginalFrameworkPath +
"%s/Versions/3.7/lib/python3.7/site-packages/" % pythonFrameworkPath)
shell_commands.append("rm -rf %s/Versions/3.7/lib/python3.7/test" % pythonFrameworkPath)
shell_commands.append("rm -rf %s/Versions/3.7/Resources" % pythonFrameworkPath)
shell_commands.append("rm -rf %s/Versions/3.7/bin" % pythonFrameworkPath)
shell_commands.append(cmd1)
shell_commands.append(cmd2)
shell_commands.append(cmd3)
shell_commands.append(cmd4)
shell_commands.append(cmd5)
shell_commands.append(cmd6)
shell_commands.append(cmd7)
for command in shell_commands:
if subprocess.call( command, shell=True ) != 0:
msg = "command failed: %s"
print( msg % command, file=sys.stderr )
exit(1)
sys.exit(1)
shutil.copy2( sourceDir2 + "/start-console.py", targetDirM )
shutil.copy2( sourceDir2 + "/klayout_console", targetDirM )
os.chmod( targetDirM + "/klayout_console", 0o0755 )
print(" [2] Relinking dylib dependencies inside Python.framework")
print(" [2.1] Patching Python Framework")
depdict = WalkFrameworkPaths(pythonFrameworkPath)
print(" [9.2] Relinking dylib dependencies inside Python.framework" )
print(" [9.2.1] Patching Python Framework" )
depdict = WalkFrameworkPaths( pythonFrameworkPath )
appPythonFrameworkPath = '@executable_path/../Frameworks/Python.framework/'
PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs)
PerformChanges(depdict, [(HBPython37FrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs)
print(" [2.2] Patching /usr/local/opt/ libs")
print(" [9.2.2] Patching /usr/local/opt/ libs")
usrLocalPath = '/usr/local/opt/'
appUsrLocalPath = '@executable_path/../Frameworks/'
replacePairs = [(usrLocalPath, appUsrLocalPath, True)]
depdict = WalkFrameworkPaths(pythonFrameworkPath, search_path_filter=r'\t+/usr/local/(opt|Cellar)')
PerformChanges(depdict, replacePairs, bundleExecPathAbs)
print(" [2.3] Patching openssl, gdbm, readline, sqlite, tcl-tk, xz")
print(" [9.2.3] Patching openssl, gdbm, readline, sqlite, tcl-tk, xz")
usrLocalPath = '/usr/local/opt'
appUsrLocalPath = '@executable_path/../Frameworks/'
replacePairs = [(usrLocalPath, appUsrLocalPath, True)]
@ -869,16 +935,16 @@ def DeployBinariesForBundle():
PerformChanges(depdict, replacePairs, bundleExecPathAbs)
print(" [3] Relinking dylib dependencies for klayout")
print(" [9.3] Relinking dylib dependencies for klayout")
klayoutPath = bundleExecPathAbs
depdict = WalkFrameworkPaths(klayoutPath, filter_regex=r'klayout$')
PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs)
PerformChanges(depdict, [(HBPython37FrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs)
libKlayoutPath = bundleExecPathAbs + '../Frameworks'
depdict = WalkFrameworkPaths(libKlayoutPath, filter_regex=r'libklayout')
PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs)
PerformChanges(depdict, [(HBPython37FrameworkPath, appPythonFrameworkPath, False)], bundleExecPathAbs)
print(" [4] Patching site.py, pip/, and distutils/")
print(" [9.4] Patching site.py, pip/, and distutils/")
site_module = "%s/Versions/3.7/lib/python3.7/site.py" % pythonFrameworkPath
with open(site_module, 'r') as site:
buf = site.readlines()
@ -915,117 +981,30 @@ def DeployBinariesForBundle():
continue
file.write(line)
#-------------------------------------------------------------
# [10] Special deployment of Ruby2.6 from Homebrew?
#-------------------------------------------------------------
deploymentRuby26HB = (ModuleRuby == 'Ruby26Brew')
if deploymentRuby26HB and NonOSStdLang:
print( "" )
print( " [10] You have reached optional deployment of Ruby from %s ..." % HBRuby26Path )
print( " [!!!] Sorry, the deployed package will not work properly since deployment of" )
print( " Ruby2.6 from Homebrew is not yet supported." )
print( " Since you have Homebrew development environment, there two options:" )
print( " (1) Retry to make a package with '-Y|--DEPLOY' option." )
print( " This will not deploy any of Qt5, Python, and Ruby from Homebrew." )
print( " Instead, the package will directly use those Frameworks and libraries" )
print( " in your Homebrew environment." )
print( " (2) Rebuild KLayout with '-r|--ruby <nil|Sys>' option depending on your preference." )
print( "" )
else:
print( " [8] Skipped deploying Qt's Frameworks ..." )
print( " [8] Skipped deploying Qt's Frameworks and optional Python/Ruby Frameworks..." )
print( "##### Finished deploying libraries and executables for <klayout.app> #####" )
print("")
os.chdir(ProjectDir)
return 0
#------------------------------------------------------------------------------
## To deploy script bundles that invoke the main bundle (klayout.app) in
# editor mode or viewer mode
#
# @return 0 on success; non-zero on failure
#------------------------------------------------------------------------------
def DeployScriptBundles():
global ProjectDir
global MacPkgDir
global AbsMacPkgDir
print("")
print( "##### Started deploying files for <KLayoutEditor.app> and <KLayoutViewer.app> #####" )
print( " [1] Checking the status of working directory ..." )
#-------------------------------------------------------------
# [1] Check the status of working directory
#-------------------------------------------------------------
os.chdir(ProjectDir)
if not os.path.isdir(MacPkgDir):
print( "!!! Package directory <%s> does not present !!!" % MacPkgDir, file=sys.stderr )
return 1
print( " [2] Creating a new empty directory <%s> for deployment ..." % (MacPkgDir + "/klayout.scripts") )
#-------------------------------------------------------------
# [2] Create a new empty directory for deploying binaries
#-------------------------------------------------------------
os.chdir(MacPkgDir)
scriptDir = "klayout.scripts"
if os.path.isfile(scriptDir):
os.remove(scriptDir)
if os.path.isdir(scriptDir):
shutil.rmtree(scriptDir)
os.mkdir(scriptDir)
print( " [3] Creating the standard directory structure for the script bundles ..." )
#--------------------------------------------------------------------------------------------
# [3] Create the directory skeleton for the two script bundles.
#
# klayout.scripts/+
# +-- KLayoutEditor.app/+
# | +-- Contents/+
# | +-- Info.plist
# | +-- Resources/+
# | | +-- 'klayout-red.icns'
# | +-- MacOS/+
# | +-- 'KLayoutEditor.sh'
# +-- KLayoutViewer.app/+
# +-- Contents/+
# +-- Info.plist
# +-- Resources/+
# | +-- 'klayout-blue.icns'
# +-- MacOS/+
# +-- 'KLayoutViewer.sh'
#--------------------------------------------------------------------------------------------
os.chdir(ProjectDir)
targetDir0E = "%s/%s/KLayoutEditor.app/Contents" % ( AbsMacPkgDir, scriptDir )
targetDir0V = "%s/%s/KLayoutViewer.app/Contents" % ( AbsMacPkgDir, scriptDir )
targetDirME = targetDir0E + "/MacOS"
targetDirMV = targetDir0V + "/MacOS"
targetDirRE = targetDir0E + "/Resources"
targetDirRV = targetDir0V + "/Resources"
os.makedirs(targetDirME)
os.makedirs(targetDirMV)
os.makedirs(targetDirRE)
os.makedirs(targetDirRV)
print( " [4] Copying script files and icon files ..." )
#-------------------------------------------------------------------------------
# [4] Copy different script files icon files
#-------------------------------------------------------------------------------
os.chdir(ProjectDir)
resourceDir = "macbuild/Resources"
shutil.copy2( resourceDir + "/KLayoutEditor.sh", targetDirME )
shutil.copy2( resourceDir + "/KLayoutViewer.sh", targetDirMV )
shutil.copy2( resourceDir + "/klayout-red.icns", targetDirRE )
shutil.copy2( resourceDir + "/klayout-blue.icns", targetDirRV )
os.chmod( targetDirME + "/KLayoutEditor.sh", 0o0755 )
os.chmod( targetDirMV + "/KLayoutViewer.sh", 0o0755 )
os.chmod( targetDirRE + "/klayout-red.icns", 0o0644 )
os.chmod( targetDirRV + "/klayout-blue.icns", 0o0644 )
tmpfileE = ProjectDir + "/macbuild/Resources/Info.plist.template"
keydicE = { 'exe': 'KLayoutEditor.sh', 'icon': 'klayout-red.icns', 'bname': 'klayout', 'ver': Version }
plistE = GenerateInfoPlist( keydicE, tmpfileE )
fileE = open( targetDir0E + "/Info.plist", "w" )
fileE.write(plistE)
fileE.close()
tmpfileV = ProjectDir + "/macbuild/Resources/Info.plist.template"
keydicV = { 'exe': 'KLayoutViewer.sh', 'icon': 'klayout-blue.icns', 'bname': 'klayout', 'ver': Version }
plistV = GenerateInfoPlist( keydicV, tmpfileV )
fileV = open( targetDir0V + "/Info.plist", "w" )
fileV.write(plistV)
fileV.close()
print( "##### Finished deploying files for <KLayoutEditor.app> and <KLayoutViewer.app> #####" )
print("")
os.chdir(ProjectDir)
return 0
#------------------------------------------------------------------------------
## The main function
@ -1033,6 +1012,7 @@ def DeployScriptBundles():
def main():
SetGlobals()
ParseCommandLineArguments()
#----------------------------------------------------------
# [The main build stage]
#----------------------------------------------------------
@ -1042,21 +1022,12 @@ def main():
sys.exit(1)
else:
#----------------------------------------------------------
# [Deployment stage-1]
# [The deployment stage]
# Deployment of dynamic link libraries, executables and
# resources to make the main "klayout.app" bundle
#----------------------------------------------------------
ret1 = DeployBinariesForBundle()
if not ret1 == 0:
sys.exit(1)
#----------------------------------------------------------
# [Deployment stage-2]
# Deployment of wrapper Bash scripts and resources
# to make "KLayoutEditor.app" and "KLayoutViewer.app"
#----------------------------------------------------------
ret2 = DeployScriptBundles()
if not ret2 == 0:
ret = DeployBinariesForBundle()
if not ret == 0:
sys.exit(1)
#===================================================================================

View File

@ -6,10 +6,12 @@
#
# Here are dictionaries of ...
# different modules for building KLayout (http://www.klayout.de/index.php)
# version 0.25 or later on different Apple Mac OSX platforms.
# version 0.26.1 or later on different Apple Mac OSX platforms.
#
# This file is imported by 'build4mac.py' script.
#===============================================================================
import os
MyHome = os.environ['HOME']
#-----------------------------------------------------
# [0] Xcode's tools
@ -21,95 +23,116 @@ XcodeToolChain = { 'nameID': '/usr/bin/install_name_tool -id ',
#-----------------------------------------------------
# [1] Qt
#-----------------------------------------------------
Qts = [ 'Qt4MacPorts', 'Qt5MacPorts', 'Qt5Brew' ]
#-----------------------------------------------------
# Whereabout of different components of Qt4
#-----------------------------------------------------
# Qt4 from MacPorts (https://www.macports.org/)
# [Key Type Name] = 'Qt4MacPorts'
Qt4MacPorts = { 'qmake' : '/opt/local/libexec/qt4/bin/qmake',
'deploy': '/opt/local/libexec/qt4/bin/macdeployqt'
}
Qts = [ 'Qt5MacPorts', 'Qt5Brew', 'Qt5Ana3' ]
#-----------------------------------------------------
# Whereabout of different components of Qt5
#-----------------------------------------------------
# Qt5 from MacPorts (https://www.macports.org/)
# install with 'sudo port install qt5'
# [Key Type Name] = 'Qt5MacPorts'
Qt5MacPorts = { 'qmake' : '/opt/local/libexec/qt5/bin/qmake',
'deploy': '/opt/local/libexec/qt5/bin/macdeployqt'
}
# Qt5 from Homebrew (https://brew.sh/)
# install with 'brew install qt'
# install with 'brew install qt'
# [Key Type Name] = 'Qt5Brew'
Qt5Brew = { 'qmake' : '/usr/local/opt/qt/bin/qmake',
'deploy': '/usr/local/opt/qt/bin/macdeployqt'
}
# Qt5 Custom (https://www1.qt.io/offline-installers/)
# Qt5 bundled with anaconda3 installed under $HOME/opt/anaconda3/
# installed by the standard installation package
# [Key Type Name] = 'Qt5Ana3'
Qt5Ana3 = { 'qmake' : '%s/opt/anaconda3/bin/qmake' % MyHome,
'deploy': '%s/opt/anaconda3/bin/macdeployqt' % MyHome
}
#-----------------------------------------------------
# [2] Ruby
#-----------------------------------------------------
Rubies = [ 'nil', 'RubyYosemite', 'RubyElCapitan', 'RubySierra', 'RubyHighSierra' ]
Rubies += [ 'Ruby24SrcBuild', 'Ruby24MacPorts', 'Ruby24Brew' ]
RubyNil = [ 'nil' ]
RubySys = [ 'RubyElCapitan', 'RubySierra', 'RubyHighSierra', 'RubyMojave', 'RubyCatalina' ]
RubyExt = [ 'Ruby26MacPorts', 'Ruby26Brew', 'RubyAnaconda3' ]
Rubies = RubyNil + RubySys + RubyExt
#-----------------------------------------------------
# Whereabout of different components of Ruby
#-----------------------------------------------------
# Bundled with Yosemite (10.10)
# !!! Yosemite is no longer supported (KLayout 0.26 ~) but remains here to keep the record of
# the directory structure of earlier generations.
# [Key Type Name] = 'Sys'
RubyYosemite = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby' ,
RubyYosemite = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby',
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.dylib'
}
# Bundled with El Capitan (10.11)
# [Key Type Name] = 'Sys'
RubyElCapitan = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby' ,
RubyElCapitan = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby',
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.dylib'
}
# Bundled with Sierra (10.12)
# [Key Type Name] = 'Sys'
RubySierra = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby' ,
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.dylib'
}
# Bundled with High Sierra (10.13)
# [Key Type Name] = 'Sys'
RubyHighSierra = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby' ,
RubySierra = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby',
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/libruby.dylib'
}
# Ruby 2.4 built from source code (https://github.com/ruby): *+*+*+ EXPERIMENTAL *+*+*+
# configured by:
# $ ./configure --prefix=$HOME/Ruby24/ --enable-shared --program-suffix=2.4
# [Key Type Name] = 'Src24'
Ruby24SrcBuild = { 'exe': '$HOME/Ruby24/bin/ruby2.4',
'inc': '$HOME/Ruby24/include/ruby-2.4.0',
'lib': '$HOME/Ruby24/lib/libruby.2.4.dylib'
# Bundled with High Sierra (10.13)
# [Key Type Name] = 'Sys'
RubyHighSierra = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby',
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/libruby.dylib'
}
# Ruby 2.4 from MacPorts (https://www.macports.org/) *+*+*+ EXPERIMENTAL *+*+*+
# [Key Type Name] = 'MP24'
Ruby24MacPorts = { 'exe': '/opt/local/bin/ruby2.4',
'inc': '/opt/local/include/ruby-2.4.0',
'lib': '/opt/local/lib/libruby.2.4.dylib'
# Bundled with Mojave (10.14)
# The missing Ruby header files under "/System/Library/Frameworks/Ruby.framework/" were manually deployed there
# from "Xcode-10.1-beta2" with the corresponding Ruby version.
# [Key Type Name] = 'Sys'
RubyMojave = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby',
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/libruby.dylib'
}
# Ruby 2.5 from Brew *+*+*+ EXPERIMENTAL *+*+*+
# [Key Type Name] = 'Brew25'
Ruby25Brew = { 'exe': '/usr/local/bin/ruby',
'inc': '/usr/local/include/ruby-2.5.0',
'lib': '/usr/local/lib/libruby.2.5.0.dylib'
}
# Bundled with Catalina (10.15)
# !!! Catalina does not allow to hack the "/System" directory; it's READ ONLY even for the super user!
# Hence, we need to refer to the Ruby header file in "Xcode.app" directly.
# [Key Type Name] = 'Sys'
CatalinaSDK = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk"
RubyCatalina = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby',
'inc': '%s/System/Library/Frameworks/Ruby.framework/Headers' % CatalinaSDK,
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.dylib'
}
# Ruby 2.6 from MacPorts (https://www.macports.org/) *+*+*+ EXPERIMENTAL *+*+*+
# install with 'sudo port install ruby26'
# [Key Type Name] = 'MP26'
Ruby26MacPorts = { 'exe': '/opt/local/bin/ruby2.6',
'inc': '/opt/local/include/ruby-2.6.0',
'lib': '/opt/local/lib/libruby.2.6.dylib'
}
# Ruby 2.6 from Homebrew *+*+*+ EXPERIMENTAL *+*+*+
# install with 'brew install ruby'
# [Key Type Name] = 'HB26'
HBRuby26Path = '/usr/local/Cellar/ruby/2.6.5'
Ruby26Brew = { 'exe': '%s/bin/ruby' % HBRuby26Path,
'inc': '%s/include/ruby-2.6.0' % HBRuby26Path,
'lib': '%s/lib/libruby.2.6.dylib' % HBRuby26Path
}
# Ruby 2.5 bundled with anaconda3 installed under $HOME/opt/anaconda3/ *+*+*+ EXPERIMENTAL *+*+*+
# install with 'conda install ruby'
# [Key Type Name] = 'Ana3'
RubyAnaconda3 = { 'exe': '%s/opt/anaconda3/bin/ruby' % MyHome,
'inc': '%s/opt/anaconda3/include/ruby-2.5.0' % MyHome,
'lib': '%s/opt/anaconda3/lib/libruby.2.5.1.dylib' % MyHome
}
# Consolidated dictionary kit for Ruby
RubyDictionary = { 'nil' : None,
@ -117,102 +140,111 @@ RubyDictionary = { 'nil' : None,
'RubyElCapitan' : RubyElCapitan,
'RubySierra' : RubySierra,
'RubyHighSierra': RubyHighSierra,
'Ruby24SrcBuild': Ruby24SrcBuild,
'Ruby24MacPorts': Ruby24MacPorts,
'Ruby25Brew' : Ruby25Brew
'RubyMojave' : RubyMojave,
'RubyCatalina' : RubyCatalina,
'Ruby26MacPorts': Ruby26MacPorts,
'Ruby26Brew' : Ruby26Brew,
'RubyAnaconda3' : RubyAnaconda3
}
#-----------------------------------------------------
# [3] Python
#-----------------------------------------------------
Pythons = [ 'nil', 'PythonYosemite', 'PythonElCapitan', 'PythonSierra', 'PythonHighSierra' ]
Pythons += [ 'Anaconda27', 'Anaconda36', 'Python36MacPorts', 'Python37Brew' ]
PythonNil = [ 'nil' ]
PythonSys = [ 'PythonElCapitan', 'PythonSierra', 'PythonHighSierra', 'PythonMojave', 'PythonCatalina' ]
PythonExt = [ 'Python37MacPorts', 'Python37Brew', 'PythonAnaconda3' ]
Pythons = PythonNil + PythonSys + PythonExt
#-----------------------------------------------------
# Whereabout of different components of Python
#-----------------------------------------------------
# Bundled with Yosemite (10.10)
# !!! Yosemite is no longer supported but remains here to keep the record of the directory structure
# of earlier generations.
# [Key Type Name] = 'Sys'
PythonYosemite = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python' ,
PythonYosemite = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
}
# Bundled with El Capitan (10.11)
# [Key Type Name] = 'Sys'
PythonElCapitan = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python' ,
PythonElCapitan = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
}
# Bundled with Sierra (10.12)
# [Key Type Name] = 'Sys'
PythonSierra = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python' ,
PythonSierra = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
}
# Bundled with High Sierra (10.13)
# [Key Type Name] = 'Sys'
PythonHighSierra= { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python' ,
PythonHighSierra= { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
}
# Using anaconda2 (https://www.anaconda.com/download/#macos) 5.0.1: *+*+*+ EXPERIMENTAL *+*+*+
# If the path to your `conda` command is '$HOME/anaconda2/bin/conda'
# and your Python environment was prepared by: $ conda create -n py27klayout python=2.7
#
# No additional modules are installed in the experiment.
# [Key Type Name] = 'Ana27'
Anaconda27 = { 'exe': '$HOME/anaconda2/envs/py27klayout/bin/python2.7' ,
'inc': '$HOME/anaconda2/envs/py27klayout/include/python2.7',
'lib': '$HOME/anaconda2/envs/py27klayout/lib/libpython2.7.dylib'
# Bundled with Mojave (10.14)
# [Key Type Name] = 'Sys'
PythonMojave = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
}
# Using anaconda2 (https://www.anaconda.com/download/#macos) 5.0.1: *+*+*+ EXPERIMENTAL *+*+*+
# If the path to your `conda` command is '$HOME/anaconda2/bin/conda'
# and your Python environment was prepared by: $ conda create -n py36klayout python=3.6
#
# No additional modules are installed in the experiment.
# [Key Type Name] = 'Ana36'
Anaconda36 = { 'exe': '$HOME/anaconda2/envs/py36klayout/bin/python3.6' ,
'inc': '$HOME/anaconda2/envs/py36klayout/include/python3.6m',
'lib': '$HOME/anaconda2/envs/py36klayout/lib/libpython3.6m.dylib'
# Bundled with Mojave (10.15)
# [Key Type Name] = 'Sys'
PythonCatalina = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python',
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
}
# Python 3.6 from MacPorts (https://www.macports.org/) *+*+*+ EXPERIMENTAL *+*+*+
# [Key Type Name] = 'MP36'
Python36MacPorts= { 'exe': '/opt/local/Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6m' ,
'inc': '/opt/local/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m',
'lib': '/opt/local/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6m.dylib'
# Python 3.7 from MacPorts (https://www.macports.org/) *+*+*+ EXPERIMENTAL *+*+*+
# install with 'sudo port install python37'
# [Key Type Name] = 'MP37'
Python37MacPorts= { 'exe': '/opt/local/Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7m',
'inc': '/opt/local/Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m',
'lib': '/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7m.dylib'
}
# Python 3.7 from Brew *+*+*+ EXPERIMENTAL *+*+*+
# [Key Type Name] = 'pybrew'
Python37Brew= { 'exe': '/usr/local/opt/python/libexec/bin/python' ,
'inc': '/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/Headers',
'lib': '/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/Python'
}
# Python 3.7 from Homebrew *+*+*+ EXPERIMENTAL *+*+*+
# install with 'brew install python'
# [Key Type Name] = 'HB37'
HBPython37FrameworkPath = '/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework'
Python37Brew = { 'exe': '%s/Versions/3.7/bin/python3.7m' % HBPython37FrameworkPath,
'inc': '%s/Versions/3.7/include/python3.7m' % HBPython37FrameworkPath,
'lib': '%s/Versions/3.7/lib/libpython3.7m.dylib' % HBPython37FrameworkPath
}
# Python 3.7 bundled with anaconda3 installed under $HOME/opt/anaconda3/ *+*+*+ EXPERIMENTAL *+*+*+
# installed by the standard installation package
# [Key Type Name] = 'Ana3'
PythonAnaconda3 = { 'exe': '%s/opt/anaconda3/bin/python3.7m' % MyHome,
'inc': '%s/opt/anaconda3/include/python3.7m' % MyHome,
'lib': '%s/opt/anaconda3/lib/libpython3.7m.dylib' % MyHome
}
# Consolidated dictionary kit for Python
PythonDictionary= { 'nil' : None,
'PythonYosemite' : PythonYosemite,
'PythonElCapitan' : PythonElCapitan,
'PythonSierra' : PythonSierra,
'PythonHighSierra': PythonHighSierra,
'Anaconda27' : Anaconda27,
'Anaconda36' : Anaconda36,
'Python36MacPorts': Python36MacPorts,
'PythonMojave' : PythonMojave,
'PythonCatalina' : PythonCatalina,
'Python37MacPorts': Python37MacPorts,
'Python37Brew' : Python37Brew,
'PythonAnaconda3' : PythonAnaconda3
}
#-----------------------------------------------------
# [4] KLayout executables including buddy tools
#-----------------------------------------------------
KLayoutExecs = ['klayout']
KLayoutExecs += ['strm2cif', 'strm2dxf', 'strm2gds', 'strm2gdstxt', 'strm2oas']
KLayoutExecs += ['strm2txt', 'strmclip', 'strmcmp', 'strmrun', 'strmxor']
KLayoutExecs = [ 'klayout' ]
KLayoutExecs += [ 'strm2cif', 'strm2dxf', 'strm2gds', 'strm2gdstxt', 'strm2oas' ]
KLayoutExecs += [ 'strm2txt', 'strmclip', 'strmcmp', 'strmrun', 'strmxor' ]
#----------------
# End of File

View File

@ -6,7 +6,7 @@
#
# Here are utility functions and classes ...
# for building KLayout (http://www.klayout.de/index.php)
# version 0.25 or later on different Apple Mac OSX platforms.
# version 0.26.1 or later on different Apple Mac OSX platforms.
#
# This file is imported by 'build4mac.py' script.
#===============================================================================
@ -32,11 +32,11 @@ from build4mac_env import *
# @param[in] depstr strings that tell dependency such as:
#
# libklayout_edt.0.dylib:
# libklayout_edt.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_tl.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_gsi.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_laybasic.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_db.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_edt.0.dylib (compatibility version 0.26.0, current version 0.26.1)
# libklayout_tl.0.dylib (compatibility version 0.26.0, current version 0.26.1)
# libklayout_gsi.0.dylib (compatibility version 0.26.0, current version 0.26.1)
# libklayout_laybasic.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)
# :
# :
#
@ -57,6 +57,7 @@ def DecomposeLibraryDependency( depstr ):
## To print the contents of a library dependency dictionary
#
# @param[in] depdic dictionary
# @param[in] pathdic path dictionary
# @param[in] namedic dictionary name
#------------------------------------------------------------------------------
def PrintLibraryDependencyDictionary( depdic, pathdic, namedic ):
@ -114,8 +115,6 @@ def SetChangeIdentificationNameOfDyLib( libdic, pathDic ):
# for-lib
return 0
#------------------------------------------------------------------------------
## To set the identification names of KLayout's libraries to an executable
# and make the application aware of the library locations
@ -362,9 +361,9 @@ def GetKLayoutVersionFrom( verfile='version.h' ):
for line in contents:
m = verReg.match(line)
if m:
# print(m.group(0)) # KLAYOUT_VERSION="0.25.1"
# print(m.group(0)) # KLAYOUT_VERSION="0.26.1"
# print(m.group(1)) # KLAYOUT_VERSION="
# print(m.group(2)) # 0.25.1
# print(m.group(2)) # 0.26.1
# print(m.group(3)) # "
version = m.group(2)
return version

View File

@ -4,7 +4,7 @@
#=============================================================================================
# File: "macbuild/makeDMG4mac.py"
#
# Python script for making a DMG file of KLayout (http://www.klayout.de/index.php) bundles.
# Python script for making a DMG file of KLayout (http://www.klayout.de/index.php) bundle.
#
# This is a derivative work of Ref. 2) below. Refer to "macbuild/LICENSE" file.
# Ref.
@ -15,6 +15,7 @@ from __future__ import print_function # to use print() of Python 3 in Python >=
from time import sleep
import sys
import os
import re
import shutil
import glob
import platform
@ -37,11 +38,15 @@ def SetGlobals():
global Usage # string on usage
global GenOSName # generic OS name
global Platform # platform
global PkgDir # the package directory where "klayout.app" and "klayout.scripts" exist
global PkgDir # the package directory where "klayout.app" exists
global OpClean # 'clean' operation
global OpMake # 'make' operation
global DefaultBundleName # the default bundle name 'klayout.app'
global BundleName # application bundle name in the DMG
global DMGSerialNum # the DMG serial number
global PackagePrefix # the package prefix: 'ST-', 'LW-', 'HW-', or 'EX-'
global QtIdentification # Qt identification
global RubyPythonID # Ruby- and Python-identification
global Version # KLayout's version
global OccupiedDS # approx. occupied disc space
global BackgroundPNG # the background PNG image file
@ -63,20 +68,20 @@ def SetGlobals():
Usage = "\n"
Usage += "--------------------------------------------------------------------------------------------------------\n"
Usage += "<< Usage of 'makeDMG4mac.py' >>\n"
Usage += " for making a DMG file of KLayout 0.25 or later on different Apple Mac OSX platforms.\n"
Usage += " for making a DMG file of KLayout 0.26.1 or later on different Apple Mac OSX platforms.\n"
Usage += "\n"
Usage += "$ [python] ./makeDMG4mac.py \n"
Usage += " option & argument : descriptions | default value\n"
Usage += " ----------------------------------------------------------------------------------+---------------\n"
Usage += " <-p|--pkg <dir>> : package directory created by `build4mac.py` with [-y|-Y] | `` \n"
Usage += " : like 'qt5.pkg.macos-HighSierra-release' | \n"
Usage += " : like 'ST-qt5MP.pkg.macos-Catalina-release-RsysPsys' | \n"
Usage += " <-c|--clean> : clean the work directory | disabled \n"
Usage += " <-m|--make> : make a compressed DMG file | disabled \n"
Usage += " : <-c|--clean> and <-m|--make> are mutually exclusive | \n"
Usage += " [-q|--qt <ID>] : ID name of deployed Qt | Qt510Xmp \n"
Usage += " [-b|--bundle <name>] : forcibly use this bundle name in the DMG | '' \n"
Usage += " [-s|--serial <num>] : DMG serial number | 1 \n"
Usage += " [-?|--?] : print this usage and exit | disabled \n"
Usage += "--------------------------------------------------------------------------------------------------------\n"
Usage += "-------------------------------------------------------------------------------------+------------------\n"
ProjectDir = os.getcwd()
(System, Node, Release, Version, Machine, Processor) = platform.uname()
@ -87,55 +92,79 @@ def SetGlobals():
print(Usage)
quit()
release = int( Release.split(".")[0] ) # take the first of ['14', '5', '0']
if release == 14:
GenOSName = "MacOSX"
Platform = "Yosemite"
elif release == 15:
GenOSName = "MacOSX"
Platform = "ElCapitan"
elif release == 16:
release = int( Release.split(".")[0] ) # take the first of ['19', '0', '0']
if release == 19:
GenOSName = "macOS"
Platform = "Sierra"
Platform = "Catalina"
elif release == 18:
GenOSName = "macOS"
Platform = "Mojave"
elif release == 17:
GenOSName = "macOS"
Platform = "HighSierra"
elif release == 16:
Platform = "Sierra"
GenOSName = "macOS"
elif release == 15:
GenOSName = "MacOSX"
Platform = "ElCapitan"
else:
Platform = ""
print("")
print( "!!! Sorry. Unsupported major OS release <%d>" % release, file=sys.stderr )
print(Usage)
quit()
sys.exit(1)
if not Machine == "x86_64":
print("")
print( "!!! Sorry. Only x86_64 architecture machine is supported but found <%s>" % Machine, file=sys.stderr )
print(Usage)
quit()
sys.exit(1)
PkgDir = ""
OpClean = False
OpMake = False
DMGSerialNum = 1
QtIdentification = "Qt510Xmp"
Version = GetKLayoutVersionFrom( "./version.sh" )
OccupiedDS = -1
BackgroundPNG = "KLayoutDMG-Back.png"
VolumeIcons = "KLayoutHDD.icns"
AppleScriptDMG = "macbuild/Resources/KLayoutDMG.applescript"
WorkDMG = "work-KLayout.dmg"
VolumeDMG = "KLayout"
TargetDMG = ""
RootApplications = "/Applications"
PkgDir = ""
OpClean = False
OpMake = False
DefaultBundleName = "klayout.app"
BundleName = ""
DMGSerialNum = 1
PackagePrefix = ""
QtIdentification = ""
RubyPythonID = ""
Version = GetKLayoutVersionFrom( "./version.sh" )
OccupiedDS = -1
BackgroundPNG = "KLayoutDMG-Back.png"
VolumeIcons = "KLayoutHDD.icns"
AppleScriptDMG = "macbuild/Resources/KLayoutDMG.applescript"
WorkDMG = "work-KLayout.dmg"
VolumeDMG = "KLayout"
TargetDMG = ""
RootApplications = "/Applications"
#------------------------------------------------------------------------------
## To check the contents of the package directory
#
# The package directory name should look like:
# * ST-qt5MP.pkg.macos-Catalina-release-RsysPsys --- (1)
# * LW-qt5Ana3.pkg.macos-Catalina-release-Rana3Pana3
# * LW-qt5Brew.pkg.macos-Catalina-release-Rhb26Phb37
# * LW-qt5MP.pkg.macos-Catalina-release-Rmp26Pmp37
#
# Generated DMG will be, for example,
# (1) ---> ST-klayout-0.26.1-macOS-Catalina-1-qt5MP-RsysPsys.dmg
#
# @return on success, positive integer in [MB] that tells approx. occupied disc space;
# on failure, -1
#------------------------------------------------------------------------------
def CheckPkgDirectory():
global DefaultBundleName
global BundleName
global PackagePrefix
global QtIdentification
global RubyPythonID
#-----------------------------------------------------------------------------
# [1] Check the contents of the package directory
#-----------------------------------------------------------------------------
if PkgDir == "":
print( "! Package directory is not specified", file=sys.stderr )
print(Usage)
@ -147,44 +176,44 @@ def CheckPkgDirectory():
return -1
os.chdir(PkgDir)
items = glob.glob( "*" ) # must be ['klayout.app', 'klayout.scripts']
if not len(items) == 2:
print( "! The package directory <%s> must have just <2> directories ['klayout.app', 'klayout.scripts']" % PkgDir, file=sys.stderr )
if not os.path.isdir( DefaultBundleName ):
print( "! The package directory <%s> does not hold <%s> bundle" % (PkgDir, DefaultBundleName), file=sys.stderr )
print( "" )
os.chdir(ProjectDir)
return -1
if not os.path.isdir( "klayout.app" ):
print( "! The package directory <%s> does not hold <klayout.app> bundle" % PkgDir, file=sys.stderr )
print( "" )
os.chdir(ProjectDir)
return -1
if not os.path.isdir( "klayout.scripts" ):
print( "! The package directory <%s> does not hold <klayout.scripts> subdirectory" % PkgDir, file=sys.stderr )
print( "" )
os.chdir(ProjectDir)
return -1
os.chdir( "klayout.scripts" )
if not os.path.isdir( "KLayoutEditor.app" ):
print( "! The package directory <%s> does not hold <KLayoutEditor.app> bundle under 'klayout.scripts/'" % PkgDir, file=sys.stderr )
print( "" )
os.chdir(ProjectDir)
return -1
if not os.path.isdir( "KLayoutViewer.app" ):
print( "! The package directory <%s> does not hold <KLayoutViewer.app> bundle under 'klayout.scripts/'" % PkgDir, file=sys.stderr )
print( "" )
os.chdir(ProjectDir)
return -1
command = "\du -sm %s" % DefaultBundleName
sizeApp = int( os.popen(command).read().strip("\n").split("\t")[0] )
#-----------------------------------------------------------------------------
# [2] Change the application bundle name on demand
#-----------------------------------------------------------------------------
if BundleName == "":
BundleName = DefaultBundleName
else:
os.rename( DefaultBundleName, BundleName )
os.chdir(ProjectDir)
os.chdir(PkgDir)
size1 = int( os.popen( "\du -sm klayout.app" ) .read().strip("\n").split("\t")[0] )
size2 = int( os.popen( "\du -sm klayout.scripts" ).read().strip("\n").split("\t")[0] )
os.chdir(ProjectDir)
return size1+size2
#-----------------------------------------------------------------------------
# [3] Identify (Qt, Ruby, Python)
#
# * ST-qt5MP.pkg.macos-Catalina-release-RsysPsys
# * LW-qt5Ana3.pkg.macos-Catalina-release-Rana3Pana3
# * HW-qt5Brew.pkg.macos-Catalina-release-RsysPhb37
# * EX-qt5MP.pkg.macos-Catalina-release-Rmp26Pmp37
#-----------------------------------------------------------------------------
patQRP = u'(ST|LW|HW|EX)([-])(qt5[0-9A-Za-z]+)([.]pkg[.])([A-Za-z]+[-][A-Za-z]+[-]release[-])([0-9A-Za-z]+)'
regQRP = re.compile(patQRP)
if not regQRP.match(PkgDir):
print( "! Cannot identify (Qt, Ruby, Python) from the package directory name" )
print( "" )
return -1
else:
pkgdirComponents = regQRP.match(PkgDir).groups()
PackagePrefix = pkgdirComponents[0]
QtIdentification = pkgdirComponents[2]
RubyPythonID = pkgdirComponents[5]
return sizeApp
#------------------------------------------------------------------------------
## To get command line parameters
@ -197,8 +226,11 @@ def ParseCommandLineArguments():
global PkgDir
global OpClean
global OpMake
global BundleName
global DMGSerialNum
global PackagePrefix
global QtIdentification
global RubyPythonID
global Version
global OccupiedDS
global TargetDMG
@ -220,9 +252,9 @@ def ParseCommandLineArguments():
default=False,
help="make operation" )
p.add_option( '-q', '--qt',
dest='qt_identification',
help="Qt's ID" )
p.add_option( '-b', '--bundle',
dest='bundle_name',
help="forcibly use this bundle name in the DMG" )
p.add_option( '-s', '--serial',
dest='dmg_serial',
@ -237,31 +269,47 @@ def ParseCommandLineArguments():
p.set_defaults( pkg_dir = "",
operation_clean = False,
operation_make = False,
qt_identification = "Qt510Xmp",
bundle_name = "",
dmg_serial = "1",
checkusage = False )
#-----------------------------------------------------------
# [1] Parse the command line options
#-----------------------------------------------------------
opt, args = p.parse_args()
if (opt.checkusage):
print(Usage)
quit()
PkgDir = opt.pkg_dir
OpClean = opt.operation_clean
OpMake = opt.operation_make
QtIdentification = opt.qt_identification
DMGSerialNum = int(opt.dmg_serial)
TargetDMG = "klayout-%s-%s-%s-%d-%s.dmg" % (Version, GenOSName, Platform, DMGSerialNum, QtIdentification)
PkgDir = opt.pkg_dir
OpClean = opt.operation_clean
OpMake = opt.operation_make
DMGSerialNum = int(opt.dmg_serial)
OccupiedDS = CheckPkgDirectory()
if not OccupiedDS > 0:
quit()
if not opt.bundle_name == "":
base, ext = os.path.splitext( os.path.basename(opt.bundle_name) )
BundleName = base + ".app"
else:
BundleName = ""
if (OpClean and OpMake) or (not OpClean and not OpMake):
print( "! Specify <-c|--clean> OR <-m|--make>", file=sys.stderr )
print(Usage)
quit()
#------------------------------------------------------------------------------------
# [2] Check the PKG directory to set QtIdentification, RubyPythonID, and BundleName
#------------------------------------------------------------------------------------
OccupiedDS = CheckPkgDirectory()
if not 0 < OccupiedDS:
print( "! Failed to check the PKG directory" )
print( "" )
quit()
else:
TargetDMG = "%s-klayout-%s-%s-%s-%d-%s-%s.dmg" \
% (PackagePrefix, Version, GenOSName, Platform, DMGSerialNum, QtIdentification, RubyPythonID)
return
#------------------------------------------------------------------------------
## Make the target DMG file
#
@ -311,12 +359,11 @@ def MakeTargetDMGFile(msg=""):
# Figures below were determined by experiments for best fit
applescript = t.safe_substitute(
ORGX='50', ORGY='100',
WIN_WIDTH='1000', WIN_HEIGHT='700',
WIN_WIDTH='1000', WIN_HEIGHT='500',
FULL_PATH_DS_STORE='/Volumes/%s/.DS_Store' % VolumeDMG,
BACKGROUND_PNG_FILE=BackgroundPNG,
ITEM_1='klayout.app', X1='960', Y1='140',
ITEM_2='klayout.scripts', X2='610', Y2='140',
ITEM_3='Applications', X3='790', Y3='140',
ITEM_1='%s' % BundleName, X1='860', Y1='165',
ITEM_2='Applications', X2='860', Y2='345',
CHECK_BASH='[ -f " & dotDSStore & " ]; echo $?'
)
try:
@ -476,6 +523,14 @@ def MakeTargetDMGFile(msg=""):
print( " generated MD5 checksum file <%s>" % md5TargetDMG )
print( "" )
#-------------------------------------------------------------
# [3] Rename the application bundle if required
#-------------------------------------------------------------
if not BundleName == DefaultBundleName:
dirPresent = "%s/%s" % (PkgDir, BundleName)
dirDefault = "%s/%s" % (PkgDir, DefaultBundleName)
os.rename( dirPresent, dirDefault )
return True
#------------------------------------------------------------------------------

View File

@ -1347,30 +1347,37 @@ private:
return;
}
db::ICplxTrans i1t = i1.complex_trans ();
db::ICplxTrans tt1 = t1 * i1t;
InstanceToInstanceInteraction ii_key;
db::ICplxTrans i1t, i2t;
db::ICplxTrans i2t = i2.complex_trans ();
db::ICplxTrans tt2 = t2 * i2t;
{
i1t = i1element.at_end () ? i1.complex_trans () : i1.complex_trans (*i1element);
db::ICplxTrans tt1 = t1 * i1t;
db::ICplxTrans tt21 = tt1.inverted () * tt2;
InstanceToInstanceInteraction ii_key (i1.cell_index (), i1.cell_inst ().delegate (), i2.cell_index (), i2.cell_inst ().delegate (), tt21);
i2t = i2element.at_end () ? i2.complex_trans () : i2.complex_trans (*i2element);
db::ICplxTrans tt2 = t2 * i2t;
instance_interaction_cache_type::iterator ii = mp_instance_interaction_cache->find (ii_key);
if (ii != mp_instance_interaction_cache->end ()) {
db::ICplxTrans tt21 = tt1.inverted () * tt2;
ii_key = InstanceToInstanceInteraction (i1.cell_index (), (! i1element.at_end () || i1.size () == 1) ? 0 : i1.cell_inst ().delegate (),
i2.cell_index (), (! i2element.at_end () || i2.size () == 1) ? 0 : i2.cell_inst ().delegate (),
tt21);
instance_interaction_cache_type::iterator ii = mp_instance_interaction_cache->find (ii_key);
if (ii != mp_instance_interaction_cache->end ()) {
// use cached interactions
interacting_clusters = ii->second;
for (std::list<std::pair<ClusterInstance, ClusterInstance> >::iterator i = interacting_clusters.begin (); i != interacting_clusters.end (); ++i) {
// translate the property IDs
i->first.set_inst_prop_id (i1.prop_id ());
i->first.transform (i1t);
i->second.set_inst_prop_id (i2.prop_id ());
i->second.transform (i2t);
}
return;
// use cached interactions
interacting_clusters = ii->second;
for (std::list<std::pair<ClusterInstance, ClusterInstance> >::iterator i = interacting_clusters.begin (); i != interacting_clusters.end (); ++i) {
// translate the property IDs
i->first.set_inst_prop_id (i1.prop_id ());
i->first.transform (i1t);
i->second.set_inst_prop_id (i2.prop_id ());
i->second.transform (i2t);
}
return;
}
// array interactions

View File

@ -765,6 +765,10 @@ struct InstanceToInstanceInteraction
: ci1 (_ci1), ci2 (_ci2), array1 (_array1), array2 (_array2), t21 (_t21)
{ }
InstanceToInstanceInteraction ()
: ci1 (0), ci2 (0), array1 (0), array2 (0)
{ }
bool operator== (const InstanceToInstanceInteraction &other) const
{
return ci1 == other.ci1 && ci2 == other.ci2 && t21.equal (other.t21) &&

View File

@ -329,7 +329,7 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
gsi::method ("global_net_name", &db::LayoutToNetlist::global_net_name, gsi::arg ("global_net_id"),
"@brief Gets the global net name for the given global net ID."
) +
gsi::method ("extract_netlist", &db::LayoutToNetlist::extract_netlist, gsi::arg ("join_net_names", std::string ()), gsi::arg ("include_floating_subcircuits", false),
gsi::method ("extract_netlist", &db::LayoutToNetlist::extract_netlist, gsi::arg ("join_net_names", std::string (), "\"\""), gsi::arg ("include_floating_subcircuits", false),
"@brief Runs the netlist extraction\n"
"'join_net_names' is a glob expression for labels. Nets on top level carrying the same label which matches this glob "
"expression will be connected implicitly even if there is no physical connection. This feature is useful to simulate a connection "
@ -359,12 +359,14 @@ Class<db::LayoutToNetlist> decl_dbLayoutToNetlist ("db", "LayoutToNetlist",
"@brief Runs the netlist extraction\n"
"This method runs the netlist extraction like the two-parameter version. In addition to the latter, this method "
"can be given a per-cell net label joining specification in 'join_net_names_per_cell'. The keys of this array "
"are cell names or cell names or cell name match expressions (glob style). The values are lable match expressions.\n"
"are cell names or cell names or cell name match expressions (glob style). The values are label match expressions.\n"
"\n"
"If not an empty string, the 'join_net_names' label match expression is applied to the top cell. For all non-top cells "
"the per-cell label match expression is applied and determines what labels are joined into single nets. "
"As the keys of 'join_net_names_per_cell' are glob expressions, a single cell may fall into more than one category. In this "
"case, the label match pattern are combined. In any case, the 'join_net_names' has priority for the top cell."
"case, the label match pattern are combined. In any case, the 'join_net_names' has priority for the top cell.\n"
"\n"
"This variant of 'extract_netlist' has been introduced in version 0.26.2."
) +
gsi::method_ext ("internal_layout", &l2n_internal_layout,
"@brief Gets the internal layout\n"

View File

@ -1275,3 +1275,9 @@ TEST(118_HierClustersMeanderArrays)
run_hc_test (_this, "meander.gds.gz", "meander_au1.gds");
run_hc_test_with_backannotation (_this, "meander.gds.gz", "meander_au2.gds");
}
TEST(119_HierClustersCombArrays)
{
run_hc_test (_this, "comb.gds", "comb_au1.gds");
run_hc_test_with_backannotation (_this, "comb.gds", "comb_au2.gds");
}

View File

@ -796,7 +796,6 @@ method_arguments (const gsi::MethodBase *method, const gsi::ClassBase *cls_obj,
if (i > 0) {
r += ",";
r += sep;
r += "&nbsp;";
}
r += escape_xml (doc.args [i]);
}
@ -816,7 +815,6 @@ method_arguments (const gsi::MethodBase *method, const gsi::ClassBase *cls_obj,
if (n > 0) {
r += ",";
r += sep;
r += "&nbsp;";
}
r += type_to_s (*a, linked, false);
r += " ";
@ -1312,7 +1310,7 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
if (! attr.empty ()) {
os << "<i>[" << escape_xml (attr) << "] </i>";
}
os << method_return (i->second.first, method_doc, true) << " <b> " << escape_xml (i->first) << " </b> " << method_arguments (i->second.first, cls_obj, method_doc, true, "");
os << method_return (i->second.first, method_doc, true) << " <b> " << escape_xml (i->first) << " </b> " << method_arguments (i->second.first, cls_obj, method_doc, true, " ");
os << "</p>" << std::endl;
os << "<p><b>" << tl::to_string (QObject::tr ("Description")) << "</b>: " << replace_references (escape_xml (method_doc.brief_doc), cls_obj) << "</p>" << std::endl;