Merge branch 'master' into macos_retina

This commit is contained in:
Thomas Ferreira de Lima 2018-03-19 23:21:06 -04:00
commit 1ed12d4715
26 changed files with 382 additions and 214 deletions

View File

@ -1,6 +1,6 @@
klayout is packaged by Peter C.S. Scholtens <peter.scholtens@xs4all.nl>
and Matthias Köfferlein <matthias@koefferlein.de>
and was obtained from https://www.klayout.org/downloads/source/klayout-0.25.1.tar.gz
and was obtained from https://www.klayout.org/downloads/source/klayout-0.25.2.tar.gz
Authors:
Matthias Köfferlein

View File

@ -1,3 +1,18 @@
0.25.2 (2018-03-17):
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/90
DRC: "extended" was not working as expected with "joined = true"
* Bugfix: https://github.com/klayoutmatthias/klayout/issues/89
Display issue on MacOS fixed
* Enhancement: https://github.com/klayoutmatthias/klayout/issues/85
IDE debugger: files can be excluded from showing exceptions when
they are thrown. To exclude a file press the new "Ignore" button
when the debugger tells you an exception has been generated.
To re-able exception reporting, clear the list of the files
in the IDE settings ("Debugging" tab)
The macro IDE settings can now be edited in the File/Setup
dialog.
* Enhancements: build enhancements for MacOS
0.25.1 (2018-02-23):
* Enhancements: build compatibility with MacOS and Qt 5.9.
Qt 4.6 supported now as well with one restriction:

View File

@ -1,3 +1,10 @@
klayout (0.25.2-1) unstable; urgency=low
* New features and bugfixes
- See changelog
-- Matthias Köfferlein <matthias@koefferlein.de> Sun, 18 Mar 2018 18:51:19 +0100
klayout (0.25.1-1) unstable; urgency=low
* New features and bugfixes

1
build4mac.py Symbolic link
View File

@ -0,0 +1 @@
macbuild/build4mac.py

View File

@ -1,37 +1,42 @@
Relevant KLayout version: 0.25.1
Relevant KLayout version: 0.25.2
# 1. Introduction
This directory "macbuild" contains different files required for building KLayout (http://www.klayout.de/) version 0.25 or later for different Mac OSXs including:
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)
* El Capitan (10.11)
* Sierra (10.12)
* High Sierra (10.13)
By default, Qt framework is "Qt5" from Mac Ports (https://www.macports.org/) which is usually located under:
By default, Qt framework is "Qt5" from MacPorts (https://www.macports.org/) which is usually located under:
```
/opt/local/libexec/qt5/
```
Alternatively, you can use "Qt5" from Homebrew (https://brew.sh/) which is usually located under:
```
/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.
### IMPORTANT
```
* Please DO NOT USE "Qt 5.10.0" which is problematic in showing your design in the main canvas.
* Please USE "Qt 5.9.x" instead (5.9.3 is recommended).
* Building with Qt4 will lead to some compile errors.
* Please DO NOT USE "Qt 4.x" which is problematic in compilation.
```
Also by default, supported script languages, i.e, Ruby and Python, are those standard ones bundled with the OS.
# 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.
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.6 provided by Mac Ports is usable.
Please try this (refer to 3B below) if you feel it's useful.
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.6 provided by MacPorts or Homebrew is usable.
Please try this (refer to 3B below or Section #5) if you feel it's useful.
# 3. Use-cases
### 3A. Debug build using the OS-standard script languages
1. Make a symbolic link from the parent directory (where 'build.sh' exists) to
'build4mac.py', that is,
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
```
@ -40,15 +45,15 @@ Please try this (refer to 3B below) if you feel it's useful.
$ cd /where/'build.sh'/exists
$ ./build4mac.py -d
```
3. Confirm successful build.
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.
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.
### 3B. Release build using the non-OS-standard Ruby 2.4 and Python 3.6 both from MacPorts
1. Make a symbolic link from the parent directory (where 'build.sh' exists) to 'build4mac.py', that is,
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
```
@ -57,8 +62,8 @@ build4mac.py -> macbuild/build4mac.py
$ cd /where/'build.sh'/exists
$ ./build4mac.py -r mp24 -p mp36
```
3. Confirm successful build.
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.
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.
```
$ ./build4mac.py -r mp24 -p mp36 -Y
```
@ -73,7 +78,7 @@ That is, paths to other modules (Ruby, Python, and Qt5 Frameworks) remain unchan
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)
1. Make a symbolic link 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
```
@ -83,26 +88,27 @@ $ cd /where/'build.sh'/exists
$ ./makeDMG4mac.py -p qt5.pkg.macos-HighSierra-release -m
```
By: Kazzz (January 16, 2018)
# 5. Alternative building options
### 5.1 Python 3.6 from brew, Qt 5.9.4 from offline installer
### 5.1 Python 3.6 from Homebrew, Qt 5.10.1 from Homebrew
Homebrew's installation of python3 places a `Python.framework` in `/usr/local/opt/python/Frameworks/Python.framework/`, which you can use to build KLayout from. Qt can be downloaded for [offline installation](https://www1.qt.io/offline-installers/). You can place it in your home folder: e.g. `/home/username/Qt5.9.4/`. Given these two dependencies, you can successfully compile KLayout with the following commands:
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 B36 -q Qt5Custom
./build4mac.py -p B36 -q Qt5Brew
# Deploy step
./build4mac.py -p B36 -q Qt5Custom -y # normal deploy
./build4mac.py -p B36 -q Qt5Custom -y -v 3 2>&1 | tee qt5.pkg.macos-HighSierra-release.log # deploy with debug options
./build4mac.py -p B36 -q Qt5Brew -y # normal deploy
./build4mac.py -p B36 -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 Qt594
./makeDMG4mac.py -p qt5.pkg.macos-HighSierra-release -m -q Qt5101
```
PS: If you get a syntax error in one of ruby's libraries because it is not compatible with C++11, do not fret. You only have to change one offending file.
#### 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]

View File

@ -1,80 +0,0 @@
<< Draft Version 0.004>>
Relevant KLayout version: 0.25.1
1. Introduction:
This directory "macbuild" contains different files required for building KLayout (http://www.klayout.de/)
version 0.25 or later for different Mac OSXs including:
* Yosemite (10.10)
* El Capitan (10.11)
* Sierra (10.12)
* High Sierra (10.13)
By default, Qt framework is "Qt5" from Mac Ports (https://www.macports.org/) which is
usually located under:
/opt/local/libexec/qt5/
<IMPORTANT>:
* Please DO NOT USE "5.10.0" which is problematic in showing your design in the main canvas.
* Please USE "5.9.x" instead (5.9.3 is recommended).
* Building with Qt4 will lead to some compile errors.
Also by default, supported script languages, i.e, Ruby and Python, are those
standard ones bundled with the OS.
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.
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.6 provided by Mac Ports is usable.
Please try this (refer to 3B below) if you feel it's useful.
3. Use-cases:
3A. Debug build using the OS-standard script languages:
(1) Make a symbolic link 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.
(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.
$ ./build4mac.py -d -y
(5) Copy/move generated bundles ("klayout.app" and "klayout.scripts/") to your
"/Applications" directory for installation.
3B. Release build using the non-OS-standard Ruby 2.4 and Python 3.6 both from MacPorts:
(1) Make a symbolic link 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:
$ cd /where/'build.sh'/exists
$ ./build4mac.py -r mp24 -p mp36
(3) Confirm successful build.
(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.
$ ./build4mac.py -r mp24 -p mp36 -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).
(5) Copy/move generated bundles ("klayout.app" and "klayout.scripts/") to your
"/Applications" directory for installation.
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)
(1) Make a symbolic link 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,
$ cd /where/'build.sh'/exists
$ ./makeDMG4mac.py -p qt5.pkg.macos-HighSierra-release -m
By: Kazzz (January 16, 2018)
[End of File]

View File

@ -26,6 +26,8 @@
<key>CFBundleTypeExtensions</key>
<array>
<string>gds</string>
<string>gds2</string>
<string>oas</string>
</array>
<key>CFBundleTypeRole</key>
<string>Editor</string>

View File

@ -65,7 +65,7 @@ def SetGlobals():
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', 'Qt5Custom'] | qt5macports \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', 'B36'] | sys \n"
Usage += " [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled \n"
@ -94,7 +94,7 @@ def SetGlobals():
print("")
print( "!!! Sorry. Your system <%s> looks like non-Mac" % System, file=sys.stderr )
print(Usage)
quit()
exit()
release = int( Release.split(".")[0] ) # take the first of ['14', '5', '0']
if release == 14:
@ -110,13 +110,13 @@ def SetGlobals():
print("")
print( "!!! Sorry. Unsupported major OS release <%d>" % release, file=sys.stderr )
print(Usage)
quit()
exit()
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()
exit()
# default modules
ModuleQt = "Qt5MacPorts"
@ -236,30 +236,21 @@ def ParseCommandLineArguments():
opt, args = p.parse_args()
if (opt.checkusage):
print(Usage)
quit()
exit()
# Determine Qt type
candidates = [ i.upper() for i in ['Qt4MacPorts', 'Qt5MacPorts', 'Qt5Custom'] ]
candidates = ['Qt4MacPorts', 'Qt5MacPorts', 'Qt5Brew']
candidates_upper = [ i.upper() for i in candidates ]
ModuleQt = ""
index = 0
for item in candidates:
if opt.type_qt.upper() == item:
if index == 0:
ModuleQt = 'Qt4MacPorts'
break
elif index == 1:
ModuleQt = 'Qt5MacPorts'
break
elif index == 2:
ModuleQt = 'Qt5Custom'
break
else:
index += 1
if ModuleQt == "":
if opt.type_qt.upper() in candidates_upper:
idx = candidates_upper.index(opt.type_qt.upper())
ModuleQt = candidates[idx]
else:
print("")
print( "!!! Unknown Qt type", file=sys.stderr )
print( "!!! Unknown Qt type %s. Candidates: %s" % (opt.type_qt, candidates), file=sys.stderr )
print(Usage)
quit()
exit(1)
# By default, OS-standard script languages (Ruby and Python) are used
NonOSStdLang = False
@ -300,7 +291,7 @@ def ParseCommandLineArguments():
print("")
print( "!!! Unknown Ruby type", file=sys.stderr )
print(Usage)
quit()
exit()
# Determine Python type
candidates = [ i.upper() for i in ['nil', 'Sys', 'Ana27', 'Ana36', 'MP36', 'B36'] ]
@ -341,7 +332,7 @@ def ParseCommandLineArguments():
print("")
print( "!!! Unknown Python type", file=sys.stderr )
print(Usage)
quit()
exit()
NoQtBindings = opt.no_qt_binding
MakeOptions = opt.make_option
@ -354,14 +345,14 @@ def ParseCommandLineArguments():
print("")
print( "!!! Choose either [-y|--deploy] or [-Y|--DEPLOY]", file=sys.stderr )
print(Usage)
quit()
exit()
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)
quit()
exit()
if not DeploymentF and not DeploymentP:
target = "%s %s %s" % (Platform, Release, Machine)
@ -436,9 +427,9 @@ def RunMainBuildBash():
AbsMacBuildLog = "%s/qt5.build.macos-%s-%s.log" % (ProjectDir, Platform, mode)
parameters += " \\\n -bin %s" % MacBinDir
parameters += " \\\n -build %s" % MacBuildDir
elif ModuleQt == 'Qt5Custom':
elif ModuleQt == 'Qt5Brew':
parameters += " \\\n -qt5"
parameters += " \\\n -qmake %s" % Qt5Custom['qmake']
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)
@ -486,7 +477,7 @@ def RunMainBuildBash():
command += " 2>&1 | tee %s" % MacBuildLog
if CheckComOnly:
print(command)
quit()
exit()
#-----------------------------------------------------
# [3] Invoke the main Bash script; takes time:-)
@ -662,7 +653,7 @@ def DeployBinariesForBundle():
depDicOrdinary.update(dependDic)
'''
PrintLibraryDependencyDictionary( depDicOrdinary, "Style (3)" )
quit()
exit()
'''
print( " [5] Setting and changing the identification names among KLayout's libraries ..." )
@ -699,13 +690,11 @@ def DeployBinariesForBundle():
shutil.copy2( sourceDir0 + "/PkgInfo", targetDir0 ) # this file is not mandatory
shutil.copy2( sourceDir1 + "/klayout", targetDirM )
shutil.copy2( sourceDir2 + "/klayout.icns", targetDirR )
shutil.copy2( sourceDir2 + "/qt.conf", targetDirM )
os.chmod( targetDir0 + "/PkgInfo", 0o0644 )
os.chmod( targetDir0 + "/Info.plist", 0o0644 )
os.chmod( targetDirM + "/klayout", 0o0755 )
os.chmod( targetDirM + "/qt.conf", 0o0644 )
os.chmod( targetDirR + "/klayout.icns", 0o0644 )
buddies = glob.glob( sourceDir3 + "/strm*" )
@ -733,7 +722,7 @@ def DeployBinariesForBundle():
buddies = glob.glob( "klayout.app/Contents/Buddy/strm*" )
macdepQtOpt = ""
for buddy in buddies:
macdepQtOpt += "-executable=%s " % buddy
macdepQtOpt += " -executable=%s" % buddy
ret = SetChangeLibIdentificationName( buddy, "../Frameworks" )
if not ret == 0:
os.chdir(ProjectDir)
@ -755,11 +744,15 @@ def DeployBinariesForBundle():
deploytool = Qt5MacPorts['deploy']
app_bundle = "klayout.app"
options = macdepQtOpt + verbose
elif ModuleQt == 'Qt5Custom':
deploytool = Qt5Custom['deploy']
elif ModuleQt == 'Qt5Brew':
deploytool = Qt5Brew['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 )
os.chmod( targetDirM + "/qt.conf", 0o0644 )
os.chdir(ProjectDir)
os.chdir(MacPkgDir)
command = "%s %s %s" % ( deploytool, app_bundle, options )
@ -770,18 +763,51 @@ def DeployBinariesForBundle():
print("")
os.chdir(ProjectDir)
return 1
else:
print( "##### Finished deploying libraries and executables for <klayout.app> #####" )
print("")
os.chdir(ProjectDir)
return 0
deploymentPython = False
if deploymentPython:
# TODO Code incomplete! To be finished.
from macbuild.build4mac_util import WalkFrameworkPaths, PerformChanges, DetectChanges
bundlePath = 'qt5.pkg.macos-HighSierra-release/klayout.app'
bundleExecPathAbs = os.getcwd() + '/%s/Contents/MacOS/' % bundlePath
# rsync -a --safe-links /usr/local/opt/python/Frameworks/Python.framework/ qt5.pkg.macos-HighSierra-release/klayout.app/Contents/Frameworks/Python.framework
# cp -RL /usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages qt5.pkg.macos-HighSierra-release/klayout.app/Contents/Frameworks/Python.framework/Versions/3.6/lib/python3.6/
# rm -rf qt5.pkg.macos-HighSierra-release/klayout.app/Contents/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/test
pythonFrameworkPath = '%s/Contents/Frameworks/Python.framework' % bundlePath
depdict = WalkFrameworkPaths(pythonFrameworkPath)
pythonOriginalFrameworkPath = '/usr/local/opt/python/Frameworks/Python.framework'
appPythonFrameworkPath = '@executable_path/../Frameworks/Python.framework/'
PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath)], bundleExecPathAbs)
klayoutPath = bundleExecPathAbs
depdict = WalkFrameworkPaths(klayoutPath, filter_regex=r'klayout$')
PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath)], bundleExecPathAbs)
klayoutPath = bundleExecPathAbs + '../Frameworks'
depdict = WalkFrameworkPaths(klayoutPath, filter_regex=r'libklayout')
PerformChanges(depdict, [(pythonOriginalFrameworkPath, appPythonFrameworkPath)], bundleExecPathAbs)
usrLocalPath = '/usr/local/opt/'
appUsrLocalPath = '@executable_path/../Frameworks/'
depdict = WalkFrameworkPaths(pythonFrameworkPath)
PerformChanges(depdict, [(usrLocalPath, appUsrLocalPath)], bundleExecPathAbs)
# usrLocalPath = '/usr/local/lib/'
# appUsrLocalPath = '@executable_path/../Frameworks/'
# depdict = WalkFrameworkPaths(pythonFrameworkPath)
# PerformChanges(depdict, [(usrLocalPath, appUsrLocalPath)], bundleExecPathAbs)
else:
print( " [8] Skipped deploying Qt's Frameworks ..." )
print( "##### Finished deploying libraries and executables for <klayout.app> #####" )
print("")
os.chdir(ProjectDir)
return 0
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

View File

@ -21,7 +21,7 @@ XcodeToolChain = { 'nameID': '/usr/bin/install_name_tool -id ',
#-----------------------------------------------------
# [1] Qt
#-----------------------------------------------------
Qts = [ 'Qt4MacPorts', 'Qt5MacPorts', 'Qt5Custom' ]
Qts = [ 'Qt4MacPorts', 'Qt5MacPorts', 'Qt5Brew' ]
#-----------------------------------------------------
# Whereabout of different components of Qt4
@ -41,17 +41,15 @@ Qt5MacPorts = { 'qmake' : '/opt/local/libexec/qt5/bin/qmake',
'deploy': '/opt/local/libexec/qt5/bin/macdeployqt'
}
# # Qt5 from Brew
# # [Key Type Name] = 'Qt5Brew'
# Qt5Brew = { 'qmake' : '/usr/local/Cellar/qt5/5.10.0_1/bin/qmake',
# 'deploy': '/usr/local/Cellar/qt5/5.10.0_1/bin/macdeployqt'
# }
# Qt5 from Homebrew (https://brew.sh/)
# 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/)
# [Key Type Name] = 'Qt5Custom'
Qt5Custom = { 'qmake' : '~/Qt5.9.4/5.9.4/clang_64/bin/qmake',
'deploy': '~/Qt5.9.4/5.9.4/clang_64/bin/macdeployqt'
}
#-----------------------------------------------------
# [2] Ruby
@ -192,9 +190,9 @@ Python36MacPorts= { 'exe': '/opt/local/Library/Frameworks/Python.framework/Versi
# Python 3.6 from Brew *+*+*+ EXPERIMENTAL *+*+*+
# [Key Type Name] = 'pybrew'
Python36Brew= { 'exe': '/usr/local/opt/python3/Frameworks/Python.framework/Versions/Current/bin/python3.6m' ,
'inc': '/usr/local/opt/python3/Frameworks/Python.framework/Versions/Current/include/python3.6m',
'lib': '/usr/local/opt/python3/Frameworks/Python.framework/Versions/Current/lib/libpython3.6m.dylib'
Python36Brew= { 'exe': '/usr/local/opt/python/libexec/bin/python' ,
'inc': '/usr/local/opt/python3/Frameworks/Python.framework/Versions/3.6/Headers',
'lib': '/usr/local/opt/python3/Frameworks/Python.framework/Versions/3.6/Python'
}
# Consolidated dictionary kit for Python

Binary file not shown.

View File

@ -16,6 +16,15 @@ import os
import re
import string
import subprocess
import shutil
CAN_DEPLOY_PYTHON = False
try:
from pathlib import Path
Path('~').expanduser()
CAN_DEPLOY_PYTHON = True
except (ImportError,AttributeError): # python2
print("Warning: Cannot import pathlib, use python3 if you need python deployment.")
#-------------------------------------------------------------------------------
## To import global dictionaries of different modules
@ -44,10 +53,10 @@ from build4mac_env import *
def DecomposeLibraryDependency( depstr ):
alllines = depstr.split('\n')
numlines = len(alllines)
dependent = alllines[0].split(':')[0].strip(' ').strip('\t')
dependent = alllines[0].split(':')[0].strip()
supporters = []
for i in range(1, numlines):
supporter = alllines[i].split(' ')[0].strip(' ').strip('\t')
for line in alllines[1:]:
supporter = line.strip().split(' ')[0].strip()
if not supporter == '':
supporters.append(supporter)
return { dependent: supporters }
@ -107,6 +116,8 @@ def SetChangeIdentificationNameOfDyLib( libdic ):
# 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
@ -170,6 +181,178 @@ def SetChangeLibIdentificationName( executable, relativedir ):
# for-lib
return 0
# TODO: undocumented
if CAN_DEPLOY_PYTHON:
def WalkLibDependencyTree( dylibPath, depth=0, filter_regex=r'\t+/usr/local/opt'):
NOTHINGTODO = [] # return empty list if nothing to do.
dylibPath = str(Path(dylibPath))
cmdNameId = XcodeToolChain['nameID']
cmdNameChg = XcodeToolChain['nameCH']
otoolCm = 'otool -L %s | grep -E "%s"' % (dylibPath, filter_regex)
otoolOut = os.popen( otoolCm ).read()
exedepdic = DecomposeLibraryDependency( dylibPath + ":\n" + otoolOut )
keys = exedepdic.keys()
deplibs = exedepdic[ list(keys)[0] ]
if depth < 5:
if len(deplibs) > 0:
for idx, lib in enumerate(deplibs):
lib = str(Path(lib))
if lib != list(keys)[0]:
deplibs[idx] = WalkLibDependencyTree(lib, depth+1, filter_regex)
else:
return NOTHINGTODO
if depth == 0:
return deplibs
return exedepdic
else:
raise RuntimeError("Exceeded maximum recursion depth.")
def WalkFrameworkPaths(frameworkPaths, filter_regex=r'\.(so|dylib)$'):
try:
frameworkPathsIter = iter(frameworkPaths)
except TypeError:
frameworkPathsIter = [frameworkPaths]
dependency_dict = dict()
for frameworkPath in frameworkPaths:
frameworkPath = str(Path(frameworkPath))
find_grep_results = os.popen('find %s -type f | grep -E "%s"' % (frameworkPath, filter_regex)).read().split('\n')
framework_files = filter(lambda x: x != '',
map(lambda x: x.strip(),
find_grep_results))
dependency_dict[frameworkPath] = list()
for idx, file in enumerate(framework_files):
dict_file = {file: WalkLibDependencyTree(file)}
dependency_dict[frameworkPath].append(dict_file)
return dependency_dict
def WalkDictTree(dependencyDict, visited_files):
libNameChanges = list()
for lib, dependencies in dependencyDict.items():
if lib in visited_files:
continue
dependency_list = list()
if isinstance(dependencies, list):
for deplib in dependencies:
if isinstance(deplib, str):
dependency_list.append(deplib)
if deplib not in visited_files:
visited_files.append(deplib)
elif isinstance(deplib, dict):
dependency_list.append(str(next(iter(deplib))))
libNameChanges.extend(WalkDictTree(deplib, visited_files))
else:
#raise RuntimeError("Unexpected value: %s" % deplib)
pass
else:
raise RuntimeError("Unexpected value: %s" % dependencies)
if len(dependency_list) > 0:
libNameChanges.append((lib, dependency_list))
else:
libNameChanges.append((lib, ))
visited_files.append(lib)
return libNameChanges
def FindFramework(path, root_path):
path = Path(path)
root_path = Path(root_path)
relPath = path.relative_to(root_path)
return str(root_path / relPath.parts[0])
def ReplaceExecutablePath(path, executable_path):
executable_path = str(executable_path)
p = Path(str(path).replace("@executable_path", "/%s/" % executable_path))
return p
def FileExists(file_path, executable_path):
p = ReplaceExecutablePath(file_path, executable_path)
return p.exists()
def DetectChanges(frameworkDependencyDict):
visited_files = list()
libNameChanges = list()
for framework, libraries in frameworkDependencyDict.items():
for libraryDict in libraries:
libNameChanges.extend(WalkDictTree(libraryDict, visited_files))
# Changes are stored in libNameChanges in the form of ('lib.dylib', ['dep1.dylib', ...])
return libNameChanges
def PerformChanges(frameworkDependencyDict, replaceFromToPairs=None, executable_path="/tmp/klayout", libdir=False):
libNameChanges = DetectChanges(frameworkDependencyDict)
cmdNameId = XcodeToolChain['nameID']
cmdNameChg = XcodeToolChain['nameCH']
if replaceFromToPairs is not None:
for libNameChange in libNameChanges:
libNameChangeIterator = iter(libNameChange)
lib = next(libNameChangeIterator)
try:
dependencies = next(libNameChangeIterator)
except StopIteration:
dependencies = list()
for replaceFrom, replaceTo in replaceFromToPairs:
replaceFrom = str(Path(replaceFrom))
replaceTo = str(Path(replaceTo))
if lib.find(replaceFrom) >= 0:
if libdir:
frameworkPath = FindFramework(lib, replaceFrom)
else:
frameworkPath = lib
destFrameworkPath = frameworkPath.replace(replaceFrom, replaceTo)
destFrameworkPath = ReplaceExecutablePath(destFrameworkPath, executable_path)
if not FileExists(lib.replace(replaceFrom, replaceTo), executable_path):
print (lib.replace(replaceFrom, replaceTo), "DOES NOT EXIST")
print ("COPY", frameworkPath, " -> ", destFrameworkPath)
shutil.copytree(frameworkPath, destFrameworkPath)
fileName = ReplaceExecutablePath(lib.replace(replaceFrom, replaceTo), executable_path)
nameId = lib.replace(replaceFrom, replaceTo)
command = "%s %s %s" % ( cmdNameId, nameId, fileName )
if not os.access(fileName, os.W_OK):
command = "chmod u+w %s; %s; chmod u-w %s" % (fileName, command, fileName)
print("\t%s" % command)
if subprocess.call( command, shell=True ) != 0:
msg = "!!! Failed to set the new identification name to <%s> !!!"
print( msg % fileName, file=sys.stderr )
return 1
fileName = ReplaceExecutablePath(lib.replace(replaceFrom, replaceTo), executable_path)
for dependency in dependencies:
if dependency.find(replaceFrom) >= 0:
print("In:", fileName)
print("\tRENAME", dependency, " -> ", dependency.replace(replaceFrom, replaceTo))
# Try changing id first
nameId = dependency.replace(replaceFrom, replaceTo)
command = "%s %s %s" % ( cmdNameId, nameId, fileName )
if not os.access(fileName, os.W_OK):
command = "chmod u+w %s; %s; chmod u-w %s" % (fileName, command, fileName)
print("\t%s" % command)
if subprocess.call( command, shell=True ) != 0:
msg = "!!! Failed to set the new identification name to <%s> !!!"
print( msg % fileName, file=sys.stderr )
return 1
# Rename dependencies
nameOld = dependency
nameNew = dependency.replace(replaceFrom, replaceTo)
command = "%s %s %s %s" % ( cmdNameChg, nameOld, nameNew, fileName )
if not os.access(fileName, os.W_OK):
command = "chmod u+w %s; %s; chmod u-w %s" % (fileName, command, fileName)
print("\t%s" % command)
if subprocess.call( command, shell=True ) != 0:
msg = "!!! Failed to set the new identification name to <%s> !!!"
print( msg % fileName, file=sys.stderr )
return 1
#------------------------------------------------------------------------------
## To get KLayout's version from a file; most likely from 'version.sh'
#

Binary file not shown.

View File

@ -73,7 +73,7 @@ def SetGlobals():
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 | Qt593mp \n"
Usage += " [-q|--qt <ID>] : ID name of deployed Qt | Qt510Xmp \n"
Usage += " [-s|--serial <num>] : DMG serial number | 1 \n"
Usage += " [-?|--?] : print this usage and exit | disabled \n"
Usage += "--------------------------------------------------------------------------------------------------------\n"
@ -117,7 +117,7 @@ def SetGlobals():
OpClean = False
OpMake = False
DMGSerialNum = 1
QtIdentification = "Qt593mp"
QtIdentification = "Qt510Xmp"
Version = GetKLayoutVersionFrom( "./version.sh" )
OccupiedDS = -1
BackgroundPNG = "KLayoutDMG-Back.png"
@ -237,7 +237,7 @@ def ParseCommandLineArguments():
p.set_defaults( pkg_dir = "",
operation_clean = False,
operation_make = False,
qt_identification = "Qt593mp",
qt_identification = "Qt510Xmp",
dmg_serial = "1",
checkusage = False )

1
makeDMG4mac.py Symbolic link
View File

@ -0,0 +1 @@
macbuild/makeDMG4mac.py

View File

@ -449,6 +449,9 @@ CIFReader::read_cell (db::Layout &layout, db::Cell &cell, double sf, int level)
if (! test_semi ()) {
denom = read_integer ();
divider = read_integer ();
if (divider == 0) {
error ("'DS' command: divider cannot be zero");
}
}
expect_semi ();
@ -476,7 +479,7 @@ CIFReader::read_cell (db::Layout &layout, db::Cell &cell, double sf, int level)
// DF command:
// "D" blank* "F"
if (level == 0) {
error ("'DS' command must be inside a cell specification");
error ("'DF' command must be inside a cell specification");
}
// skip the rest of the command
@ -490,7 +493,7 @@ CIFReader::read_cell (db::Layout &layout, db::Cell &cell, double sf, int level)
// "D" blank* "D" integer
read_integer ();
warn ("DD command ignored");
warn ("'DD' command ignored");
skip_to_end ();
} else {

View File

@ -665,6 +665,9 @@ OASISWriter::OASISWriter ()
mp_cell (0),
m_layer (0), m_datatype (0),
m_in_cblock (false),
m_propname_id (0),
m_propstring_id (0),
m_proptables_written (false),
m_progress (tl::to_string (QObject::tr ("Writing OASIS file")), 10000)
{
m_progress.set_format (tl::to_string (QObject::tr ("%.0f MB")));

View File

@ -104,6 +104,8 @@ RecursiveShapeIterator::RecursiveShapeIterator ()
mp_shape_prop_sel = 0;
m_shape_inv_prop_sel = false;
m_needs_reinit = false;
m_inst_quad_id = 0;
m_shape_quad_id = 0;
}
RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes)

View File

@ -36,7 +36,8 @@ class LayoutDiff
{
public:
LayoutDiff ()
: mp_layout_a (0), mp_layout_b (0)
: mp_layout_a (0), mp_cell_a (0), m_layer_index_a (0),
mp_layout_b (0), mp_cell_b (0), m_layer_index_b (0)
{
// .. nothing yet ..
}

View File

@ -49,13 +49,13 @@ struct A : public db::Object
x += d;
}
void undo (db::Op *op) throw ()
void undo (db::Op *op)
{
AO *aop = dynamic_cast<AO *> (op);
x -= aop->d;
}
void redo (db::Op *op) throw ()
void redo (db::Op *op)
{
AO *aop = dynamic_cast<AO *> (op);
tl_assert (aop != 0);
@ -154,13 +154,13 @@ struct B : public db::Object
}
}
void undo (db::Op *op) throw ()
void undo (db::Op *op)
{
BO *bop = dynamic_cast<BO *> (op);
x -= bop->d;
}
void redo (db::Op *op) throw ()
void redo (db::Op *op)
{
BO *bop = dynamic_cast<BO *> (op);
tl_assert (bop != 0);

View File

@ -37,9 +37,11 @@ namespace lay
{
struct MacroEditorSetupDialogData
: public QObject
{
MacroEditorSetupDialogData ()
: basic_attributes (0), tab_width (8), indent (2), save_all_on_run (true), stop_on_exception (true), file_watcher_enabled (true), font_size (0)
MacroEditorSetupDialogData (QObject *parent)
: QObject(parent),
basic_attributes (0), tab_width (8), indent (2), save_all_on_run (true), stop_on_exception (true), file_watcher_enabled (true), font_size (0)
{
}
@ -56,7 +58,7 @@ struct MacroEditorSetupDialogData
void setup (lay::PluginRoot *root)
{
lay::MacroEditorHighlighters highlighters (lay::MacroEditorDialog::instance ());
lay::MacroEditorHighlighters highlighters (this);
std::string styles;
root->config_get (cfg_macro_editor_styles, styles);
highlighters.load (styles);
@ -91,7 +93,7 @@ struct MacroEditorSetupDialogData
void commit (lay::PluginRoot *root)
{
lay::MacroEditorHighlighters highlighters (lay::MacroEditorDialog::instance ());
lay::MacroEditorHighlighters highlighters (this);
if (highlighters.basic_attributes ()) {
highlighters.basic_attributes ()->assign (basic_attributes);
@ -138,7 +140,8 @@ update_item (QListWidgetItem *item, QTextCharFormat format)
}
MacroEditorSetupPage::MacroEditorSetupPage (QWidget *parent)
: lay::ConfigPage (parent), mp_data (0)
: lay::ConfigPage (parent),
mp_data (new MacroEditorSetupDialogData (this))
{
setupUi (this);
@ -156,8 +159,7 @@ MacroEditorSetupPage::MacroEditorSetupPage (QWidget *parent)
MacroEditorSetupPage::~MacroEditorSetupPage ()
{
delete mp_data;
mp_data = 0;
// .. nothing yet ..
}
void
@ -175,20 +177,16 @@ MacroEditorSetupPage::cb_changed (int)
void
MacroEditorSetupPage::clear_exception_list ()
{
if (mp_data) {
mp_data->ignore_exceptions_list.clear ();
update_ignore_exception_list ();
}
mp_data->ignore_exceptions_list.clear ();
update_ignore_exception_list ();
}
void
MacroEditorSetupPage::update_ignore_exception_list ()
{
if (mp_data) {
exception_list->clear ();
for (std::set<std::string>::const_iterator i = mp_data->ignore_exceptions_list.begin (); i != mp_data->ignore_exceptions_list.end (); ++i) {
exception_list->addItem (tl::to_qstring (*i));
}
exception_list->clear ();
for (std::set<std::string>::const_iterator i = mp_data->ignore_exceptions_list.begin (); i != mp_data->ignore_exceptions_list.end (); ++i) {
exception_list->addItem (tl::to_qstring (*i));
}
}
@ -206,7 +204,7 @@ void
MacroEditorSetupPage::setup (PluginRoot *root)
{
delete mp_data;
mp_data = new MacroEditorSetupDialogData ();
mp_data = new MacroEditorSetupDialogData (this);
mp_data->setup (root);
update_ignore_exception_list ();
@ -276,19 +274,16 @@ MacroEditorSetupPage::commit (PluginRoot *root)
commit_attributes (styles_list->currentItem ());
}
if (mp_data) {
mp_data->tab_width = tab_width->value ();
mp_data->indent = indent->value ();
mp_data->save_all_on_run = save_all_cb->isChecked ();
mp_data->stop_on_exception = stop_on_exception->isChecked ();
mp_data->file_watcher_enabled = watch_files->isChecked ();
mp_data->tab_width = tab_width->value ();
mp_data->indent = indent->value ();
mp_data->save_all_on_run = save_all_cb->isChecked ();
mp_data->stop_on_exception = stop_on_exception->isChecked ();
mp_data->file_watcher_enabled = watch_files->isChecked ();
mp_data->font_family = tl::to_string (font_sel->currentFont ().family ());
mp_data->font_size = font_size->value ();
mp_data->font_family = tl::to_string (font_sel->currentFont ().family ());
mp_data->font_size = font_size->value ();
mp_data->commit (root);
}
mp_data->commit (root);
}
void

View File

@ -703,7 +703,8 @@ SearchReplaceDialog::SearchReplaceDialog (lay::PluginRoot *root, lay::LayoutView
m_current_mode (0),
m_window (FitMarker),
m_window_dim (0.0),
m_max_item_count (0)
m_max_item_count (0),
m_last_query_cv_index (0)
{
setObjectName (QString::fromUtf8 ("search_replace_dialog"));

View File

@ -1143,7 +1143,7 @@ static bool
skip_quad (const db::Box &qb, const lay::Bitmap *vertex_bitmap, const db::CplxTrans &trans)
{
double threshold = 32 / trans.mag (); // don't check cells below 32x32 pixels
if (qb.empty () || qb.width () > threshold || qb.height () > threshold) {
if (qb.empty () || qb.width () > threshold || qb.height () > threshold || !vertex_bitmap) {
return false;
}

View File

@ -321,7 +321,7 @@ SaveLayoutOptionsDialog::get_options_internal ()
// SaveLayoutAsOptionsDialog implementation
SaveLayoutAsOptionsDialog::SaveLayoutAsOptionsDialog (QWidget *parent, const std::string &title)
: QDialog (parent), Ui::SaveLayoutAsOptionsDialog ()
: QDialog (parent), Ui::SaveLayoutAsOptionsDialog (), mp_tech (0)
{
setObjectName (QString::fromUtf8 ("save_layout_options_dialog"));

View File

@ -401,7 +401,7 @@ public:
bool cat_matches (const QModelIndex &index, const QString &filter) const
{
MarkerBrowserTreeViewModelCacheEntry *node = (MarkerBrowserTreeViewModelCacheEntry *)(index.internalPointer ());
if (node) {
if (node && mp_database) {
rdb::id_type id = node->id ();
const rdb::Category *category = mp_database->category_by_id (id);
@ -418,7 +418,7 @@ public:
bool cell_matches (const QModelIndex &index, const QString &filter) const
{
MarkerBrowserTreeViewModelCacheEntry *node = (MarkerBrowserTreeViewModelCacheEntry *)(index.internalPointer ());
if (node) {
if (node && mp_database) {
rdb::id_type id = node->id ();
const rdb::Cell *cell = mp_database->cell_by_id (id);
@ -435,7 +435,7 @@ public:
bool no_errors (const QModelIndex &index) const
{
MarkerBrowserTreeViewModelCacheEntry *node = (MarkerBrowserTreeViewModelCacheEntry *)(index.internalPointer ());
if (node) {
if (node && mp_database) {
rdb::id_type id = node->id ();
bool none = false;
@ -638,6 +638,10 @@ public:
QModelIndex next_index (QModelIndex current_index, bool up)
{
if (!mp_database) {
return QModelIndex ();
}
MarkerBrowserTreeViewModelCacheEntry *node = (MarkerBrowserTreeViewModelCacheEntry *) current_index.internalPointer ();
rdb::id_type id = node->id ();

View File

@ -41,7 +41,7 @@ inline void usleep(long us)
class Sum
{
public:
Sum () : m_sum(0) { }
Sum () : m_sum(0), m_flag (false) { }
void reset () { lock.lock (); m_sum = 0; lock.unlock (); m_flag = false; }
void add(int n) { lock.lock (); m_sum += n; lock.unlock (); m_flag = true; }

View File

@ -2,7 +2,7 @@
# This script is sourced to define the main version parameters
# The main version
KLAYOUT_VERSION="0.25.1"
KLAYOUT_VERSION="0.25.2"
# The build date
KLAYOUT_VERSION_DATE=$(date "+%Y-%m-%d")