diff --git a/README.md b/README.md index 32bcfbc1c..8873c3dce 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,20 @@ For more details see http://www.klayout.org. ## Building requirements +Building on Linux: + * Qt 4.7 or later (4.6 with some restrictions) or Qt 5 * gcc 4.6 or later or clang 3.8 or later +Building on Windows with MSYS2: + +* MSYS2 with gcc, Qt4 or 5, zlib, ruby and python packages installed + +Building on Windows with MSVC 2017: + +* MSVC 2017 +* Build requisites from klayout-kit + For more build instructions see http://www.klayout.de/build.html. ## Build options @@ -25,16 +36,16 @@ For more build instructions see http://www.klayout.de/build.html. ### Plain building for Qt4 - ./build.sh - + ./build.sh + ### Plain building for Qt5 - ./build.sh -qt5 - + ./build.sh -qt5 + ### Building without Qt binding ./build.sh -without-qtbinding - + ### Debug build ./build.sh -debug @@ -63,8 +74,8 @@ For more build instructions see http://www.klayout.de/build.html. ### Pass make options - ./build.sh -j4 - + ./build.sh -j4 + (for running 4 jobs in parallel) ### More options @@ -80,9 +91,54 @@ Go to the build directory (i.e. "bin-release") and enter export TESTTMP=testtmp # path to a directory that will hold temporary data (will be created) export TESTSRC=.. # path to the source directory ./ut_runner - + For more options use ./ut_runner -h +## Build instructions (Windows, MSYS2) +From the MSYS2 MinGW bash (32 bit or 64 bit) use the same commands as for Linux to build the +binaries. + +## Build instructions (Windows, MSVC 2017) + +The combination supported and tested was Qt 5.11/MSVC 2017 64bit. +It's sufficient to install the build tools from MSVC's community edition. + +A build script similar to build.sh is provided for Windows +(build.bat). + +For details about this build script use + +``` +build.bat -h +``` + +For MSVC builds a number of third party libraries are required: + + * Ruby + * Python + * zlib + * expat + * curl + * pthread-win + +The "klayout-bits4msvc2017" project (https://github.com/klayoutmatthias/klayout_bits4msvc2017) targets towards providing a binary distribution for this purpose. +See the release notes there for download links. Download the .zip archive from there and unpack it to some folder, e.g. "c:\klayout-bits". + +The build script needs the path to this package. "qmake" and (for obtaining the build version) "git" should be in the path. If qmake is not in the path, you can use "build.bat -qmake ..." to specify qmake's path. + +Here is an example for the build.bat call: + +``` +build.bat -bits c:\klayout-bits +``` + +The 3rd party bits kit can also be used to build the Python +standalone package on setuptools. Specify the full path to the 3rd party package up to the compiler and architecture. On 64bit with the bits package installed in "c:\klayout-bits" the build call is this: + +``` +set KLAYOUT_BITS=c:\klayout-bits\msvc2017\x64 +python setup.py build +``` diff --git a/build.bat b/build.bat new file mode 100644 index 000000000..bdee5a50a --- /dev/null +++ b/build.bat @@ -0,0 +1,255 @@ + +@echo off +setlocal EnableDelayedExpansion + +rem ---------------------------------------------------------- +rem KLAYOUT build script +rem See build.bat -h for details +rem + +rem ---------------------------------------------------------- +rem parse command lines + +set CONFIG=release +set HAVE_QTBINDINGS=1 +set HAVE_QT=1 +set HAVE_64BIT_COORD=0 +set HAVE_PYTHON=1 +set HAVE_RUBY=1 +set MAKE_OPT= + +set arch=x64 +set compiler=msvc2017 +set dry_run=0 +set option-qmake=qmake +set "option-bits=c:\klayout-bits" +set "option-build=%TEMP%\klayout-build" +set "option-bin=%TEMP%\klayout-bin" + +set "option=" +for %%a in (%*) do ( + if not defined option ( + set arg=%%a + if "!arg:~0,1!" equ "-" ( + if "!arg!" equ "-h" ( + set "option-h=1" + set "option=" + ) else if "!arg!" equ "--help" ( + set "option-h=1" + set "option=" + ) else if "!arg!" equ "-help" ( + set "option-h=1" + set "option=" + ) else if "!arg!" equ "-bits" ( + set "option=!arg!" + ) else if "!arg!" equ "-qmake" ( + set "option=!arg!" + ) else if "!arg!" equ "-build" ( + set "option=!arg!" + ) else if "!arg!" equ "-bin" ( + set "option-bin=%TEMP%\klayout-bin" + set "option=!arg!" + ) else if "!arg!" equ "-prefix" ( + set "option-bin=%TEMP%\klayout-bin" + set "option=!arg!" + ) else if "!arg!" equ "-build" ( + set "option=!arg!" + ) else if "!arg!" equ "-debug" ( + set "CONFIG=debug" + ) else if "!arg!" equ "-release" ( + set "CONFIG=release" + ) else if "!arg!" equ "-with-qtbinding" ( + set "HAVE_QTBINDINGS=1" + ) else if "!arg!" equ "-without-qtbinding" ( + set "HAVE_QTBINDINGS=0" + ) else if "!arg!" equ "-without-qt" ( + set "HAVE_QT=0" + ) else if "!arg!" equ "-with-64bit-coord" ( + set "HAVE_64BIT_COORD=1" + ) else if "!arg!" equ "-without-64bit-coord" ( + set "HAVE_64BIT_COORD=0" + ) else if "!arg!" equ "-nopython" ( + set "HAVE_PYTHON=0" + ) else if "!arg!" equ "-noruby" ( + set "HAVE_RUBY=0" + ) else if "!arg!" equ "-dry-run" ( + set "dry_run=1" + ) else if "!arg!" equ "-x64" ( + set "arch=x64" + ) else if "!arg!" equ "-x86" ( + set "arch=x86" + ) + ) else ( + set "MAKE_OPT=!MAKE_OPT! !arg!" + ) + ) else ( + set "option!option!=%%a" + set "option=" + ) +) + +if defined option-h ( + echo build.bat - KLayout build script + echo. + echo Mandatory options: + echo -bits [path] Path to the 3rd party binary kit + echo -build [path] Path to the build directory + echo -bin [path] Path to the installation directory + echo -prefix [path] Same as -bin + echo -x86 32 bit build + echo -x64 64 bit build [default] + echo. + echo Other options: + echo -h -help --help Show this help + echo -qmake [path] Path to the qmake binary + echo -debug Perform a debug build + echo -release Perform a release build [the default] + echo -with-qtbinding Enable Qt support for Ruby/Python [the default] + echo -without-qtbinding Disable Qt support for Ruby/Python + echo -without-qt Entirely Qt-free build of a tool subset + echo -with-64bit-coord Enable 64bit coordinate support [experimental] + echo -without-64bit-coord Disable 64bit coordinate support [default] + echo -nopython Dont include Python support + echo -noruby Dont include Ruby support + echo -dry-run Dont actually make + goto :eof +) + +echo Analysing installation ... +echo. + +rem ---------------------------------------------------------- +rem locate MSVC 2017 on the system + +set MSVC2017_COMPILER_INST=notfound +rem VS 2017 sets exactly one install as the "main" install, so we may find MSBuild in there. +reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7" /v 15.0 /reg:32 >nul 2>nul +if NOT ERRORLEVEL 1 ( + for /F "tokens=1,2*" %%i in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7" /v 15.0 /reg:32') DO ( + if "%%i"=="15.0" ( + if exist "%%k\VC\Auxiliary\Build" ( + set "MSVC2017_COMPILER_INST=%%k\VC\Auxiliary\Build" + set "msg=Found MSVC installation at !MSVC2017_COMPILER_INST!" + echo !msg! + ) + ) + ) +) + +if "%MSVC2017_COMPILER_INST%" == "notfound" ( + echo ERROR: Unable to find MSVC 2017 installation + goto :eof +) +if %arch% equ x64 ( + call "%MSVC2017_COMPILER_INST%\vcvars64" +) else ( + call "%MSVC2017_COMPILER_INST%\vcvars32" +) + +rem ---------------------------------------------------------- +rem check the kit + +if not exist "%option-bits%"\%compiler%\%arch% ( + echo ERROR: no 3rd party binary kit found in %option-bits%\%compiler%\%arch% + goto :eof +) +if not exist "%option-bits%\%compiler%\%arch%\ruby\bin\ruby.exe" ( + echo ERROR: %option-bits% not installed properly or + echo path does not point to architecture folder. + echo Use -bits to specfiy the path to the 3rd party binary kit. + goto :eof +) +echo Using bits from %option-bits%\%compiler%\%arch% + +rem ---------------------------------------------------------- +rem check the qmake binary + +"%option-qmake%" -v >nul 2>nul +if ERRORLEVEL 1 ( + echo ERROR: Not a valid qmake: %option-qmake% + echo Use -qmake option to specify the path to the qmake binary. + goto :eof +) +echo Using qmake from %option-qmake% + +rem ---------------------------------------------------------- +rem read klayout Version + +for /F "tokens=1" %%i in ('type version.sh') do ( + set line=%%i + if "!line:~0,16!" equ "KLAYOUT_VERSION=" ( + set "version=!line:~16,100!" + set "KLAYOUT_VERSION=!version:"=!" + ) +) + +date /t >%TEMP%\klayout-build-tmp.txt +set /P KLAYOUT_VERSION_DATE=<%TEMP%\klayout-build-tmp.txt +del %TEMP%\klayout-build-tmp.txt + +rem The short SHA hash of the commit +git rev-parse --short HEAD 2>nul >%TEMP%\klayout-build-tmp.txt +set /P KLAYOUT_VERSION_REV=<%TEMP%\klayout-build-tmp.txt +if ERRORLEVEL 1 ( + set "KLAYOUT_VERSION_REV=LatestSourcePackage" +) +del %TEMP%\klayout-build-tmp.txt + +rem ---------------------------------------------------------- +rem dump settings + +echo. +echo Architecture: %arch% +echo Compiler: %compiler% +echo. +echo CONFIG: %CONFIG% +echo KLAYOUT_VERSION: %KLAYOUT_VERSION% +echo KLAYOUT_VERSION_DATE: %KLAYOUT_VERSION_DATE% +echo KLAYOUT_VERSION_REV: %KLAYOUT_VERSION_REV% +echo HAVE_QTBINDINGS: %HAVE_QTBINDINGS% +echo HAVE_QT: %HAVE_QT% +echo HAVE_64BIT_COORD: %HAVE_64BIT_COORD% +echo HAVE_PYTHON: %HAVE_PYTHON% +echo HAVE_RUBY: %HAVE_RUBY% +echo MAKE_OPT: %MAKE_OPT% +echo. +echo qmake binary: %option-qmake% +echo Build directory: %option-build% +echo Installation directory: %option-bin% + +if %dry_run% equ 1 ( + echo. + echo Dry run ... stopping now. + goto :eof +) + +rem ---------------------------------------------------------- +rem Run qmake + +set "inst_path=%~dp0" +mkdir "%option-build%" 2>nul +cd "%option-build%" +if not exist "%option-build%" ( + echo ERROR: build directory does not exists and cannot be created + goto :eof +) + +echo on +"%option-qmake%" ^ + HAVE_QT5=1 ^ + -recursive ^ + -spec win32-msvc ^ + "CONFIG+=%CONFIG%" ^ + "KLAYOUT_VERSION=%KLAYOUT_VERSION%" ^ + "KLAYOUT_VERSION_DATE=%KLAYOUT_VERSION_DATE%" ^ + "KLAYOUT_VERSION_REV=%KLAYOUT_VERSION_REV%" ^ + "HAVE_QTBINDINGS=%HAVE_QTBINDINGS%" ^ + "HAVE_QT=%HAVE_QT%" ^ + "HAVE_RUBY=%HAVE_RUBY%" ^ + "HAVE_PYTHON=%HAVE_PYTHON%" ^ + "HAVE_64BIT_COORD=%HAVE_64BIT_COORD%" ^ + "PREFIX=%option-bin%" ^ + "BITS_PATH=%option-bits%\%compiler%\%arch%" ^ + %inst_path%\src\klayout.pro ^ +&& nmake %MAKE_OPT% ^ +&& nmake install diff --git a/setup.py b/setup.py index 122bfda60..f817cf5b0 100644 --- a/setup.py +++ b/setup.py @@ -344,12 +344,11 @@ rdb = Extension(config.root + '.rdb', # Core setup function if __name__ == '__main__': - print("Number of cores", N_cores) - setup(name=config.root, - version=config.version(), - description='KLayout standalone Python package', - author='Matthias Koefferlein', - author_email='matthias@klayout.de', - packages=[config.root], - package_dir={config.root: 'src/pymod/distutils_src'}, - ext_modules=[_tl, _gsi, _pya, _db, _rdb] + db_plugins + [tl, db, rdb]) + setup(name = config.root, + version = config.version(), + description = 'KLayout standalone Python package', + author = 'Matthias Koefferlein', + author_email = 'matthias@klayout.de', + packages = [config.root], + package_dir = {config.root: 'src/pymod/distutils_src'}, + ext_modules = [_tl, _gsi, _pya, _db, _rdb] + db_plugins + [tl, db, rdb]) diff --git a/src/db/db/dbPolygonTools.cc b/src/db/db/dbPolygonTools.cc index 77f7c9dcd..e44ecfa8b 100644 --- a/src/db/db/dbPolygonTools.cc +++ b/src/db/db/dbPolygonTools.cc @@ -112,7 +112,7 @@ struct cut_polygon_edge { typedef typename PointType::coord_type coord_type; typedef typename db::edge edge_type; - typedef typename db::coord_traits::area_type projection_type; + typedef double projection_type; cut_polygon_edge () : contour (-1), index (0), projected (0), point (), last_point () @@ -179,7 +179,7 @@ public: bool operator< (const loose_end_struct &other) const { - if (proj () != other.proj ()) { + if (! db::coord_traits::equal (proj (), other.proj ())) { return proj () < other.proj (); } else { return db::vprod_sign (edge (), other.edge ()) > 0; @@ -196,13 +196,13 @@ static bool _cut_polygon_internal (const PolygonType &input, const Edge &line, C typedef db::edge edge_type; typedef cut_polygon_edge cut_polygon_edge_type; typedef cut_polygon_segment cutting_segment_type; - typedef typename db::coord_traits::area_type projection_type; bool do_hole_assignment = (input.holes () > 0); std::vector hull_polygons; std::vector hole_polygons; std::vector cutting_segments; + double line_length = line.double_length (); for (unsigned int nc = 0; nc < input.holes () + 1; ++nc) { @@ -229,7 +229,7 @@ static bool _cut_polygon_internal (const PolygonType &input, const Edge &line, C int s1 = line.side_of (e.p1 ()); int s2 = line.side_of (e.p2 ()); - projection_type p = db::sprod (ip.second - line.p1 (), line.p2 () - line.p1 ()); + double p = line_length * double (db::vprod (e.p1 () - line.p1 (), e.d ())) / double (db::vprod (line.d (), e.d ())); if (s1 < 0 && s2 >= 0) { // right -> left or on edge diff --git a/src/db/unit_tests/dbPolygonTools.cc b/src/db/unit_tests/dbPolygonTools.cc index 79880ccd0..6229f89f4 100644 --- a/src/db/unit_tests/dbPolygonTools.cc +++ b/src/db/unit_tests/dbPolygonTools.cc @@ -2242,3 +2242,19 @@ TEST(403) } } +// issue 166 +TEST(404) +{ + db::Polygon poly; + std::string s ("(390,0;438,936;176,874;0,832;438,937;541,961;821,102)"); + tl::Extractor ex (s.c_str ()); + ex.read (poly); + + std::vector sp; + db::split_polygon (poly, sp); + EXPECT_EQ (sp.size (), size_t (2)); + if (sp.size () >= 2) { + EXPECT_EQ (sp[0].to_string (), "(390,0;438,936;390,925;438,937;541,961;821,102)"); + EXPECT_EQ (sp[1].to_string (), "(0,832;176,874;390,925)"); + } +} diff --git a/src/plugins/streamers/gds2/unit_tests/dbGDS2Writer.cc b/src/plugins/streamers/gds2/unit_tests/dbGDS2Writer.cc index 7481dec1c..b48066aad 100644 --- a/src/plugins/streamers/gds2/unit_tests/dbGDS2Writer.cc +++ b/src/plugins/streamers/gds2/unit_tests/dbGDS2Writer.cc @@ -1145,3 +1145,11 @@ TEST(121) opt.max_vertex_count = 4; run_test (_this, "t121.oas.gz", "t121_au.gds.gz", true, opt); } + +// Extreme fracturing by max. points +TEST(166) +{ + db::GDS2WriterOptions opt; + opt.max_vertex_count = 4; + run_test (_this, "t166.oas.gz", "t166_au.gds.gz", false, opt); +} diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index c16d732ed..15638f065 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -70,17 +70,6 @@ DEFImporter::get_orient (bool optional) } } -/** - * @brief A structure describing a via - */ -struct ViaDesc -{ - ViaDesc () : cell (0) { } - - db::Cell *cell; - std::string m1, m2; -}; - void DEFImporter::read_polygon (db::Polygon &poly, double scale) { @@ -153,7 +142,7 @@ DEFImporter::do_read (db::Layout &layout) double dbu_mic = 1000.0; double scale = 1.0 / (dbu_mic * layout.dbu ()); std::map styles; - std::map via_desc; + std::map via_desc = m_lef_importer.vias (); std::map > regions; std::list groups; std::list > instances; diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index 1b716023e..c61501cbb 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -533,6 +533,24 @@ private: const LEFDEFReaderOptions *mp_tech_comp; }; +/** + * @brief A structure describing a via + */ +struct DB_PLUGIN_PUBLIC ViaDesc +{ + ViaDesc () : cell (0) { } + + /** + * @brief The cell representing the via + */ + db::Cell *cell; + + /** + * @brief The names of bottom and top metal respectively + */ + std::string m1, m2; +}; + /** * @brief The LEF importer object */ diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc index 105ddcc32..639d52549 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc @@ -458,6 +458,9 @@ LEFImporter::do_read (db::Layout &layout) std::string cellname = "VIA_" + n; db::Cell &cell = layout.cell (layout.add_cell (cellname.c_str ())); + ViaDesc &via_desc = m_vias[n]; + via_desc.cell = &cell; + while (test ("DEFAULT") || test ("TOPOFSTACKONLY")) ; test (";"); @@ -543,9 +546,9 @@ LEFImporter::do_read (db::Layout &layout) } else if (test ("LAYERS")) { - geometry[0].first = get (); + via_desc.m1 = geometry[0].first = get (); geometry[1].first = get (); - geometry[2].first = get (); + via_desc.m2 = geometry[2].first = get (); test (";"); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h index 2d47040ac..c1467cb5c 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h @@ -86,6 +86,16 @@ public: */ double layer_ext (const std::string &layer, double def_ext = 0.0) const; + /** + * @brief Gets a map of the vias defined in this LEF file + * + * The map maps the via name to the via description. + */ + const std::map &vias () const + { + return m_vias; + } + protected: void do_read (db::Layout &layout); @@ -95,6 +105,7 @@ private: std::map m_default_ext; std::map m_macros_by_name; std::map m_macro_bboxes_by_name; + std::map m_vias; std::vector get_iteration (db::Layout &layout); void read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose purpose, std::map *collect_bboxes = 0); diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImport.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImport.cc index 6fe739373..3da2eec81 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImport.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImport.cc @@ -30,7 +30,7 @@ #include -static void run_test (tl::TestBase *_this, const char *lef_dir, const char *filename, const char *au) +static void run_test (tl::TestBase *_this, const char *lef_dir, const char *filename, const char *au, bool priv = true) { db::LEFDEFReaderOptions tc; tc.set_via_geometry_datatype (0); @@ -60,7 +60,7 @@ static void run_test (tl::TestBase *_this, const char *lef_dir, const char *file if (ex.test ("def:")) { - std::string fn (tl::testsrc_private ()); + std::string fn (priv ? tl::testsrc_private () : tl::testsrc ()); fn += "/testdata/lefdef/"; fn += lef_dir; fn += "/"; @@ -73,7 +73,7 @@ static void run_test (tl::TestBase *_this, const char *lef_dir, const char *file } else if (ex.test ("lef:")) { - std::string fn (tl::testsrc_private ()); + std::string fn (priv ? tl::testsrc_private () : tl::testsrc ()); fn += "/testdata/lefdef/"; fn += lef_dir; fn += "/"; @@ -118,7 +118,7 @@ static void run_test (tl::TestBase *_this, const char *lef_dir, const char *file if (au) { - std::string fn (tl::testsrc_private ()); + std::string fn (priv ? tl::testsrc_private () : tl::testsrc ()); fn += "/testdata/lefdef/"; fn += lef_dir; fn += "/"; @@ -233,3 +233,8 @@ TEST(19) run_test (_this, "def10", "def:in.def", "au.oas.gz"); } +TEST(20) +{ + run_test (_this, "issue-172", "lef:in.lef+def:in.def", "au.oas.gz", false); +} + diff --git a/src/pymod/pymod.pri b/src/pymod/pymod.pri index 1fd8cd1b0..4715b50ce 100644 --- a/src/pymod/pymod.pri +++ b/src/pymod/pymod.pri @@ -42,6 +42,9 @@ lib_target.path = $$PREFIX/pymod/klayout # This would be nice: # lib_target.files += $$DESTDIR_PYMOD/$${TARGET}$${PYTHONEXTSUFFIX} # but some Qt versions need this explicitly: -lib_target.extra = $(INSTALL_PROGRAM) $$DESTDIR_PYMOD/$${TARGET}$${PYTHONEXTSUFFIX} $(INSTALLROOT)$$PREFIX/pymod/klayout +msvc { + lib_target.extra = $(INSTALL_PROGRAM) $$shell_path($$DESTDIR_PYMOD/$${TARGET}$${PYTHONEXTSUFFIX}) $$shell_path($(INSTALLROOT)$$PREFIX/pymod/klayout) +} else { + lib_target.extra = $(INSTALL_PROGRAM) $$DESTDIR_PYMOD/$${TARGET}$${PYTHONEXTSUFFIX} $(INSTALLROOT)$$PREFIX/pymod/klayout +} INSTALLS = lib_target - diff --git a/src/pymod/tl/tl.pro b/src/pymod/tl/tl.pro index 6f7fe6d37..b4f161393 100644 --- a/src/pymod/tl/tl.pro +++ b/src/pymod/tl/tl.pro @@ -35,5 +35,9 @@ init_target.path = $$PREFIX/pymod/klayout # This would be nice: # init_target.files += $$DESTDIR_PYMOD/__init__.py # but some Qt versions need this explicitly: -init_target.extra = $(INSTALL_PROGRAM) $$DESTDIR_PYMOD/__init__.py $(INSTALLROOT)$$PREFIX/pymod/klayout +msvc { + init_target.extra = $(INSTALL_PROGRAM) $$shell_path($$DESTDIR_PYMOD/__init__.py) $$shell_path($(INSTALLROOT)$$PREFIX/pymod/klayout) +} else { + init_target.extra = $(INSTALL_PROGRAM) $$DESTDIR_PYMOD/__init__.py $(INSTALLROOT)$$PREFIX/pymod/klayout +} INSTALLS += init_target diff --git a/testdata/gds/t166.oas.gz b/testdata/gds/t166.oas.gz new file mode 100644 index 000000000..3a209870a Binary files /dev/null and b/testdata/gds/t166.oas.gz differ diff --git a/testdata/gds/t166_au.gds.gz b/testdata/gds/t166_au.gds.gz new file mode 100644 index 000000000..7766ef28e Binary files /dev/null and b/testdata/gds/t166_au.gds.gz differ diff --git a/testdata/lefdef/issue-172/au.oas.gz b/testdata/lefdef/issue-172/au.oas.gz new file mode 100644 index 000000000..ce4faf592 Binary files /dev/null and b/testdata/lefdef/issue-172/au.oas.gz differ diff --git a/testdata/lefdef/issue-172/in.def b/testdata/lefdef/issue-172/in.def new file mode 100644 index 000000000..a4311b4ae --- /dev/null +++ b/testdata/lefdef/issue-172/in.def @@ -0,0 +1,16 @@ +VERSION 5.6 ; +NAMESCASESENSITIVE ON ; +DIVIDERCHAR "/" ; +BUSBITCHARS "<>" ; +DESIGN SMALL ; +UNITS DISTANCE MICRONS 100 ; + +DIEAREA ( -30 -30 ) ( 1030 1030 ) ; + +NETS 1 ; +- TOP ++ ROUTED M1 ( 0 0 ) ( 1000 * ) M2_M1 + NEW M2 ( 1000 0 ) ( 1000 1000 ) ; +END NETS + +END DESIGN diff --git a/testdata/lefdef/issue-172/in.lef b/testdata/lefdef/issue-172/in.lef new file mode 100644 index 000000000..a0359f764 --- /dev/null +++ b/testdata/lefdef/issue-172/in.lef @@ -0,0 +1,40 @@ +VERSION 5.7 ; +NAMESCASESENSITIVE ON ; +BUSBITCHARS "[]" ; +DIVIDERCHAR "/" ; +UNITS + DATABASE MICRONS 1000 ; +END UNITS + +USEMINSPACING OBS ON ; +USEMINSPACING PIN OFF ; +CLEARANCEMEASURE EUCLIDEAN ; + +MANUFACTURINGGRID 0.05 ; + +LAYER M1 + TYPE ROUTING ; + DIRECTION HORIZONTAL ; + WIDTH 0.2 ; +END M1 + +LAYER V2 + TYPE CUT ; +END V2 + +LAYER M2 + TYPE ROUTING ; + DIRECTION VERTICAL ; + WIDTH 0.2 ; +END M2 + +VIA M2_M1 DEFAULT + LAYER M1 ; + RECT -0.300 -0.300 0.300 0.300 ; + LAYER V2 ; + RECT -0.200 -0.200 0.200 0.200 ; + LAYER M2 ; + RECT -0.300 -0.300 0.300 0.300 ; +END M2_M1 + +END LIBRARY diff --git a/testdata/python/dbTransTest.py b/testdata/python/dbTransTest.py index c08d638e0..8f7643f45 100644 --- a/testdata/python/dbTransTest.py +++ b/testdata/python/dbTransTest.py @@ -150,7 +150,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual( c.is_mirror(), True ) self.assertEqual( c.rot(), pya.DCplxTrans.M135.rot() ) self.assertEqual( str(c.s_trans()), "m135 0,0" ) - self.assertEqual( c.angle, 270 ) + self.assertAlmostEqual( c.angle, 270 ) self.assertEqual( str(c.trans( pya.Edge(0, 1, 2, 3) )), "(-1,0;-3,-2)" ) self.assertEqual( str(( c * pya.Edge(0, 1, 2, 3) )), "(-1,0;-3,-2)" ) @@ -174,7 +174,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual( c.is_mirror(), False ) self.assertEqual( c.rot(), pya.DCplxTrans.R0.rot() ) self.assertEqual( str(c.s_trans()), "r0 0,0" ) - self.assertEqual( c.angle, 0 ) + self.assertAlmostEqual( c.angle, 0 ) c = pya.DCplxTrans( 0.75, 45, True, 2.5, -12.5 ) self.assertEqual( str(c), "m22.5 *0.75 2.5,-12.5" ) @@ -185,7 +185,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual( c.is_mag(), True ) self.assertEqual( c.rot(), pya.DCplxTrans.M0.rot() ) self.assertEqual( str(c.s_trans()), "m0 2.5,-12.5" ) - self.assertEqual( c.angle, 45 ) + self.assertAlmostEqual( c.angle, 45 ) self.assertEqual( str(c.ctrans( 5 )), "3.75" ) self.assertEqual( str(c.trans( pya.DPoint( 12, 16 ) )), "17.3492424049,-14.6213203436" ) @@ -335,7 +335,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual( c.is_mirror(), True ) self.assertEqual( c.rot(), pya.CplxTrans.M135.rot() ) self.assertEqual( str(c.s_trans()), "m135 0,0" ) - self.assertEqual( c.angle, 270 ) + self.assertAlmostEqual( c.angle, 270 ) c = pya.CplxTrans.from_dtrans( pya.DCplxTrans.M135 ) self.assertEqual( str(c), "m135 *1 0,0" ) @@ -348,7 +348,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual( c.is_mirror(), False ) self.assertEqual( c.rot(), pya.CplxTrans.R0.rot() ) self.assertEqual( str(c.s_trans()), "r0 0,0" ) - self.assertEqual( c.angle, 0 ) + self.assertAlmostEqual( c.angle, 0 ) c = pya.CplxTrans( 0.75, 45, True, 2.5, -12.5 ) self.assertEqual( str(c), "m22.5 *0.75 2.5,-12.5" ) @@ -360,7 +360,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual( c.is_mag(), True ) self.assertEqual( c.rot(), pya.CplxTrans.M0.rot() ) self.assertEqual( str(c.s_trans()), "m0 3,-13" ) - self.assertEqual( c.angle, 45 ) + self.assertAlmostEqual( c.angle, 45 ) self.assertEqual( str(c.ctrans( 5 )), "3.75" ) self.assertEqual( str(c.trans( pya.Point( 12, 16 ) )), "17.3492424049,-14.6213203436" ) @@ -517,7 +517,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual(t1 < t4, True) self.assertEqual(t4 < t1, False) - # Hash values + # Hash values def test_5_Trans_Hash(self): t1 = pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 )) diff --git a/testdata/python/qtbinding.py b/testdata/python/qtbinding.py index 77ec69173..a077656e4 100644 --- a/testdata/python/qtbinding.py +++ b/testdata/python/qtbinding.py @@ -471,9 +471,11 @@ class QtBindingTest(unittest.TestCase): pya.QApplication.processEvents() - s1 = "QKeyEvent: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)\nQKeyEvent: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)\nQKeyEvent: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)" - s2 = "QKeyEvent: KeyPress (6)\nQKeyEvent: KeyPress (6)\nQKeyEvent: KeyPress (6)" - self.assertEqual("\n".join(ef.log()) == s1 or "\n".join(ef.log()) == s2, True) + s1 = "QKeyEvent: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)\nQKeyEvent: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)\nQKeyEvent: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)" + s2 = "QKeyEvent: KeyPress (6)\nQKeyEvent: KeyPress (6)\nQKeyEvent: KeyPress (6)" + s3 = "QKeyEvent_Native: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)\nQKeyEvent_Native: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)\nQKeyEvent_Native: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)" + self.assertIn("\n".join(ef.log()), (s1, s2, s3)) + ef = None self.assertEqual(widget.text, "ABCpO") diff --git a/testdata/ruby/qtbinding.rb b/testdata/ruby/qtbinding.rb index 884f05e7b..e8d044dee 100644 --- a/testdata/ruby/qtbinding.rb +++ b/testdata/ruby/qtbinding.rb @@ -534,7 +534,10 @@ class QtBinding_TestClass < TestBase GC.start - assert_equal(ef.log.select { |s| s !~ /RBA::QKeyEvent: ShortcutOverride/ }.join("\n"), "RBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent: KeyPress (6)") + assert_equal(ef.log.select { |s| s !~ /RBA::QKeyEvent: ShortcutOverride/ }.join("\n"), "RBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent: KeyPress (6)") + + # TODO: on macOS 10.13, ef.log yields "RBA::QKeyEvent_Native: ShortcutOverride (51)\nRBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent_Native: ShortcutOverride (51)\nRBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent_Native: ShortcutOverride (51)\nRBA::QKeyEvent: KeyPress (6)", causing this test to fail. + ef = nil ef = EventFilter::new GC.start