From 88a3068a0be4e2a91cfda0d871f2301a504a4484 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 19 Jun 2017 22:33:37 +0200 Subject: [PATCH] More abilities for native plugins This commit is a preparation for native plugins. It adds the ability to register for autorun and autorun-early for native, binary extensions. Plus, the search path for binary extensions was modified so it does not need to be ABI specific (i.e. without -gcc). This prepares for a plugin scheme which uses a C-only API and does not impose ABI compatibility requirements. --- src/lay/lay.pro | 3 ++- src/lay/layApplication.cc | 39 +++++++++++++++++++++------ src/lay/layMainWindow.cc | 2 +- src/lay/layNativePlugin.cc | 55 ++++++++++++++++++++++++++++++++++++++ src/lay/layNativePlugin.h | 30 ++++++++++++++++++--- 5 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 src/lay/layNativePlugin.cc diff --git a/src/lay/lay.pro b/src/lay/lay.pro index efefe08c1..94d345676 100644 --- a/src/lay/lay.pro +++ b/src/lay/lay.pro @@ -165,7 +165,8 @@ SOURCES = \ laySaltController.cc \ laySignalHandler.cc \ layLibraryController.cc \ - layFontController.cc + layFontController.cc \ + layNativePlugin.cc RESOURCES = layBuildInMacros.qrc \ layHelpResources.qrc \ diff --git a/src/lay/layApplication.cc b/src/lay/layApplication.cc index ddea21698..f03dc0987 100644 --- a/src/lay/layApplication.cc +++ b/src/lay/layApplication.cc @@ -329,6 +329,13 @@ Application::Application (int &argc, char **argv, bool non_ui_mode) std::string version = lay::Version::version (); std::vector vv = tl::split (version, "."); + std::string arch_string = tl::arch_string (); + std::vector as = tl::split (arch_string, "-"); + if (as.size () > 2) { + as.resize (2); + } + std::string short_arch_string = tl::join (as, "-"); + for (std::vector ::const_iterator p = m_klayout_path.begin (); p != m_klayout_path.end (); ++p) { std::set modules; @@ -345,26 +352,28 @@ Application::Application (int &argc, char **argv, bool non_ui_mode) // salt/mypackage/x86_64-linux-gcc-0.25 // salt/mypackage/x86_64-linux-gcc-0 // salt/mypackage/x86_64-linux-gcc + // salt/mypackage/x86_64-linux // salt/mypackage for (lay::Salt::flat_iterator g = salt.begin_flat (); g != salt.end_flat (); ++g) { QDir dir = QDir (tl::to_qstring ((*g)->path ())); - klp_paths.push_back (dir.filePath (tl::to_qstring (tl::arch_string () + "-" + lay::Version::version()))); + klp_paths.push_back (dir.filePath (tl::to_qstring (arch_string + "-" + lay::Version::version()))); if (vv.size () >= 2) { - klp_paths.push_back (dir.filePath (tl::to_qstring (tl::arch_string () + "-" + vv[0] + "." + vv[1]))); + klp_paths.push_back (dir.filePath (tl::to_qstring (arch_string + "-" + vv[0] + "." + vv[1]))); } if (vv.size () >= 1) { - klp_paths.push_back (dir.filePath (tl::to_qstring (tl::arch_string () + "-" + vv[0]))); + klp_paths.push_back (dir.filePath (tl::to_qstring (arch_string + "-" + vv[0]))); } - klp_paths.push_back (dir.filePath (tl::to_qstring (tl::arch_string () + "-" + tl::to_string (lay::Version::version ())))); - klp_paths.push_back (dir.filePath (tl::to_qstring (tl::arch_string ()))); + klp_paths.push_back (dir.filePath (tl::to_qstring (arch_string + "-" + tl::to_string (lay::Version::version ())))); + klp_paths.push_back (dir.filePath (tl::to_qstring (arch_string))); + klp_paths.push_back (dir.filePath (tl::to_qstring (short_arch_string))); klp_paths.push_back (tl::to_qstring ((*g)->path ())); } - for (std::vector::const_iterator p = klp_paths.begin (); p != klp_paths.end (); ++p) { + QStringList name_filters; + name_filters << QString::fromUtf8 ("*.klp"); - QStringList name_filters; - name_filters << QString::fromUtf8 ("*.klp"); + for (std::vector::const_iterator p = klp_paths.begin (); p != klp_paths.end (); ++p) { QStringList inst_modules = QDir (*p).entryList (name_filters); inst_modules.sort (); @@ -778,6 +787,13 @@ Application::Application (int &argc, char **argv, bool non_ui_mode) tl::Variant kp (m_klayout_path.begin (), m_klayout_path.end ()); tl::Eval::set_global_var ("klayout_path", kp); + // call "autorun_early" on all plugins that wish so + for (std::vector ::const_iterator p = m_native_plugins.begin (); p != m_native_plugins.end (); ++p) { + if (p->autorun_early) { + (*p->autorun_early) (); + } + } + // run all early autorun macros lay::MacroCollection::root ().autorun_early (); @@ -1123,6 +1139,13 @@ Application::run () } + // call "autorun" on all plugins that wish so + for (std::vector ::const_iterator p = m_native_plugins.begin (); p != m_native_plugins.end (); ++p) { + if (p->autorun) { + (*p->autorun) (); + } + } + // run all autorun macros lay::MacroCollection::root ().autorun (); diff --git a/src/lay/layMainWindow.cc b/src/lay/layMainWindow.cc index 49826e749..2e0db46e9 100644 --- a/src/lay/layMainWindow.cc +++ b/src/lay/layMainWindow.cc @@ -5432,7 +5432,7 @@ HelpAboutDialog::HelpAboutDialog (QWidget *parent) if (! lay::Application::instance ()->native_plugins ().empty ()) { s += "

"; s += "

"; - s += escape_xml (tl::to_string (QObject::tr ("Native extensions:"))); + s += escape_xml (tl::to_string (QObject::tr ("Binary extensions:"))); s += "

    "; for (std::vector::const_iterator pd = lay::Application::instance ()->native_plugins ().begin (); pd != lay::Application::instance ()->native_plugins ().end (); ++pd) { s += "
  • "; diff --git a/src/lay/layNativePlugin.cc b/src/lay/layNativePlugin.cc new file mode 100644 index 000000000..9c1f11393 --- /dev/null +++ b/src/lay/layNativePlugin.cc @@ -0,0 +1,55 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2017 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 "layNativePlugin.h" + +#include "gsiDecl.h" + +const klp_class_t *klp_class_by_name (const char *name) +{ + return reinterpret_cast (gsi::class_by_name (name)); +} + +void *klp_create (const klp_class_t *cls) +{ + return reinterpret_cast (cls)->create (); +} + +void klp_destroy (const klp_class_t *cls, void *obj) +{ + reinterpret_cast (cls)->destroy (obj); +} + +void *klp_clone (const klp_class_t *cls, const void *source) +{ + return reinterpret_cast (cls)->clone (source); +} + +void klp_assign (const klp_class_t *cls, void *target, const void *source) +{ + reinterpret_cast (cls)->assign (target, source); +} + +void klp_require_api_version (const char * /*version*/) +{ + // TODO: implement +} diff --git a/src/lay/layNativePlugin.h b/src/lay/layNativePlugin.h index 38abcaa04..8ecb4194c 100644 --- a/src/lay/layNativePlugin.h +++ b/src/lay/layNativePlugin.h @@ -23,6 +23,8 @@ #ifndef HDR_layNativePlugin #define HDR_layNativePlugin +#include "layCommon.h" + /** * @brief A struct to hold the data of the plugin * @@ -51,19 +53,19 @@ struct NativePlugin { typedef void (*klp_init_func_t) (void (**autorun) (), void (**autorun_early) (), const char **version, const char **description); # if defined _WIN32 || defined __CYGWIN__ -# define _INIT_PUBLIC __declspec(dllexport) +# define KLP_PUBLIC __declspec(dllexport) # else # if __GNUC__ >= 4 -# define _INIT_PUBLIC __attribute__ ((visibility ("default"))) +# define KLP_PUBLIC __attribute__ ((visibility ("default"))) # else -# define _INIT_PUBLIC +# define KLP_PUBLIC # endif # endif #define DECLARE_NATIVE_PLUGIN(desc) \ extern "C" { \ - _INIT_PUBLIC void klp_init (void (**autorun) (), void (**autorun_early) (), const char **version, const char **description) { \ + KLP_PUBLIC void klp_init (void (**autorun) (), void (**autorun_early) (), const char **version, const char **description) { \ *autorun = desc.autorun; \ *autorun_early = desc.autorun_early; \ *version = desc.version; \ @@ -71,5 +73,25 @@ typedef void (*klp_init_func_t) (void (**autorun) (), void (**autorun_early) (), } \ } +/** + * @brief Some (opaque) types for representing some gsi classes in the native API + */ + +struct klp_class_t { }; +struct klp_method_t { }; + +/** + * @brief The gsi API functions wrapped for the native API + */ +extern "C" { + LAY_PUBLIC const klp_class_t *klp_class_by_name (const char *name); + LAY_PUBLIC void *klp_create (const klp_class_t *cls); + LAY_PUBLIC void klp_destroy (const klp_class_t *cls, void *obj); + LAY_PUBLIC void *klp_clone (const klp_class_t *cls, const void *source); + LAY_PUBLIC void klp_assign (const klp_class_t *cls, void *target, const void *source); + LAY_PUBLIC void klp_require_api_version (const char *version); +} + + #endif