Merge branch 'macos-build' from kazzz

This commit is contained in:
Matthias Koefferlein 2018-01-14 17:29:16 +01:00
commit 53328d1767
91 changed files with 2362 additions and 499 deletions

View File

@ -1,6 +1,6 @@
#!/bin/bash
#
#
# KLayout Layout Viewer
# Copyright (C) 2006-2018 Matthias Koefferlein
#
@ -17,10 +17,11 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
#
CURR_DIR=`pwd`
RUN_MAKE=1
IS_MAC="no"
HAVE_QTBINDINGS=1
HAVE_64BIT_COORD=0
@ -46,6 +47,16 @@ MAKE_OPT=""
CONFIG="release"
BUILD_EXPERT=0
# Check if building on Mac OSX Darwin family
case `uname` in
Darwin*)
IS_MAC="yes"
;;
*)
IS_MAC="no"
;;
esac
# Check, whether build.sh is run from the top level folder
if ! [ -e src ] || ! [ -e src/klayout.pro ]; then
echo "*** ERROR: run build.sh from the top level folder"
@ -200,7 +211,7 @@ done
echo "Scanning installation .."
echo ""
# Import version info
# Import version info
. ./version.sh
echo "Version Info:"
@ -212,8 +223,8 @@ echo ""
# if not given, try to detect the qmake binary
if [ "$QMAKE" = "" ]; then
for qmake in "qmake5" "qmake-qt5" "qmake4" "qmake-qt4" "qmake"; do
if [ "$QMAKE" = "" ] && [ "`$qmake -v 2>/dev/null`" != "" ]; then
QMAKE="$qmake"
if [ "$QMAKE" = "" ] && [ "`$qmake -v 2>/dev/null`" != "" ]; then
QMAKE="$qmake"
fi
done
fi
@ -246,8 +257,8 @@ echo ""
# if not given, locate ruby interpreter (prefer 1.9, then default, finally 1.8 as fallback)
if [ "$RUBY" = "" ]; then
for ruby in "ruby2.4" "ruby2.3" "ruby2.2" "ruby2.1" "ruby2" "ruby1.9" "ruby" "ruby1.8"; do
if [ "$RUBY" = "" ] && [ "`$ruby -e 'puts 1' 2>/dev/null`" = "1" ]; then
RUBY="$ruby"
if [ "$RUBY" = "" ] && [ "`$ruby -e 'puts 1' 2>/dev/null`" = "1" ]; then
RUBY="$ruby"
fi
done
fi
@ -314,7 +325,7 @@ if [ "$RUBY" != "" ] && [ "$RUBY" != "-" ]; then
RUBYINCLUDE2=`$RUBY -rrbconfig -e "puts (RbConfig::CONFIG['rubyarchhdrdir'] || '')"`
fi
if [ "$RUBYINCLUDE2" = "" ]; then
RUBYINCLUDE2="$RUBYHDRDIR"/`$RUBY -rrbconfig -e "puts (RbConfig::CONFIG['arch'] || '')"`
RUBYINCLUDE2="$RUBYHDRDIR"/`$RUBY -rrbconfig -e "puts (RbConfig::CONFIG['arch'] || '')"`
fi
echo " Ruby headers found: $RUBYINCLUDE and $RUBYINCLUDE2"
fi
@ -329,11 +340,11 @@ if [ "$RUBY" != "" ] && [ "$RUBY" != "-" ]; then
fi
# if not given, locate Python interpreter
# if not given, locate Python interpreter
if [ "$PYTHON" = "" ]; then
for python in "python3.5" "python3.4" "python3.3" "python3.2" "python3.1" "python3" "python2.8" "python2.7" "python2" "python"; do
if [ "$PYTHON" = "" ] && [ "`$python -c 'print(1)' 2>/dev/null`" = "1" ]; then
PYTHON="$python"
if [ "$PYTHON" = "" ] && [ "`$python -c 'print(1)' 2>/dev/null`" = "1" ]; then
PYTHON="$python"
fi
done
fi
@ -468,11 +479,21 @@ mkdir -p $BUILD
. $(dirname $(which $0))/version.sh
# qmake needs absolute paths, so we get them now:
BUILD=`readlink -f $BUILD`
BIN=`readlink -f $BIN`
# OSX does not have `readlink -f` command. Use equivalent Perl script.
if [ "$IS_MAC" = "no" ]; then
BUILD=`readlink -f $BUILD`
BIN=`readlink -f $BIN`
else
BUILD=`perl -MCwd -le 'print Cwd::abs_path(shift)' $BUILD`
BIN=`perl -MCwd -le 'print Cwd::abs_path(shift)' $BIN`
fi
if ( gmake -v >/dev/null 2>/dev/null ); then
MAKE_PRG=gmake
if [ "$IS_MAC" = "no" ]; then
if ( gmake -v >/dev/null 2>/dev/null ); then
MAKE_PRG=gmake
else
MAKE_PRG=make
fi
else
MAKE_PRG=make
fi

72
macbuild/ReadMe.md Normal file
View File

@ -0,0 +1,72 @@
<< Draft Version 0.003>> 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 "Qt 5.10.0" which is problematic in showing your design in the main canvas.
* Please USE "Qt 5.9.x" instead.
* 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.
```
$ ./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.
```
$ ./build4mac.py -r mp24 -p mp36 -Y
```
* [-Y|--DEPOLY] 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.
By: Kazzz (January 08, 2018)
[End of File]

69
macbuild/ReadMe.txt Normal file
View File

@ -0,0 +1,69 @@
<< Draft Version 0.003>>
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.
* 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.
$ ./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.
$ ./build4mac.py -r mp24 -p mp36 -Y
* [-Y|--DEPOLY] 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.
By: Kazzz (January 08, 2018)
[End of File]

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NOTE</key>
<string>This file was originally generated by Qt/QMake.</string>
<key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE}</string>
<key>CFBundleIconFile</key>
<string>${ICONFILE}</string>
<key>CFBundleIdentifier</key>
<string>de.klayout</string>
<key>CFBundleName</key>
<string>${BUNDLENAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleVersion</key>
<string>${VERSION}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>
</plist>

View File

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

Binary file not shown.

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

901
macbuild/build4mac.py Executable file
View File

@ -0,0 +1,901 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
#===============================================================================
# File: "macbuild/build4mac.py"
#
# The top Python script for building KLayout (http://www.klayout.de/index.php)
# version 0.25 or later on different Apple Mac OSX platforms.
#===============================================================================
from __future__ import print_function # to use print() of Python 3 in Python >= 2.7
import sys
import os
import shutil
import glob
import platform
import optparse
import subprocess
#-------------------------------------------------------------------------------
## To import global dictionaries of different modules and utility functions
#-------------------------------------------------------------------------------
mydir = os.path.dirname(os.path.abspath(__file__))
sys.path.append( mydir + "/macbuild" )
from build4mac_env import *
from build4mac_util import *
#-------------------------------------------------------------------------------
## To set global variables including present directory and platform info.
#-------------------------------------------------------------------------------
def SetGlobals():
global ProjectDir # project directory where "build.sh" exists
global Usage # string on usage
global BuildBash # the main build Bash script
global Platform # platform
global ModuleQt # Qt module to be used
global ModuleRuby # Ruby module to be used
global ModulePython # Python module to be used
global NonOSStdLang # True if non-OS-standard language is chosen
global NoQtBindings # True if not creating Qt bindings for Ruby scripts
global MakeOptions # options passed to `make`
global DebugMode # True if debug mode build
global CheckComOnly # True if only for checking the command line parameters to "build.sh"
global DeploymentF # True if fully (including Qt's Frameworks) deploy the binaries for bundles
global DeploymentP # True if partially deploy the binaries excluding Qt's Frameworks
global DeployVerbose # -verbose=<0-3> level passed to 'macdeployqt' tool
global Version # KLayout's version
# auxiliary variables on platform
global System # 6-tuple from platform.uname()
global Node # - do -
global Release # - do -
global Version # - do -
global Machine # - do -
global Processor # - do -
global Bit # machine bit-size
Usage = "\n"
Usage += "--------------------------------------------------------------------------------------------------------\n"
Usage += "<< Usage of 'build4mac.py' >>\n"
Usage += " for building KLayout 0.25 or later on different Apple Mac OSX platforms.\n"
Usage += "\n"
Usage += "$ [python] ./build4mac.py \n"
Usage += " option & argument : descriptions | default value\n"
Usage += " ----------------------------------------------------------------------------------+---------------\n"
Usage += " : * key type names below are case insensitive * | \n"
Usage += " : 'nil' = not to support the script language | \n"
Usage += " : 'Sys' = using the OS standard script language | \n"
Usage += " : Refer to 'macbuild/build4mac_env.py' for details | \n"
Usage += " [-q|--qt <type>] : type=['Qt4MacPorts', 'Qt5MacPorts'] | qt5macports \n"
Usage += " [-r|--ruby <type>] : type=['nil', 'Sys', 'Src24', 'MP24'] | sys \n"
Usage += " [-p|--python <type>] : type=['nil', 'Sys', 'Ana27', 'Ana36', 'MP36'] | sys \n"
Usage += " [-n|--noqtbinding] : don't create Qt bindings for ruby scripts | disabled \n"
Usage += " [-m|--make <option>] : option passed to 'make' | -j4 \n"
Usage += " [-d|--debug] : enable debug mode build | disabled \n"
Usage += " [-c|--checkcom] : check command line and exit without building | disabled \n"
Usage += " [-y|--deploy] : deploy executables and dylibs including Qt's Frameworks | disabled \n"
Usage += " [-Y|--DEPLOY] : deploy executables and dylibs for those who built KLayout | disabled \n"
Usage += " : from the source code and use the tools in the same machine | \n"
Usage += " : ! After confirmation of successful build of | \n"
Usage += " : KLayout, rerun this script with BOTH: | \n"
Usage += " : 1) the same options used for building AND | \n"
Usage += " : 2) <-y|--deploy> OR <-Y|--DEPLOY> | \n"
Usage += " : optionally with [-v|--verbose <0-3>] | \n"
Usage += " [-v|--verbose <0-3>] : verbose level of `macdeployqt' (effective with -y only) | 1 \n"
Usage += " : 0 = no output, 1 = error/warning (default), | \n"
Usage += " : 2 = normal, 3 = debug | \n"
Usage += " [-?|--?] : print this usage and exit | disabled \n"
Usage += "--------------------------------------------------------------------------------------------------------\n"
ProjectDir = os.getcwd()
BuildBash = "./build.sh"
(System, Node, Release, Version, Machine, Processor) = platform.uname()
if not System == "Darwin":
print("")
print( "!!! Sorry. Your system <%s> looks like non-Mac" % System, file=sys.stderr )
print(Usage)
quit()
release = int( Release.split(".")[0] ) # take the first of ['14', '5', '0']
if release == 14:
Platform = "Yosemite"
elif release == 15:
Platform = "ElCapitan"
elif release == 16:
Platform = "Sierra"
elif release == 17:
Platform = "HighSierra"
else:
Platform = ""
print("")
print( "!!! Sorry. Unsupported major OS release <%d>" % release, file=sys.stderr )
print(Usage)
quit()
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()
# default modules
ModuleQt = "Qt5MacPorts"
if Platform == "Yosemite":
ModuleRuby = "RubyYosemite"
ModulePython = "PythonYosemite"
elif Platform == "ElCapitan":
ModuleRuby = "RubyElCapitan"
ModulePytyon = "PythonElCapitan"
elif Platform == "Sierra":
ModuleRuby = "RubySierra"
ModulePython = "PythonSierra"
elif Platform == "HighSierra":
ModuleRuby = "RubyHighSierra"
ModulePython = "PythonHighSierra"
else:
ModuleRuby = "nil"
ModulePython = "nil"
NonOSStdLang = False
NoQtBindings = False
MakeOptions = "-j4"
DebugMode = False
CheckComOnly = False
DeploymentF = False
DeploymentP = False
DeployVerbose = 1
Version = GetKLayoutVersionFrom( "./version.sh" )
#------------------------------------------------------------------------------
## To get command line parameters
#------------------------------------------------------------------------------
def ParseCommandLineArguments():
global Usage
global Platform
global ModuleQt
global ModuleRuby
global ModulePython
global NonOSStdLang
global NoQtBindings
global MakeOptions
global DebugMode
global CheckComOnly
global DeploymentF
global DeploymentP
global DeployVerbose
p = optparse.OptionParser( usage=Usage )
p.add_option( '-q', '--qt',
dest='type_qt',
help="Qt type=['Qt4MacPorts', 'Qt5MacPorts']" )
p.add_option( '-r', '--ruby',
dest='type_ruby',
help="Ruby type=['nil', 'Sys', 'Src24', 'MP24']" )
p.add_option( '-p', '--python',
dest='type_python',
help="Python type=['nil', 'Sys', 'Ana27', 'Ana36', 'MP36']" )
p.add_option( '-n', '--noqtbinding',
action='store_true',
dest='no_qt_binding',
default=False,
help="do not create Qt bindings for Ruby scripts" )
p.add_option( '-m', '--make',
dest='make_option',
help="options passed to `make`" )
p.add_option( '-d', '--debug',
action='store_true',
dest='debug_build',
default=False,
help="enable debug mode build" )
p.add_option( '-c', '--checkcom',
action='store_true',
dest='check_command',
default=False,
help="check command line and exit without building" )
p.add_option( '-y', '--deploy',
action='store_true',
dest='deploy_full',
default=False,
help="fully deploy built binaries" )
p.add_option( '-Y', '--DEPLOY',
action='store_true',
dest='deploy_partial',
default=False,
help="deploy built binaries when non-OS-standard script language is chosen" )
p.add_option( '-v', '--verbose',
dest='deploy_verbose',
help="verbose level of `macdeployqt` tool" )
p.add_option( '-?', '--??',
action='store_true',
dest='checkusage',
default=False,
help='check usage' )
p.set_defaults( type_qt = "qt5macports",
type_ruby = "sys",
type_python = "sys",
no_qt_binding = False,
make_option = "-j4",
debug_build = False,
check_command = False,
deploy_full = False,
deploy_partial = False,
deploy_verbose = "1",
checkusage = False )
opt, args = p.parse_args()
if (opt.checkusage):
print(Usage)
quit()
# Determine Qt type
candidates = [ i.upper() for i in ['Qt4MacPorts', 'Qt5MacPorts'] ]
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
else:
index += 1
if ModuleQt == "":
print("")
print( "!!! Unknown Qt type", file=sys.stderr )
print(Usage)
quit()
# By default, OS-standard script languages (Ruby and Python) are used
NonOSStdLang = False
# Determine Ruby type
candidates = [ i.upper() for i in ['nil', 'Sys', 'Src24', 'MP24'] ]
ModuleRuby = ""
index = 0
for item in candidates:
if opt.type_ruby.upper() == item:
if index == 0:
ModuleRuby = 'nil'
break
elif index == 1:
if Platform == "Yosemite":
ModuleRuby = 'RubyYosemite'
elif Platform == "ElCapitan":
ModuleRuby = 'RubyElCapitan'
elif Platform == "Sierra":
ModuleRuby = 'RubySierra'
elif Platform == "HighSierra":
ModuleRuby = 'RubyHighSierra'
else:
ModuleRuby = ''
break
elif index == 2:
ModuleRuby = 'Ruby24SrcBuild'
NonOSStdLang = True
elif index == 3:
ModuleRuby = 'Ruby24MacPorts'
NonOSStdLang = True
else:
index += 1
if ModuleRuby == "":
print("")
print( "!!! Unknown Ruby type", file=sys.stderr )
print(Usage)
quit()
# Determine Python type
candidates = [ i.upper() for i in ['nil', 'Sys', 'Ana27', 'Ana36', 'MP36'] ]
ModulePython = ""
index = 0
for item in candidates:
if opt.type_python.upper() == item:
if index == 0:
ModulePython = 'nil'
break
elif index == 1:
if Platform == "Yosemite":
ModulePython = 'PythonYosemite'
elif Platform == "ElCapitan":
ModulePython = 'PythonElCapitan'
elif Platform == "Sierra":
ModulePython = 'PythonSierra'
elif Platform == "HighSierra":
ModulePython = 'PythonHighSierra'
else:
ModulePython = ''
break
elif index == 2:
ModulePython = 'Anaconda27'
NonOSStdLang = True
elif index == 3:
ModulePython = 'Anaconda36'
NonOSStdLang = True
elif index == 4:
ModulePython = 'Python36MacPorts'
NonOSStdLang = True
else:
index += 1
if ModulePython == "":
print("")
print( "!!! Unknown Python type", file=sys.stderr )
print(Usage)
quit()
NoQtBindings = opt.no_qt_binding
MakeOptions = opt.make_option
DebugMode = opt.debug_build
CheckComOnly = opt.check_command
DeploymentF = opt.deploy_full
DeploymentP = opt.deploy_partial
if DeploymentF and DeploymentP:
print("")
print( "!!! Choose either [-y|--deploy] or [-Y|--DEPLOY]", file=sys.stderr )
print(Usage)
quit()
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()
if not DeploymentF and not DeploymentP:
target = "%s %s %s" % (Platform, Release, Machine)
modules = "Qt=%s, Ruby=%s, Python=%s" % (ModuleQt, ModuleRuby, ModulePython)
message = "### You are going to build KLayout\n for <%s>\n with <%s>...\n"
print("")
print( message % (target, modules) )
#------------------------------------------------------------------------------
## To run the main Bash script "build.sh" with appropriate options
#
# @return 0 on success; non-zero on failure
#------------------------------------------------------------------------------
def RunMainBuildBash():
global ProjectDir
global Platform
global BuildBash
global ModuleQt
global ModuleRuby
global ModulePython
global NoQtBindings
global MakeOptions
global DebugMode
global CheckComOnly
global DeploymentF
global MacPkgDir # relative path to package directory
global MacBinDir # relative path to binary directory
global MacBuildDir # relative path to build directory
global MacBuildLog # relative path to build log file
global AbsMacPkgDir # absolute path to package directory
global AbsMacBinDir # absolute path to binary directory
global AbsMacBuildDir # absolute path to build directory
global AbsMacBuildLog # absolute path to build log file
#-----------------------------------------------------
# [1] Set parameters passed to the main Bash script
#-----------------------------------------------------
parameters = ""
# (A) debug or release
if DebugMode:
mode = "debug"
parameters += " -debug"
else:
mode = "release"
parameters += " -release"
# (B) Qt4 or Qt5
if ModuleQt == 'Qt4MacPorts':
parameters += " \\\n -qt4"
parameters += " \\\n -qmake %s" % Qt4MacPorts['qmake']
MacPkgDir = "./qt4.pkg.macos-%s-%s" % (Platform, mode)
MacBinDir = "./qt4.bin.macos-%s-%s" % (Platform, mode)
MacBuildDir = "./qt4.build.macos-%s-%s" % (Platform, mode)
MacBuildLog = "./qt4.build.macos-%s-%s.log" % (Platform, mode)
AbsMacPkgDir = "%s/qt4.pkg.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBinDir = "%s/qt4.bin.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBuildDir = "%s/qt4.build.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBuildLog = "%s/qt4.build.macos-%s-%s.log" % (ProjectDir, Platform, mode)
parameters += " \\\n -bin %s" % MacBinDir
parameters += " \\\n -build %s" % MacBuildDir
elif ModuleQt == 'Qt5MacPorts':
parameters += " \\\n -qt5"
parameters += " \\\n -qmake %s" % Qt5MacPorts['qmake']
MacPkgDir = "./qt5.pkg.macos-%s-%s" % (Platform, mode)
MacBinDir = "./qt5.bin.macos-%s-%s" % (Platform, mode)
MacBuildDir = "./qt5.build.macos-%s-%s" % (Platform, mode)
MacBuildLog = "./qt5.build.macos-%s-%s.log" % (Platform, mode)
AbsMacPkgDir = "%s/qt5.pkg.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBinDir = "%s/qt5.bin.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBuildDir = "%s/qt5.build.macos-%s-%s" % (ProjectDir, Platform, mode)
AbsMacBuildLog = "%s/qt5.build.macos-%s-%s.log" % (ProjectDir, Platform, mode)
parameters += " \\\n -bin %s" % MacBinDir
parameters += " \\\n -build %s" % MacBuildDir
# (C) want Qt bindings with Ruby scripts?
if NoQtBindings:
parameters += " \\\n -without-qtbinding"
else:
parameters += " \\\n -with-qtbinding"
# (D) options to `make` tool
if not MakeOptions == "":
parameters += " \\\n -option %s" % MakeOptions
# (E) about Ruby
if ModuleRuby == "nil":
parameters += " \\\n -noruby"
else:
parameters += " \\\n -ruby %s" % RubyDictionary[ModuleRuby]['exe']
parameters += " \\\n -rbinc %s" % RubyDictionary[ModuleRuby]['inc']
parameters += " \\\n -rblib %s" % RubyDictionary[ModuleRuby]['lib']
# (F) about Python
if ModulePython == "nil":
parameters += " \\\n -nopython"
else:
parameters += " \\\n -python %s" % PythonDictionary[ModulePython]['exe']
parameters += " \\\n -pyinc %s" % PythonDictionary[ModulePython]['inc']
parameters += " \\\n -pylib %s" % PythonDictionary[ModulePython]['lib']
#-----------------------------------------------------
# [2] Make the consolidated command line
#-----------------------------------------------------
command = "time"
command += " \\\n %s" % BuildBash
command += parameters
command += " 2>&1 | tee %s" % MacBuildLog
if CheckComOnly:
print(command)
quit()
#-----------------------------------------------------
# [3] Invoke the main Bash script; takes time:-)
#-----------------------------------------------------
if DeploymentF:
return 0
elif DeploymentP:
return 0
else:
myscript = "build4mac.py"
if subprocess.call( command, shell=True ) != 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
else:
print( "", file=sys.stderr )
print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++", file=sys.stderr )
print( "### <%s>: successfully built KLayout" % 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
# on which those binaries depend.
#
# Reference: "Deploying an Application on Mac OS X" of Qt Assistant.
#
# @return 0 on success; non-zero on failure
#------------------------------------------------------------------------------
def DeployBinariesForBundle():
global ProjectDir
global ModuleQt
global NonOSStdLang
global DeploymentF
global DeploymentP
global MacPkgDir
global MacBinDir
global MacBuildDir
global MacBuildLog
global AbsMacPkgDir
global AbsMacBinDir
global AbsMacBuildDir
global AbsMacBuildLog
global Version
global DeployVerbose
print("")
print( "##### Started deploying libraries and executables for <klayout.app> #####" )
print( " [1] Checking the status of working directory ..." )
#-------------------------------------------------------------
# [1] Check the status of working directory
#-------------------------------------------------------------
os.chdir(ProjectDir)
if not DeploymentF and not DeploymentP:
return 1
if DeploymentF and NonOSStdLang:
print( "!!! You chose <-y|--deploy> while using non-OS-standard script language.", file=sys.stderr )
print( " Use <-Y|--DEPLOY> instead", file=sys.stderr )
return 1
if not os.path.isfile(MacBuildLog):
print( "!!! Build log file <%s> does not present !!!" % MacBuildLog, file=sys.stderr )
return 1
if not os.path.isdir(MacBuildDir):
print( "!!! Build directory <%s> does not present !!!" % MacBuildDir, file=sys.stderr )
return 1
if not os.path.isdir(MacBinDir):
print( "!!! Binary directory <%s> does not present !!!" % MacBinDir, file=sys.stderr )
return 1
print( " [2] Creating a new empty directory <%s> for deployment ..." % MacPkgDir )
#-------------------------------------------------------------
# [2] Create a new empty directory for deploying binaries
#-------------------------------------------------------------
os.chdir(ProjectDir)
if os.path.isfile(MacPkgDir):
os.remove(MacPkgDir)
if os.path.isdir(MacPkgDir):
shutil.rmtree(MacPkgDir)
os.mkdir(MacPkgDir)
print( " [3] Creating the standard directory structure for 'klayout.app' bundle ..." )
#-----------------------------------------------------------------
# [3] Create the directory skeleton for "klayout.app" bundle
# and command line buddy tools such as "strm2cif".
# They are stored in the directory structure below.
#
# klayout.app/+
# +-- Contents/+
# +-- Info.plist
# +-- PkgInfo
# +-- Resources/+
# | +-- 'klayout.icns'
# +-- Frameworks/+
# | +-- '*.framework'
# | +-- '*.dylib'
# +-- MacOS/+
# | +-- 'klayout'
# +-- Buddy/+
# +-- 'strm2cif'
# +-- 'strm2dxf'
# :
# +-- 'strmxor'
#-----------------------------------------------------------------
targetDir0 = "%s/klayout.app/Contents" % AbsMacPkgDir
targetDirR = targetDir0 + "/Resources"
targetDirF = targetDir0 + "/Frameworks"
targetDirM = targetDir0 + "/MacOS"
targetDirB = targetDir0 + "/Buddy"
os.makedirs(targetDirR)
os.makedirs(targetDirF)
os.makedirs(targetDirM)
os.makedirs(targetDirB)
print( " [4] Copying KLayout's dynamic link libraries to 'Frameworks' ..." )
#-------------------------------------------------------------------------------
# [4] Copy KLayout's dynamic link libraries to "Frameworks/" and create
# the library dependency dictionary.
# <<< Do this job in "Frameworks/" >>>
#
# Note:
# KLayout's dynamic link library is built as below:
# (1) libklayout_lay.0.25.0.dylib
# (2) libklayout_lay.0.25.dylib -> libklayout_lay.0.25.0.dylib
# (3) libklayout_lay.0.dylib -> libklayout_lay.0.25.0.dylib
# (4) libklayout_lay.dylib -> libklayout_lay.0.25.0.dylib
# where,
# (1) is an ordinary file with full version number 'major.minor.teeny'
# between "library_name."='libklayout_lay.' and '.dylib'
# (2) is a symbolic link with 'major.minor' version number
# (3) is a symbolic link with 'major' version number
# (4) is a symbolic link without version number number
#
# The dynamic linker tries to find a library name in style (3) as shown
# in the example below.
#
# Example:
# MacBookPro(1)$ otool -L klayout
# klayout:
# :
# :
# libklayout_tl.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_gsi.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_db.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# :
#-------------------------------------------------------------------------------
os.chdir( targetDirF )
dynamicLinkLibs = glob.glob( AbsMacBinDir + "/*.dylib" )
depDicOrdinary = {} # inter-library dependency dictionary
for item in dynamicLinkLibs:
if os.path.isfile(item) and not os.path.islink(item):
#-------------------------------------------------------------------
# (A) Copy an ordinary *.dylib file here by changing the name
# to style (3) and set its mode to 0755 (sanity check).
#-------------------------------------------------------------------
fullName = os.path.basename(item).split('.')
# e.g. [ 'libklayout_lay', '0', '25', '0', 'dylib' ]
nameStyle3 = fullName[0] + "." + fullName[1] + ".dylib"
shutil.copy2( item, nameStyle3 )
os.chmod( nameStyle3, 0755 )
#-------------------------------------------------------------------
# (B) Then get inter-library dependencies
#-------------------------------------------------------------------
otoolCm = "otool -L %s | grep libklayout" % nameStyle3
otoolOut = os.popen( otoolCm ).read()
dependDic = DecomposeLibraryDependency(otoolOut)
depDicOrdinary.update(dependDic)
'''
PrintLibraryDependencyDictionary( depDicOrdinary, "Style (3)" )
quit()
'''
print( " [5] Setting and changing the identification names among KLayout's libraries ..." )
#-------------------------------------------------------------
# [5] Set the identification names for KLayout's libraries
# and make the library aware of the locations of libraries
# on which it depends; that is, inter-library dependency
#-------------------------------------------------------------
ret = SetChangeIdentificationNameOfDyLib( depDicOrdinary )
if not ret == 0:
msg = "!!! Failed to set and change to new identification names !!!"
print(msg)
return 1
print( " [6] Copying built executables and resource files ..." )
#-------------------------------------------------------------
# [6] Copy some known files in source directories to
# relevant target directories
#-------------------------------------------------------------
os.chdir(ProjectDir)
sourceDir0 = "%s/klayout.app/Contents" % MacBinDir
sourceDir1 = sourceDir0 + "/MacOS"
sourceDir2 = "%s/macbuild/Resources" % ProjectDir
sourceDir3 = "%s" % MacBinDir
tmpfileM = ProjectDir + "/macbuild/Resources/Info.plist.template"
keydicM = { 'exe': 'klayout', 'icon': 'klayout.icns', 'bname': 'klayout', 'ver': Version }
plistM = GenerateInfoPlist( keydicM, tmpfileM )
file = open( targetDir0 + "/Info.plist", "w" )
file.write(plistM)
file.close()
shutil.copy2( sourceDir0 + "/PkgInfo", targetDir0 ) # this file is not mandatory
shutil.copy2( sourceDir1 + "/klayout", targetDirM )
shutil.copy2( sourceDir2 + "/klayout.icns", targetDirR )
os.chmod( targetDir0 + "/PkgInfo", 0644 )
os.chmod( targetDir0 + "/Info.plist", 0644 )
os.chmod( targetDirM + "/klayout", 0755 )
os.chmod( targetDirR + "/klayout.icns", 0644 )
buddies = glob.glob( sourceDir3 + "/strm*" )
for item in buddies:
shutil.copy2( item, targetDirB )
buddy = os.path.basename(item)
os.chmod( targetDirB + "/" + buddy, 0755 )
print( " [7] Setting and changing the identification names of KLayout's libraries in each executable ..." )
#-------------------------------------------------------------
# [7] Set and change the library identification name(s) of
# different executables
#-------------------------------------------------------------
os.chdir(ProjectDir)
os.chdir(MacPkgDir)
klayoutexec = "klayout.app/Contents/MacOS/klayout"
ret = SetChangeLibIdentificationName( klayoutexec, "../Frameworks" )
if not ret == 0:
os.chdir(ProjectDir)
msg = "!!! Failed to set/change library identification name for <%s> !!!"
print( msg % klayoutexec, file=sys.stderr )
return 1
buddies = glob.glob( "klayout.app/Contents/Buddy/strm*" )
macdepQtOpt = ""
for buddy in buddies:
macdepQtOpt += "-executable=%s " % buddy
ret = SetChangeLibIdentificationName( buddy, "../Frameworks" )
if not ret == 0:
os.chdir(ProjectDir)
msg = "!!! Failed to set/change library identification name for <%s> !!!"
print( msg % buddy, file=sys.stderr )
return 1
if DeploymentF:
print( " [8] Finally, deploying Qt's Frameworks ..." )
#-------------------------------------------------------------
# [8] Deploy Qt Frameworks
#-------------------------------------------------------------
verbose = " -verbose=%d" % DeployVerbose
if ModuleQt == 'Qt4MacPorts':
deploytool = Qt4MacPorts['deploy']
app_bundle = "klayout.app"
options = macdepQtOpt + verbose
elif ModuleQt == 'Qt5MacPorts':
deploytool = Qt5MacPorts['deploy']
app_bundle = "klayout.app"
options = macdepQtOpt + verbose
os.chdir(ProjectDir)
os.chdir(MacPkgDir)
command = "%s %s %s" % ( deploytool, app_bundle, options )
if subprocess.call( command, shell=True ) != 0:
msg = "!!! Failed to deploy applications on OSX !!!"
print( msg, file=sys.stderr )
print("")
os.chdir(ProjectDir)
return 1
else:
print( "##### Finished deploying libraries and executables for <klayout.app> #####" )
print("")
os.chdir(ProjectDir)
return 0
else:
print( " [8] Skipped deploying Qt's Frameworks ..." )
print( "##### Finished deploying libraries and executables for <klayout.app> #####" )
print("")
os.chdir(ProjectDir)
return 0
#------------------------------------------------------------------------------
## To deploy script bundles that invoke the main bundle (klayout.app) in
# editor mode or viewer mode
#
# @return 0 on success; non-zero on failure
#------------------------------------------------------------------------------
def DeployScriptBundles():
global ProjectDir
global MacPkgDir
global AbsMacPkgDir
print("")
print( "##### Started deploying files for <KLayoutEditor.app> and <KLayoutViewer.app> #####" )
print( " [1] Checking the status of working directory ..." )
#-------------------------------------------------------------
# [1] Check the status of working directory
#-------------------------------------------------------------
os.chdir(ProjectDir)
if not os.path.isdir(MacPkgDir):
print( "!!! Package directory <%s> does not present !!!" % MacPkgDir, file=sys.stderr )
return 1
print( " [2] Creating a new empty directory <%s> for deployment ..." % (MacPkgDir + "/klayout.scripts") )
#-------------------------------------------------------------
# [2] Create a new empty directory for deploying binaries
#-------------------------------------------------------------
os.chdir(MacPkgDir)
scriptDir = "klayout.scripts"
if os.path.isfile(scriptDir):
os.remove(scriptDir)
if os.path.isdir(scriptDir):
shutil.rmtree(scriptDir)
os.mkdir(scriptDir)
print( " [3] Creating the standard directory structure for the script bundles ..." )
#--------------------------------------------------------------------------------------------
# [3] Create the directory skeleton for the two script bundles.
#
# klayout.scripts/+
# +-- KLayoutEditor.app/+
# | +-- Contents/+
# | +-- Info.plist
# | +-- Resources/+
# | | +-- 'klayout-red.icns'
# | +-- MacOS/+
# | +-- 'KLayoutEditor.sh'
# +-- KLayoutViewer.app/+
# +-- Contents/+
# +-- Info.plist
# +-- Resources/+
# | +-- 'klayout-blue.icns'
# +-- MacOS/+
# +-- 'KLayoutViewer.sh'
#--------------------------------------------------------------------------------------------
os.chdir(ProjectDir)
targetDir0E = "%s/%s/KLayoutEditor.app/Contents" % ( AbsMacPkgDir, scriptDir )
targetDir0V = "%s/%s/KLayoutViewer.app/Contents" % ( AbsMacPkgDir, scriptDir )
targetDirME = targetDir0E + "/MacOS"
targetDirMV = targetDir0V + "/MacOS"
targetDirRE = targetDir0E + "/Resources"
targetDirRV = targetDir0V + "/Resources"
os.makedirs(targetDirME)
os.makedirs(targetDirMV)
os.makedirs(targetDirRE)
os.makedirs(targetDirRV)
print( " [4] Copying script files and icon files ..." )
#-------------------------------------------------------------------------------
# [4] Copy different script files icon files
#-------------------------------------------------------------------------------
os.chdir(ProjectDir)
resourceDir = "macbuild/Resources"
shutil.copy2( resourceDir + "/KLayoutEditor.sh", targetDirME )
shutil.copy2( resourceDir + "/KLayoutViewer.sh", targetDirMV )
shutil.copy2( resourceDir + "/klayout-red.icns", targetDirRE )
shutil.copy2( resourceDir + "/klayout-blue.icns", targetDirRV )
os.chmod( targetDirME + "/KLayoutEditor.sh", 0755 )
os.chmod( targetDirMV + "/KLayoutViewer.sh", 0755 )
os.chmod( targetDirRE + "/klayout-red.icns", 0644 )
os.chmod( targetDirRV + "/klayout-blue.icns", 0644 )
tmpfileE = ProjectDir + "/macbuild/Resources/Info.plist.template"
keydicE = { 'exe': 'KLayoutEditor.sh', 'icon': 'klayout-red.icns', 'bname': 'klayout', 'ver': Version }
plistE = GenerateInfoPlist( keydicE, tmpfileE )
fileE = open( targetDir0E + "/Info.plist", "w" )
fileE.write(plistE)
fileE.close()
tmpfileV = ProjectDir + "/macbuild/Resources/Info.plist.template"
keydicV = { 'exe': 'KLayoutViewer.sh', 'icon': 'klayout-blue.icns', 'bname': 'klayout', 'ver': Version }
plistV = GenerateInfoPlist( keydicV, tmpfileV )
fileV = open( targetDir0V + "/Info.plist", "w" )
fileV.write(plistV)
fileV.close()
print( "##### Finished deploying files for <KLayoutEditor.app> and <KLayoutViewer.app> #####" )
print("")
os.chdir(ProjectDir)
return 0
#------------------------------------------------------------------------------
## The main function
#------------------------------------------------------------------------------
def main():
SetGlobals()
ParseCommandLineArguments()
#----------------------------------------------------------
# [The main build stage]
#----------------------------------------------------------
ret = RunMainBuildBash()
if not DeploymentF and not DeploymentP:
if ret == 0:
sys.exit(0)
else:
sys.exit(1)
else:
#----------------------------------------------------------
# [Deployment stage-1]
# Deployment of dynamic link libraries, executables and
# resources to make the main "klayout.app" bundle
#----------------------------------------------------------
ret1 = DeployBinariesForBundle()
if not ret1 == 0:
sys.exit(1)
#----------------------------------------------------------
# [Deployment stage-2]
# Deployment of wrapper Bash scripts and resources
# to make "KLayoutEditor.app" and "KLayoutViewer.app"
#----------------------------------------------------------
ret2 = DeployScriptBundles()
if ret2 == 0:
sys.exit(1)
else:
sys.exit(0)
#===================================================================================
if __name__ == "__main__":
main()
#---------------
# End of file
#---------------

193
macbuild/build4mac_env.py Executable file
View File

@ -0,0 +1,193 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
#===============================================================================
# File: "macbuild/build4mac_env.py"
#
# Here are dictionaries of ...
# different modules for building KLayout (http://www.klayout.de/index.php)
# version 0.25 or later on different Apple Mac OSX platforms.
#
# This file is imported by 'build4mac.py' script.
#===============================================================================
#-----------------------------------------------------
# [0] Xcode's tools
#-----------------------------------------------------
XcodeToolChain = { 'nameID': '/usr/bin/install_name_tool -id ',
'nameCH': '/usr/bin/install_name_tool -change '
}
#-----------------------------------------------------
# [1] Qt
#-----------------------------------------------------
Qts = [ 'Qt4MacPorts', 'Qt5MacPorts' ]
#-----------------------------------------------------
# Whereabout of different components of Qt4
#-----------------------------------------------------
# Qt4 from MacPorts (https://www.macports.org/)
# [Key Type Name] = 'Qt4MacPorts'
Qt4MacPorts = { 'qmake' : '/opt/local/libexec/qt4/bin/qmake',
'deploy': '/opt/local/libexec/qt4/bin/macdeployqt'
}
#-----------------------------------------------------
# Whereabout of different components of Qt5
#-----------------------------------------------------
# Qt5 from MacPorts (https://www.macports.org/)
# [Key Type Name] = 'Qt5MacPorts'
Qt5MacPorts = { 'qmake' : '/opt/local/libexec/qt5/bin/qmake',
'deploy': '/opt/local/libexec/qt5/bin/macdeployqt'
}
#-----------------------------------------------------
# [2] Ruby
#-----------------------------------------------------
Rubies = [ 'nil', 'RubyYosemite', 'RubyElCapitan', 'RubySierra', 'RubyHighSierra' ]
Rubies += [ 'Ruby24SrcBuild', 'Ruby24MacPorts' ]
#-----------------------------------------------------
# Whereabout of different components of Ruby
#-----------------------------------------------------
# Bundled with Yosemite (10.10)
# [Key Type Name] = 'Sys'
RubyYosemite = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby' ,
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.dylib'
}
# Bundled with El Capitan (10.11)
# [Key Type Name] = 'Sys'
RubyElCapitan = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby' ,
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.dylib'
}
# Bundled with Sierra (10.12)
# [Key Type Name] = 'Sys'
RubySierra = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby' ,
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.dylib'
}
# Bundled with High Sierra (10.13)
# [Key Type Name] = 'Sys'
RubyHighSierra = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby' ,
'inc': '/System/Library/Frameworks/Ruby.framework/Headers',
'lib': '/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/libruby.dylib'
}
# Ruby 2.4 built from source code (https://github.com/ruby): *+*+*+ EXPERIMENTAL *+*+*+
# configured by:
# $ ./configure --prefix=$HOME/Ruby24/ --enable-shared --program-suffix=2.4
# [Key Type Name] = 'Src24'
Ruby24SrcBuild = { 'exe': '$HOME/Ruby24/bin/ruby2.4',
'inc': '$HOME/Ruby24/include/ruby-2.4.0',
'lib': '$HOME/Ruby24/lib/libruby.2.4.dylib'
}
# Ruby 2.4 from MacPorts (https://www.macports.org/) *+*+*+ EXPERIMENTAL *+*+*+
# [Key Type Name] = 'MP24'
Ruby24MacPorts = { 'exe': '/opt/local/bin/ruby2.4',
'inc': '/opt/local/include/ruby-2.4.0',
'lib': '/opt/local/lib/libruby.2.4.dylib'
}
# Consolidated dictionary kit for Ruby
RubyDictionary = { 'nil' : None,
'RubyYosemite' : RubyYosemite,
'RubyElCapitan' : RubyElCapitan,
'RubySierra' : RubySierra,
'RubyHighSierra': RubyHighSierra,
'Ruby24SrcBuild': Ruby24SrcBuild,
'Ruby24MacPorts': Ruby24MacPorts
}
#-----------------------------------------------------
# [3] Python
#-----------------------------------------------------
Pythons = [ 'nil', 'PythonYosemite', 'PythonElCapitan', 'PythonSierra', 'PythonHighSierra' ]
Pythons += [ 'Anaconda27', 'Anaconda36', 'Python36MacPorts' ]
#-----------------------------------------------------
# Whereabout of different components of Python
#-----------------------------------------------------
# Bundled with Yosemite (10.10)
# [Key Type Name] = 'Sys'
PythonYosemite = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python' ,
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
}
# Bundled with El Capitan (10.11)
# [Key Type Name] = 'Sys'
PythonElCapitan = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python' ,
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
}
# Bundled with Sierra (10.12)
# [Key Type Name] = 'Sys'
PythonSierra = { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python' ,
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
}
# Bundled with High Sierra (10.13)
# [Key Type Name] = 'Sys'
PythonHighSierra= { 'exe': '/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python' ,
'inc': '/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7',
'lib': '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib'
}
# Using anaconda2 (https://www.anaconda.com/download/#macos) 5.0.1: *+*+*+ EXPERIMENTAL *+*+*+
# If the path to your `conda` command is '$HOME/anaconda2/bin/conda'
# and your Python environment was prepared by: $ conda create -n py27klayout python=2.7
#
# No additional modules are installed in the experiment.
# [Key Type Name] = 'Ana27'
Anaconda27 = { 'exe': '$HOME/anaconda2/envs/py27klayout/bin/python2.7' ,
'inc': '$HOME/anaconda2/envs/py27klayout/include/python2.7',
'lib': '$HOME/anaconda2/envs/py27klayout/lib/libpython2.7.dylib'
}
# Using anaconda2 (https://www.anaconda.com/download/#macos) 5.0.1: *+*+*+ EXPERIMENTAL *+*+*+
# If the path to your `conda` command is '$HOME/anaconda2/bin/conda'
# and your Python environment was prepared by: $ conda create -n py36klayout python=3.6
#
# No additional modules are installed in the experiment.
# [Key Type Name] = 'Ana36'
Anaconda36 = { 'exe': '$HOME/anaconda2/envs/py36klayout/bin/python3.6' ,
'inc': '$HOME/anaconda2/envs/py36klayout/include/python3.6m',
'lib': '$HOME/anaconda2/envs/py36klayout/lib/libpython3.6m.dylib'
}
# Python 3.6 from MacPorts (https://www.macports.org/) *+*+*+ EXPERIMENTAL *+*+*+
# [Key Type Name] = 'MP36'
Python36MacPorts= { 'exe': '/opt/local/Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6m' ,
'inc': '/opt/local/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m',
'lib': '/opt/local/Library/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6m.dylib'
}
# Consolidated dictionary kit for Python
PythonDictionary= { 'nil' : None,
'PythonYosemite' : PythonYosemite,
'PythonElCapitan' : PythonElCapitan,
'PythonSierra' : PythonSierra,
'PythonHighSierra': PythonHighSierra,
'Anaconda27' : Anaconda27,
'Anaconda36' : Anaconda36,
'Python36MacPorts': Python36MacPorts
}
#-----------------------------------------------------
# [4] KLayout executables including buddy tools
#-----------------------------------------------------
KLayoutExecs = ['klayout']
KLayoutExecs += ['strm2cif', 'strm2dxf', 'strm2gds', 'strm2gdstxt', 'strm2oas']
KLayoutExecs += ['strm2txt', 'strmclip', 'strmcmp', 'strmrun', 'strmxor']
#----------------
# End of File
#----------------

231
macbuild/build4mac_util.py Executable file
View File

@ -0,0 +1,231 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
#===============================================================================
# File: "macbuild/build4mac_util.py"
#
# Here are utility functions and classes ...
# for building KLayout (http://www.klayout.de/index.php)
# version 0.25 or later on different Apple Mac OSX platforms.
#
# This file is imported by 'build4mac.py' script.
#===============================================================================
from __future__ import print_function # to use print() of Python 3 in Python >= 2.7
import sys
import os
import re
import string
import subprocess
#-------------------------------------------------------------------------------
## To import global dictionaries of different modules
#-------------------------------------------------------------------------------
mydir = os.path.dirname(os.path.abspath(__file__))
sys.path.append( mydir )
from build4mac_env import *
#------------------------------------------------------------------------------
## To decompose strings obtained by 'otool -L <*.dylib>' command and to
# generate a dictionary of KLayout's inter-library dependency.
#
# @param[in] depstr strings that tell dependency such as:
#
# libklayout_edt.0.dylib:
# libklayout_edt.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_tl.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_gsi.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_laybasic.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# libklayout_db.0.dylib (compatibility version 0.25.0, current version 0.25.0)
# :
# :
#
# @return a dictionary
#------------------------------------------------------------------------------
def DecomposeLibraryDependency( depstr ):
alllines = depstr.split('\n')
numlines = len(alllines)
dependent = alllines[0].split(':')[0].strip(' ').strip('\t')
supporters = []
for i in range(1, numlines):
supporter = alllines[i].split(' ')[0].strip(' ').strip('\t')
if not supporter == '':
supporters.append(supporter)
return { dependent: supporters }
#------------------------------------------------------------------------------
## To print the contents of a library dependency dictionary
#
# @param[in] depdic dictionary
# @param[in] namedic dictionary name
#------------------------------------------------------------------------------
def PrintLibraryDependencyDictionary( depdic, namedic ):
keys = depdic.keys()
print("")
print("##### Contents of <%s> #####:" % namedic )
for key in keys:
supporters = depdic[key]
print( " %s:" % key )
for item in supporters:
print( " %s" % item )
#------------------------------------------------------------------------------
## To set and change identification name of KLayout's dylib
#
# @param[in] libdic inter-library dependency dictionary
#
# @return 0 on success; non-zero on failure
#------------------------------------------------------------------------------
def SetChangeIdentificationNameOfDyLib( libdic ):
cmdNameId = XcodeToolChain['nameID']
cmdNameChg = XcodeToolChain['nameCH']
dependentLibs = libdic.keys()
for lib in dependentLibs:
#-----------------------------------------------------------
# [1] Set the identification name of each dependent library
#-----------------------------------------------------------
nameOld = "%s" % lib
nameNew = "@executable_path/../Frameworks/%s" % lib
command = "%s %s %s" % ( cmdNameId, nameNew, nameOld )
if subprocess.call( command, shell=True ) != 0:
msg = "!!! Failed to set the new identification name to <%s> !!!"
print( msg % lib, file=sys.stderr )
return 1
#-------------------------------------------------------------------------
# [2] Make the library aware of the new identifications of all supporters
#-------------------------------------------------------------------------
supporters = libdic[lib]
for sup in supporters:
nameOld = "%s" % sup
nameNew = "@executable_path/../Frameworks/%s" % sup
command = "%s %s %s %s" % ( cmdNameChg, nameOld, nameNew, lib )
if subprocess.call( command, shell=True ) != 0:
msg = "!!! Failed to make the library aware of the new identification name <%s> of supporter <%s> !!!"
print( msg % (nameNew, sup), file=sys.stderr )
return 1
# 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
#
# @param[in] executable path/to/executable -- (1)
# @param[in] relativedir directory of dylib relative to executable -- (2)
#
# Example: (1) "klayout.app/Contents/MacOS/klayout"
# (2) "../Frameworks"
#
# klayout.app/+
# +-- Contents/+
# +-- Info.plist
# +-- PkgInfo
# +-- Resources/+
# | +-- 'klayout.icns'
# +-- Frameworks/+
# | +-- '*.framework'
# | +-- '*.dylib'
# +-- MacOS/+
# | +-- 'klayout'
# +-- Buddy/+
# +-- 'strm2cif'
# +-- 'strm2dxf'
# :
# +-- 'strmxor'
#
# @return 0 on success; non-zero on failure
#------------------------------------------------------------------------------
def SetChangeLibIdentificationName( executable, relativedir ):
cmdNameId = XcodeToolChain['nameID']
cmdNameChg = XcodeToolChain['nameCH']
otoolCm = "otool -L %s | grep libklayout" % executable
otoolOut = os.popen( otoolCm ).read()
exedepdic = DecomposeLibraryDependency( executable + ":\n" + otoolOut )
keys = exedepdic.keys()
deplibs = exedepdic[ keys[0] ]
for lib in deplibs:
#-----------------------------------------------------------
# [1] Set the identification names for the library
#-----------------------------------------------------------
nameOld = "klayout.app/Contents/Frameworks/%s" % lib
nameNew = "@executable_path/%s/%s" % ( relativedir, lib )
command = "%s %s %s" % ( cmdNameId, nameNew, nameOld )
if subprocess.call( command, shell=True ) != 0:
msg = "!!! Failed to set the new identification name to <%s> !!!"
print( msg % lib, file=sys.stderr )
return 1
#-----------------------------------------------------------
# [2] Make the application aware of the new identification
#-----------------------------------------------------------
nameOld = "%s" % lib
nameNew = "@executable_path/%s/%s" % ( relativedir, lib )
command = "%s %s %s %s" % ( cmdNameChg, nameOld, nameNew, executable )
if subprocess.call( command, shell=True ) != 0:
msg = "!!! Failed to make the application aware of the new identification name <%s> !!!"
print( msg % nameNew, file=sys.stderr )
return 1
# for-lib
return 0
#------------------------------------------------------------------------------
## To get KLayout's version from a file; most likely from 'version.sh'
#
# @param[in] verfile version file from which version is retrieved
#
# @return version string
#------------------------------------------------------------------------------
def GetKLayoutVersionFrom( verfile='version.h' ):
version = "?.?.?"
try:
fd = open( verfile, "r" )
contents = fd.readlines()
fd.close()
except Exception as e:
return version
verReg = re.compile( u'(KLAYOUT_VERSION=\")([0-9A-Z_a-z\.]+)(\")' )
for line in contents:
m = verReg.match(line)
if m:
# print(m.group(0)) # KLAYOUT_VERSION="0.25.1"
# print(m.group(1)) # KLAYOUT_VERSION="
# print(m.group(2)) # 0.25.1
# print(m.group(3)) # "
version = m.group(2)
return version
return version
#------------------------------------------------------------------------------
## To generate the contents of "Info.plist" file from a template
#
# @param[in] keydic dictionary of four key words ['exe', 'icon', 'bname', 'ver']
# @param[in] templfile template file ("macbuild/Resources/Info.plist.template")
#
# @return generated strings
#------------------------------------------------------------------------------
def GenerateInfoPlist( keydic, templfile ):
val_exe = keydic['exe']
val_icon = keydic['icon']
val_bname = keydic['bname']
val_ver = keydic['ver']
try:
fd = open( templfile, "r" )
template = fd.read()
fd.close()
except Exception as e:
return "???"
t = string.Template(template)
s = t.substitute( EXECUTABLE = val_exe,
ICONFILE = val_icon,
BUNDLENAME = val_bname,
VERSION = val_ver)
return s
#----------------
# End of File
#----------------

View File

@ -10,6 +10,8 @@
# drops enum members
drop_enum_const "Qt", /WindowType::WindowSoftkeysVisibleHint/
drop_enum_const "Qt", /WindowType::WindowSoftkeysRespondHint/
drop_enum_const "Qt", /WindowType::WindowOkButtonHint/ # only available on CE
drop_enum_const "Qt", /WindowType::WindowCancelButtonHint/ # only available on CE
# --------------------------------------------------------------
# QtCore

View File

@ -10,6 +10,8 @@
# drops enum members
drop_enum_const "Qt", /WindowType::WindowSoftkeysVisibleHint/
drop_enum_const "Qt", /WindowType::WindowSoftkeysRespondHint/
drop_enum_const "Qt", /WindowType::WindowOkButtonHint/ # only available on CE
drop_enum_const "Qt", /WindowType::WindowCancelButtonHint/ # only available on CE
# --------------------------------------------------------------
# QtCore
@ -1484,6 +1486,8 @@ final_class "QAccessibleObject" # because navigate cannot be implemented
# final_class "QAccessiblePlugin" # because navigate cannot be implemented
final_class "QAccessibleWidget" # because navigate cannot be implemented
no_copy_ctor "QIconEngine"
# --------------------------------------------------------------
# QtXml

View File

@ -32,14 +32,17 @@
# define ANT_PUBLIC __declspec(dllimport)
# endif
# define ANT_LOCAL
# define ANT_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define ANT_PUBLIC __attribute__ ((visibility ("default")))
# define ANT_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define ANT_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define ANT_PUBLIC
# define ANT_PUBLIC_TEMPLATE
# define ANT_LOCAL
# endif

View File

@ -32,14 +32,17 @@
# define BD_PUBLIC __declspec(dllimport)
# endif
# define BD_LOCAL
# define BD_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define BD_PUBLIC __attribute__ ((visibility ("default")))
# define BD_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define BD_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define BD_PUBLIC
# define BD_PUBLIC_TEMPLATE
# define BD_LOCAL
# endif

View File

@ -7,6 +7,12 @@ DESTDIR = $$OUT_PWD/../../..
include($$PWD/../../app.pri)
# On Mac OSX, these buddy tools have to be built as ordinary command line tools;
# not as bundles (*.app)
mac {
CONFIG -= app_bundle
}
# Since the main function is entirely unspecific, we can put it into a common
# place - it's not part of the bd sources.
SOURCES = $$PWD/bd/main.cc

View File

@ -1208,7 +1208,7 @@ struct array_iterator
typedef void pointer_type;
typedef void difference_type;
typedef void pointer;
typedef void iterator_category;
typedef std::forward_iterator_tag iterator_category;
/**
* @brief The default constructor

View File

@ -57,7 +57,7 @@ class ArrayRepository;
*/
template <class C, class R = C>
struct box
struct DB_PUBLIC_TEMPLATE box
{
typedef C coord_type;
typedef box<C, R> box_type;

View File

@ -32,14 +32,17 @@
# define DB_PUBLIC __declspec(dllimport)
# endif
# define DB_LOCAL
# define DB_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define DB_PUBLIC __attribute__ ((visibility ("default")))
# define DB_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define DB_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define DB_PUBLIC
# define DB_PUBLIC_TEMPLATE
# define DB_LOCAL
# endif

View File

@ -42,7 +42,7 @@ template <class C> class generic_repository;
class ArrayRepository;
template <class C>
class edge
class DB_PUBLIC_TEMPLATE edge
{
public:
typedef C coord_type;

View File

@ -40,7 +40,7 @@
namespace db {
template <class C>
class edge_pair
class DB_PUBLIC_TEMPLATE edge_pair
{
public:
typedef C coord_type;

View File

@ -229,8 +229,11 @@ private:
* @brief ctor from a recursive shape iterator
*/
EdgesIterator (const db::RecursiveShapeIterator &iter, const db::ICplxTrans &trans)
: m_rec_iter (iter), m_iter_trans (trans)
{
: m_rec_iter (iter), m_iter_trans (trans), m_from (), m_to ()
{
// NOTE: the following initialization appears to be required on some compilers
// (specifically MacOS/clang) to ensure the proper initialization of the iterators
m_from = m_to;
set ();
}

View File

@ -45,34 +45,34 @@ GDS2Writer::GDS2Writer ()
m_progress.set_unit (1024 * 1024);
}
inline void
void
GDS2Writer::write_byte (unsigned char b)
{
mp_stream->put ((const char *) &b, 1);
}
inline void
void
GDS2Writer::write_record_size (int16_t i)
{
gds2h (i);
mp_stream->put ( (char*)(&i), sizeof (i));
}
inline void
void
GDS2Writer::write_record (int16_t i)
{
gds2h (i);
mp_stream->put ( (char*)(&i), sizeof (i));
}
inline void
void
GDS2Writer::write_short (int16_t i)
{
gds2h (i);
mp_stream->put ( (char*)(&i), sizeof (i));
}
inline void
void
GDS2Writer::write_int (int32_t l)
{
gds2h (l);

View File

@ -74,7 +74,7 @@ namespace DB_HASH_NAMESPACE
};
#endif
#if defined(_WIN64)
#if defined(_WIN64) || defined(__APPLE__)
/**
* @brief Specialization missing for long long on WIN64
*/

View File

@ -509,6 +509,8 @@ private:
* determines how to initialize the iterators and what types to use.
*/
// NOTE: we do explicit instantiation, so the exposure is declared
// as DB_PUBLIC - as if it wasn't a template
template <class IterTraits>
class DB_PUBLIC instance_iterator
{

View File

@ -69,7 +69,7 @@ typedef generic_repository<db::Coord> GenericRepository;
* Since we are using a custom cell list, we have to provide our own iterator
*/
template <class C>
class DB_PUBLIC cell_list_iterator
class DB_PUBLIC_TEMPLATE cell_list_iterator
{
public:
typedef C cell_type;

View File

@ -207,6 +207,8 @@ private:
* The path can be converted to a polygon.
*/
// NOTE: we do explicit instantiation, so the exposure is declared
// as DB_PUBLIC - as if it wasn't a template
template <class C>
class DB_PUBLIC path
{

View File

@ -43,7 +43,7 @@ template <class C> class vector;
*/
template <class C>
class point
class DB_PUBLIC_TEMPLATE point
{
public:
typedef C coord_type;

View File

@ -83,6 +83,8 @@ inline bool default_compression<db::DCoord> ()
* hull and holes respectively.
*/
// NOTE: we do explicit instantiation, so the exposure is declared
// as DB_PUBLIC - as if it wasn't a template
template <class C>
class DB_PUBLIC polygon_contour
{
@ -1364,7 +1366,7 @@ private:
*/
template <class C>
class polygon
class DB_PUBLIC_TEMPLATE polygon
{
public:
typedef C coord_type;
@ -2324,7 +2326,7 @@ private:
*/
template <class C>
class simple_polygon
class DB_PUBLIC_TEMPLATE simple_polygon
{
public:
typedef C coord_type;

View File

@ -1593,7 +1593,7 @@ public:
* into the db::Object manager's undo/redo queue.
*/
template <class Sh, class StableTag>
class DB_PUBLIC layer_op
class DB_PUBLIC_TEMPLATE layer_op
: public LayerOpBase
{
public:

View File

@ -222,7 +222,7 @@ private:
*/
template <class C>
class text
class DB_PUBLIC_TEMPLATE text
{
public:
typedef C coord_type;

View File

@ -42,10 +42,10 @@ namespace tl {
namespace db {
template <class I, class F, class R = double> class complex_trans;
template <class C> class simple_trans;
template <class C> class disp_trans;
template <class C> class fixpoint_trans;
template <class I, class F, class R = double> class DB_PUBLIC_TEMPLATE complex_trans;
template <class C> class DB_PUBLIC_TEMPLATE simple_trans;
template <class C> class DB_PUBLIC_TEMPLATE disp_trans;
template <class C> class DB_PUBLIC_TEMPLATE fixpoint_trans;
/**
* @brief Provide the default predicates and properties for transformations for the coordinate type C
@ -1035,7 +1035,7 @@ operator<< (std::ostream &os, const disp_trans<C> &t)
*/
template <class C>
class simple_trans
class DB_PUBLIC_TEMPLATE simple_trans
: public fixpoint_trans<C>
{
public:
@ -1439,7 +1439,7 @@ operator<< (std::ostream &os, const simple_trans<C> &t)
* type used internally for representing the floating-point members).
*/
template <class I, class F, class R>
class complex_trans
class DB_PUBLIC_TEMPLATE complex_trans
{
public:
typedef I coord_type;

View File

@ -54,7 +54,7 @@ DB_PUBLIC unsigned int get_unique_user_object_class_id ();
* in order to be able to be put into a user_object<C>.
*/
template <class C>
class user_object_base
class DB_PUBLIC_TEMPLATE user_object_base
{
public:
typedef C coord_type;
@ -399,7 +399,7 @@ typedef user_object<db::DCoord> DUserObject;
* @brief The base object of a factory-instantiable object
*/
template <class C>
class user_object_factory_base
class DB_PUBLIC_TEMPLATE user_object_factory_base
{
public:
user_object_factory_base () { }
@ -414,7 +414,7 @@ public:
* This implements a factory for objects of class X with coordinate base type C.
*/
template <class X, class C>
class user_object_factory_impl
class DB_PUBLIC_TEMPLATE user_object_factory_impl
: public user_object_factory_base <C>
{
public:

View File

@ -45,7 +45,7 @@ template <class C> class point;
*/
template <class C>
class vector
class DB_PUBLIC_TEMPLATE vector
{
public:
typedef C coord_type;

View File

@ -70,7 +70,7 @@ struct LayoutQueryIteratorWrapper
{
typedef db::LayoutQueryIterator &reference;
// Dummy declarations
typedef void iterator_category;
typedef std::forward_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;

View File

@ -954,7 +954,7 @@ struct ConvertingIteratorWrapper
typedef T value_type;
typedef T reference;
typedef void pointer;
typedef void iterator_category;
typedef std::forward_iterator_tag iterator_category;
ConvertingIteratorWrapper (double dbu, const I &b, const I &e)
: m_b (b), m_e (e), m_dbu (dbu)
@ -989,7 +989,7 @@ struct ConvertingFreeIteratorWrapper
typedef T value_type;
typedef T reference;
typedef void pointer;
typedef void iterator_category;
typedef std::forward_iterator_tag iterator_category;
ConvertingFreeIteratorWrapper (double dbu, const I &b)
: m_b (b), m_dbu (dbu)

View File

@ -570,13 +570,13 @@ TEST(2)
}
c0.erase (i4);
EXPECT_EQ (c2s_unsorted(c0), "5[r0 *1 0,0]#2,3[r0 *1 0,0]#13");
EXPECT_EQ (c0.cell_instances (), size_t (2));
c0.erase (i5);
EXPECT_EQ (c2s_unsorted(c0), "5[r0 *1 0,0]#2,1[r0 *1 0,0]#1");
EXPECT_EQ (c0.cell_instances (), size_t (2));
c0.erase (i4);
EXPECT_EQ (c2s_unsorted(c0), "5[r0 *1 0,0]#2");
EXPECT_EQ (c0.cell_instances (), size_t (1));
// not yet: EXPECT_EQ (c0.empty (), false);
// Not yet: EXPECT_EQ (c0.empty (), false);
// note: double delete is not supported in non-editable mode
if (db::default_editable_mode ()) {
@ -608,7 +608,7 @@ TEST(2)
c0.erase (i3);
EXPECT_EQ (c2s_unsorted(c0), "");
EXPECT_EQ (c0.cell_instances (), size_t (0));
// not yet: EXPECT_EQ (c0.empty (), true);
// Not yet: EXPECT_EQ (c0.empty (), true);
}
TEST(3)

View File

@ -32,14 +32,17 @@
# define DRC_PUBLIC __declspec(dllimport)
# endif
# define DRC_LOCAL
# define DRC_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define DRC_PUBLIC __attribute__ ((visibility ("default")))
# define DRC_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define DRC_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define DRC_PUBLIC
# define DRC_PUBLIC_TEMPLATE
# define DRC_LOCAL
# endif

View File

@ -32,14 +32,17 @@
# define EDT_PUBLIC __declspec(dllimport)
# endif
# define EDT_LOCAL
# define EDT_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define EDT_PUBLIC __attribute__ ((visibility ("default")))
# define EDT_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define EDT_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define EDT_PUBLIC
# define EDT_PUBLIC_TEMPLATE
# define EDT_LOCAL
# endif

View File

@ -32,14 +32,17 @@
# define EXT_PUBLIC __declspec(dllimport)
# endif
# define EXT_LOCAL
# define EXT_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define EXT_PUBLIC __attribute__ ((visibility ("default")))
# define EXT_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define EXT_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define EXT_PUBLIC
# define EXT_PUBLIC_TEMPLATE
# define EXT_LOCAL
# endif

View File

@ -34,7 +34,7 @@ namespace gsi
*
* This class is specialized to implement the actual call process later.
*/
struct Callee
struct GSI_PUBLIC Callee
: public tl::Object
{
Callee () { }
@ -49,7 +49,7 @@ struct Callee
* This object holds informations about the actual implementation of the callback
* on the scripting client's side.
*/
struct Callback
struct Callback
{
Callback ()
: id (-1), callee (0), argsize (0), retsize (0)

View File

@ -116,7 +116,7 @@ void _var_user_read_impl (T * /*a*/, tl::Extractor & /*ex*/, tl::false_tag)
* @brief A VariantUserClassBase specialization that links GSI classes and Variant classes
*/
template <class T>
class VariantUserClass
class GSI_PUBLIC_TEMPLATE VariantUserClass
: public tl::VariantUserClass<T>, private VariantUserClassImpl
{
public:
@ -551,7 +551,7 @@ public:
* the given methods.
*/
template <class X>
class ClassExt
class GSI_PUBLIC_TEMPLATE ClassExt
: public ClassBase
{
public:
@ -708,7 +708,7 @@ struct adaptor_type_info<X, NoAdaptorTag>
* or to call it's methods in some generic way.
*/
template <class X, class Adapted = NoAdaptorTag>
class Class
class GSI_PUBLIC_TEMPLATE Class
: public ClassBase
{
public:
@ -937,7 +937,7 @@ public:
* a subclass of the parent.
*/
template <class P, class X, class Adapted = NoAdaptorTag>
class ChildClass
class GSI_PUBLIC_TEMPLATE ChildClass
: public Class<X, Adapted>
{
public:
@ -970,7 +970,7 @@ public:
* a subclass of the parent.
*/
template <class P, class X, class B, class Adapted = NoAdaptorTag>
class ChildSubClass
class GSI_PUBLIC_TEMPLATE ChildSubClass
: public SubClass<X, B, Adapted>
{
public:

View File

@ -32,14 +32,17 @@
# define GSI_PUBLIC __declspec(dllimport)
# endif
# define GSI_LOCAL
# define GSI_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define GSI_PUBLIC __attribute__ ((visibility ("default")))
# define GSI_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define GSI_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define GSI_PUBLIC
# define GSI_PUBLIC_TEMPLATE
# define GSI_LOCAL
# endif

View File

@ -37,7 +37,7 @@ namespace gsi
/**
* @brief Provides a basic implementation for a "boxed" plain value using a Variant as the basic type
*/
class Value
class GSI_PUBLIC Value
{
public:
/**

View File

@ -34,9 +34,9 @@
namespace gsi
{
class ClassBase;
class GSI_PUBLIC ClassBase;
struct NoAdaptorTag;
template <class T, class A> class Class;
template <class T, class A> class GSI_PUBLIC_TEMPLATE Class;
/**
* @brief The implementation delegate for the VariantUserClass<T>

View File

@ -28,6 +28,8 @@
#include "tlTypeTraits.h"
#include "gsiSerialisation.h"
#include <iterator>
// For a comprehensive documentation see gsi.h
namespace gsi

View File

@ -35,7 +35,7 @@
namespace gsi
{
class ClassBase;
class GSI_PUBLIC ClassBase;
/**
* @brief Definition of the client indexes

View File

@ -30,7 +30,7 @@
namespace gsi
{
class ClassBase;
class GSI_PUBLIC ClassBase;
/**
* @brief Implements an object holder

View File

@ -37,7 +37,7 @@ namespace gsi
// ------------------------------------------------------------
// SerialArgs definition
class AdaptorBase;
class GSI_PUBLIC AdaptorBase;
/**
* @brief Copy the contents of adaptor-provided data to the given type X
@ -650,7 +650,7 @@ public:
* @brief Generic string adaptor implementation
*/
template <class X>
class StringAdaptorImpl
class GSI_PUBLIC_TEMPLATE StringAdaptorImpl
: public StringAdaptor
{
};
@ -659,7 +659,7 @@ class StringAdaptorImpl
* @brief Specialization for QByteArray
*/
template <>
class StringAdaptorImpl<QByteArray>
class GSI_PUBLIC StringAdaptorImpl<QByteArray>
: public StringAdaptor
{
public:
@ -729,7 +729,7 @@ private:
* @brief Specialization for QString
*/
template <>
class StringAdaptorImpl<QString>
class GSI_PUBLIC StringAdaptorImpl<QString>
: public StringAdaptor
{
public:
@ -801,7 +801,7 @@ private:
* @brief Specialization for QStringRef
*/
template <>
class StringAdaptorImpl<QStringRef>
class GSI_PUBLIC StringAdaptorImpl<QStringRef>
: public StringAdaptor
{
public:
@ -875,7 +875,7 @@ private:
* @brief Specialization for std::string
*/
template <>
class StringAdaptorImpl<std::string>
class GSI_PUBLIC StringAdaptorImpl<std::string>
: public StringAdaptor
{
public:
@ -945,7 +945,7 @@ private:
* @brief Specialization for const unsigned char *
*/
template <class CP>
class StringAdaptorImplCCP
class GSI_PUBLIC_TEMPLATE StringAdaptorImplCCP
: public StringAdaptor
{
public:
@ -1019,7 +1019,7 @@ private:
* @brief Specialization for const char *
*/
template <>
class StringAdaptorImpl<const char *>
class GSI_PUBLIC StringAdaptorImpl<const char *>
: public StringAdaptorImplCCP<const char *>
{
public:
@ -1033,7 +1033,7 @@ public:
* @brief Specialization for const unsigned char *
*/
template <>
class StringAdaptorImpl<const unsigned char *>
class GSI_PUBLIC StringAdaptorImpl<const unsigned char *>
: public StringAdaptorImplCCP<const unsigned char *>
{
public:
@ -1047,7 +1047,7 @@ public:
* @brief Specialization for const signed char *
*/
template <>
class StringAdaptorImpl<const signed char *>
class GSI_PUBLIC StringAdaptorImpl<const signed char *>
: public StringAdaptorImplCCP<const signed char *>
{
public:
@ -1103,7 +1103,7 @@ public:
* @brief Generic string adaptor implementation
*/
template <class X>
class VariantAdaptorImpl
class GSI_PUBLIC_TEMPLATE VariantAdaptorImpl
: public VariantAdaptor
{
};
@ -1112,7 +1112,7 @@ class VariantAdaptorImpl
* @brief Specialization for QVariant
*/
template <>
class VariantAdaptorImpl<QVariant>
class GSI_PUBLIC VariantAdaptorImpl<QVariant>
: public VariantAdaptor
{
public:
@ -1182,7 +1182,7 @@ private:
* @brief Specialization for tl::Variant
*/
template <>
class VariantAdaptorImpl<tl::Variant>
class GSI_PUBLIC VariantAdaptorImpl<tl::Variant>
: public VariantAdaptor
{
public:
@ -1359,7 +1359,7 @@ public:
* @brief Implementation of the generic iterator adaptor for a specific container
*/
template <class Cont>
class VectorAdaptorIteratorImpl
class GSI_PUBLIC_TEMPLATE VectorAdaptorIteratorImpl
: public VectorAdaptorIterator
{
public:
@ -1434,7 +1434,7 @@ void push_vector (QSet<X> &v, const X &x)
* @brief Implementation of the generic adaptor for a specific container
*/
template <class Cont>
class VectorAdaptorImpl
class GSI_PUBLIC_TEMPLATE VectorAdaptorImpl
: public VectorAdaptor
{
public:
@ -1709,7 +1709,7 @@ struct map_access<QHash<X, Y> >
* @brief Implementation of the generic iterator adaptor for a specific container
*/
template <class Cont>
class MapAdaptorIteratorImpl
class GSI_PUBLIC_TEMPLATE MapAdaptorIteratorImpl
: public MapAdaptorIterator
{
public:
@ -1745,7 +1745,7 @@ private:
* @brief Implementation of the generic adaptor for a specific container
*/
template <class Cont>
class MapAdaptorImpl
class GSI_PUBLIC_TEMPLATE MapAdaptorImpl
: public MapAdaptor
{
public:

View File

@ -55,19 +55,19 @@ namespace gsi
// ---------------------------------------------------------------------------------
// Type system of GSI
class SerialArgs;
class VectorAdaptor;
class MapAdaptor;
class StringAdaptor;
class VariantAdaptor;
class ClassBase;
class GSI_PUBLIC SerialArgs;
class GSI_PUBLIC VectorAdaptor;
class GSI_PUBLIC MapAdaptor;
class GSI_PUBLIC StringAdaptor;
class GSI_PUBLIC VariantAdaptor;
class GSI_PUBLIC ClassBase;
struct NoAdaptorTag;
template <class X, class A> class Class;
template <class X, class A> class GSI_PUBLIC_TEMPLATE Class;
template <class X> struct ClassTag;
template <class I> class IterAdaptor;
template <class V> class IterPtrAdaptor;
template <class V> class ConstIterPtrAdaptor;
template <class I> class FreeIterAdaptor;
template <class I> class GSI_PUBLIC_TEMPLATE IterAdaptor;
template <class V> class GSI_PUBLIC_TEMPLATE IterPtrAdaptor;
template <class V> class GSI_PUBLIC_TEMPLATE ConstIterPtrAdaptor;
template <class I> class GSI_PUBLIC_TEMPLATE FreeIterAdaptor;
template <class X> const ClassBase *cls_decl ();
/**

View File

@ -35,7 +35,7 @@
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define GSIQT_PUBLIC __attribute__ ((visibility ("default")))
# define GSIQT_LOCAL __attribute__ ((visibility ("hidden")))
# else

View File

@ -453,9 +453,7 @@ static gsi::Enum<Qt::WindowType> decl_Qt_WindowType_Enum ("Qt_WindowType",
gsi::enum_const ("WindowStaysOnBottomHint", Qt::WindowStaysOnBottomHint, "@brief Enum constant Qt::WindowStaysOnBottomHint") +
gsi::enum_const ("WindowCloseButtonHint", Qt::WindowCloseButtonHint, "@brief Enum constant Qt::WindowCloseButtonHint") +
gsi::enum_const ("MacWindowToolBarButtonHint", Qt::MacWindowToolBarButtonHint, "@brief Enum constant Qt::MacWindowToolBarButtonHint") +
gsi::enum_const ("BypassGraphicsProxyWidget", Qt::BypassGraphicsProxyWidget, "@brief Enum constant Qt::BypassGraphicsProxyWidget") +
gsi::enum_const ("WindowOkButtonHint", Qt::WindowOkButtonHint, "@brief Enum constant Qt::WindowOkButtonHint") +
gsi::enum_const ("WindowCancelButtonHint", Qt::WindowCancelButtonHint, "@brief Enum constant Qt::WindowCancelButtonHint"),
gsi::enum_const ("BypassGraphicsProxyWidget", Qt::BypassGraphicsProxyWidget, "@brief Enum constant Qt::BypassGraphicsProxyWidget"),
"@qt\n@brief This class represents the Qt::WindowType enum");
static gsi::QFlagsClass<Qt::WindowType > decl_Qt_WindowType_Enums ("Qt_QFlags_WindowType",

View File

@ -3418,6 +3418,7 @@ template <> struct type_traits<QIconEngine> : public type_traits<void> {
class QIconEngine_Adaptor;
namespace tl {
template <> struct type_traits<QIconEngine_Adaptor> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
};
}

View File

@ -153,9 +153,7 @@ static gsi::Enum<Qt::WindowType> decl_Qt_WindowType_Enum ("Qt_WindowType",
gsi::enum_const ("MacWindowToolBarButtonHint", Qt::MacWindowToolBarButtonHint, "@brief Enum constant Qt::MacWindowToolBarButtonHint") +
gsi::enum_const ("BypassGraphicsProxyWidget", Qt::BypassGraphicsProxyWidget, "@brief Enum constant Qt::BypassGraphicsProxyWidget") +
gsi::enum_const ("NoDropShadowWindowHint", Qt::NoDropShadowWindowHint, "@brief Enum constant Qt::NoDropShadowWindowHint") +
gsi::enum_const ("WindowFullscreenButtonHint", Qt::WindowFullscreenButtonHint, "@brief Enum constant Qt::WindowFullscreenButtonHint") +
gsi::enum_const ("WindowOkButtonHint", Qt::WindowOkButtonHint, "@brief Enum constant Qt::WindowOkButtonHint") +
gsi::enum_const ("WindowCancelButtonHint", Qt::WindowCancelButtonHint, "@brief Enum constant Qt::WindowCancelButtonHint"),
gsi::enum_const ("WindowFullscreenButtonHint", Qt::WindowFullscreenButtonHint, "@brief Enum constant Qt::WindowFullscreenButtonHint"),
"@qt\n@brief This class represents the Qt::WindowType enum");
static gsi::QFlagsClass<Qt::WindowType > decl_Qt_WindowType_Enums ("Qt_QFlags_WindowType",

View File

@ -32,14 +32,17 @@
# define IMG_PUBLIC __declspec(dllimport)
# endif
# define IMG_LOCAL
# define IMG_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define IMG_PUBLIC __attribute__ ((visibility ("default")))
# define IMG_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define IMG_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define IMG_PUBLIC
# define IMG_PUBLIC_TEMPLATE
# define IMG_LOCAL
# endif

View File

@ -32,14 +32,17 @@
# define LAY_PUBLIC __declspec(dllimport)
# endif
# define LAY_LOCAL
# define LAY_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define LAY_PUBLIC __attribute__ ((visibility ("default")))
# define LAY_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define LAY_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define LAY_PUBLIC
# define LAY_PUBLIC_TEMPLATE
# define LAY_LOCAL
# endif

File diff suppressed because it is too large Load Diff

View File

@ -55,7 +55,7 @@ typedef void (*klp_init_func_t) (void (**autorun) (), void (**autorun_early) (),
# if defined _WIN32 || defined __CYGWIN__
# define KLP_PUBLIC __declspec(dllexport)
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define KLP_PUBLIC __attribute__ ((visibility ("default")))
# else
# define KLP_PUBLIC

View File

@ -30,7 +30,7 @@
#include "imgService.h"
#include <QVBoxLayout>
#include <QMenuBar>
#include <QFrame>
#include <QLabel>
namespace lay
@ -443,7 +443,8 @@ Navigator::Navigator (MainWindow *main_window)
{
setObjectName (QString::fromUtf8 ("navigator"));
mp_menu_bar = new QMenuBar (this);
mp_menu_bar = new QFrame (this);
mp_menu_bar->setFrameShape (QFrame::NoFrame);
mp_menu_bar->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Preferred);
mp_view = new LayoutView (0, false, mp_main_window, this, "navigator", LayoutView::LV_Naked + LayoutView::LV_NoZoom + LayoutView::LV_NoServices + LayoutView::LV_NoGrid);

View File

@ -33,7 +33,7 @@
class QCloseEvent;
class QShowEvent;
class QMenuBar;
class QFrame;
class QLabel;
namespace lay
@ -102,7 +102,7 @@ private:
MainWindow *mp_main_window;
LayoutView *mp_view;
QLabel *mp_placeholder_label;
QMenuBar *mp_menu_bar;
QFrame *mp_menu_bar;
LayoutView *mp_source_view;
NavigatorService *mp_service;
tl::DeferredMethod<Navigator> m_do_view_changed;

View File

@ -30,6 +30,9 @@
#ifdef _WIN32
# include <windows.h>
#elif __APPLE__
# include <libproc.h>
# include <unistd.h>
#else
# include <unistd.h>
#endif
@ -79,6 +82,15 @@ get_inst_path_internal ()
return tl::to_string (fi.absolutePath ());
}
#elif __APPLE__
char buffer[PROC_PIDPATHINFO_MAXSIZE];
int ret = proc_pidpath (getpid (), buffer, sizeof (buffer));
if (ret > 0) {
// TODO: does this correctly translate paths? (MacOS uses UTF-8 encoding with D-like normalization)
return tl::to_string (QFileInfo (QString::fromUtf8 (buffer)).absolutePath ());
}
#else
QFileInfo proc_exe (tl::to_qstring (tl::sprintf ("/proc/%d/exe", getpid ())));

View File

@ -320,7 +320,7 @@ namespace {
typedef lay::LayerPropertiesNodeRef value_type;
typedef lay::LayerPropertiesNodeRef reference;
// Dummy declarations required for std::iterator_traits
typedef void iterator_category;
typedef std::forward_iterator_tag iterator_category;
typedef void difference_type;
typedef void pointer;

View File

@ -37,12 +37,34 @@
#include <QToolButton>
#include <QApplication>
#include <QMessageBox>
#include <QHBoxLayout>
#include <ctype.h>
namespace lay
{
// ---------------------------------------------------------------
#if defined(__APPLE__)
// On MacOS, the main menu bar and it's decendent children
// can't be modified using "removeAction", followrd by "addAction"
// to achieve a move operation.If we try to do so, segmentation faults happen
// in the timer event that presumably tries to merge the menu bar
// with the application menu.
// The fallback is to only allow add/delete, not move operations on the
// menu. In effect, the order of the menu items may not be the one desired
// if menus are dynamically created. However, this will only happen when
// new packages or macros are installed.
static const bool s_can_move_menu = false;
#else
static const bool s_can_move_menu = true;
#endif
// ---------------------------------------------------------------
// Helper function to parse a title with potential shortcut and
// icon specification
@ -101,13 +123,13 @@ parse_menu_title (const std::string &s, std::string &title, std::string &shortcu
// AbstractMenuItem implementation
AbstractMenuItem::AbstractMenuItem ()
: mp_menu (0), m_has_submenu (false), m_remove_on_empty (false)
: m_has_submenu (false), m_remove_on_empty (false)
{
// ... nothing yet ..
}
AbstractMenuItem::AbstractMenuItem (const AbstractMenuItem &)
: mp_menu (0), m_has_submenu (false), m_remove_on_empty (false)
: m_has_submenu (false), m_remove_on_empty (false)
{
// ... nothing yet ..
}
@ -159,6 +181,10 @@ AbstractMenuItem::set_action (const Action &a, bool copy_properties)
m_action.set_visible (visible);
m_action.set_object_name (m_basename);
if (m_action.menu ()) {
m_action.menu ()->setObjectName (tl::to_qstring (m_basename));
}
}
void
@ -179,15 +205,6 @@ AbstractMenuItem::set_remove_on_empty ()
m_remove_on_empty = true;
}
void
AbstractMenuItem::set_menu (QMenu *menu)
{
mp_menu = menu;
if (mp_menu) {
mp_menu->setObjectName (tl::to_qstring (m_basename));
}
}
// ---------------------------------------------------------------
// Action implementation
@ -237,7 +254,8 @@ public:
};
ActionHandle::ActionHandle (QWidget *parent)
: mp_action (new ActionObject (parent)),
: mp_menu (0),
mp_action (new ActionObject (parent)),
m_ref_count (0),
m_owned (true),
m_visible (true),
@ -253,7 +271,8 @@ ActionHandle::ActionHandle (QWidget *parent)
}
ActionHandle::ActionHandle (QAction *action, bool owned)
: mp_action (action),
: mp_menu (0),
mp_action (action),
m_ref_count (0),
m_owned (owned),
m_visible (true),
@ -268,6 +287,23 @@ ActionHandle::ActionHandle (QAction *action, bool owned)
connect (mp_action, SIGNAL (destroyed (QObject *)), this, SLOT (destroyed (QObject *)));
}
ActionHandle::ActionHandle (QMenu *menu, bool owned)
: mp_menu (menu),
mp_action (menu->menuAction ()),
m_ref_count (0),
m_owned (owned),
m_visible (true),
m_hidden (false)
{
if (! sp_actionHandles) {
sp_actionHandles = new std::set<ActionHandle *> ();
}
sp_actionHandles->insert (this);
// catch the destroyed signal to tell if the QAction object is deleted.
connect (mp_action, SIGNAL (destroyed (QObject *)), this, SLOT (destroyed (QObject *)));
}
ActionHandle::~ActionHandle ()
{
if (sp_actionHandles) {
@ -278,7 +314,14 @@ ActionHandle::~ActionHandle ()
}
}
if (mp_action) {
if (mp_menu) {
if (m_owned) {
delete mp_menu;
m_owned = false;
}
mp_menu = 0;
mp_action = 0;
} else if (mp_action) {
if (m_owned) {
delete mp_action;
m_owned = false;
@ -307,6 +350,12 @@ ActionHandle::ptr () const
return mp_action;
}
QMenu *
ActionHandle::menu () const
{
return mp_menu;
}
void
ActionHandle::destroyed (QObject * /*obj*/)
{
@ -581,6 +630,12 @@ Action::qaction () const
return mp_handle ? mp_handle->ptr () : 0;
}
QMenu *
Action::menu () const
{
return mp_handle ? mp_handle->menu () : 0;
}
void
Action::add_to_exclusive_group (lay::AbstractMenu *menu, const std::string &group_name)
{
@ -869,7 +924,7 @@ AbstractMenu::AbstractMenu (AbstractMenuProvider *provider)
AbstractMenu::~AbstractMenu ()
{
reset_menu_objects (m_root);
// .. nothing yet ..
}
void
@ -879,15 +934,6 @@ AbstractMenu::init (const MenuLayoutEntry *layout)
transfer (layout, m_root);
}
void
AbstractMenu::reset_menu_objects (AbstractMenuItem &item)
{
for (std::list<AbstractMenuItem>::iterator c = item.children.begin (); c != item.children.end (); ++c) {
reset_menu_objects (*c);
}
item.set_menu (0);
}
QActionGroup *
AbstractMenu::make_exclusive_group (const std::string &name)
{
@ -903,31 +949,60 @@ AbstractMenu::make_exclusive_group (const std::string &name)
}
void
AbstractMenu::build_detached (const std::string &name, QMenuBar *mbar)
AbstractMenu::build_detached (const std::string &name, QFrame *mbar)
{
// Clean up the menu bar before rebuilding
if (mbar->layout ()) {
delete mbar->layout ();
}
QObjectList children = mbar->children ();
for (QObjectList::const_iterator c = children.begin (); c != children.end (); ++c) {
if (dynamic_cast<QToolButton *> (*c)) {
delete *c;
}
}
QHBoxLayout *menu_layout = new QHBoxLayout (mbar);
menu_layout->setMargin (0);
mbar->setLayout (menu_layout);
AbstractMenuItem *item = find_item_exact ("@@" + name);
tl_assert (item != 0);
mbar->clear ();
for (std::list<AbstractMenuItem>::iterator c = item->children.begin (); c != item->children.end (); ++c) {
if (c->has_submenu ()) {
QToolButton *menu_button = new QToolButton (mbar);
menu_layout->addWidget (menu_button);
menu_button->setAutoRaise (true);
menu_button->setPopupMode (QToolButton::MenuButtonPopup);
menu_button->setText (tl::to_qstring (c->action ().get_title ()));
if (c->menu () == 0) {
c->set_menu (mbar->addMenu (tl::to_qstring (c->action ().get_title ())));
c->set_action (Action (new ActionHandle (c->menu ()->menuAction (), false)), true);
QMenu *menu = new QMenu ();
menu_button->setMenu (menu);
c->set_action (Action (new ActionHandle (menu)), true);
} else {
mbar->addMenu (c->menu ());
menu_button->setMenu (c->menu ());
}
build (c->menu (), c->children);
} else {
mbar->addAction (c->action ().qaction ());
QAction *action = c->action ().qaction ();
QToolButton *menu_button = new QToolButton (mbar);
menu_layout->addWidget (menu_button);
menu_button->setAutoRaise (true);
menu_button->setDefaultAction (action);
}
}
menu_layout->addStretch (1);
}
void
@ -936,9 +1011,12 @@ AbstractMenu::build (QMenuBar *mbar, QToolBar *tbar)
tl_assert (mp_provider != 0);
m_helper_menu_items.clear ();
mbar->clear ();
tbar->clear ();
std::set<QAction *> present_actions;
QList<QAction *> a = mbar->actions ();
present_actions.insert (a.begin (), a.end ());
for (std::list<AbstractMenuItem>::iterator c = m_root.children.begin (); c != m_root.children.end (); ++c) {
if (c->has_submenu ()) {
@ -954,14 +1032,13 @@ AbstractMenu::build (QMenuBar *mbar, QToolBar *tbar)
} else if (c->name ().find ("@") == 0) {
if (c->menu () == 0) {
QMenu *menu = new QMenu (tl::to_qstring (c->action ().get_title ()), mp_provider->menu_parent_widget ());
QMenu *menu = new QMenu (tl::to_qstring (c->action ().get_title ()));
// HINT: it is necessary to add the menu action to a widget below the main window.
// Otherwise, the keyboard shortcuts do not work for menu items inside such a
// popup menu. It seems not to have a negative effect to add the menu to the
// main widget.
mp_provider->menu_parent_widget ()->addAction (menu->menuAction ());
c->set_menu (menu);
c->set_action (Action (new ActionHandle (c->menu ()->menuAction (), false)), true);
c->set_action (Action (new ActionHandle (menu)), true);
}
// prepare a detached menu which can be used as context menues
@ -970,10 +1047,22 @@ AbstractMenu::build (QMenuBar *mbar, QToolBar *tbar)
} else {
if (c->menu () == 0) {
c->set_menu (mbar->addMenu (tl::to_qstring (c->action ().get_title ())));
c->set_action (Action (new ActionHandle (c->menu ()->menuAction (), false)), true);
QMenu *menu = new QMenu ();
menu->setTitle (tl::to_qstring (c->action ().get_title ()));
mbar->addMenu (menu);
c->set_action (Action (new ActionHandle (menu)), true);
} else {
mbar->addMenu (c->menu ());
// Move the action to the end if present in the menu already
std::set<QAction *>::iterator a = present_actions.find (c->menu ()->menuAction ());
if (a != present_actions.end ()) {
if (s_can_move_menu) {
mbar->removeAction (*a);
mbar->addMenu (c->menu ());
}
present_actions.erase (*a);
} else {
mbar->addMenu (c->menu ());
}
}
build (c->menu (), c->children);
@ -981,30 +1070,82 @@ AbstractMenu::build (QMenuBar *mbar, QToolBar *tbar)
}
} else {
mbar->addAction (c->action ().qaction ());
// Move the action to the end if present in the menu already
std::set<QAction *>::iterator a = present_actions.find (c->action ().qaction ());
if (a != present_actions.end ()) {
if (s_can_move_menu) {
mbar->removeAction (*a);
mbar->addAction (c->action ().qaction ());
}
present_actions.erase (*a);
} else {
mbar->addAction (c->action ().qaction ());
}
}
}
// Remove all actions that have vanished
for (std::set<QAction *>::iterator a = present_actions.begin (); a != present_actions.end (); ++a) {
mbar->removeAction (*a);
}
}
void
AbstractMenu::build (QMenu *m, std::list<AbstractMenuItem> &items)
{
m->clear ();
std::set<QAction *> present_actions;
QList<QAction *> a = m->actions ();
present_actions.insert (a.begin (), a.end ());
for (std::list<AbstractMenuItem>::iterator c = items.begin (); c != items.end (); ++c) {
if (c->has_submenu ()) {
// HINT: the action acts as a container for the title. Unfortunately, we cannot create a
// menu with a given action. The action is provided by addMenu instead.
QMenu *menu = m->addMenu (tl::to_qstring (c->action ().get_title ()));
c->set_action (Action (new ActionHandle (menu->menuAction (), false)), true);
// HINT: build must be done before set_menu because set_menu might delete all child QAction's ..
build (menu, c->children);
c->set_menu (menu);
if (! c->menu ()) {
// HINT: the action acts as a container for the title. Unfortunately, we cannot create a
// menu with a given action. The action is provided by addMenu instead.
QMenu *menu = new QMenu ();
menu->setTitle (tl::to_qstring (c->action ().get_title ()));
m->addMenu (menu);
c->set_action (Action (new ActionHandle (menu)), true);
} else {
// Move the action to the end if present in the menu already
std::set<QAction *>::iterator a = present_actions.find (c->menu ()->menuAction ());
if (a != present_actions.end ()) {
if (s_can_move_menu) {
m->removeAction (*a);
m->addMenu (c->menu ());
}
present_actions.erase (*a);
} else {
m->addMenu (c->menu ());
}
}
build (c->menu (), c->children);
} else {
m->addAction (c->action ().qaction ());
// Move the action to the end if present in the menu already
std::set<QAction *>::iterator a = present_actions.find (c->action ().qaction ());
if (a != present_actions.end ()) {
if (s_can_move_menu) {
m->removeAction (*a);
m->addAction (c->action ().qaction ());
}
present_actions.erase (*a);
} else {
m->addAction (c->action ().qaction ());
}
}
}
// Remove all actions that have vanished
for (std::set<QAction *>::iterator a = present_actions.begin (); a != present_actions.end (); ++a) {
m->removeAction (*a);
}
}
void
@ -1205,7 +1346,6 @@ AbstractMenu::delete_item (const std::string &p)
break;
}
reset_menu_objects (*p->second);
p->first->children.erase (p->second);
}
@ -1521,4 +1661,3 @@ AbstractMenu::collect_group (std::vector<std::string> &grp, const std::string &n
}
}

View File

@ -42,6 +42,7 @@
#include "tlObject.h"
#include "laybasicCommon.h"
class QFrame;
class QMenuBar;
class QToolBar;
class QMenu;
@ -65,10 +66,12 @@ Q_OBJECT
public:
ActionHandle (QWidget *parent);
ActionHandle (QAction *action, bool owned = true);
ActionHandle (QMenu *menu, bool owned = true);
~ActionHandle ();
void add_ref ();
void remove_ref ();
QAction *ptr () const;
QMenu *menu () const;
void set_visible (bool v);
void set_hidden (bool h);
@ -86,6 +89,7 @@ protected slots:
void destroyed (QObject *obj);
private:
QMenu *mp_menu;
QAction *mp_action;
int m_ref_count;
bool m_owned;
@ -343,6 +347,11 @@ public:
*/
QAction *qaction () const;
/**
* @brief Gets the QMenu object if the action is a menu action
*/
QMenu *menu () const;
/**
* @brief Compares two action objects
*
@ -564,11 +573,9 @@ struct LAYBASIC_PUBLIC AbstractMenuItem
return m_action;
}
void set_menu (QMenu *menu);
QMenu *menu () const
{
return mp_menu;
return m_action.menu ();
}
void set_has_submenu ();
@ -588,7 +595,6 @@ struct LAYBASIC_PUBLIC AbstractMenuItem
std::list <AbstractMenuItem> children;
private:
QMenu *mp_menu;
bool m_has_submenu;
bool m_remove_on_empty;
Action m_action;
@ -681,7 +687,7 @@ public:
* @param name The name of the detached menu, without the "@"
* @param mbar The menu bar into which to build the menu
*/
void build_detached (const std::string &name, QMenuBar *mbar);
void build_detached (const std::string &name, QFrame *mbar);
/**
* @brief Get the reference to a QMenu object
@ -844,7 +850,6 @@ private:
void build (QMenu *menu, std::list<AbstractMenuItem> &items);
void build (QToolBar *tbar, std::list<AbstractMenuItem> &items);
void collect_group (std::vector<std::string> &grp, const std::string &name, const AbstractMenuItem &item) const;
void reset_menu_objects (AbstractMenuItem &item);
/**
* @brief Create a action from a string

View File

@ -32,14 +32,17 @@
# define LAYBASIC_PUBLIC __declspec(dllimport)
# endif
# define LAYBASIC_LOCAL
# define LAYBASIC_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define LAYBASIC_PUBLIC __attribute__ ((visibility ("default")))
# define LAYBASIC_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define LAYBASIC_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define LAYBASIC_PUBLIC
# define LAYBASIC_PUBLIC_TEMPLATE
# define LAYBASIC_LOCAL
# endif

View File

@ -32,14 +32,17 @@
# define LIB_PUBLIC __declspec(dllimport)
# endif
# define LIB_LOCAL
# define LIB_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define LIB_PUBLIC __attribute__ ((visibility ("default")))
# define LIB_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define LIB_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define LIB_PUBLIC
# define LIB_PUBLIC_TEMPLATE
# define LIB_LOCAL
# endif

View File

@ -32,14 +32,17 @@
# define LYM_PUBLIC __declspec(dllimport)
# endif
# define LYM_LOCAL
# define LYM_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define LYM_PUBLIC __attribute__ ((visibility ("default")))
# define LYM_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define LYM_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define LYM_PUBLIC
# define LYM_PUBLIC_TEMPLATE
# define LYM_LOCAL
# endif

View File

@ -32,14 +32,17 @@
# define PYA_PUBLIC __declspec(dllimport)
# endif
# define PYA_LOCAL
# define PYA_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define PYA_PUBLIC __attribute__ ((visibility ("default")))
# define PYA_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define PYA_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define PYA_PUBLIC
# define PYA_PUBLIC_TEMPLATE
# define PYA_LOCAL
# endif

View File

@ -36,8 +36,8 @@
namespace gsi
{
class ClassBase;
class ArgType;
class GSI_PUBLIC ClassBase;
class GSI_PUBLIC ArgType;
}
namespace pya

View File

@ -32,14 +32,17 @@
# define PYA_PUBLIC __declspec(dllimport)
# endif
# define PYA_LOCAL
# define PYA_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define PYA_PUBLIC __attribute__ ((visibility ("default")))
# define PYA_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define PYA_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define PYA_PUBLIC
# define PYA_PUBLIC_TEMPLATE
# define PYA_LOCAL
# endif

View File

@ -32,14 +32,17 @@
# define RBA_PUBLIC __declspec(dllimport)
# endif
# define RBA_LOCAL
# define RBA_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define RBA_PUBLIC __attribute__ ((visibility ("default")))
# define RBA_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define RBA_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define RBA_PUBLIC
# define RBA_PUBLIC_TEMPLATE
# define RBA_LOCAL
# endif

View File

@ -32,14 +32,17 @@
# define RBA_PUBLIC __declspec(dllimport)
# endif
# define RBA_LOCAL
# define RBA_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define RBA_PUBLIC __attribute__ ((visibility ("default")))
# define RBA_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define RBA_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define RBA_PUBLIC
# define RBA_PUBLIC_TEMPLATE
# define RBA_LOCAL
# endif

View File

@ -32,14 +32,17 @@
# define RDB_PUBLIC __declspec(dllimport)
# endif
# define RDB_LOCAL
# define RDB_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define RDB_PUBLIC __attribute__ ((visibility ("default")))
# define RDB_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define RDB_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define RDB_PUBLIC
# define RDB_PUBLIC_TEMPLATE
# define RDB_LOCAL
# endif

View File

@ -32,17 +32,47 @@
# define TL_PUBLIC __declspec(dllimport)
# endif
# define TL_LOCAL
# define TL_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4
# if __GNUC__ >= 4 || defined(__clang__)
# define TL_PUBLIC __attribute__ ((visibility ("default")))
# define TL_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define TL_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define TL_PUBLIC
# define TL_PUBLIC_TEMPLATE
# define TL_LOCAL
# endif
# endif
// NOTE: this is required because we have some forward declarations to
// gsi::Class and gsi::ClassBase in tlVariant.h.
// TODO: there should not be any dependency of tl on gsi.
# if defined _WIN32 || defined __CYGWIN__
# ifdef MAKE_GSI_LIBRARY
# define GSI_PUBLIC __declspec(dllexport)
# else
# define GSI_PUBLIC __declspec(dllimport)
# endif
# define GSI_LOCAL
# define GSI_PUBLIC_TEMPLATE
# else
# if __GNUC__ >= 4 || defined(__clang__)
# define GSI_PUBLIC __attribute__ ((visibility ("default")))
# define GSI_PUBLIC_TEMPLATE __attribute__ ((visibility ("default")))
# define GSI_LOCAL __attribute__ ((visibility ("hidden")))
# else
# define GSI_PUBLIC
# define GSI_PUBLIC_TEMPLATE
# define GSI_LOCAL
# endif
# endif
#endif

View File

@ -114,12 +114,12 @@ void handle_event_exception (std::exception &ex);
* @endcode
*/
template <class A1 = void, class A2 = void, class A3 = void, class A4 = void, class A5 = void> class event_function_base;
template <class T, class A1 = void, class A2 = void, class A3 = void, class A4 = void, class A5 = void> class event_function;
template <class T, class D, class A1 = void, class A2 = void, class A3 = void, class A4 = void, class A5 = void> class event_function_with_data;
template <class T, class A1 = void, class A2 = void, class A3 = void, class A4 = void, class A5 = void> class generic_event_function;
template <class T, class D, class A1 = void, class A2 = void, class A3 = void, class A4 = void, class A5 = void> class generic_event_function_with_data;
template <class A1 = void, class A2 = void, class A3 = void, class A4 = void, class A5 = void> class event;
template <class A1 = void, class A2 = void, class A3 = void, class A4 = void, class A5 = void> class TL_PUBLIC_TEMPLATE event_function_base;
template <class T, class A1 = void, class A2 = void, class A3 = void, class A4 = void, class A5 = void> class TL_PUBLIC_TEMPLATE event_function;
template <class T, class D, class A1 = void, class A2 = void, class A3 = void, class A4 = void, class A5 = void> class TL_PUBLIC_TEMPLATE event_function_with_data;
template <class T, class A1 = void, class A2 = void, class A3 = void, class A4 = void, class A5 = void> class TL_PUBLIC_TEMPLATE generic_event_function;
template <class T, class D, class A1 = void, class A2 = void, class A3 = void, class A4 = void, class A5 = void> class TL_PUBLIC_TEMPLATE generic_event_function_with_data;
template <class A1 = void, class A2 = void, class A3 = void, class A4 = void, class A5 = void> class TL_PUBLIC_TEMPLATE event;
typedef event<> Event;
#define _COUNT 0

View File

@ -31,7 +31,7 @@
#endif
template <_TMPLARGS>
class event_function_base<_TMPLARGLISTP>
class TL_PUBLIC_TEMPLATE event_function_base<_TMPLARGLISTP>
: public tl::Object
{
public:
@ -42,7 +42,7 @@ public:
};
template <_JOIN(class T, _TMPLARGS)>
class event_function<T, _TMPLARGLISTP>
class TL_PUBLIC_TEMPLATE event_function<T, _TMPLARGLISTP>
: public event_function_base<_TMPLARGLIST>
{
public:
@ -71,7 +71,7 @@ private:
};
template <class T, _JOIN(class D, _TMPLARGS)>
class event_function_with_data<T, D, _TMPLARGLISTP>
class TL_PUBLIC_TEMPLATE event_function_with_data<T, D, _TMPLARGLISTP>
: public event_function_base<_TMPLARGLIST>
{
public:
@ -101,7 +101,7 @@ private:
};
template <_JOIN(class T, _TMPLARGS)>
class generic_event_function<T, _TMPLARGLISTP>
class TL_PUBLIC_TEMPLATE generic_event_function<T, _TMPLARGLISTP>
: public event_function_base<_TMPLARGLIST>
{
public:
@ -131,7 +131,7 @@ private:
};
template <class T, _JOIN(class D, _TMPLARGS)>
class generic_event_function_with_data<T, D, _TMPLARGLISTP>
class TL_PUBLIC_TEMPLATE generic_event_function_with_data<T, D, _TMPLARGLISTP>
: public event_function_base<_TMPLARGLIST>
{
public:
@ -162,7 +162,7 @@ private:
};
template <_TMPLARGS>
class event<_TMPLARGLISTP>
class TL_PUBLIC_TEMPLATE event<_TMPLARGLISTP>
{
public:
typedef event_function_base<_TMPLARGLISTP> func;

View File

@ -137,7 +137,7 @@ private:
* @brief A "neutral" exception thrown to terminate some operation
* This exception is not shown.
*/
struct CancelException
struct TL_PUBLIC CancelException
: public Exception
{
CancelException ()
@ -148,7 +148,7 @@ struct CancelException
/**
* @brief A special "internal" exception class used by tl_assert
*/
struct InternalException
struct TL_PUBLIC InternalException
: public Exception
{
InternalException (const char *file, int line, const char *cond)

View File

@ -240,7 +240,7 @@ private:
* This class represents a weak or shared pointer for the given type T.
*/
template <class T, bool Shared>
class weak_or_shared_ptr
class TL_PUBLIC_TEMPLATE weak_or_shared_ptr
: public WeakOrSharedPtr
{
public:
@ -376,7 +376,7 @@ public:
* See description of tl::Object for details.
*/
template <class T>
class weak_ptr
class TL_PUBLIC_TEMPLATE weak_ptr
: public weak_or_shared_ptr<T, false>
{
public:
@ -404,7 +404,7 @@ public:
* See description of tl::Object for details.
*/
template <class T>
class shared_ptr
class TL_PUBLIC_TEMPLATE shared_ptr
: public weak_or_shared_ptr<T, true>
{
public:

View File

@ -42,9 +42,9 @@
namespace gsi
{
class ClassBase;
class GSI_PUBLIC ClassBase;
struct NoAdaptorTag;
template <class T, class A> class Class;
template <class T, class A> class GSI_PUBLIC_TEMPLATE Class;
template <class X> const ClassBase *cls_decl ();
}
@ -102,7 +102,7 @@ protected:
* We will employ RTTI to identify a type through that base class.
*/
template <class T>
class VariantUserClass
class TL_PUBLIC_TEMPLATE VariantUserClass
: public VariantUserClassBase
{
public:

View File

@ -150,7 +150,7 @@ public:
*/
template <class Obj>
class XMLReaderProxy
class TL_PUBLIC_TEMPLATE XMLReaderProxy
: public XMLReaderProxyBase
{
public:
@ -412,7 +412,7 @@ private:
// -----------------------------------------------------------------
// The C++ structure definition interface (for use cases see tlXMLParser.ut)
class XMLElementBase;
class TL_PUBLIC XMLElementBase;
struct pass_by_value_tag {
pass_by_value_tag () { }
@ -714,7 +714,7 @@ private:
*/
template <class Obj, class Parent, class Read, class Write>
class XMLElement
class TL_PUBLIC_TEMPLATE XMLElement
: public XMLElementBase
{
public:
@ -819,7 +819,7 @@ private:
*/
template <class Obj, class Parent, class Read, class Write>
class XMLElementWithParentRef
class TL_PUBLIC_TEMPLATE XMLElementWithParentRef
: public XMLElementBase
{
public:
@ -933,7 +933,7 @@ private:
*/
template <class Value, class Parent, class Read, class Write, class Converter>
class XMLMember
class TL_PUBLIC_TEMPLATE XMLMember
: public XMLElementBase
{
public:
@ -1024,7 +1024,7 @@ private:
*/
template <class Value, class Parent, class Write, class Converter>
class XMLWildcardMember
class TL_PUBLIC_TEMPLATE XMLWildcardMember
: public XMLElementBase
{
public:
@ -1092,7 +1092,7 @@ private:
*/
template <class Obj>
class XMLStruct
class TL_PUBLIC_TEMPLATE XMLStruct
: public XMLElementBase
{
public:

View File

@ -378,6 +378,10 @@ main_cont (int &argc, char **argv)
}
if (! tl::TestRegistrar::instance()) {
throw tl::Exception ("No test libraries found - make sure, the *.ut files are next to the ut_runner executable.");
}
// No side effects
lay::set_klayout_path (std::vector<std::string> ());

View File

@ -6,6 +6,11 @@ include($$PWD/../with_all_libs.pri)
TEMPLATE = app
# Don't build the ut_runner app as ordinary command line tool on MacOS
mac {
CONFIG -= app_bundle
}
TARGET = ut_runner
SOURCES = \

View File

@ -92,6 +92,28 @@ def ph(x):
else:
return x.replace("X", "")
def map2str(dict):
# A helper function to product a "canonical" (i.e. sorted-keys) string
# representation of a dict
keys = list(dict)
for k in keys:
if type(k) is str:
strKeys = []
strDict = {}
for x in keys:
strKeys.append(str(x))
strDict[str(x)] = dict[x]
strings = []
for x in sorted(strKeys):
strings.append(str(x) + ": " + str(strDict[x]))
return "{" + ", ".join(strings) + "}"
strings = []
for x in sorted(keys):
strings.append(str(x) + ": " + str(dict[x]))
return "{" + ", ".join(strings) + "}"
class PyGObject(pya.GObject):
z = -1
def __init__(self, z):
@ -2087,44 +2109,27 @@ class BasicTest(unittest.TestCase):
def test_41(self):
v3 = sys.version_info >= (3, 0)
# maps
b = pya.B()
b.insert_map1(1, "hello")
if v3:
self.assertEqual(repr(b.map1), "{1: 'hello'}")
else:
self.assertEqual(repr(b.map1), "{1L: 'hello'}")
self.assertEqual(map2str(b.map1), "{1: hello}")
b.map1 = {}
b.insert_map1(2, "hello")
if v3:
self.assertEqual(repr(b.map1_cref()), "{2: 'hello'}")
else:
self.assertEqual(repr(b.map1_cref()), "{2L: 'hello'}")
self.assertEqual(map2str(b.map1_cref()), "{2: hello}")
b.map1 = {}
b.insert_map1(3, "hello")
if v3:
self.assertEqual(repr(b.map1_cptr()), "{3: 'hello'}")
else:
self.assertEqual(repr(b.map1_cptr()), "{3L: 'hello'}")
self.assertEqual(map2str(b.map1_cptr()), "{3: hello}")
b.map1 = {}
b.insert_map1(4, "hello")
if v3:
self.assertEqual(repr(b.map1_ref()), "{4: 'hello'}")
else:
self.assertEqual(repr(b.map1_ref()), "{4L: 'hello'}")
self.assertEqual(map2str(b.map1_ref()), "{4: hello}")
b.map1 = {}
b.insert_map1(5, "hello")
if v3:
self.assertEqual(repr(b.map1_ptr()), "{5: 'hello'}")
else:
self.assertEqual(repr(b.map1_ptr()), "{5L: 'hello'}")
self.assertEqual(map2str(b.map1_ptr()), "{5: hello}")
self.assertEqual(b.map1_cptr_null() == None, True);
self.assertEqual(b.map1_ptr_null() == None, True);
@ -2138,52 +2143,28 @@ class BasicTest(unittest.TestCase):
self.assertEqual(error_caught, True)
b.map1 = { 42: "1", -17: "True" }
if v3:
self.assertEqual(repr(b.map1), "{42: '1', -17: 'True'}")
else:
self.assertEqual(repr(b.map1), "{42L: '1', -17L: 'True'}")
self.assertEqual(map2str(b.map1), "{-17: True, 42: 1}")
b.set_map1_cref({ 42: "2", -17: "True" })
if v3:
self.assertEqual(repr(b.map1), "{42: '2', -17: 'True'}")
else:
self.assertEqual(repr(b.map1), "{42L: '2', -17L: 'True'}")
self.assertEqual(map2str(b.map1), "{-17: True, 42: 2}")
b.set_map1_cptr({ 42: "3", -17: "True" })
if v3:
self.assertEqual(repr(b.map1), "{42: '3', -17: 'True'}")
else:
self.assertEqual(repr(b.map1), "{42L: '3', -17L: 'True'}")
self.assertEqual(map2str(b.map1), "{-17: True, 42: 3}")
b.set_map1_cptr(None)
if v3:
self.assertEqual(repr(b.map1), "{42: '3', -17: 'True'}")
else:
self.assertEqual(repr(b.map1), "{42L: '3', -17L: 'True'}")
self.assertEqual(map2str(b.map1), "{-17: True, 42: 3}")
b.set_map1_ref({ 42: "4", -17: "True" })
if v3:
self.assertEqual(repr(b.map1), "{42: '4', -17: 'True'}")
else:
self.assertEqual(repr(b.map1), "{42L: '4', -17L: 'True'}")
self.assertEqual(map2str(b.map1), "{-17: True, 42: 4}")
b.set_map1_ptr({ 42: "5", -17: "True" })
if v3:
self.assertEqual(repr(b.map1), "{42: '5', -17: 'True'}")
else:
self.assertEqual(repr(b.map1), "{42L: '5', -17L: 'True'}")
self.assertEqual(map2str(b.map1), "{-17: True, 42: 5}")
b.set_map1_ptr(None)
if v3:
self.assertEqual(repr(b.map1), "{42: '5', -17: 'True'}")
else:
self.assertEqual(repr(b.map1), "{42L: '5', -17L: 'True'}")
self.assertEqual(map2str(b.map1), "{-17: True, 42: 5}")
b.map2 = { 'xy': 1, -17: True }
if v3:
self.assertEqual(repr(b.map2), "{'xy': 1, -17: True}")
else:
self.assertEqual(repr(b.map2), "{'xy': 1L, -17L: True}")
self.assertEqual(map2str(b.map2), "{-17: True, xy: 1}")
self.assertEqual(b.map2_null(), None)

View File

@ -77,6 +77,28 @@ class MyObject(pya.QObject):
def on_event_filter(self, ef):
self.ef = ef
def map2str(dict):
# A helper function to product a "canonical" (i.e. sorted-keys) string
# representation of a dict
keys = list(dict)
for k in keys:
if type(k) is str:
strKeys = []
strDict = {}
for x in keys:
strKeys.append(str(x))
strDict[str(x)] = dict[x]
strings = []
for x in sorted(strKeys):
strings.append(str(x) + ": " + str(strDict[x]))
return "{" + ", ".join(strings) + "}"
strings = []
for x in sorted(keys):
strings.append(str(x) + ": " + str(dict[x]))
return "{" + ", ".join(strings) + "}"
# The Qt binding tests
class QtBindingTest(unittest.TestCase):
@ -462,15 +484,13 @@ class QtBindingTest(unittest.TestCase):
# QHash bindings
slm = MyStandardItemModel()
r1 = "{0: \'display\', 1: \'decoration\', 2: \'edit\', 3: \'toolTip\', 4: \'statusTip\', 5: \'whatsThis\'}"
r2 = "{0L: \'display\', 1L: \'decoration\', 2L: \'edit\', 3L: \'toolTip\', 4L: \'statusTip\', 5L: \'whatsThis\'}"
self.assertEqual(str(slm.roleNames()) == r1 or str(slm.roleNames()) == r2, True)
rn = slm.roleNames()
rn[7] = "blabla"
slm.srn(rn)
r1 = "{0: \'display\', 1: \'decoration\', 2: \'edit\', 3: \'toolTip\', 4: \'statusTip\', 5: \'whatsThis\', 7: \'blabla\'}"
r2 = "{0L: \'display\', 1L: \'decoration\', 2L: \'edit\', 3L: \'toolTip\', 4L: \'statusTip\', 5L: \'whatsThis\', 7L: \'blabla\'}"
self.assertEqual(str(slm.roleNames()) == r1 or str(slm.roleNames()) == r2, True)
self.assertEqual(map2str(rn), "{0: display, 1: decoration, 2: edit, 3: toolTip, 4: statusTip, 5: whatsThis}")
rnNew = slm.roleNames()
rnNew[7] = "blabla"
slm.srn(rnNew)
rn = slm.roleNames()
self.assertEqual(map2str(rn), "{0: display, 1: decoration, 2: edit, 3: toolTip, 4: statusTip, 5: whatsThis, 7: blabla}")
def test_44(self):
@ -488,8 +508,8 @@ class QtBindingTest(unittest.TestCase):
self.assertEqual(child.height > 100, True)
parent.resize(100, 100)
self.assertEqual(child.width < 100, True)
self.assertEqual(child.height < 100, True)
self.assertEqual(child.width <= 100, True)
self.assertEqual(child.height <= 100, True)
# now if we delete the parent, the child needs to become disconnected

View File

@ -191,7 +191,7 @@ class DBTrans_TestClass < TestBase
assert_equal( c.is_mag?, true )
assert_equal( c.rot, RBA::DCplxTrans::M0.rot )
assert_equal( c.s_trans.to_s, "m0 2.5,-12.5" )
assert_equal( c.angle, 45 )
assert_equal( (c.angle - 45).abs < 1e-10, true )
assert_equal( c.ctrans( 5 ).to_s, "3.75" )
assert_equal( c.trans( RBA::DPoint::new( 12, 16 ) ).to_s, "17.3492424049,-14.6213203436" )
@ -345,7 +345,7 @@ class DBTrans_TestClass < TestBase
assert_equal( c.is_mag?, true )
assert_equal( c.rot, RBA::CplxTrans::M0.rot )
assert_equal( c.s_trans.to_s, "m0 3,-13" )
assert_equal( c.angle, 45 )
assert_equal( (c.angle - 45).abs < 1e-10, true )
assert_equal( c.ctrans( 5 ).to_s, "3.75" )
assert_equal( c.trans( RBA::Point::new( 12, 16 ) ).to_s, "17.3492424049,-14.6213203436" )

View File

@ -576,8 +576,8 @@ class QtBinding_TestClass < TestBase
assert_equal(child.height() > 100, true)
parent.resize(100, 100)
assert_equal(child.width() < 100, true)
assert_equal(child.height() < 100, true)
assert_equal(child.width() <= 100, true)
assert_equal(child.height() <= 100, true)
# now if we delete the parent, the child needs to become disconnected

View File

@ -5,8 +5,11 @@
KLAYOUT_VERSION="0.25.1"
# The build date
KLAYOUT_VERSION_DATE=$(date --iso-8601)
KLAYOUT_VERSION_DATE=$(date "+%Y-%m-%d")
# The short SHA hash of the commit
KLAYOUT_VERSION_REV=$(git rev-parse --short HEAD)
KLAYOUT_VERSION_REV=$(git rev-parse --short HEAD 2>/dev/null)
if [ "$KLAYOUT_VERSION_REV" = "" ]; then
KLAYOUT_VERSION_REV="LatestSourcePackage"
fi