Merge branch 'master' of github.com:KLayout/klayout

This commit is contained in:
Matthias Koefferlein 2022-05-12 00:35:41 +02:00
commit 46bab7ce39
9 changed files with 582 additions and 148 deletions

96
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,96 @@
---
name: Build Python Wheels
# https://docs.github.com/en/free-pro-team@latest/actions/guides/building-and-testing-python
on:
pull_request:
push:
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
max-parallel: 12
matrix:
include:
- os: "macos-latest"
cibuild: "*macosx*"
- os: "ubuntu-latest"
cibuild: "*manylinux*"
- os: "ubuntu-latest"
cibuild: "*musllinux*"
steps:
- name: Cancel Workflow Action
uses: styfle/cancel-workflow-action@0.9.1
- uses: actions/checkout@v3
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ github.job }}-${{ matrix.os }}-${{ matrix.cibuild }} # Make cache specific to OS
max-size: "5G"
- name: Install dependencies
run: |
env
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
echo "/usr/lib/ccache:/usr/local/opt/ccache/libexec" >> $GITHUB_PATH
HOST_CCACHE_DIR="$(ccache -k cache_dir)"
mkdir -p $HOST_CCACHE_DIR
- name: Build wheels # check https://cibuildwheel.readthedocs.io/en/stable/setup/#github-actions
uses: pypa/cibuildwheel@v2.5.0
# to supply options, put them in 'env', like:
# env:
# CIBW_SOME_OPTION: value
env:
CIBW_BUILD: ${{ matrix.cibuild }}
- name: Download Cache from Docker (linux only)
if: ${{ runner.os == 'Linux' }}
# hack until https://github.com/pypa/cibuildwheel/issues/1030 is fixed
run: |
env
ccache -s
HOST_CCACHE_DIR="$(ccache -k cache_dir)"
rm -rf $HOST_CCACHE_DIR
mv ./wheelhouse/.ccache $HOST_CCACHE_DIR
ls -la $HOST_CCACHE_DIR
ccache -s
- uses: actions/upload-artifact@v2
with:
path: ./wheelhouse/*.whl
# The following was taken from https://cibuildwheel.readthedocs.io/en/stable/deliver-to-pypi/
make_sdist:
name: Make SDist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # Optional, use if you use setuptools_scm
submodules: true # Optional, use if you have submodules
- name: Build SDist
run: pipx run build --sdist
- uses: actions/upload-artifact@v2
with:
path: dist/*.tar.gz
upload_all:
needs: [build, make_sdist]
runs-on: ubuntu-latest
# Uncomment for real PyPi
if: github.event_name == 'release' && github.event.action == 'published'
steps:
- uses: actions/download-artifact@v2
with:
name: artifact
path: dist
- uses: pypa/gh-action-pypi-publish@v1.4.2
with:
user: __token__
# Test PyPI
# password: ${{ secrets.test_pypi_password }}
# repository_url: https://test.pypi.org/legacy/
# Uncomment for Real Pypi
password: ${{ secrets.pypi_password }}

View File

@ -0,0 +1,50 @@
#!/usr/bin/env bash
set -xe
# manylinux prep
if [[ -f "/etc/centos-release" ]]; then
# sometimes the epel server is down. retry 5 times
for i in $(seq 1 5); do
yum install -y zlib-devel curl-devel expat-devel ccache && s=0 && break || s=$? && sleep 15;
done
[ $s -eq 0 ] || exit $s
if [[ -d "/usr/lib64/ccache" ]]; then
ln -s /usr/bin/ccache /usr/lib64/ccache/c++
ln -s /usr/bin/ccache /usr/lib64/ccache/cc
ln -s /usr/bin/ccache /usr/lib64/ccache/gcc
ln -s /usr/bin/ccache /usr/lib64/ccache/g++
export PATH="/usr/lib64/ccache:$PATH"
elif [[ -d "/usr/lib/ccache" ]]; then
ln -s /usr/bin/ccache /usr/lib/ccache/c++
ln -s /usr/bin/ccache /usr/lib/ccache/cc
ln -s /usr/bin/ccache /usr/lib/ccache/gcc
ln -s /usr/bin/ccache /usr/lib/ccache/g++
export PATH="/usr/lib/ccache:$PATH"
fi
elif [[ -f "/etc/alpine-release" ]]; then
# musllinux prep
# ccache already present
apk add curl-dev expat-dev zlib-dev ccache
export PATH="/usr/lib/ccache/bin:$PATH"
fi
# hack until https://github.com/pypa/cibuildwheel/issues/1030 is fixed
# Place ccache folder in /outputs
HOST_CCACHE_DIR="/host${HOST_CCACHE_DIR:-/home/runner/work/klayout/klayout/.ccache}"
if [ -d $HOST_CCACHE_DIR ]; then
mkdir -p /output
cp -R $HOST_CCACHE_DIR /output/.ccache
fi
ls -la /output/
ccache -o cache_dir="/output/.ccache"
# export CCACHE_DIR="/host/home/runner/work/klayout/klayout/.ccache"
ccache -M 5 G # set cache size to 5 G
# Show ccache stats
echo "Cache stats:"
ccache -s

View File

@ -1,9 +1,9 @@
Relevant KLayout version: 0.27.5<br> Relevant KLayout version: 0.27.9<br>
Author: Kazzz-S<br> Author: Kazzz-S<br>
Last modified: 2021-11-27<br> Last modified: 2022-05-08<br>
# 1. Introduction # 1. Introduction
This directory **`macbuild`** contains different files required for building KLayout (http://www.klayout.de/) version 0.27.5 or later for different 64-bit macOS, including: This directory **`macbuild`** contains different files required for building KLayout (http://www.klayout.de/) version 0.27.9 or later for different 64-bit macOS, including:
* Catalina (10.15.7) : the primary development environment * Catalina (10.15.7) : the primary development environment
* Big Sur (11.x) : experimental; Apple M1 chip is not tested since the author does not own an M1 Mac * Big Sur (11.x) : experimental; Apple M1 chip is not tested since the author does not own an M1 Mac
* Monterey (12.x) : -- ditto -- * Monterey (12.x) : -- ditto --
@ -63,8 +63,9 @@ $ /usr/bin/python --version
Python 2.7.16 Python 2.7.16
``` ```
Big Sur (11.x) and Monterey (12.x) still provide the Python 2.7 binaries to run various legacy applications.<br> Big Sur (11.x) and Monterey (< 12.3) still provide the Python 2.7 binaries to run various legacy applications.<br>
However, the latest Xcode 13.1 does not allow us to link the legacy Python 2.7 library with the newly compiled KLayout binaries.<br> However, the latest Xcode 13.1 does not allow us to link the legacy Python 2.7 library with the newly compiled KLayout binaries.<br>
Moreover, Monterey (12.3.1) finally eliminated the Python 2.7 binaries.<br>
Therefore, Homebrew is adopted as the default environment for Big Sur and Monterey. Therefore, Homebrew is adopted as the default environment for Big Sur and Monterey.
The build script **`build4mac.py`** provides several possible combinations of Qt[6|5], Ruy, and Python modules to accommodate such a slightly complex environment.<br> The build script **`build4mac.py`** provides several possible combinations of Qt[6|5], Ruy, and Python modules to accommodate such a slightly complex environment.<br>
@ -82,7 +83,7 @@ You need to have:
``` ```
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
<< Usage of 'build4mac.py' >> << Usage of 'build4mac.py' >>
for building KLayout 0.27.5 or later on different Apple macOS / Mac OSX platforms. for building KLayout 0.27.9 or later on different Apple macOS / Mac OSX platforms.
$ [python] ./build4mac.py $ [python] ./build4mac.py
option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value
@ -109,6 +110,7 @@ $ [python] ./build4mac.py
: Ana3: use Python 3.8 from Anaconda3 | : Ana3: use Python 3.8 from Anaconda3 |
: HB39: use Python 3.9 from Homebrew | : HB39: use Python 3.9 from Homebrew |
: HBAuto: use the latest Python 3.x auto-detected from Homebrew | : HBAuto: use the latest Python 3.x auto-detected from Homebrew |
[-P|--buildPymod] : build and deploy Pymod (*.whl and *.egg) for LW-*.dmg | disabled
[-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled
[-u|--noqtuitools] : don't include uitools in Qt binding | disabled [-u|--noqtuitools] : don't include uitools in Qt binding | disabled
[-m|--make <option>] : option passed to 'make' | '--jobs=4' [-m|--make <option>] : option passed to 'make' | '--jobs=4'
@ -133,7 +135,7 @@ $ [python] ./build4mac.py
``` ```
--------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------
<< Usage of 'build4mac.py' >> << Usage of 'build4mac.py' >>
for building KLayout 0.27.5 or later on different Apple macOS / Mac OSX platforms. for building KLayout 0.27.9 or later on different Apple macOS / Mac OSX platforms.
$ [python] ./build4mac.py $ [python] ./build4mac.py
option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value
@ -160,6 +162,7 @@ $ [python] ./build4mac.py
: Ana3: use Python 3.8 from Anaconda3 | : Ana3: use Python 3.8 from Anaconda3 |
: HB39: use Python 3.9 from Homebrew | : HB39: use Python 3.9 from Homebrew |
: HBAuto: use the latest Python 3.x auto-detected from Homebrew | : HBAuto: use the latest Python 3.x auto-detected from Homebrew |
[-P|--buildPymod] : build and deploy Pymod (*.whl and *.egg) for LW-*.dmg | disabled
[-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled
[-u|--noqtuitools] : don't include uitools in Qt binding | disabled [-u|--noqtuitools] : don't include uitools in Qt binding | disabled
[-m|--make <option>] : option passed to 'make' | '--jobs=4' [-m|--make <option>] : option passed to 'make' | '--jobs=4'
@ -231,7 +234,9 @@ $ ./build4mac.py -q qt6macports -r mp27 -p mp38
``` ```
2. Confirm successful build (it will take about one hour depending on your machine spec). 2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br> 3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step. The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.<br>
If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Python Module (\*.whl, \*.egg) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
``` ```
$ ./build4mac.py -q qt6macports -r mp27 -p mp38 -Y $ ./build4mac.py -q qt6macports -r mp27 -p mp38 -Y
``` ```
@ -256,7 +261,9 @@ $ ./build4mac.py -q qt6brew -r hb27 -p hb38
``` ```
2. Confirm successful build (it will take about one hour depending on your machine spec). 2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br> 3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step. The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.<br>
If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Python Module (\*.whl, \*.egg) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
``` ```
$ ./build4mac.py -q qt6brew -r hb27 -p hb38 -Y $ ./build4mac.py -q qt6brew -r hb27 -p hb38 -Y
``` ```
@ -280,7 +287,8 @@ $ ./build4mac.py -q qt6brew -r sys -p hb38
``` ```
2. Confirm successful build (it will take about one hour depending on your machine spec). 2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-y" to deploy executables and libraries (including Qt's framework and Python framework) under **`klayout.app`** bundle.<br> 3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-y" to deploy executables and libraries (including Qt's framework and Python framework) under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step. The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.
``` ```
$ ./build4mac.py -q qt6brew -r sys -p hb38 -y $ ./build4mac.py -q qt6brew -r sys -p hb38 -y
``` ```
@ -306,7 +314,9 @@ $ ./build4mac.py -q qt5ana3 -r ana3 -p ana3
``` ```
2. Confirm successful build (it will take about one hour depending on your machine spec). 2. Confirm successful build (it will take about one hour depending on your machine spec).
3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br> 3. Run **`build4mac.py`** again with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
The buddy command-line tools (strm*) will also be deployed in this step. The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.<br>
If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Python Module (\*.whl, \*.egg) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
``` ```
$ ./build4mac.py -q qt5ana3 -r ana3 -p ana3 -Y $ ./build4mac.py -q qt5ana3 -r ana3 -p ana3 -Y
``` ```
@ -341,8 +351,8 @@ $ cd /where/'build.sh'/exists
$ ./makeDMG4mac.py -p ST-qt6Brew.pkg.macos-Catalina-release-RsysPsys -m $ ./makeDMG4mac.py -p ST-qt6Brew.pkg.macos-Catalina-release-RsysPsys -m
``` ```
This command will generate the two files below:<br> This command will generate the two files below:<br>
* **`ST-klayout-0.27.5-macOS-Catalina-1-qt6Brew-RsysPsys.dmg`** ---(1) the main DMG file * **`ST-klayout-0.27.9-macOS-Catalina-1-qt5MP-RsysPsys.dmg`** ---(1) the main DMG file
* **`ST-klayout-0.27.5-macOS-Catalina-1-qt6Brew-RsysPsys.dmg.md5`** ---(2) MD5-value text file * **`ST-klayout-0.27.9-macOS-Catalina-1-qt5MP-RsysPsys.dmg.md5`** ---(2) MD5-value text file
# Known issues # Known issues
Because we assume some specific versions of non-OS-standard Ruby and Python, updating Homebrew, MacPorts, or Anaconda3 may cause build- and link errors.<br> Because we assume some specific versions of non-OS-standard Ruby and Python, updating Homebrew, MacPorts, or Anaconda3 may cause build- and link errors.<br>

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#=============================================================================== #===============================================================================
@ -47,7 +47,7 @@ def GenerateUsage(platform):
usage = "\n" usage = "\n"
usage += "---------------------------------------------------------------------------------------------------------\n" usage += "---------------------------------------------------------------------------------------------------------\n"
usage += "<< Usage of 'build4mac.py' >>\n" usage += "<< Usage of 'build4mac.py' >>\n"
usage += " for building KLayout 0.27.5 or later on different Apple macOS / Mac OSX platforms.\n" usage += " for building KLayout 0.27.9 or later on different Apple macOS / Mac OSX platforms.\n"
usage += "\n" usage += "\n"
usage += "$ [python] ./build4mac.py\n" usage += "$ [python] ./build4mac.py\n"
usage += " option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value\n" usage += " option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value\n"
@ -74,6 +74,7 @@ def GenerateUsage(platform):
usage += " : Ana3: use Python 3.8 from Anaconda3 | \n" usage += " : Ana3: use Python 3.8 from Anaconda3 | \n"
usage += " : HB39: use Python 3.9 from Homebrew | \n" usage += " : HB39: use Python 3.9 from Homebrew | \n"
usage += " : HBAuto: use the latest Python 3.x auto-detected from Homebrew | \n" usage += " : HBAuto: use the latest Python 3.x auto-detected from Homebrew | \n"
usage += " [-P|--buildPymod] : build and deploy Pymod (*.whl and *.egg) for LW-*.dmg | disabled\n"
usage += " [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled\n" usage += " [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled\n"
usage += " [-u|--noqtuitools] : don't include uitools in Qt binding | disabled\n" usage += " [-u|--noqtuitools] : don't include uitools in Qt binding | disabled\n"
usage += " [-m|--make <option>] : option passed to 'make' | '--jobs=4'\n" usage += " [-m|--make <option>] : option passed to 'make' | '--jobs=4'\n"
@ -180,6 +181,7 @@ def Get_Default_Config():
ModuleRuby = "nil" ModuleRuby = "nil"
ModulePython = "nil" ModulePython = "nil"
BuildPymod = False
NonOSStdLang = False NonOSStdLang = False
NoQtBindings = False NoQtBindings = False
NoQtUiTools = False NoQtUiTools = False
@ -200,6 +202,7 @@ def Get_Default_Config():
config['ModuleQt'] = ModuleQt # Qt module to be used config['ModuleQt'] = ModuleQt # Qt module to be used
config['ModuleRuby'] = ModuleRuby # Ruby module to be used config['ModuleRuby'] = ModuleRuby # Ruby module to be used
config['ModulePython'] = ModulePython # Python module to be used config['ModulePython'] = ModulePython # Python module to be used
config['BuildPymod'] = BuildPymod # True to build and deploy "Pymod"
config['NonOSStdLang'] = NonOSStdLang # True if non-OS-standard language is chosen config['NonOSStdLang'] = NonOSStdLang # True if non-OS-standard language is chosen
config['NoQtBindings'] = NoQtBindings # True if not creating Qt bindings for Ruby scripts config['NoQtBindings'] = NoQtBindings # True if not creating Qt bindings for Ruby scripts
config['NoQtUiTools'] = NoQtUiTools # True if not to include QtUiTools in Qt binding config['NoQtUiTools'] = NoQtUiTools # True if not to include QtUiTools in Qt binding
@ -239,6 +242,7 @@ def Parse_CLI_Args(config):
ModuleQt = config['ModuleQt'] ModuleQt = config['ModuleQt']
ModuleRuby = config['ModuleRuby'] ModuleRuby = config['ModuleRuby']
ModulePython = config['ModulePython'] ModulePython = config['ModulePython']
BuildPymod = config['BuildPymod']
NonOSStdLang = config['NonOSStdLang'] NonOSStdLang = config['NonOSStdLang']
NoQtBindings = config['NoQtBindings'] NoQtBindings = config['NoQtBindings']
NoQtUiTools = config['NoQtUiTools'] NoQtUiTools = config['NoQtUiTools']
@ -267,6 +271,12 @@ def Parse_CLI_Args(config):
dest='type_python', dest='type_python',
help="Python type=['nil', 'Sys', 'MP38', 'HB38', 'Ana3', 'HB39', 'HBAuto']" ) help="Python type=['nil', 'Sys', 'MP38', 'HB38', 'Ana3', 'HB39', 'HBAuto']" )
p.add_option( '-P', '--buildPymod',
action='store_true',
dest='build_pymod',
default=False,
help="build and deploy <Pymod> (disabled)" )
p.add_option( '-n', '--noqtbinding', p.add_option( '-n', '--noqtbinding',
action='store_true', action='store_true',
dest='no_qt_binding', dest='no_qt_binding',
@ -321,6 +331,7 @@ def Parse_CLI_Args(config):
p.set_defaults( type_qt = "qt6brew", p.set_defaults( type_qt = "qt6brew",
type_ruby = "hb27", type_ruby = "hb27",
type_python = "hb38", type_python = "hb38",
build_pymod = False,
no_qt_binding = False, no_qt_binding = False,
no_qt_uitools = False, no_qt_uitools = False,
make_option = "--jobs=4", make_option = "--jobs=4",
@ -334,6 +345,7 @@ def Parse_CLI_Args(config):
p.set_defaults( type_qt = "qt6brew", p.set_defaults( type_qt = "qt6brew",
type_ruby = "sys", type_ruby = "sys",
type_python = "sys", type_python = "sys",
build_pymod = False,
no_qt_binding = False, no_qt_binding = False,
no_qt_uitools = False, no_qt_uitools = False,
make_option = "--jobs=4", make_option = "--jobs=4",
@ -487,6 +499,8 @@ def Parse_CLI_Args(config):
# (D) Set of modules chosen # (D) Set of modules chosen
ModuleSet = ( choiceQt65, choiceRuby, choicePython ) ModuleSet = ( choiceQt65, choiceRuby, choicePython )
# (E) Set other parameters
BuildPymod = opt.build_pymod
NoQtBindings = opt.no_qt_binding NoQtBindings = opt.no_qt_binding
NoQtUiTools = opt.no_qt_uitools NoQtUiTools = opt.no_qt_uitools
MakeOptions = opt.make_option MakeOptions = opt.make_option
@ -511,14 +525,21 @@ def Parse_CLI_Args(config):
if not DeploymentF and not DeploymentP: if not DeploymentF and not DeploymentP:
target = "%s %s %s" % (Platform, Release, Machine) target = "%s %s %s" % (Platform, Release, Machine)
modules = "Qt=%s, Ruby=%s, Python=%s" % (ModuleQt, ModuleRuby, ModulePython) modules = "Qt=%s, Ruby=%s, Python=%s" % (ModuleQt, ModuleRuby, ModulePython)
message = "### You are going to build KLayout\n for <%s>\n with <%s>...\n" if BuildPymod:
pymodbuild = "enabled"
else:
pymodbuild = "disabled"
message = "### You are going to build KLayout\n for <%s>\n with <%s>\n with Pymod <%s>...\n"
print("") print("")
print( message % (target, modules) ) print( message % (target, modules, pymodbuild) )
else: else:
message = "### You are going to make " message = "### You are going to make "
if DeploymentP: if DeploymentP:
PackagePrefix = "LW-" PackagePrefix = "LW-"
message += "a lightweight (LW-) package excluding Qt[6|5], Ruby, and Python..." if not BuildPymod:
message += "a lightweight (LW-) package excluding Qt5, Ruby, and Python..."
else:
message += "a lightweight (LW-) package with Pymod excluding Qt5, Ruby, and Python..."
elif DeploymentF: elif DeploymentF:
if (ModuleRuby in RubySys) and (ModulePython in PythonSys): if (ModuleRuby in RubySys) and (ModulePython in PythonSys):
PackagePrefix = "ST-" PackagePrefix = "ST-"
@ -543,6 +564,7 @@ def Parse_CLI_Args(config):
config['ModuleQt'] = ModuleQt config['ModuleQt'] = ModuleQt
config['ModuleRuby'] = ModuleRuby config['ModuleRuby'] = ModuleRuby
config['ModulePython'] = ModulePython config['ModulePython'] = ModulePython
config['BuildPymod'] = BuildPymod
config['NonOSStdLang'] = NonOSStdLang config['NonOSStdLang'] = NonOSStdLang
config['NoQtBindings'] = NoQtBindings config['NoQtBindings'] = NoQtBindings
config['NoQtUiTools'] = NoQtUiTools config['NoQtUiTools'] = NoQtUiTools
@ -553,8 +575,16 @@ def Parse_CLI_Args(config):
config['DeploymentP'] = DeploymentP config['DeploymentP'] = DeploymentP
config['PackagePrefix'] = PackagePrefix config['PackagePrefix'] = PackagePrefix
config['DeployVerbose'] = DeployVerbose config['DeployVerbose'] = DeployVerbose
config['ModuleSet'] = ModuleSet # config['ModuleSet'] = ModuleSet
return config
if CheckComOnly:
pp = pprint.PrettyPrinter( indent=4, width=140 )
parameters = Get_Build_Parameters(config)
Build_pymod(parameters)
pp.pprint(parameters)
sys.exit(0)
else:
return config
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
## To run the main Bash script "build.sh" with appropriate options ## To run the main Bash script "build.sh" with appropriate options
@ -573,6 +603,7 @@ def Get_Build_Parameters(config):
ModuleQt = config['ModuleQt'] ModuleQt = config['ModuleQt']
ModuleRuby = config['ModuleRuby'] ModuleRuby = config['ModuleRuby']
ModulePython = config['ModulePython'] ModulePython = config['ModulePython']
BuildPymod = config['BuildPymod']
ModuleSet = config['ModuleSet'] ModuleSet = config['ModuleSet']
NoQtBindings = config['NoQtBindings'] NoQtBindings = config['NoQtBindings']
NoQtUiTools = config['NoQtUiTools'] NoQtUiTools = config['NoQtUiTools']
@ -640,6 +671,13 @@ def Get_Build_Parameters(config):
# (G) options to `make` tool # (G) options to `make` tool
if not MakeOptions == "": if not MakeOptions == "":
parameters['make_options'] = MakeOptions parameters['make_options'] = MakeOptions
try:
jobopt, number = MakeOptions.split('=') # like '--jobs=4' ?
pnum = int(number)
except Exception:
parameters['num_parallel'] = 4 # default
else:
parameters['num_parallel'] = pnum
# (H) about Ruby # (H) about Ruby
if ModuleRuby != "nil": if ModuleRuby != "nil":
@ -663,8 +701,167 @@ def Get_Build_Parameters(config):
# (J) Extra parameters needed for deployment # (J) Extra parameters needed for deployment
parameters['project_dir'] = ProjectDir parameters['project_dir'] = ProjectDir
# (K) Extra parameters needed for <pymod>
# <pymod> will be built if:
# BuildPymod = True
# Platform = [ 'Monterey', 'BigSur', 'Catalina' ]
# ModuleRuby = [ 'Ruby27MacPorts', 'Ruby27Brew', 'RubyAnaconda3' ]
# ModulePython = [ 'Python38MacPorts', 'Python38Brew',
# 'PythonAnaconda3', 'PythonAutoBrew' ]
parameters['BuildPymod'] = BuildPymod
parameters['Platform'] = Platform
parameters['ModuleRuby'] = ModuleRuby
parameters['ModulePython'] = ModulePython
PymodDistDir = dict()
if Platform in [ 'Monterey', 'BigSur', 'Catalina' ]:
if ModuleRuby in [ 'Ruby27MacPorts', 'Ruby27Brew', 'RubyAnaconda3' ]:
if ModulePython in ['Python38MacPorts']:
PymodDistDir[ModulePython] = 'dist-MP3'
elif ModulePython in [ 'Python38Brew', 'PythonAutoBrew' ]:
PymodDistDir[ModulePython] = 'dist-HB3'
elif ModulePython in [ 'PythonAnaconda3' ]:
PymodDistDir[ModulePython] = 'dist-ana3'
parameters['pymod_dist'] = PymodDistDir
return parameters return parameters
#------------------------------------------------------------------------------
## To run the "setup.py" script with appropriate options for building
# the klayout Python Module "pymod".
#
# @param[in] parameters dictionary containing the build parameters
#
# @return 0 on success; non-zero (1), otherwise
#------------------------------------------------------------------------------
def Build_pymod(parameters):
#---------------------------------------------------------------------------
# [1] <pymod> will be built if:
# BuildPymod = True
# Platform = [ 'Monterey', 'BigSur', 'Catalina' ]
# ModuleRuby = [ 'Ruby27MacPorts', 'Ruby27Brew', 'RubyAnaconda3' ]
# ModulePython = [ 'Python38MacPorts', 'Python38Brew',
# 'PythonAnaconda3', 'PythonAutoBrew' ]
#---------------------------------------------------------------------------
BuildPymod = parameters['BuildPymod']
Platform = parameters['Platform']
ModuleRuby = parameters['ModuleRuby']
ModulePython = parameters['ModulePython']
if not BuildPymod:
return 0
if not Platform in [ 'Monterey', 'BigSur', 'Catalina' ]:
return 0
elif not ModuleRuby in [ 'Ruby27MacPorts', 'Ruby27Brew', 'RubyAnaconda3' ]:
return 0
elif not ModulePython in [ 'Python38MacPorts', 'Python38Brew', 'PythonAnaconda3', 'PythonAutoBrew' ]:
return 0
#--------------------------------------------------------------------
# [2] Get the new directory names (dictionary) for "dist"
#--------------------------------------------------------------------
PymodDistDir = parameters['pymod_dist']
#--------------------------------------------------------------------
# [3] Set different command line parameters for building <pymod>
#--------------------------------------------------------------------
cmd1_args = " setup.py build \\\n"
cmd2_args = " setup.py bdist_wheel \\\n"
cmd3_args = " setup.py bdist_egg \\\n"
cmd4_args = " setup.py clean --all \\\n"
#--------------------------------------------------------------------
# [4] Make the consolidated command lines
#--------------------------------------------------------------------
command1 = "time"
command1 += " \\\n %s \\\n" % parameters['python']
command1 += cmd1_args
command1 += " 2>&1 | tee -a %s; \\\n" % parameters['logfile']
command1 += " test ${PIPESTATUS[0]} -eq 0" # tee always exits with 0
command2 = "time"
command2 += " \\\n %s \\\n" % parameters['python']
command2 += cmd2_args
command2 += " 2>&1 | tee -a %s; \\\n" % parameters['logfile']
command2 += " test ${PIPESTATUS[0]} -eq 0" # tee always exits with 0
command3 = "time"
command3 += " \\\n %s \\\n" % parameters['python']
command3 += cmd3_args
command3 += " 2>&1 | tee -a %s; \\\n" % parameters['logfile']
command3 += " test ${PIPESTATUS[0]} -eq 0" # tee always exits with 0
command4 = "time"
command4 += " \\\n %s \\\n" % parameters['python']
command4 += cmd4_args
command4 += " 2>&1 | tee -a %s; \\\n" % parameters['logfile']
command4 += " test ${PIPESTATUS[0]} -eq 0" # tee always exits with 0
print( "" )
print( "### You are going to build <pymod> with the following four stages." )
print( "<Stage-1>")
print( " ", command1 )
print( "" )
print( "<Stage-2>")
print( " ", command2 )
print( "" )
print( "<Stage-3>")
print( " ", command3 )
print( "" )
print( "<Stage-4>")
print( " ", command4 )
print( "" )
if parameters['check_cmd_only']:
return 0
#-----------------------------------------------------
# [5] Invoke the main Python scripts; takes time:-)
#-----------------------------------------------------
myscript = os.path.basename(__file__)
ret = subprocess.call( command1, shell=True )
if ret != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to build <pymod>" % myscript, file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
ret = subprocess.call( command2, shell=True )
if ret != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to build <pymod-wheel>" % myscript, file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
ret = subprocess.call( command3, shell=True )
if ret != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to build <pymod-egg>" % myscript, file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
ret = subprocess.call( command4, shell=True )
if ret != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to clean <pymod>" % myscript, file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
#-----------------------------------------------------
# [6] Rename the "dist/" directory
#-----------------------------------------------------
os.rename( "dist", PymodDistDir[ModulePython] )
return 0
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
## To run the main Bash script "build.sh" with appropriate options ## To run the main Bash script "build.sh" with appropriate options
# #
@ -673,135 +870,145 @@ def Get_Build_Parameters(config):
# @return 0 on success; non-zero (1), otherwise # @return 0 on success; non-zero (1), otherwise
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
def Run_Build_Command(parameters): def Run_Build_Command(parameters):
#----------------------------------------------------- jump2pymod = False # default=False; set True to jump into pymod-build for debugging
# [1] Set parameters passed to the main Bash script
#-----------------------------------------------------
cmd_args = ""
# (A) debug or release if not jump2pymod:
if parameters["debug_mode"]: #-----------------------------------------------------
mode = "debug" # [1] Set parameters passed to the main Bash script
cmd_args += " -debug" #-----------------------------------------------------
else: cmd_args = ""
mode = "release"
cmd_args += " -release"
# (C) Target directories and files # (A) debug or release
MacBuildDirQAT = parameters['build'] + ".macQAT" if parameters["debug_mode"]:
mode = "debug"
cmd_args += " -debug"
else:
mode = "release"
cmd_args += " -release"
# (D) Qt[6|5] # (C) Target directories and files
# '-qt6' is not yet supported as of 2021-11-27 MacBuildDirQAT = parameters['build'] + ".macQAT"
# Passing '-qt5' with the Qt6 environments looks conflict
#cmd_args += " \\\n -qt5"
cmd_args += " \\\n -qmake %s" % parameters['qmake']
cmd_args += " \\\n -bin %s" % parameters['bin']
cmd_args += " \\\n -build %s" % parameters['build']
cmd_args += " \\\n -rpath %s" % parameters['rpath']
# (E) want Qt bindings with Ruby scripts? # (D) Qt5
if parameters['no_qt_bindings']: cmd_args += " \\\n -qt5"
cmd_args += " \\\n -without-qtbinding" cmd_args += " \\\n -qmake %s" % parameters['qmake']
else: cmd_args += " \\\n -bin %s" % parameters['bin']
cmd_args += " \\\n -with-qtbinding" cmd_args += " \\\n -build %s" % parameters['build']
cmd_args += " \\\n -rpath %s" % parameters['rpath']
# (F) want QtUiTools? # (E) want Qt bindings with Ruby scripts?
if parameters['no_qt_uitools']: if parameters['no_qt_bindings']:
cmd_args += " \\\n -without-qt-uitools" cmd_args += " \\\n -without-qtbinding"
else:
cmd_args += " \\\n -with-qtbinding"
# (G) options to `make` tool # (F) want QtUiTools?
if 'make_options' in parameters: if parameters['no_qt_uitools']:
cmd_args += " \\\n -option %s" % parameters['make_options'] cmd_args += " \\\n -without-qt-uitools"
# (H) about Ruby # (G) options to `make` tool
if 'ruby' in parameters: if 'make_options' in parameters:
cmd_args += " \\\n -ruby %s" % parameters['ruby'] cmd_args += " \\\n -option %s" % parameters['make_options']
cmd_args += " \\\n -rbinc %s" % parameters['rbinc']
cmd_args += " \\\n -rblib %s" % parameters['rblib']
if 'rbinc2' in parameters:
cmd_args += " \\\n -rbinc2 %s" % parameters['rbinc2']
else:
cmd_args += " \\\n -noruby"
# (I) about Python # (H) about Ruby
if 'python' in parameters: if 'ruby' in parameters:
cmd_args += " \\\n -python %s" % parameters['python'] cmd_args += " \\\n -ruby %s" % parameters['ruby']
cmd_args += " \\\n -pyinc %s" % parameters['pyinc'] cmd_args += " \\\n -rbinc %s" % parameters['rbinc']
cmd_args += " \\\n -pylib %s" % parameters['pylib'] cmd_args += " \\\n -rblib %s" % parameters['rblib']
else: if 'rbinc2' in parameters:
cmd_args += " \\\n -nopython" cmd_args += " \\\n -rbinc2 %s" % parameters['rbinc2']
else:
cmd_args += " \\\n -noruby"
#----------------------------------------------------- # (I) about Python
# [2] Make the consolidated command line if 'python' in parameters:
#----------------------------------------------------- cmd_args += " \\\n -python %s" % parameters['python']
command = "time" cmd_args += " \\\n -pyinc %s" % parameters['pyinc']
command += " \\\n %s" % parameters['build_cmd'] cmd_args += " \\\n -pylib %s" % parameters['pylib']
command += cmd_args else:
command += " 2>&1 | tee %s; \\\n" % parameters['logfile'] cmd_args += " \\\n -nopython"
command += "test ${PIPESTATUS[0]} -eq 0" # tee always exits with 0
if parameters['check_cmd_only']: #-----------------------------------------------------
print(command) # [2] Make the consolidated command line
sys.exit(0) #-----------------------------------------------------
command = "time"
command += " \\\n %s" % parameters['build_cmd']
command += cmd_args
command += " 2>&1 | tee %s; \\\n" % parameters['logfile']
command += "test ${PIPESTATUS[0]} -eq 0" # tee always exits with 0
if parameters['check_cmd_only']:
print(command)
sys.exit(0)
#-----------------------------------------------------
# [3] Invoke the main Bash script; takes time:-)
#-----------------------------------------------------
myscript = os.path.basename(__file__)
ret = subprocess.call( command, shell=True )
if ret != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to build KLayout" % myscript, file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
#-----------------------------------------------------
# [3] Invoke the main Bash script; takes time:-)
#-----------------------------------------------------
myscript = os.path.basename(__file__)
ret = subprocess.call( command, shell=True )
if ret != 0:
print( "", file=sys.stderr ) print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr ) print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", file=sys.stderr )
print( "!!! <%s>: failed to build KLayout" % myscript, file=sys.stderr ) print( "### <%s>: successfully built KLayout" % myscript, file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr ) print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", file=sys.stderr )
print( "", file=sys.stderr ) print( "", file=sys.stderr )
return 1
print( "", file=sys.stderr ) #------------------------------------------------------------------------
print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", file=sys.stderr ) # [4] Prepare "*.macQAT/" directory for the QATest.
print( "### <%s>: successfully built KLayout" % myscript, file=sys.stderr ) # Binaries under "*.macQAT/" such as *.dylib will be touched later.
print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", file=sys.stderr ) #------------------------------------------------------------------------
print( "", file=sys.stderr ) print( "### Preparing <%s>" % MacBuildDirQAT )
if os.path.isdir( MacBuildDirQAT ):
shutil.rmtree( MacBuildDirQAT )
os.chdir( parameters['build'] )
tarFile = "../macQATest.tar"
tarCmdC = "tar cf %s ." % tarFile
if subprocess.call( tarCmdC, shell=True ) != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to create <%s>" % (myscript, tarFile), file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
os.chdir( "../" )
os.mkdir( MacBuildDirQAT )
os.chdir( MacBuildDirQAT )
tarCmdX = "tar xf %s" % tarFile
if subprocess.call( tarCmdX, shell=True ) != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to unpack <%s>" % (myscript, tarFile), file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
os.remove( tarFile )
os.chdir( "../" )
shutil.copy2( "macbuild/macQAT.sh", MacBuildDirQAT )
shutil.copy2( "macbuild/macQAT.py", MacBuildDirQAT )
print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", file=sys.stderr )
print( "### <%s>: prepared the initial *.macQAT/" % myscript, file=sys.stderr )
print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", file=sys.stderr )
print( "", file=sys.stderr )
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# [4] Prepare "*.macQAT/" directory for the QATest. # [5] Build <pymod> for some predetermined environments on demand
# Binaries under "*.macQAT/" such as *.dylib will be touched later.
#------------------------------------------------------------------------ #------------------------------------------------------------------------
print( "### Preparing <%s>" % MacBuildDirQAT ) BuildPymod = parameters['BuildPymod']
if os.path.isdir( MacBuildDirQAT ): if BuildPymod:
shutil.rmtree( MacBuildDirQAT ) ret = Build_pymod(parameters)
return ret
os.chdir( parameters['build'] ) else:
tarFile = "../macQATest.tar" return 0
tarCmdC = "tar cf %s ." % tarFile
if subprocess.call( tarCmdC, shell=True ) != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to create <%s>" % (myscript, tarFile), file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
os.chdir( "../" )
os.mkdir( MacBuildDirQAT )
os.chdir( MacBuildDirQAT )
tarCmdX = "tar xf %s" % tarFile
if subprocess.call( tarCmdX, shell=True ) != 0:
print( "", file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "!!! <%s>: failed to unpack <%s>" % (myscript, tarFile), file=sys.stderr )
print( "-------------------------------------------------------------", file=sys.stderr )
print( "", file=sys.stderr )
return 1
os.remove( tarFile )
os.chdir( "../" )
shutil.copy2( "macbuild/macQAT.sh", MacBuildDirQAT )
shutil.copy2( "macbuild/macQAT.py", MacBuildDirQAT )
print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", file=sys.stderr )
print( "### <%s>: prepared the initial *.macQAT/" % myscript, file=sys.stderr )
print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", file=sys.stderr )
print( "", file=sys.stderr )
return 0
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
## For making a bundle (klayout.app), deploy built binaries and libraries ## For making a bundle (klayout.app), deploy built binaries and libraries
@ -827,6 +1034,7 @@ def Deploy_Binaries_For_Bundle(config, parameters):
ModuleRuby = config['ModuleRuby'] ModuleRuby = config['ModuleRuby']
ModulePython = config['ModulePython'] ModulePython = config['ModulePython']
BuildPymod = parameters['BuildPymod']
ProjectDir = parameters['project_dir'] ProjectDir = parameters['project_dir']
MacBinDir = parameters['bin'] MacBinDir = parameters['bin']
MacBuildDir = parameters['build'] MacBuildDir = parameters['build']
@ -837,6 +1045,16 @@ def Deploy_Binaries_For_Bundle(config, parameters):
AbsMacBuildDir = "%s/%s" % (ProjectDir, MacBuildDir) AbsMacBuildDir = "%s/%s" % (ProjectDir, MacBuildDir)
AbsMacBuildLog = "%s/%s" % (ProjectDir, MacBuildLog) AbsMacBuildLog = "%s/%s" % (ProjectDir, MacBuildLog)
if BuildPymod:
try:
PymodDistDir = parameters['pymod_dist']
pymodDistDir = PymodDistDir[ModulePython] # [ 'dist-MP3', 'dist-HB3', 'dist-ana3' ]
except KeyError:
pymodDistDir = ""
else:
pass
else:
pymodDistDir = ""
print("") print("")
print( "##### Started deploying libraries and executables for <klayout.app> #####" ) print( "##### Started deploying libraries and executables for <klayout.app> #####" )
@ -875,7 +1093,7 @@ def Deploy_Binaries_For_Bundle(config, parameters):
print( " [3] Creating the standard directory structure for 'klayout.app' bundle ..." ) print( " [3] Creating the standard directory structure for 'klayout.app' bundle ..." )
#----------------------------------------------------------------- #--------------------------------------------------------------------------------------------------------------
# [3] Create the directory skeleton for "klayout.app" bundle # [3] Create the directory skeleton for "klayout.app" bundle
# and command line buddy tools such as "strm2cif". # and command line buddy tools such as "strm2cif".
# They are stored in the directory structure below. # They are stored in the directory structure below.
@ -895,24 +1113,34 @@ def Deploy_Binaries_For_Bundle(config, parameters):
# | +-- db_plugins/ # | +-- db_plugins/
# | +-- lay_plugins/ # | +-- lay_plugins/
# +-- Buddy/+ # +-- Buddy/+
# +-- 'strm2cif' # | +-- 'strm2cif'
# +-- 'strm2dxf' # | +-- 'strm2dxf'
# : # | :
# +-- 'strmxor' # | +-- 'strmxor'
#----------------------------------------------------------------- # |
# +-- pymod-dist/+ (created only if *.whl and *.egg are available)
# +-- klayout-0.27.8-cp38-cp38-macosx_10_9_x86_64.whl (example)(1)
# +-- klayout-0.27.8-py3.8-macosx-10.9-x86_64.egg (example)(2)
#
# (1) *.whl is recommended to install with 'pip3'
# (2) *.egg is for 'easy_install' users
#--------------------------------------------------------------------------------------------------------------
targetDir0 = "%s/klayout.app/Contents" % AbsMacPkgDir targetDir0 = "%s/klayout.app/Contents" % AbsMacPkgDir
targetDirR = targetDir0 + "/Resources" targetDirR = targetDir0 + "/Resources"
targetDirF = targetDir0 + "/Frameworks" targetDirF = targetDir0 + "/Frameworks"
targetDirM = targetDir0 + "/MacOS" targetDirM = targetDir0 + "/MacOS"
targetDirB = targetDir0 + "/Buddy" targetDirB = targetDir0 + "/Buddy"
targetDirP = targetDir0 + "/pymod-dist"
os.makedirs(targetDirR) os.makedirs(targetDirR)
os.makedirs(targetDirF) os.makedirs(targetDirF)
os.makedirs(targetDirM) os.makedirs(targetDirM)
os.makedirs(targetDirB) os.makedirs(targetDirB)
if BuildPymod and not pymodDistDir == "":
os.makedirs(targetDirP)
print( " [4] Copying KLayout's dynamic link libraries to 'Frameworks' ..." ) print( " [4] Copying KLayout's dynamic link libraries to 'Frameworks' ..." )
#------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------
# [4] Copy KLayout's dynamic link libraries to "Frameworks/" and create # [4] Copy KLayout's dynamic link libraries to "Frameworks/" and create
# the library dependency dictionary. # the library dependency dictionary.
# <<< Do this job in "Frameworks/" >>> # <<< Do this job in "Frameworks/" >>>
@ -942,7 +1170,7 @@ def Deploy_Binaries_For_Bundle(config, parameters):
# libklayout_gsi.0.dylib (compatibility version 0.26.0, current version 0.26.1) # libklayout_gsi.0.dylib (compatibility version 0.26.0, current version 0.26.1)
# libklayout_db.0.dylib (compatibility version 0.26.0, current version 0.26.1) # libklayout_db.0.dylib (compatibility version 0.26.0, current version 0.26.1)
# : # :
#------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------
os.chdir( targetDirF ) os.chdir( targetDirF )
dynamicLinkLibs = glob.glob( os.path.join( AbsMacBinDir, "*.dylib" ) ) dynamicLinkLibs = glob.glob( os.path.join( AbsMacBinDir, "*.dylib" ) )
depDicOrdinary = {} # inter-library dependency dictionary depDicOrdinary = {} # inter-library dependency dictionary
@ -1056,7 +1284,9 @@ def Deploy_Binaries_For_Bundle(config, parameters):
sourceDir1 = sourceDir0 + "/MacOS" sourceDir1 = sourceDir0 + "/MacOS"
sourceDir2 = "%s/macbuild/Resources" % ProjectDir sourceDir2 = "%s/macbuild/Resources" % ProjectDir
sourceDir3 = "%s" % MacBinDir sourceDir3 = "%s" % MacBinDir
sourceDir4 = "%s/pymod" % MacBinDir
# (A) the main components
tmpfileM = ProjectDir + "/macbuild/Resources/Info.plist.template" tmpfileM = ProjectDir + "/macbuild/Resources/Info.plist.template"
keydicM = { 'exe': 'klayout', 'icon': 'klayout.icns', 'bname': 'klayout', 'ver': Version } keydicM = { 'exe': 'klayout', 'icon': 'klayout.icns', 'bname': 'klayout', 'ver': Version }
plistM = GenerateInfoPlist( keydicM, tmpfileM ) plistM = GenerateInfoPlist( keydicM, tmpfileM )
@ -1068,18 +1298,24 @@ def Deploy_Binaries_For_Bundle(config, parameters):
shutil.copy2( sourceDir1 + "/klayout", targetDirM ) shutil.copy2( sourceDir1 + "/klayout", targetDirM )
shutil.copy2( sourceDir2 + "/klayout.icns", targetDirR ) shutil.copy2( sourceDir2 + "/klayout.icns", targetDirR )
os.chmod( targetDir0 + "/PkgInfo", 0o0644 ) os.chmod( targetDir0 + "/PkgInfo", 0o0644 )
os.chmod( targetDir0 + "/Info.plist", 0o0644 ) os.chmod( targetDir0 + "/Info.plist", 0o0644 )
os.chmod( targetDirM + "/klayout", 0o0755 ) os.chmod( targetDirM + "/klayout", 0o0755 )
os.chmod( targetDirR + "/klayout.icns", 0o0644 ) os.chmod( targetDirR + "/klayout.icns", 0o0644 )
# (B) the buddy command line tools
buddies = glob.glob( sourceDir3 + "/strm*" ) buddies = glob.glob( sourceDir3 + "/strm*" )
for item in buddies: for item in buddies:
shutil.copy2( item, targetDirB ) shutil.copy2( item, targetDirB )
buddy = os.path.basename(item) buddy = os.path.basename(item)
os.chmod( targetDirB + "/" + buddy, 0o0755 ) os.chmod( targetDirB + "/" + buddy, 0o0755 )
# (C) the Pymod
if BuildPymod and not pymodDistDir == "":
for item in glob.glob( pymodDistDir + "/*.whl" ):
shutil.copy2( item, targetDirP )
for item in glob.glob( pymodDistDir + "/*.egg" ):
shutil.copy2( item, targetDirP )
print( " [7] Setting and changing the identification names of KLayout's libraries in each executable ..." ) print( " [7] Setting and changing the identification names of KLayout's libraries in each executable ..." )
#------------------------------------------------------------- #-------------------------------------------------------------

View File

@ -88,6 +88,11 @@ def Get_Build_Options( targetDic ):
buildOp["brewA"] = [ '-q', 'Qt5Brew', '-r', 'HB27', '-p', 'HBAuto' ] buildOp["brewA"] = [ '-q', 'Qt5Brew', '-r', 'HB27', '-p', 'HBAuto' ]
elif target == "brewAHW": elif target == "brewAHW":
buildOp["brewAHW"] = [ '-q', 'Qt5Brew', '-r', 'sys', '-p', 'HBAuto' ] buildOp["brewAHW"] = [ '-q', 'Qt5Brew', '-r', 'sys', '-p', 'HBAuto' ]
if WithPymod:
buildOp["ports"] = buildOp["ports"] + ['--buildPymod']
buildOp["brew"] = buildOp["brew"] + ['--buildPymod']
buildOp["ana3"] = buildOp["ana3"] + ['--buildPymod']
return buildOp return buildOp
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@ -167,6 +172,7 @@ def Parse_CommandLine_Arguments():
global Usage # usage global Usage # usage
global Target # target list global Target # target list
global Build # operation flag global Build # operation flag
global WithPymod # operation flag
global QATest # operation flag global QATest # operation flag
global QACheck # operation flag global QACheck # operation flag
global MakeDMG # operation flag global MakeDMG # operation flag
@ -194,6 +200,7 @@ def Parse_CommandLine_Arguments():
Usage += " [--target <list>] : 0='std', 1='ports', 2='brew', 3='brewHW', 4='ana3', | '%s'\n" % targetopt Usage += " [--target <list>] : 0='std', 1='ports', 2='brew', 3='brewHW', 4='ana3', | '%s'\n" % targetopt
Usage += " 5='brewA', 6='brewAHW' | \n" Usage += " 5='brewA', 6='brewAHW' | \n"
Usage += " [--build] : build and deploy | disabled\n" Usage += " [--build] : build and deploy | disabled\n"
Usage += " [--pymod] : build and deploy Pymod, too | disabled\n"
Usage += " [--test] : run the QA Test | disabled\n" Usage += " [--test] : run the QA Test | disabled\n"
Usage += " [--check] : check the QA Test results | disabled\n" Usage += " [--check] : check the QA Test results | disabled\n"
Usage += " [--makedmg|--cleandmg <srlno>] : make or clean DMGs | disabled\n" Usage += " [--makedmg|--cleandmg <srlno>] : make or clean DMGs | disabled\n"
@ -204,12 +211,12 @@ def Parse_CommandLine_Arguments():
Usage += " $ ln -s ./macbuild/nightlyBuild.py . | \n" Usage += " $ ln -s ./macbuild/nightlyBuild.py . | \n"
Usage += " | \n" Usage += " | \n"
Usage += " Regular sequence for using this script: | \n" Usage += " Regular sequence for using this script: | \n"
Usage += " (1) $ ./nightlyBuild.py --build | \n" Usage += " (1) $ ./nightlyBuild.py --build --pymod | \n"
Usage += " (2) (confirm the build results) | \n" Usage += " (2) (confirm the build results) | \n"
Usage += " (3) $ ./nightlyBuild.py --test | \n" Usage += " (3) $ ./nightlyBuild.py --test | \n"
Usage += " (4) $ ./nightlyBuild.py --check (confirm the QA Test results) | \n" Usage += " (4) $ ./nightlyBuild.py --check (confirm the QA Test results) | \n"
Usage += " (5) $ ./nightlyBuild.py --makedmg 1 | \n" Usage += " (5) $ ./nightlyBuild.py --makedmg 1 | \n"
Usage += " (6) $ ./nightlyBuild.py --upload '0.27.4' | \n" Usage += " (6) $ ./nightlyBuild.py --upload '0.27.9' | \n"
Usage += " (7) $ ./nightlyBuild.py --cleandmg 1 | \n" Usage += " (7) $ ./nightlyBuild.py --cleandmg 1 | \n"
Usage += "---------------------------------------------------------------------------+----------------------\n" Usage += "---------------------------------------------------------------------------+----------------------\n"
@ -224,6 +231,12 @@ def Parse_CommandLine_Arguments():
default=False, default=False,
help='build and deploy' ) help='build and deploy' )
p.add_option( '--pymod',
action='store_true',
dest='with_pymod',
default=False,
help='build and deploy Pymod, too ' )
p.add_option( '--test', p.add_option( '--test',
action='store_true', action='store_true',
dest='qa_test', dest='qa_test',
@ -256,6 +269,7 @@ def Parse_CommandLine_Arguments():
p.set_defaults( targets = "%s" % targetopt, p.set_defaults( targets = "%s" % targetopt,
build = False, build = False,
with_pymod = False,
qa_test = False, qa_test = False,
qa_check = False, qa_check = False,
makedmg = "", makedmg = "",
@ -280,12 +294,13 @@ def Parse_CommandLine_Arguments():
if idx in range(0, 7): if idx in range(0, 7):
Target.append( targetDic[idx] ) Target.append( targetDic[idx] )
Build = opt.build Build = opt.build
QATest = opt.qa_test WithPymod = opt.with_pymod
QACheck = opt.qa_check QATest = opt.qa_test
MakeDMG = False QACheck = opt.qa_check
CleanDMG = False MakeDMG = False
Upload = False CleanDMG = False
Upload = False
if not opt.makedmg == "": if not opt.makedmg == "":
MakeDMG = True MakeDMG = True

27
pyproject.toml Normal file
View File

@ -0,0 +1,27 @@
[tool.cibuildwheel]
build-verbosity = "3"
test-command = [
"python {package}/testdata/pymod/import_db.py",
"python {package}/testdata/pymod/import_rdb.py",
"python {package}/testdata/pymod/import_tl.py",
"python {package}/testdata/pymod/import_lib.py",
"python {package}/testdata/pymod/pya_tests.py"
]
# Disable building PyPy wheels on all platforms
skip = "pp*"
[tool.cibuildwheel.linux]
# beware: the before-all script does not persist environment variables!
# No point in defining $PATH or $CCACHE_DIR
before-all = "source {project}/ci-scripts/docker/docker_prepare.sh"
archs = ["auto64"]
# Append a directory to the PATH variable (this is expanded in the build environment)
environment = { PATH="/usr/lib/ccache:/usr/lib64/ccache:/usr/lib/ccache/bin:$PATH" }
before-build = "ccache -s"
# Export a variable to docker
# CCACHE_DIR="/home/runner/work/klayout/klayout/.ccache"
environment-pass = ["HOST_CCACHE_DIR"]
[tool.cibuildwheel.macos]
# Don't repair macOS wheels
repair-wheel-command = ""