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.
This commit is contained in:
Matthias Koefferlein 2017-06-19 22:33:37 +02:00
parent 19777e5629
commit 88a3068a0b
5 changed files with 115 additions and 14 deletions

View File

@ -165,7 +165,8 @@ SOURCES = \
laySaltController.cc \
laySignalHandler.cc \
layLibraryController.cc \
layFontController.cc
layFontController.cc \
layNativePlugin.cc
RESOURCES = layBuildInMacros.qrc \
layHelpResources.qrc \

View File

@ -329,6 +329,13 @@ Application::Application (int &argc, char **argv, bool non_ui_mode)
std::string version = lay::Version::version ();
std::vector<std::string> vv = tl::split (version, ".");
std::string arch_string = tl::arch_string ();
std::vector<std::string> as = tl::split (arch_string, "-");
if (as.size () > 2) {
as.resize (2);
}
std::string short_arch_string = tl::join (as, "-");
for (std::vector <std::string>::const_iterator p = m_klayout_path.begin (); p != m_klayout_path.end (); ++p) {
std::set<std::string> 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<QString>::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<QString>::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 <lay::PluginDescriptor>::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 <lay::PluginDescriptor>::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 ();

View File

@ -5432,7 +5432,7 @@ HelpAboutDialog::HelpAboutDialog (QWidget *parent)
if (! lay::Application::instance ()->native_plugins ().empty ()) {
s += "<p>";
s += "<h4>";
s += escape_xml (tl::to_string (QObject::tr ("Native extensions:")));
s += escape_xml (tl::to_string (QObject::tr ("Binary extensions:")));
s += "</h4><ul>";
for (std::vector<lay::PluginDescriptor>::const_iterator pd = lay::Application::instance ()->native_plugins ().begin (); pd != lay::Application::instance ()->native_plugins ().end (); ++pd) {
s += "<li>";

View File

@ -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<const klp_class_t *> (gsi::class_by_name (name));
}
void *klp_create (const klp_class_t *cls)
{
return reinterpret_cast<const gsi::ClassBase *> (cls)->create ();
}
void klp_destroy (const klp_class_t *cls, void *obj)
{
reinterpret_cast<const gsi::ClassBase *> (cls)->destroy (obj);
}
void *klp_clone (const klp_class_t *cls, const void *source)
{
return reinterpret_cast<const gsi::ClassBase *> (cls)->clone (source);
}
void klp_assign (const klp_class_t *cls, void *target, const void *source)
{
reinterpret_cast<const gsi::ClassBase *> (cls)->assign (target, source);
}
void klp_require_api_version (const char * /*version*/)
{
// TODO: implement
}

View File

@ -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