From 655e59d11ad4d53d7e040c9f5f0963c157edf3e3 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 3 Jun 2018 19:54:18 +0200 Subject: [PATCH] WIP: Fixed build dependencies and code dependencies for Python modules (Qt5) --- src/db/db/db.pro | 6 +- src/db/db/dbForceLink.cc | 32 ++ src/db/db/dbForceLink.h | 40 +++ src/gsiqt/qt4/QtCore/QtCore.pro | 2 +- src/gsiqt/qt4/QtCore/gsiDeclQtCoreAdd.cc | 5 - src/gsiqt/qt4/QtGui/gsiDeclQtGuiAdd.cc | 2 + src/gsiqt/qt5/QtCore/gsiDeclQtCoreAdd.cc | 291 ++++++++++++++++-- src/gsiqt/qt5/QtGui/QtGui.pro | 3 + src/gsiqt/qt5/QtGui/gsiDeclQtGuiAdd.cc | 3 +- src/gsiqt/qt5/QtNetwork/QtNetwork.pro | 3 + .../qt5/QtNetwork/gsiDeclQtNetworkAdd.cc | 273 ---------------- .../qt5/QtPrintSupport/QtPrintSupport.pro | 6 + src/gsiqt/qt5/QtSql/QtSql.pro | 3 + src/gsiqt/qt5/QtSvg/QtSvg.pro | 6 + src/gsiqt/qt5/QtWidgets/QtWidgets.pro | 6 + .../qt5/QtWidgets/gsiDeclQtWidgetsAdd.cc | 25 ++ src/gsiqt/qt5/QtXmlPatterns/QtXmlPatterns.pro | 3 + src/gsiqt/qt5/qt5.pro | 10 + src/lay/lay/lay.pro | 6 +- src/lay/lay/layForceLink.cc | 32 ++ src/lay/lay/layForceLink.h | 40 +++ src/laybasic/laybasic/laybasic.pro | 3 + src/pya/pya/pya.cc | 112 ++++--- src/pya/pya/pya.h | 6 +- src/pymod/QtCore/QtCore.pro | 2 +- src/pymod/QtCore/QtCoreMain.cc | 14 + src/pymod/QtDesigner/QtDesignerMain.cc | 4 + src/pymod/QtGui/QtGui.pro | 7 +- src/pymod/QtGui/QtGuiMain.cc | 9 + src/pymod/QtMultimedia/QtMultimediaMain.cc | 4 + src/pymod/QtNetwork/QtNetworkMain.cc | 4 + .../QtPrintSupport/QtPrintSupportMain.cc | 4 + src/pymod/QtSql/QtSqlMain.cc | 4 + src/pymod/QtSvg/QtSvgMain.cc | 4 + src/pymod/QtWidgets/QtWidgetsMain.cc | 4 + src/pymod/QtXml/QtXml.pro | 5 +- src/pymod/QtXml/QtXmlMain.cc | 20 ++ src/pymod/QtXmlPatterns/QtXmlPatterns.pro | 2 +- src/pymod/QtXmlPatterns/QtXmlPatternsMain.cc | 9 + src/pymod/db/dbMain.cc | 3 + src/pymod/lay/layMain.cc | 3 + src/pymod/pymodHelper.h | 6 +- 42 files changed, 664 insertions(+), 362 deletions(-) create mode 100644 src/db/db/dbForceLink.cc create mode 100644 src/db/db/dbForceLink.h create mode 100644 src/gsiqt/qt5/QtWidgets/gsiDeclQtWidgetsAdd.cc create mode 100644 src/lay/lay/layForceLink.cc create mode 100644 src/lay/lay/layForceLink.h diff --git a/src/db/db/db.pro b/src/db/db/db.pro index fde996345..3e3e13f88 100644 --- a/src/db/db/db.pro +++ b/src/db/db/db.pro @@ -131,7 +131,8 @@ SOURCES = \ gsiDeclDbGlyphs.cc \ dbVariableWidthPath.cc \ dbNamedLayerReader.cc \ - dbEdgesToContours.cc + dbEdgesToContours.cc \ + dbForceLink.cc HEADERS = \ dbArray.h \ @@ -233,7 +234,8 @@ HEADERS = \ dbGlyphs.h \ dbCommon.h \ dbVariableWidthPath.h \ - dbNamedLayerReader.h + dbNamedLayerReader.h \ + dbForceLink.h RESOURCES = \ dbResources.qrc diff --git a/src/db/db/dbForceLink.cc b/src/db/db/dbForceLink.cc new file mode 100644 index 000000000..238eac374 --- /dev/null +++ b/src/db/db/dbForceLink.cc @@ -0,0 +1,32 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2018 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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 + +*/ + +#include "dbForceLink.h" + +namespace db +{ + int _force_link_f () + { + return 0; + } +} + diff --git a/src/db/db/dbForceLink.h b/src/db/db/dbForceLink.h new file mode 100644 index 000000000..25d239016 --- /dev/null +++ b/src/db/db/dbForceLink.h @@ -0,0 +1,40 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2018 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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 + +*/ + + +#ifndef HDR_dbForceLink +#define HDR_dbForceLink + +#include "dbCommon.h" + +/** + * @file Include this function to force linking of the db module + */ + +namespace db +{ + DB_PUBLIC int _force_link_f (); + static int _force_link_target = _force_link_f (); +} + +#endif + diff --git a/src/gsiqt/qt4/QtCore/QtCore.pro b/src/gsiqt/qt4/QtCore/QtCore.pro index 4620526ed..0d7c55d5b 100644 --- a/src/gsiqt/qt4/QtCore/QtCore.pro +++ b/src/gsiqt/qt4/QtCore/QtCore.pro @@ -11,7 +11,7 @@ DEFINES += MAKE_GSI_QTCORE_LIBRARY INCLUDEPATH += $$TL_INC $$GSI_INC $$DB_INC $$QTBASIC_INC DEPENDPATH += $$TL_INC $$GSI_INC $$DB_INC $$QTBASIC_INC -LIBS += -L$$DESTDIR -lklayout_tl -lklayout_gsi -lklayout_qtbasic -lklayout_QtGui +LIBS += -L$$DESTDIR -lklayout_tl -lklayout_gsi -lklayout_qtbasic SOURCES += \ gsiDeclQtCoreAdd.cc diff --git a/src/gsiqt/qt4/QtCore/gsiDeclQtCoreAdd.cc b/src/gsiqt/qt4/QtCore/gsiDeclQtCoreAdd.cc index b89a006e1..cbdd3114d 100644 --- a/src/gsiqt/qt4/QtCore/gsiDeclQtCoreAdd.cc +++ b/src/gsiqt/qt4/QtCore/gsiDeclQtCoreAdd.cc @@ -34,11 +34,6 @@ // namespace which is in QtCore ... this introduces a dependency of QtCore GSI lib on QtGui. #include -// And this is *only* required because of QSignalMapper which takes a QWidget argument from -// the QtGui library and we need to supply the GSI binding for this ... -#include "gsiQtGuiExternals.h" -FORCE_LINK_GSI_QTGUI - class Qt_Namespace { }; namespace gsi_qt diff --git a/src/gsiqt/qt4/QtGui/gsiDeclQtGuiAdd.cc b/src/gsiqt/qt4/QtGui/gsiDeclQtGuiAdd.cc index 937784427..8a8d03c80 100644 --- a/src/gsiqt/qt4/QtGui/gsiDeclQtGuiAdd.cc +++ b/src/gsiqt/qt4/QtGui/gsiDeclQtGuiAdd.cc @@ -22,6 +22,8 @@ #include "gsiQt.h" +// required to pull in the GSI declarations from db: +#include "dbForceLink.h" #include #include diff --git a/src/gsiqt/qt5/QtCore/gsiDeclQtCoreAdd.cc b/src/gsiqt/qt5/QtCore/gsiDeclQtCoreAdd.cc index 3dc7cdf87..33e4418fc 100644 --- a/src/gsiqt/qt5/QtCore/gsiDeclQtCoreAdd.cc +++ b/src/gsiqt/qt5/QtCore/gsiDeclQtCoreAdd.cc @@ -20,7 +20,6 @@ */ - #include "gsiQt.h" #include @@ -174,23 +173,6 @@ gsi::Class > decl_double_QVariant_QPair ("QtCore", "QPai "@qt\\n@brief Represents a QPair" ); -// --------------------------------------------------------------------------- -// Add declaration for HitTestAccuracy which would be in QtGui, but is in Qt namespace -// (hence QtCore) - -static gsi::Enum decl_Qt_HitTestAccuracy_Enum ("QtCore", "Qt_HitTestAccuracy", - gsi::enum_const ("ExactHit", Qt::ExactHit, "@brief Enum constant Qt::ExactHit") + - gsi::enum_const ("FuzzyHit", Qt::FuzzyHit, "@brief Enum constant Qt::FuzzyHit"), - "@qt\n@brief This class represents the Qt::HitTestAccuracy enum"); - -static gsi::QFlagsClass decl_Qt_HitTestAccuracy_Enums ("QtCore", "Qt_QFlags_HitTestAccuracy", - "@qt\n@brief This class represents the QFlags flag set"); - -// Inject the declarations into the parent -static gsi::ClassExt inject_Qt_HitTestAccuracy_Enum_in_parent (decl_Qt_HitTestAccuracy_Enum.defs ()); -static gsi::ClassExt decl_Qt_HitTestAccuracy_Enum_as_child (decl_Qt_HitTestAccuracy_Enum, "HitTestAccuracy"); -static gsi::ClassExt decl_Qt_HitTestAccuracy_Enums_as_child (decl_Qt_HitTestAccuracy_Enums, "QFlags_HitTestAccuracy"); - // --------------------------------------------------------------------------- // QtMsgType implementation // (this type is not created automatically since QtMsgType is not within a namespace) @@ -205,4 +187,277 @@ static gsi::Enum decl_QtMsgType ("QtCore", "QtMsgType", gsi::enum_const ("QtSystemMsg", QtSystemMsg, "@brief Enum constant QtSystemMsg of QtMsgType") ); +// --------------------------------------------------------------------------- +// QUrlTwoFlags bindings + +template +class QUrlTwoFlagsClass; + +/** + * @brief An adaptor class for the QUrlTwoFlags template derived from QFlagsAdaptor template + */ +template +class QUrlTwoFlagsAdaptor +{ +public: + QUrlTwoFlagsAdaptor () : m_qf () { } + QUrlTwoFlagsAdaptor (A e) : m_qf (e) { } + QUrlTwoFlagsAdaptor (B e) : m_qf (e) { } + QUrlTwoFlagsAdaptor (QFlags e) : m_qf (e) { } + QUrlTwoFlagsAdaptor (QFlags e) : m_qf (e) { } + QUrlTwoFlagsAdaptor (const QUrlTwoFlags &qf) : m_qf (qf) { } + QUrlTwoFlagsAdaptor (int i) : m_qf (i) { } + + QUrlTwoFlagsAdaptor (const std::string &s) + { + const QUrlTwoFlagsClass *ecls = dynamic_cast *> (gsi::cls_decl > ()); + tl_assert (ecls != 0); + m_qf = ecls->qflags_from_string (s); + } + + QUrlTwoFlags &value () { return m_qf; } + const QUrlTwoFlags &value () const { return m_qf; } + +private: + QUrlTwoFlags m_qf; +}; + +/** + * @brief A binding for QUrlTwoFlags derived from QFlags binding + */ +template +class QUrlTwoFlagsClass + : public gsi::Class, QUrlTwoFlags > +{ +public: + typedef typename QFlags::Int int_repr; + + QUrlTwoFlagsClass (const std::string &module, const std::string &name, const std::string &doc = std::string ()) + : gsi::Class, QUrlTwoFlags > (module, name, methods (), doc) + { + } + + static QUrlTwoFlags *new_from_i (int_repr i) + { + return new QUrlTwoFlags (i); + } + + static QUrlTwoFlags *new_from_e1 (A e) + { + return new QUrlTwoFlags (e); + } + + static QUrlTwoFlags *new_from_e1f (QFlags e) + { + return new QUrlTwoFlags (e); + } + + static QUrlTwoFlags *new_from_e2 (B e) + { + return new QUrlTwoFlags (e); + } + + static QUrlTwoFlags *new_from_e2f (QFlags e) + { + return new QUrlTwoFlags (e); + } + + static QUrlTwoFlags *new_from_s (const std::string &s) + { + QUrlTwoFlags flags; + + const gsi::Enum *acls = dynamic_cast *> (gsi::cls_decl ()); + const gsi::Enum *bcls = dynamic_cast *> (gsi::cls_decl ()); + tl_assert (acls != 0 && bcls != 0); + + tl::Extractor ex (s.c_str ()); + while (! ex.at_end ()) { + + bool any = false; + + for (typename gsi::EnumSpecs::iterator s = acls->specs ().begin (); s != acls->specs ().end () && !any; ++s) { + if (ex.test (s->str.c_str ())) { + flags |= A (s->evalue); + any = true; + } + } + + for (typename gsi::EnumSpecs::iterator s = bcls->specs ().begin (); s != bcls->specs ().end () && !any; ++s) { + if (ex.test (s->str.c_str ())) { + flags |= B (s->evalue); + any = true; + } + } + + if (any) { + ex.test ("|"); + ex.test (","); + } else { + break; + } + + } + + return new QUrlTwoFlags (flags); + } + + static std::string to_s (const QUrlTwoFlags *self) + { + std::string res; + + const gsi::Enum *acls = dynamic_cast *> (gsi::cls_decl ()); + const gsi::Enum *bcls = dynamic_cast *> (gsi::cls_decl ()); + tl_assert (acls != 0 && bcls != 0); + + for (typename gsi::EnumSpecs::iterator s = acls->specs ().begin (); s != acls->specs ().end (); ++s) { + if (self->testFlag (s->evalue)) { + if (! res.empty ()) { + res += "|"; + } + res += s->str; + } + } + + for (typename gsi::EnumSpecs::iterator s = bcls->specs ().begin (); s != bcls->specs ().end (); ++s) { + if (self->testFlag (s->evalue)) { + if (! res.empty ()) { + res += "|"; + } + res += s->str; + } + } + + return res; + } + + static int_repr to_i (const QUrlTwoFlags *self) + { + return int_repr (*self); + } + + static bool test_flag1 (const QUrlTwoFlags *self, A e) + { + return self->testFlag (e); + } + + static bool test_flag2 (const QUrlTwoFlags *self, B e) + { + return self->testFlag (e); + } + + static std::string inspect (const QUrlTwoFlags *self) + { + return to_s (self) + tl::sprintf(" (%u)", (unsigned int) (int_repr (*self))); + } + + static QUrlTwoFlags invert (const QUrlTwoFlags *self) + { + return ~*self; + } + + static QUrlTwoFlags or_op (const QUrlTwoFlags *self, const QUrlTwoFlags &other) + { + return *self | other; + } + + static QUrlTwoFlags or_op_with_e1 (const QUrlTwoFlags *self, A e) + { + return *self | e; + } + + static QUrlTwoFlags or_op_with_e2 (const QUrlTwoFlags *self, B e) + { + return *self | e; + } + + static QUrlTwoFlags and_op (const QUrlTwoFlags *self, const QUrlTwoFlags &other) + { + return *self & other; + } + + static QUrlTwoFlags and_op_with_e1 (const QUrlTwoFlags *self, A e) + { + return *self & e; + } + + static QUrlTwoFlags and_op_with_e2 (const QUrlTwoFlags *self, B e) + { + return *self & e; + } + + static QUrlTwoFlags xor_op (const QUrlTwoFlags *self, const QUrlTwoFlags &other) + { + return *self ^ other; + } + + static QUrlTwoFlags xor_op_with_e1 (const QUrlTwoFlags *self, A e) + { + return *self ^ e; + } + + static QUrlTwoFlags xor_op_with_e2 (const QUrlTwoFlags *self, B e) + { + return *self ^ e; + } + + static bool not_equal_with_i (const QUrlTwoFlags *self, int_repr i) + { + return int_repr (*self) != i; + } + + static bool not_equal (const QUrlTwoFlags *self, const QUrlTwoFlags &other) + { + // See equal() for an explanation why we compare int's. + return int_repr (*self) != int_repr (other); + } + + static bool equal_with_i (const QUrlTwoFlags *self, int_repr i) + { + return int_repr (*self) == i; + } + + static bool equal (const QUrlTwoFlags *self, const QUrlTwoFlags &other) + { + // NOTE: in order to avoid ambiguities with non-explicit constructors of objects taking a QFlag as an argument, + // we compare int's explicitly. An example for such an ambiguity is QSurfaceFormat in Qt 5.5.1 which takes a QFlags + // object in a non-explicit constructor. + return int_repr (*self) == int_repr (other); + } + + static gsi::Methods methods () + { + return + gsi::constructor ("new", &new_from_i, gsi::arg ("i"), "@brief Creates a flag set from an integer value") + + gsi::constructor ("new", &new_from_s, gsi::arg ("s"), "@brief Creates a flag set from a string") + + gsi::constructor ("new", &new_from_e1, gsi::arg ("e"), "@brief Creates a flag set from an enum") + + gsi::constructor ("new", &new_from_e1f, gsi::arg ("e"), "@brief Creates a flag set from a QFlags set") + + gsi::constructor ("new", &new_from_e2, gsi::arg ("e"), "@brief Creates a flag set from an enum") + + gsi::constructor ("new", &new_from_e2f, gsi::arg ("e"), "@brief Creates a flag set from a QFlags set") + + gsi::method_ext ("to_s", &to_s, "@brief Converts the flag set to a string") + + gsi::method_ext ("to_i", &to_i, "@brief Converts the flag set to an integer") + + gsi::method_ext ("testFlag1", &test_flag1, gsi::arg ("flag"), "@brief Tests whether the flag set contains the given flag") + + gsi::method_ext ("testFlag2", &test_flag2, gsi::arg ("flag"), "@brief Tests whether the flag set contains the given flag") + + gsi::method_ext ("inspect", &inspect, "@brief Converts the flag set to a visual string") + + gsi::method_ext ("|", &or_op, gsi::arg ("other"), "@brief Computes the union of two flag sets") + + gsi::method_ext ("|", &or_op_with_e1, gsi::arg ("flag"), "@brief Adds the given flag to the flag set and returns the new flag set") + + gsi::method_ext ("|", &or_op_with_e2, gsi::arg ("flag"), "@brief Adds the given flag to the flag set and returns the new flag set") + + gsi::method_ext ("&", &and_op, gsi::arg ("other"), "@brief Computes the intersection between the two flag sets") + + gsi::method_ext ("&", &and_op_with_e1, gsi::arg ("flag"), "@brief Tests whether the given flag is contained in the flag set and returns a null flag set if not") + + gsi::method_ext ("&", &and_op_with_e2, gsi::arg ("flag"), "@brief Tests whether the given flag is contained in the flag set and returns a null flag set if not") + + gsi::method_ext ("^", &xor_op, gsi::arg ("other"), "@brief Computes the exclusive-or between the flag set and the other flag set") + + gsi::method_ext ("^", &xor_op_with_e1, gsi::arg ("flag"), "@brief Inverts the given flag in the flag set and returns the new flag set") + + gsi::method_ext ("^", &xor_op_with_e2, gsi::arg ("flag"), "@brief Inverts the given flag in the flag set and returns the new flag set") + + gsi::method_ext ("==", &equal_with_i, gsi::arg ("other"), "@brief Returns true if the flag set equals the given integer value") + + gsi::method_ext ("==", &equal, gsi::arg ("i"), "@brief Returns true if the flag set equals the given other flag set") + + gsi::method_ext ("!=", ¬_equal_with_i, gsi::arg ("other"), "@brief Returns true if the flag set is not equal to the given integer value") + + gsi::method_ext ("!=", ¬_equal, gsi::arg ("i"), "@brief Returns true if the flag set is not equal to the given other flag set") + + gsi::method_ext ("~", &invert, "@brief Returns the inverted flag set"); + } +}; + +static QUrlTwoFlagsClass decl_QUrlTwoFlags ("QtCore", "QUrl_FormattingOptions", "@brief Binding of QUrl::FormattingOptions"); + +// inject as QUrl::FormattingOptions +static gsi::ClassExt decl_QUrlTwoFlags_as_child (decl_QUrlTwoFlags, "FormattingOptions", "@brief Binding of QUrl::FormattingOptions"); + } diff --git a/src/gsiqt/qt5/QtGui/QtGui.pro b/src/gsiqt/qt5/QtGui/QtGui.pro index a8d38e9c9..9da92edf4 100644 --- a/src/gsiqt/qt5/QtGui/QtGui.pro +++ b/src/gsiqt/qt5/QtGui/QtGui.pro @@ -17,6 +17,9 @@ INCLUDEPATH += $$DB_INC DEPENDPATH += $$DB_INC LIBS += -lklayout_db +# because QQbject is used as base class for many classes, we need this: +LIBS += -lklayout_QtCore + SOURCES += \ gsiDeclQtGuiAdd.cc diff --git a/src/gsiqt/qt5/QtGui/gsiDeclQtGuiAdd.cc b/src/gsiqt/qt5/QtGui/gsiDeclQtGuiAdd.cc index 89da38fa4..97eceb3d4 100644 --- a/src/gsiqt/qt5/QtGui/gsiDeclQtGuiAdd.cc +++ b/src/gsiqt/qt5/QtGui/gsiDeclQtGuiAdd.cc @@ -20,8 +20,9 @@ */ - #include "gsiQt.h" +// required to pull in the GSI declarations from db: +#include "dbForceLink.h" #include #include diff --git a/src/gsiqt/qt5/QtNetwork/QtNetwork.pro b/src/gsiqt/qt5/QtNetwork/QtNetwork.pro index 8de6821fc..1005c81d0 100644 --- a/src/gsiqt/qt5/QtNetwork/QtNetwork.pro +++ b/src/gsiqt/qt5/QtNetwork/QtNetwork.pro @@ -12,6 +12,9 @@ DEPENDPATH += $$TL_INC $$GSI_INC $$QTBASIC_INC LIBS += -L$$DESTDIR -lklayout_tl -lklayout_gsi -lklayout_qtbasic +# because QQbject is used as base class for many classes, we need this: +LIBS += -lklayout_QtCore + SOURCES += \ gsiDeclQtNetworkAdd.cc diff --git a/src/gsiqt/qt5/QtNetwork/gsiDeclQtNetworkAdd.cc b/src/gsiqt/qt5/QtNetwork/gsiDeclQtNetworkAdd.cc index 742e0d719..2ece2a754 100644 --- a/src/gsiqt/qt5/QtNetwork/gsiDeclQtNetworkAdd.cc +++ b/src/gsiqt/qt5/QtNetwork/gsiDeclQtNetworkAdd.cc @@ -38,277 +38,4 @@ gsi::Class > decl_QHostAddress_int_QPair ("QtNetwork", "@qt\\n@brief Represents a QPair" ); -// --------------------------------------------------------------------------- -// QUrlTwoFlags bindings - -template -class QUrlTwoFlagsClass; - -/** - * @brief An adaptor class for the QUrlTwoFlags template derived from QFlagsAdaptor template - */ -template -class QUrlTwoFlagsAdaptor -{ -public: - QUrlTwoFlagsAdaptor () : m_qf () { } - QUrlTwoFlagsAdaptor (A e) : m_qf (e) { } - QUrlTwoFlagsAdaptor (B e) : m_qf (e) { } - QUrlTwoFlagsAdaptor (QFlags e) : m_qf (e) { } - QUrlTwoFlagsAdaptor (QFlags e) : m_qf (e) { } - QUrlTwoFlagsAdaptor (const QUrlTwoFlags &qf) : m_qf (qf) { } - QUrlTwoFlagsAdaptor (int i) : m_qf (i) { } - - QUrlTwoFlagsAdaptor (const std::string &s) - { - const QUrlTwoFlagsClass *ecls = dynamic_cast *> (gsi::cls_decl > ()); - tl_assert (ecls != 0); - m_qf = ecls->qflags_from_string (s); - } - - QUrlTwoFlags &value () { return m_qf; } - const QUrlTwoFlags &value () const { return m_qf; } - -private: - QUrlTwoFlags m_qf; -}; - -/** - * @brief A binding for QUrlTwoFlags derived from QFlags binding - */ -template -class QUrlTwoFlagsClass - : public gsi::Class, QUrlTwoFlags > -{ -public: - typedef typename QFlags::Int int_repr; - - QUrlTwoFlagsClass (const std::string &module, const std::string &name, const std::string &doc = std::string ()) - : gsi::Class, QUrlTwoFlags > (module, name, methods (), doc) - { - } - - static QUrlTwoFlags *new_from_i (int_repr i) - { - return new QUrlTwoFlags (i); - } - - static QUrlTwoFlags *new_from_e1 (A e) - { - return new QUrlTwoFlags (e); - } - - static QUrlTwoFlags *new_from_e1f (QFlags e) - { - return new QUrlTwoFlags (e); - } - - static QUrlTwoFlags *new_from_e2 (B e) - { - return new QUrlTwoFlags (e); - } - - static QUrlTwoFlags *new_from_e2f (QFlags e) - { - return new QUrlTwoFlags (e); - } - - static QUrlTwoFlags *new_from_s (const std::string &s) - { - QUrlTwoFlags flags; - - const gsi::Enum *acls = dynamic_cast *> (gsi::cls_decl ()); - const gsi::Enum *bcls = dynamic_cast *> (gsi::cls_decl ()); - tl_assert (acls != 0 && bcls != 0); - - tl::Extractor ex (s.c_str ()); - while (! ex.at_end ()) { - - bool any = false; - - for (typename gsi::EnumSpecs::iterator s = acls->specs ().begin (); s != acls->specs ().end () && !any; ++s) { - if (ex.test (s->str.c_str ())) { - flags |= A (s->evalue); - any = true; - } - } - - for (typename gsi::EnumSpecs::iterator s = bcls->specs ().begin (); s != bcls->specs ().end () && !any; ++s) { - if (ex.test (s->str.c_str ())) { - flags |= B (s->evalue); - any = true; - } - } - - if (any) { - ex.test ("|"); - ex.test (","); - } else { - break; - } - - } - - return new QUrlTwoFlags (flags); - } - - static std::string to_s (const QUrlTwoFlags *self) - { - std::string res; - - const gsi::Enum *acls = dynamic_cast *> (gsi::cls_decl ()); - const gsi::Enum *bcls = dynamic_cast *> (gsi::cls_decl ()); - tl_assert (acls != 0 && bcls != 0); - - for (typename gsi::EnumSpecs::iterator s = acls->specs ().begin (); s != acls->specs ().end (); ++s) { - if (self->testFlag (s->evalue)) { - if (! res.empty ()) { - res += "|"; - } - res += s->str; - } - } - - for (typename gsi::EnumSpecs::iterator s = bcls->specs ().begin (); s != bcls->specs ().end (); ++s) { - if (self->testFlag (s->evalue)) { - if (! res.empty ()) { - res += "|"; - } - res += s->str; - } - } - - return res; - } - - static int_repr to_i (const QUrlTwoFlags *self) - { - return int_repr (*self); - } - - static bool test_flag1 (const QUrlTwoFlags *self, A e) - { - return self->testFlag (e); - } - - static bool test_flag2 (const QUrlTwoFlags *self, B e) - { - return self->testFlag (e); - } - - static std::string inspect (const QUrlTwoFlags *self) - { - return to_s (self) + tl::sprintf(" (%u)", (unsigned int) (int_repr (*self))); - } - - static QUrlTwoFlags invert (const QUrlTwoFlags *self) - { - return ~*self; - } - - static QUrlTwoFlags or_op (const QUrlTwoFlags *self, const QUrlTwoFlags &other) - { - return *self | other; - } - - static QUrlTwoFlags or_op_with_e1 (const QUrlTwoFlags *self, A e) - { - return *self | e; - } - - static QUrlTwoFlags or_op_with_e2 (const QUrlTwoFlags *self, B e) - { - return *self | e; - } - - static QUrlTwoFlags and_op (const QUrlTwoFlags *self, const QUrlTwoFlags &other) - { - return *self & other; - } - - static QUrlTwoFlags and_op_with_e1 (const QUrlTwoFlags *self, A e) - { - return *self & e; - } - - static QUrlTwoFlags and_op_with_e2 (const QUrlTwoFlags *self, B e) - { - return *self & e; - } - - static QUrlTwoFlags xor_op (const QUrlTwoFlags *self, const QUrlTwoFlags &other) - { - return *self ^ other; - } - - static QUrlTwoFlags xor_op_with_e1 (const QUrlTwoFlags *self, A e) - { - return *self ^ e; - } - - static QUrlTwoFlags xor_op_with_e2 (const QUrlTwoFlags *self, B e) - { - return *self ^ e; - } - - static bool not_equal_with_i (const QUrlTwoFlags *self, int_repr i) - { - return int_repr (*self) != i; - } - - static bool not_equal (const QUrlTwoFlags *self, const QUrlTwoFlags &other) - { - // See equal() for an explanation why we compare int's. - return int_repr (*self) != int_repr (other); - } - - static bool equal_with_i (const QUrlTwoFlags *self, int_repr i) - { - return int_repr (*self) == i; - } - - static bool equal (const QUrlTwoFlags *self, const QUrlTwoFlags &other) - { - // NOTE: in order to avoid ambiguities with non-explicit constructors of objects taking a QFlag as an argument, - // we compare int's explicitly. An example for such an ambiguity is QSurfaceFormat in Qt 5.5.1 which takes a QFlags - // object in a non-explicit constructor. - return int_repr (*self) == int_repr (other); - } - - static gsi::Methods methods () - { - return - gsi::constructor ("new", &new_from_i, gsi::arg ("i"), "@brief Creates a flag set from an integer value") + - gsi::constructor ("new", &new_from_s, gsi::arg ("s"), "@brief Creates a flag set from a string") + - gsi::constructor ("new", &new_from_e1, gsi::arg ("e"), "@brief Creates a flag set from an enum") + - gsi::constructor ("new", &new_from_e1f, gsi::arg ("e"), "@brief Creates a flag set from a QFlags set") + - gsi::constructor ("new", &new_from_e2, gsi::arg ("e"), "@brief Creates a flag set from an enum") + - gsi::constructor ("new", &new_from_e2f, gsi::arg ("e"), "@brief Creates a flag set from a QFlags set") + - gsi::method_ext ("to_s", &to_s, "@brief Converts the flag set to a string") + - gsi::method_ext ("to_i", &to_i, "@brief Converts the flag set to an integer") + - gsi::method_ext ("testFlag1", &test_flag1, gsi::arg ("flag"), "@brief Tests whether the flag set contains the given flag") + - gsi::method_ext ("testFlag2", &test_flag2, gsi::arg ("flag"), "@brief Tests whether the flag set contains the given flag") + - gsi::method_ext ("inspect", &inspect, "@brief Converts the flag set to a visual string") + - gsi::method_ext ("|", &or_op, gsi::arg ("other"), "@brief Computes the union of two flag sets") + - gsi::method_ext ("|", &or_op_with_e1, gsi::arg ("flag"), "@brief Adds the given flag to the flag set and returns the new flag set") + - gsi::method_ext ("|", &or_op_with_e2, gsi::arg ("flag"), "@brief Adds the given flag to the flag set and returns the new flag set") + - gsi::method_ext ("&", &and_op, gsi::arg ("other"), "@brief Computes the intersection between the two flag sets") + - gsi::method_ext ("&", &and_op_with_e1, gsi::arg ("flag"), "@brief Tests whether the given flag is contained in the flag set and returns a null flag set if not") + - gsi::method_ext ("&", &and_op_with_e2, gsi::arg ("flag"), "@brief Tests whether the given flag is contained in the flag set and returns a null flag set if not") + - gsi::method_ext ("^", &xor_op, gsi::arg ("other"), "@brief Computes the exclusive-or between the flag set and the other flag set") + - gsi::method_ext ("^", &xor_op_with_e1, gsi::arg ("flag"), "@brief Inverts the given flag in the flag set and returns the new flag set") + - gsi::method_ext ("^", &xor_op_with_e2, gsi::arg ("flag"), "@brief Inverts the given flag in the flag set and returns the new flag set") + - gsi::method_ext ("==", &equal_with_i, gsi::arg ("other"), "@brief Returns true if the flag set equals the given integer value") + - gsi::method_ext ("==", &equal, gsi::arg ("i"), "@brief Returns true if the flag set equals the given other flag set") + - gsi::method_ext ("!=", ¬_equal_with_i, gsi::arg ("other"), "@brief Returns true if the flag set is not equal to the given integer value") + - gsi::method_ext ("!=", ¬_equal, gsi::arg ("i"), "@brief Returns true if the flag set is not equal to the given other flag set") + - gsi::method_ext ("~", &invert, "@brief Returns the inverted flag set"); - } -}; - -static QUrlTwoFlagsClass decl_QUrlTwoFlags ("QtNetwork", "QUrl_FormattingOptions", "@brief Binding of QUrl::FormattingOptions"); - -// inject as QUrl::FormattingOptions -static gsi::ClassExt decl_QUrlTwoFlags_as_child (decl_QUrlTwoFlags, "FormattingOptions", "@brief Binding of QUrl::FormattingOptions"); - } diff --git a/src/gsiqt/qt5/QtPrintSupport/QtPrintSupport.pro b/src/gsiqt/qt5/QtPrintSupport/QtPrintSupport.pro index ce9a6e032..0df4f3d33 100644 --- a/src/gsiqt/qt5/QtPrintSupport/QtPrintSupport.pro +++ b/src/gsiqt/qt5/QtPrintSupport/QtPrintSupport.pro @@ -12,6 +12,12 @@ DEPENDPATH += $$TL_INC $$GSI_INC $$QTBASIC_INC LIBS += -L$$DESTDIR -lklayout_tl -lklayout_gsi -lklayout_qtbasic +# because QQbject is used as base class for many classes, we need this: +LIBS += -lklayout_QtCore + +# because QWidget is used for some UI stuff, we need this: +LIBS += -lklayout_QtWidgets + SOURCES += \ HEADERS += \ diff --git a/src/gsiqt/qt5/QtSql/QtSql.pro b/src/gsiqt/qt5/QtSql/QtSql.pro index 663f99b2b..db3622eb6 100644 --- a/src/gsiqt/qt5/QtSql/QtSql.pro +++ b/src/gsiqt/qt5/QtSql/QtSql.pro @@ -12,6 +12,9 @@ DEPENDPATH += $$TL_INC $$GSI_INC $$QTBASIC_INC LIBS += -L$$DESTDIR -lklayout_tl -lklayout_gsi -lklayout_qtbasic +# because QQbject is used as base class for many classes, we need this: +LIBS += -lklayout_QtCore + SOURCES += \ HEADERS += \ diff --git a/src/gsiqt/qt5/QtSvg/QtSvg.pro b/src/gsiqt/qt5/QtSvg/QtSvg.pro index ce7c54482..1988667c0 100644 --- a/src/gsiqt/qt5/QtSvg/QtSvg.pro +++ b/src/gsiqt/qt5/QtSvg/QtSvg.pro @@ -12,6 +12,12 @@ DEPENDPATH += $$TL_INC $$GSI_INC $$QTBASIC_INC LIBS += -L$$DESTDIR -lklayout_tl -lklayout_gsi -lklayout_qtbasic +# because QQbject is used as base class for many classes, we need this: +LIBS += -lklayout_QtCore + +# because QWidget is used for some UI stuff, we need this: +LIBS += -lklayout_QtWidgets + SOURCES += \ HEADERS += \ diff --git a/src/gsiqt/qt5/QtWidgets/QtWidgets.pro b/src/gsiqt/qt5/QtWidgets/QtWidgets.pro index 8e9a0812e..8209ae850 100644 --- a/src/gsiqt/qt5/QtWidgets/QtWidgets.pro +++ b/src/gsiqt/qt5/QtWidgets/QtWidgets.pro @@ -12,6 +12,12 @@ DEPENDPATH += $$TL_INC $$GSI_INC $$QTBASIC_INC LIBS += -L$$DESTDIR -lklayout_tl -lklayout_gsi -lklayout_qtbasic +# because QPainter is used as base class for QStylePainter, we need this: +LIBS += -lklayout_QtGui + +SOURCES += \ + gsiDeclQtWidgetsAdd.cc + HEADERS += \ include(QtWidgets.pri) diff --git a/src/gsiqt/qt5/QtWidgets/gsiDeclQtWidgetsAdd.cc b/src/gsiqt/qt5/QtWidgets/gsiDeclQtWidgetsAdd.cc new file mode 100644 index 000000000..39b6ec5ce --- /dev/null +++ b/src/gsiqt/qt5/QtWidgets/gsiDeclQtWidgetsAdd.cc @@ -0,0 +1,25 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2018 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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 + +*/ + +#include "gsiQt.h" + +// .. nothing yet .. diff --git a/src/gsiqt/qt5/QtXmlPatterns/QtXmlPatterns.pro b/src/gsiqt/qt5/QtXmlPatterns/QtXmlPatterns.pro index 83f57ba96..97aae43db 100644 --- a/src/gsiqt/qt5/QtXmlPatterns/QtXmlPatterns.pro +++ b/src/gsiqt/qt5/QtXmlPatterns/QtXmlPatterns.pro @@ -12,6 +12,9 @@ DEPENDPATH += $$TL_INC $$GSI_INC $$QTBASIC_INC LIBS += -L$$DESTDIR -lklayout_tl -lklayout_gsi -lklayout_qtbasic +# because QQbject is used as base class for many classes, we need this: +LIBS += -lklayout_QtCore + SOURCES += \ HEADERS += \ diff --git a/src/gsiqt/qt5/qt5.pro b/src/gsiqt/qt5/qt5.pro index 346332bf2..258113d46 100644 --- a/src/gsiqt/qt5/qt5.pro +++ b/src/gsiqt/qt5/qt5.pro @@ -14,3 +14,13 @@ SUBDIRS = \ QtXmlPatterns \ QtXml +QtGui.depends += QtCore +QtNetwork.depends += QtCore +QtSql.depends += QtCore +QtWidgets.depends += QtGui +QtDesigner.depends += QtCore +QtMultimedia.depends += QtCore +QtPrintSupports.depends += QtCore QtWidgets +QtSvg.depends += QtCore QtWidgets +QtXmlPatterns.depends += QtCore +QtXml.depends += QtCore diff --git a/src/lay/lay/lay.pro b/src/lay/lay/lay.pro index fcb3eedcd..78d7262ea 100644 --- a/src/lay/lay/lay.pro +++ b/src/lay/lay/lay.pro @@ -58,7 +58,8 @@ HEADERS = \ layNativePlugin.h \ laySystemPaths.h \ layMacroEditorSetupPage.h \ - layPasswordDialog.h + layPasswordDialog.h \ + layForceLink.h FORMS = \ ClipDialog.ui \ @@ -163,7 +164,8 @@ SOURCES = \ layNativePlugin.cc \ laySystemPaths.cc \ layMacroEditorSetupPage.cc \ - layPasswordDialog.cc + layPasswordDialog.cc \ + layForceLink.cc RESOURCES = layBuildInMacros.qrc \ layHelpResources.qrc \ diff --git a/src/lay/lay/layForceLink.cc b/src/lay/lay/layForceLink.cc new file mode 100644 index 000000000..65988510c --- /dev/null +++ b/src/lay/lay/layForceLink.cc @@ -0,0 +1,32 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2018 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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 + +*/ + +#include "layForceLink.h" + +namespace lay +{ + int _force_link_f () + { + return 0; + } +} + diff --git a/src/lay/lay/layForceLink.h b/src/lay/lay/layForceLink.h new file mode 100644 index 000000000..b107d99fe --- /dev/null +++ b/src/lay/lay/layForceLink.h @@ -0,0 +1,40 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2018 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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 + +*/ + + +#ifndef HDR_layForceLink +#define HDR_layForceLink + +#include "layCommon.h" + +/** + * @file Include this function to force linking of the lay module + */ + +namespace lay +{ + LAY_PUBLIC int _force_link_f (); + static int _force_link_target = _force_link_f (); +} + +#endif + diff --git a/src/laybasic/laybasic/laybasic.pro b/src/laybasic/laybasic/laybasic.pro index a0925cf7a..7b6f6b0cc 100644 --- a/src/laybasic/laybasic/laybasic.pro +++ b/src/laybasic/laybasic/laybasic.pro @@ -282,5 +282,8 @@ DEPENDPATH += $$QTBASIC_INC equals(HAVE_QTBINDINGS, "1") { LIBS += -lklayout_qtbasic -lklayout_QtGui -lklayout_QtCore + equals(HAVE_QT5, "1") { + LIBS += -lklayout_QtWidgets + } } diff --git a/src/pya/pya/pya.cc b/src/pya/pya/pya.cc index 6b104add0..0668299ba 100644 --- a/src/pya/pya/pya.cc +++ b/src/pya/pya/pya.cc @@ -2214,6 +2214,8 @@ std::map PythonModule::m_python_doc; std::map PythonModule::m_cls_map; std::map PythonModule::m_rev_cls_map; +const std::string pymod_name ("pykl"); + PythonModule::PythonModule () : mp_mod_def (0) { @@ -2229,27 +2231,6 @@ PythonModule::~PythonModule () mp_module.release (); mp_base_class.release (); - delete_module (); -} - -PyObject * -PythonModule::module () -{ - return mp_module.get (); -} - -PyObject * -PythonModule::take_module () -{ - return mp_module.release (); -} - -void -PythonModule::delete_module () -{ - mp_module = PythonRef (); - mp_base_class = PythonRef (); - while (!m_methods_heap.empty ()) { delete m_methods_heap.back (); m_methods_heap.pop_back (); @@ -2266,10 +2247,27 @@ PythonModule::delete_module () } } +PyObject * +PythonModule::module () +{ + return mp_module.get (); +} + +PyObject * +PythonModule::take_module () +{ + return mp_module.release (); +} + void PythonModule::init (const char *mod_name, const char *description) { - m_mod_name = mod_name; + // do some checks before we create the module + tl_assert (mod_name != 0); + tl_assert (mp_module.get () == 0); + check (mod_name); + + m_mod_name = pymod_name + "." + mod_name; m_mod_description = description; static PyMethodDef module_methods[] = { @@ -2308,6 +2306,10 @@ PythonModule::init (const char *mod_name, const char *description) void PythonModule::init (const char *mod_name, PyObject *module) { + // do some checks before we create the module + tl_assert (mp_module.get () == 0); + check (mod_name); + m_mod_name = mod_name; mp_module = PythonRef (module); } @@ -2357,41 +2359,45 @@ PythonModule::python_doc (const gsi::MethodBase *method) } void -PythonModule::make_classes (const char *mod_name) +PythonModule::check (const char *mod_name) { + if (! mod_name) { + return; + } + // Check whether the new classes are self-contained within this module - if (mod_name) { + for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) { - for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) { + if (c->module () != mod_name) { + // don't handle classes outside this module + continue; + } - if (c->module () != mod_name) { - // don't handle classes outside this module - continue; - } - - if (m_rev_cls_map.find (&*c) != m_rev_cls_map.end ()) { - // don't handle classes twice - continue; - } - - // All child classes must originate from this module or be known already - for (tl::weak_collection::const_iterator cc = c->begin_child_classes (); cc != c->end_child_classes (); ++cc) { - if (m_rev_cls_map.find (cc->declaration ()) == m_rev_cls_map.end () - && cc->module () != mod_name) { - throw tl::Exception (tl::sprintf (tl::to_string (QObject::tr ("Class %s from module %s depends on %s.%s (try 'import klayout.%s' before 'import klayout.%s')")), c->name (), mod_name, cc->module (), cc->name (), cc->module (), mod_name)); - } - } - - // Same for base class - if (c->base () && m_rev_cls_map.find (c->base ()) == m_rev_cls_map.end () - && c->base ()->module () != mod_name) { - throw tl::Exception (tl::sprintf (tl::to_string (QObject::tr ("Class %s from module %s depends on %s.%s (try 'import klayout.%s' before 'import klayout.%s')")), c->name (), mod_name, c->base ()->module (), c->base ()->name (), c->base ()->module (), mod_name)); + if (m_rev_cls_map.find (&*c) != m_rev_cls_map.end ()) { + // don't handle classes twice + continue; + } + + // All child classes must originate from this module or be known already + for (tl::weak_collection::const_iterator cc = c->begin_child_classes (); cc != c->end_child_classes (); ++cc) { + if (m_rev_cls_map.find (cc->declaration ()) == m_rev_cls_map.end () + && cc->module () != mod_name) { + throw tl::Exception (tl::sprintf (tl::to_string (QObject::tr ("Class %s from module %s depends on %s.%s (try 'import %s' before 'import %s')")), c->name (), mod_name, cc->module (), cc->name (), pymod_name + "." + cc->module (), pymod_name + "." + mod_name)); } + } + // Same for base class + if (c->base () && m_rev_cls_map.find (c->base ()) == m_rev_cls_map.end () + && c->base ()->module () != mod_name) { + throw tl::Exception (tl::sprintf (tl::to_string (QObject::tr ("Class %s from module %s depends on %s.%s (try 'import %s' before 'import %s')")), c->name (), mod_name, c->base ()->module (), c->base ()->name (), pymod_name + "." + c->base ()->module (), pymod_name + "." + mod_name)); } } +} +void +PythonModule::make_classes (const char *mod_name) +{ PyObject *module = mp_module.get (); // Prepare an __all__ index for the module @@ -2451,6 +2457,9 @@ PythonModule::make_classes (const char *mod_name) bool more_classes = true; while (more_classes) { + std::string reason_for_more; + bool any = false; + more_classes = false; for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) { @@ -2468,6 +2477,7 @@ PythonModule::make_classes (const char *mod_name) for (tl::weak_collection::const_iterator cc = c->begin_child_classes (); cc != c->end_child_classes (); ++cc) { tl_assert (cc->declaration () != 0); if (m_rev_cls_map.find (cc->declaration ()) == m_rev_cls_map.end ()) { + reason_for_more = tl::sprintf ("child of class %s.%s not available (%s.%s)", c->module (), c->name (), cc->module (), cc->name ()); all_children_available = false; break; } @@ -2480,6 +2490,7 @@ PythonModule::make_classes (const char *mod_name) if (c->base () && m_rev_cls_map.find (c->base ()) == m_rev_cls_map.end ()) { // can't produce this class yet. The base class needs to be handled first. + reason_for_more = tl::sprintf ("base of class %s.%s not available (%s.%s)", c->module (), c->name (), c->base ()->module (), c->base ()->name ()); more_classes = true; continue; } @@ -2489,6 +2500,8 @@ PythonModule::make_classes (const char *mod_name) // Create the class as a heap object, since that way we can dynamically extend the objects + any = true; + PythonRef bases (PyTuple_New (1)); PyObject *base = mp_base_class.get (); if (c->base () != 0) { @@ -2949,6 +2962,11 @@ PythonModule::make_classes (const char *mod_name) } + if (! any && more_classes) { + // prevent infinite recursion + throw tl::Exception ("Internal error: infinite recursion on class building. Reason is: " + reason_for_more); + } + } } diff --git a/src/pya/pya/pya.h b/src/pya/pya/pya.h index 7298bdecd..8c6c88967 100644 --- a/src/pya/pya/pya.h +++ b/src/pya/pya/pya.h @@ -189,16 +189,12 @@ public: */ PyObject *take_module (); - /** - * @brief Deletes the PyModule object - */ - void delete_module (); - private: void add_python_doc (const gsi::ClassBase &cls, const MethodTable *mt, int mid, const std::string &doc); PyMethodDef *make_method_def (); PyGetSetDef *make_getset_def (); char *make_string (const std::string &s); + static void check (const char *mod_name); std::list m_string_heap; std::vector m_methods_heap; diff --git a/src/pymod/QtCore/QtCore.pro b/src/pymod/QtCore/QtCore.pro index 80fc673b9..40caf843a 100644 --- a/src/pymod/QtCore/QtCore.pro +++ b/src/pymod/QtCore/QtCore.pro @@ -8,4 +8,4 @@ SOURCES = \ HEADERS += \ -LIBS += -lklayout_QtCore +LIBS += -lklayout_QtCore -lklayout_QtGui -lklayout_QtWidgets diff --git a/src/pymod/QtCore/QtCoreMain.cc b/src/pymod/QtCore/QtCoreMain.cc index a325ad7db..d3bf7d9c1 100644 --- a/src/pymod/QtCore/QtCoreMain.cc +++ b/src/pymod/QtCore/QtCoreMain.cc @@ -22,4 +22,18 @@ #include "../pymodHelper.h" +// To force linking of the QtCore module +#include "../../gsiqt/qtbasic/gsiQtCoreExternals.h" +FORCE_LINK_GSI_QTCORE + +// And this is *only* required because of QSignalMapper which takes a QWidget argument from +// the QtGui library and we need to supply the GSI binding for this ... +#include "../../gsiqt/qtbasic/gsiQtGuiExternals.h" +FORCE_LINK_GSI_QTGUI + +// And because we pull in QtGui, we also need to pull in QtWidgets because QtGui bindings +// use QAction and QWidget which are itself in QtWidgets +#include "../../gsiqt/qtbasic/gsiQtWidgetsExternals.h" +FORCE_LINK_GSI_QTWIDGETS + DEFINE_PYMOD(QtCore, "QtCore", "KLayout/Qt module 'QtCore'") diff --git a/src/pymod/QtDesigner/QtDesignerMain.cc b/src/pymod/QtDesigner/QtDesignerMain.cc index 000fa722c..1fab66e43 100644 --- a/src/pymod/QtDesigner/QtDesignerMain.cc +++ b/src/pymod/QtDesigner/QtDesignerMain.cc @@ -22,4 +22,8 @@ #include "../pymodHelper.h" +// To force linking of the QtDesigner module +#include "../../gsiqt/qtbasic/gsiQtDesignerExternals.h" +FORCE_LINK_GSI_QTDESIGNER + DEFINE_PYMOD(QtDesigner, "QtDesigner", "KLayout/Qt module 'QtDesigner'") diff --git a/src/pymod/QtGui/QtGui.pro b/src/pymod/QtGui/QtGui.pro index 909a18b95..a2f39a5bc 100644 --- a/src/pymod/QtGui/QtGui.pro +++ b/src/pymod/QtGui/QtGui.pro @@ -8,4 +8,9 @@ SOURCES = \ HEADERS += \ -LIBS += -lklayout_QtGui +LIBS += -lklayout_QtGui -lklayout_QtCore + +equals(HAVE_QT5, "1") { + LIBS += -lklayout_QtWidgets +} + diff --git a/src/pymod/QtGui/QtGuiMain.cc b/src/pymod/QtGui/QtGuiMain.cc index 43b77f742..c6a9f1d26 100644 --- a/src/pymod/QtGui/QtGuiMain.cc +++ b/src/pymod/QtGui/QtGuiMain.cc @@ -22,4 +22,13 @@ #include "../pymodHelper.h" +// To force linking of the QtGui module +#include "../../gsiqt/qtbasic/gsiQtGuiExternals.h" +FORCE_LINK_GSI_QTGUI + +// This is required because QAction and QWidget are used are arguments in QtGui, but are +// defined in QtWidgets +#include "../../gsiqt/qtbasic/gsiQtWidgetsExternals.h" +FORCE_LINK_GSI_QTWIDGETS + DEFINE_PYMOD(QtGui, "QtGui", "KLayout/Qt module 'QtGui'") diff --git a/src/pymod/QtMultimedia/QtMultimediaMain.cc b/src/pymod/QtMultimedia/QtMultimediaMain.cc index c8fc0c3f5..ebf03244d 100644 --- a/src/pymod/QtMultimedia/QtMultimediaMain.cc +++ b/src/pymod/QtMultimedia/QtMultimediaMain.cc @@ -22,4 +22,8 @@ #include "../pymodHelper.h" +// To force linking of the QtMultimedia module +#include "../../gsiqt/qtbasic/gsiQtMultimediaExternals.h" +FORCE_LINK_GSI_QTMULTIMEDIA + DEFINE_PYMOD(QtMultimedia, "QtMultimedia", "KLayout/Qt module 'QtMultimedia'") diff --git a/src/pymod/QtNetwork/QtNetworkMain.cc b/src/pymod/QtNetwork/QtNetworkMain.cc index fcc8c3f26..ce53c598b 100644 --- a/src/pymod/QtNetwork/QtNetworkMain.cc +++ b/src/pymod/QtNetwork/QtNetworkMain.cc @@ -22,4 +22,8 @@ #include "../pymodHelper.h" +// To force linking of the QtNetwork module +#include "../../gsiqt/qtbasic/gsiQtNetworkExternals.h" +FORCE_LINK_GSI_QTNETWORK + DEFINE_PYMOD(QtNetwork, "QtNetwork", "KLayout/Qt module 'QtNetwork'") diff --git a/src/pymod/QtPrintSupport/QtPrintSupportMain.cc b/src/pymod/QtPrintSupport/QtPrintSupportMain.cc index 2bf8b0253..f216b01dc 100644 --- a/src/pymod/QtPrintSupport/QtPrintSupportMain.cc +++ b/src/pymod/QtPrintSupport/QtPrintSupportMain.cc @@ -22,4 +22,8 @@ #include "../pymodHelper.h" +// To force linking of the QtPrintSupport module +#include "../../gsiqt/qtbasic/gsiQtPrintSupportExternals.h" +FORCE_LINK_GSI_QTPRINTSUPPORT + DEFINE_PYMOD(QtPrintSupport, "QtPrintSupport", "KLayout/Qt module 'QtPrintSupport'") diff --git a/src/pymod/QtSql/QtSqlMain.cc b/src/pymod/QtSql/QtSqlMain.cc index 7bd362201..0fb46fa02 100644 --- a/src/pymod/QtSql/QtSqlMain.cc +++ b/src/pymod/QtSql/QtSqlMain.cc @@ -22,4 +22,8 @@ #include "../pymodHelper.h" +// To force linking of the QtSql module +#include "../../gsiqt/qtbasic/gsiQtSqlExternals.h" +FORCE_LINK_GSI_QTSQL + DEFINE_PYMOD(QtSql, "QtSql", "KLayout/Qt module 'QtSql'") diff --git a/src/pymod/QtSvg/QtSvgMain.cc b/src/pymod/QtSvg/QtSvgMain.cc index 39a670d0e..28ef8ca66 100644 --- a/src/pymod/QtSvg/QtSvgMain.cc +++ b/src/pymod/QtSvg/QtSvgMain.cc @@ -22,4 +22,8 @@ #include "../pymodHelper.h" +// To force linking of the QtSvg module +#include "../../gsiqt/qtbasic/gsiQtSvgExternals.h" +FORCE_LINK_GSI_QTSVG + DEFINE_PYMOD(QtSvg, "QtSvg", "KLayout/Qt module 'QtSvg'") diff --git a/src/pymod/QtWidgets/QtWidgetsMain.cc b/src/pymod/QtWidgets/QtWidgetsMain.cc index 37395d454..bfd46c577 100644 --- a/src/pymod/QtWidgets/QtWidgetsMain.cc +++ b/src/pymod/QtWidgets/QtWidgetsMain.cc @@ -22,4 +22,8 @@ #include "../pymodHelper.h" +// To force linking of the QtWidgets module +#include "../../gsiqt/qtbasic/gsiQtWidgetsExternals.h" +FORCE_LINK_GSI_QTWIDGETS + DEFINE_PYMOD(QtWidgets, "QtWidgets", "KLayout/Qt module 'QtWidgets'") diff --git a/src/pymod/QtXml/QtXml.pro b/src/pymod/QtXml/QtXml.pro index b4c626bda..532447f86 100644 --- a/src/pymod/QtXml/QtXml.pro +++ b/src/pymod/QtXml/QtXml.pro @@ -8,4 +8,7 @@ SOURCES = \ HEADERS += \ -LIBS += -lklayout_QtXml +LIBS += -lklayout_QtCore -lklayout_QtXml + +# Because of stupid dependency of QtCore on QtGui and this on QtWidgets: +LIBS += -lklayout_QtGui -lklayout_QtWidgets diff --git a/src/pymod/QtXml/QtXmlMain.cc b/src/pymod/QtXml/QtXmlMain.cc index daf9bec5e..87976b47a 100644 --- a/src/pymod/QtXml/QtXmlMain.cc +++ b/src/pymod/QtXml/QtXmlMain.cc @@ -22,4 +22,24 @@ #include "../pymodHelper.h" +// To force linking of the QtXml module +#include "../../gsiqt/qtbasic/gsiQtXmlExternals.h" +FORCE_LINK_GSI_QTXML + +// To force linking of the QtCore module (some arguments +// are QIODevice or QTextStream) +#include "../../gsiqt/qtbasic/gsiQtCoreExternals.h" +FORCE_LINK_GSI_QTCORE + +// And because will pull in QtCore: +// This is *only* required because of QSignalMapper which takes a QWidget argument from +// the QtGui library and we need to supply the GSI binding for this ... +#include "../../gsiqt/qtbasic/gsiQtGuiExternals.h" +FORCE_LINK_GSI_QTGUI + +// And because we pull in QtGui, we also need to pull in QtWidgets because QtGui bindings +// use QAction and QWidget which are itself in QtWidgets +#include "../../gsiqt/qtbasic/gsiQtWidgetsExternals.h" +FORCE_LINK_GSI_QTWIDGETS + DEFINE_PYMOD(QtXml, "QtXml", "KLayout/Qt module 'QtXml'") diff --git a/src/pymod/QtXmlPatterns/QtXmlPatterns.pro b/src/pymod/QtXmlPatterns/QtXmlPatterns.pro index 72a6329a0..9420f99c8 100644 --- a/src/pymod/QtXmlPatterns/QtXmlPatterns.pro +++ b/src/pymod/QtXmlPatterns/QtXmlPatterns.pro @@ -8,4 +8,4 @@ SOURCES = \ HEADERS += \ -LIBS += -lklayout_QtXmlPatterns +LIBS += -lklayout_QtXmlPatterns -lklayout_QtNetwork diff --git a/src/pymod/QtXmlPatterns/QtXmlPatternsMain.cc b/src/pymod/QtXmlPatterns/QtXmlPatternsMain.cc index ce6c64e71..9e6c8e92c 100644 --- a/src/pymod/QtXmlPatterns/QtXmlPatternsMain.cc +++ b/src/pymod/QtXmlPatterns/QtXmlPatternsMain.cc @@ -22,4 +22,13 @@ #include "../pymodHelper.h" +// To force linking of the QtXmlPatterns module +#include "../../gsiqt/qtbasic/gsiQtXmlPatternsExternals.h" +FORCE_LINK_GSI_QTXMLPATTERNS + +// To force linking of the QtNetwork module (some arguments +// are QNetworkAccessManager) +#include "../../gsiqt/qtbasic/gsiQtNetworkExternals.h" +FORCE_LINK_GSI_QTNETWORK + DEFINE_PYMOD(QtXmlPatterns, "QtXmlPatterns", "KLayout/Qt module 'QtXmlPatterns'") diff --git a/src/pymod/db/dbMain.cc b/src/pymod/db/dbMain.cc index a0886149d..686fa149c 100644 --- a/src/pymod/db/dbMain.cc +++ b/src/pymod/db/dbMain.cc @@ -22,4 +22,7 @@ #include "../pymodHelper.h" +// to force linking of the db module +#include "../../db/db/dbForceLink.h" + DEFINE_PYMOD(db, "db", "KLayout core module 'db'") diff --git a/src/pymod/lay/layMain.cc b/src/pymod/lay/layMain.cc index 30b945094..aa9865404 100644 --- a/src/pymod/lay/layMain.cc +++ b/src/pymod/lay/layMain.cc @@ -22,4 +22,7 @@ #include "../pymodHelper.h" +// to force linking of the lay module +#include "../../lay/lay/layForceLink.h" + DEFINE_PYMOD(lay, "lay", "KLayout core module 'lay'") diff --git a/src/pymod/pymodHelper.h b/src/pymod/pymodHelper.h index b0faf530b..3d72247e7 100644 --- a/src/pymod/pymodHelper.h +++ b/src/pymod/pymodHelper.h @@ -39,8 +39,7 @@ static PyObject * module_init (const char *mod_name, const char *mod_description) { static pya::PythonModule module; - std::string mod_qname (std::string ("pykl.") + mod_name); - + PYA_TRY gsi::initialize (); @@ -48,14 +47,13 @@ module_init (const char *mod_name, const char *mod_description) // required for the tiling processor for example gsi::initialize_expressions (); - module.init (mod_qname.c_str (), mod_description); + module.init (mod_name, mod_description); module.make_classes (mod_name); return module.take_module (); PYA_CATCH_ANYWHERE - module.delete_module (); return 0; }