mirror of https://github.com/KLayout/klayout.git
WIP: more python modules, made gsi initialization safe against duplicate init.
This commit is contained in:
parent
73297a3810
commit
07d9363ea7
|
|
@ -35,16 +35,15 @@ namespace gsi
|
|||
void GSI_PUBLIC
|
||||
initialize ()
|
||||
{
|
||||
// Allow duplicate initialization without any effect
|
||||
static bool s_is_initialized = false;
|
||||
if (s_is_initialized) {
|
||||
// do something only if there are new classes
|
||||
if (gsi::ClassBase::begin_new_classes () == gsi::ClassBase::end_new_classes ()) {
|
||||
return;
|
||||
}
|
||||
s_is_initialized = true;
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 21, "Initializing script environment");
|
||||
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
// Do a first initialization of the new classes because they might add more classes
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
||||
// TODO: get rid of that const cast
|
||||
(const_cast<gsi::ClassBase *> (&*c))->initialize ();
|
||||
}
|
||||
|
|
@ -52,6 +51,7 @@ initialize ()
|
|||
// merge the extensions to the main declaration
|
||||
gsi::ClassBase::merge_declarations ();
|
||||
|
||||
// do a full re-initialization - maybe merge_declarations modified existing classes too
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
// Initialize the method table once again after we have merged the declarations
|
||||
// TODO: get rid of that const cast
|
||||
|
|
@ -61,6 +61,9 @@ initialize ()
|
|||
tl_assert (c->declaration () == &*c);
|
||||
}
|
||||
|
||||
// build or rebuild the variant user class table
|
||||
// NOTE: as the variant classes are tied to the gsi::Class objects, we can rebuild the table
|
||||
// and will get the same pointers for the classes that have been there before
|
||||
tl::VariantUserClassBase::clear_class_table ();
|
||||
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
|
|
|
|||
|
|
@ -38,15 +38,36 @@ namespace gsi
|
|||
// ClassBase implementation
|
||||
|
||||
ClassBase::class_collection *ClassBase::mp_class_collection = 0;
|
||||
ClassBase::class_collection *ClassBase::mp_new_class_collection = 0;
|
||||
|
||||
namespace {
|
||||
struct type_info_compare
|
||||
{
|
||||
bool operator() (const std::type_info *a, const std::type_info *b) const
|
||||
{
|
||||
return a->before (*b);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: thread-safe? Unlikely that multiple threads access this member -
|
||||
// we do a initial scan and after this no more write access here.
|
||||
static std::map<const std::type_info *, const ClassBase *, type_info_compare> s_ti_to_class;
|
||||
|
||||
ClassBase::ClassBase (const std::string &doc, const Methods &mm, bool do_register)
|
||||
: mp_base (0), mp_parent (0), m_doc (doc), m_methods (mm)
|
||||
{
|
||||
if (do_register) {
|
||||
if (! mp_class_collection) {
|
||||
mp_class_collection = new class_collection ();
|
||||
|
||||
// enter the class into the "new" collection
|
||||
if (! mp_new_class_collection) {
|
||||
mp_new_class_collection = new class_collection ();
|
||||
}
|
||||
mp_class_collection->push_back (this);
|
||||
mp_new_class_collection->push_back (this);
|
||||
|
||||
// invalidate the "typeinfo to class" map
|
||||
s_ti_to_class.clear ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -186,6 +207,17 @@ ClassBase::collection ()
|
|||
}
|
||||
}
|
||||
|
||||
const ClassBase::class_collection &
|
||||
ClassBase::new_collection ()
|
||||
{
|
||||
if (!mp_new_class_collection) {
|
||||
static const class_collection empty;
|
||||
return empty;
|
||||
} else {
|
||||
return *mp_new_class_collection;
|
||||
}
|
||||
}
|
||||
|
||||
static SpecialMethod *
|
||||
sm_default_ctor (const char *name, const gsi::ClassBase *cls)
|
||||
{
|
||||
|
|
@ -340,127 +372,132 @@ sm_assign (const char *name, const gsi::ClassBase *cls)
|
|||
void
|
||||
ClassBase::merge_declarations ()
|
||||
{
|
||||
tl_assert (mp_class_collection != 0);
|
||||
if (gsi::ClassBase::begin_new_classes () == gsi::ClassBase::end_new_classes ()) {
|
||||
// Nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
// merge the extensions to the main declaration
|
||||
static bool merged = false;
|
||||
if (! merged) {
|
||||
|
||||
// HINT: this code block must be called exactly ONCE!
|
||||
merged = true;
|
||||
|
||||
// Check for duplicate declarations
|
||||
std::set<const std::type_info *> types;
|
||||
std::set<std::string> names;
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
if (c->declaration () == &*c && !types.insert (&c->type ()).second) {
|
||||
tl::warn << "Duplicate GSI declaration of type " << c->type ().name ();
|
||||
}
|
||||
if (c->declaration () == &*c && !names.insert (c->declaration ()->name ()).second) {
|
||||
tl::warn << "Duplicate GSI declaration of name " << c->declaration ()->name ();
|
||||
}
|
||||
// Check for duplicate declarations
|
||||
std::set<const std::type_info *> types;
|
||||
std::set<std::string> names;
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
if (c->declaration () == &*c && !types.insert (&c->type ()).second) {
|
||||
tl::warn << "Duplicate GSI declaration of type " << c->type ().name ();
|
||||
}
|
||||
|
||||
std::vector <const gsi::ClassBase *> to_remove;
|
||||
|
||||
// Consolidate the classes (merge, remove etc.)
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
if (! c->consolidate()) {
|
||||
to_remove.push_back (&*c);
|
||||
}
|
||||
if (c->declaration () == &*c && !names.insert (c->declaration ()->name ()).second) {
|
||||
tl::warn << "Duplicate GSI declaration of name " << c->declaration ()->name ();
|
||||
}
|
||||
}
|
||||
|
||||
// removed the classes which are no longer required
|
||||
for (std::vector <const gsi::ClassBase *>::const_iterator ed = to_remove.begin (); ed != to_remove.end (); ++ed) {
|
||||
std::vector <const gsi::ClassBase *> to_remove;
|
||||
|
||||
// Consolidate the classes (merge, remove etc.)
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
||||
if (! c->consolidate()) {
|
||||
to_remove.push_back (&*c);
|
||||
}
|
||||
}
|
||||
|
||||
// removed the classes which are no longer required
|
||||
for (std::vector <const gsi::ClassBase *>::const_iterator ed = to_remove.begin (); ed != to_remove.end (); ++ed) {
|
||||
// TODO: ugly const_cast hack
|
||||
mp_new_class_collection->erase (const_cast<gsi::ClassBase *> (*ed));
|
||||
}
|
||||
|
||||
// collect the subclasses of a class
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
||||
if (c->base ()) {
|
||||
// TODO: ugly const_cast hack
|
||||
mp_class_collection->erase (const_cast<gsi::ClassBase *> (*ed));
|
||||
const_cast<gsi::ClassBase *> (c->base ())->m_subclasses.push_back (const_cast<gsi::ClassBase *> (c.operator-> ()));
|
||||
}
|
||||
}
|
||||
|
||||
// collect the subclasses of a class
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
if (c->base ()) {
|
||||
// TODO: ugly const_cast hack
|
||||
const_cast<gsi::ClassBase *> (c->base ())->m_subclasses.push_back (const_cast<gsi::ClassBase *> (c.operator-> ()));
|
||||
// Add to the classes the special methods and clean up the method table
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
||||
|
||||
std::set<std::pair<std::string, bool> > name_map;
|
||||
for (gsi::ClassBase::method_iterator m = c->begin_methods (); m != c->end_methods (); ++m) {
|
||||
for (gsi::MethodBase::synonym_iterator syn = (*m)->begin_synonyms (); syn != (*m)->end_synonyms (); ++syn) {
|
||||
name_map.insert (std::make_pair (syn->name, (*m)->is_static ()));
|
||||
}
|
||||
}
|
||||
|
||||
// Add to the classes the special methods and clean up the method table
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
// We don't want the declaration object to be non-const except for this case. So
|
||||
// we const_cast here.
|
||||
gsi::ClassBase *non_const_decl = const_cast<gsi::ClassBase *> (c.operator-> ());
|
||||
|
||||
std::set<std::pair<std::string, bool> > name_map;
|
||||
for (gsi::ClassBase::method_iterator m = c->begin_methods (); m != c->end_methods (); ++m) {
|
||||
for (gsi::MethodBase::synonym_iterator syn = (*m)->begin_synonyms (); syn != (*m)->end_synonyms (); ++syn) {
|
||||
name_map.insert (std::make_pair (syn->name, (*m)->is_static ()));
|
||||
}
|
||||
}
|
||||
if (name_map.find (std::make_pair ("new", true)) == name_map.end ()) {
|
||||
non_const_decl->add_method (sm_default_ctor ("new", &*c), false);
|
||||
}
|
||||
|
||||
// We don't want the declaration object to be non-const except for this case. So
|
||||
// we const_cast here.
|
||||
gsi::ClassBase *non_const_decl = const_cast<gsi::ClassBase *> (&*c);
|
||||
// Note: "unmanage" and "manage" is a better name ...
|
||||
non_const_decl->add_method (sm_keep ("_unmanage"));
|
||||
non_const_decl->add_method (sm_release ("_manage"));
|
||||
|
||||
if (name_map.find (std::make_pair ("new", true)) == name_map.end ()) {
|
||||
non_const_decl->add_method (sm_default_ctor ("new", &*c), false);
|
||||
}
|
||||
if (name_map.find (std::make_pair ("create", false)) == name_map.end ()) {
|
||||
// deprecate "create"
|
||||
non_const_decl->add_method (sm_create ("_create|#create"));
|
||||
} else {
|
||||
// fallback name is "_create" to avoid conflicts
|
||||
non_const_decl->add_method (sm_create ("_create"));
|
||||
}
|
||||
|
||||
// Note: "unmanage" and "manage" is a better name ...
|
||||
non_const_decl->add_method (sm_keep ("_unmanage"));
|
||||
non_const_decl->add_method (sm_release ("_manage"));
|
||||
|
||||
if (name_map.find (std::make_pair ("create", false)) == name_map.end ()) {
|
||||
// deprecate "create"
|
||||
non_const_decl->add_method (sm_create ("_create|#create"));
|
||||
if (c->can_destroy ()) {
|
||||
if (name_map.find (std::make_pair ("destroy", false)) == name_map.end ()) {
|
||||
// deprecate "destroy"
|
||||
non_const_decl->add_method (sm_destroy ("_destroy|#destroy"));
|
||||
} else {
|
||||
// fallback name is "_create" to avoid conflicts
|
||||
non_const_decl->add_method (sm_create ("_create"));
|
||||
// fallback name is "_destroy" to avoid conflicts
|
||||
non_const_decl->add_method (sm_destroy ("_destroy"));
|
||||
}
|
||||
}
|
||||
|
||||
if (c->can_destroy ()) {
|
||||
if (name_map.find (std::make_pair ("destroy", false)) == name_map.end ()) {
|
||||
// deprecate "destroy"
|
||||
non_const_decl->add_method (sm_destroy ("_destroy|#destroy"));
|
||||
} else {
|
||||
// fallback name is "_destroy" to avoid conflicts
|
||||
non_const_decl->add_method (sm_destroy ("_destroy"));
|
||||
}
|
||||
}
|
||||
if (c->can_copy ()) {
|
||||
|
||||
if (c->can_copy ()) {
|
||||
|
||||
if (name_map.find (std::make_pair ("dup", false)) == name_map.end ()) {
|
||||
non_const_decl->add_method (sm_dup ("dup", &*c));
|
||||
} else {
|
||||
// fallback name is "_dup" to avoid conflicts
|
||||
non_const_decl->add_method (sm_dup ("_dup", &*c));
|
||||
}
|
||||
|
||||
if (name_map.find (std::make_pair ("assign", false)) == name_map.end ()) {
|
||||
non_const_decl->add_method (sm_assign ("assign", &*c));
|
||||
} else {
|
||||
// fallback name is "_assign" to avoid conflicts
|
||||
non_const_decl->add_method (sm_assign ("_assign", &*c));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (name_map.find (std::make_pair ("destroyed", false)) == name_map.end ()) {
|
||||
// deprecate "destroyed"
|
||||
non_const_decl->add_method (sm_destroyed ("_destroyed?|#destroyed?"));
|
||||
if (name_map.find (std::make_pair ("dup", false)) == name_map.end ()) {
|
||||
non_const_decl->add_method (sm_dup ("dup", &*c));
|
||||
} else {
|
||||
// fallback name is "_destroyed" to avoid conflicts
|
||||
non_const_decl->add_method (sm_destroyed ("_destroyed?"));
|
||||
// fallback name is "_dup" to avoid conflicts
|
||||
non_const_decl->add_method (sm_dup ("_dup", &*c));
|
||||
}
|
||||
|
||||
if (name_map.find (std::make_pair ("is_const_object", false)) == name_map.end ()) {
|
||||
// deprecate "is_const"
|
||||
non_const_decl->add_method (sm_is_const ("_is_const_object?|#is_const_object?"));
|
||||
if (name_map.find (std::make_pair ("assign", false)) == name_map.end ()) {
|
||||
non_const_decl->add_method (sm_assign ("assign", &*c));
|
||||
} else {
|
||||
// fallback name is "_is_const" to avoid conflicts
|
||||
non_const_decl->add_method (sm_is_const ("_is_const_object?"));
|
||||
// fallback name is "_assign" to avoid conflicts
|
||||
non_const_decl->add_method (sm_assign ("_assign", &*c));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (name_map.find (std::make_pair ("destroyed", false)) == name_map.end ()) {
|
||||
// deprecate "destroyed"
|
||||
non_const_decl->add_method (sm_destroyed ("_destroyed?|#destroyed?"));
|
||||
} else {
|
||||
// fallback name is "_destroyed" to avoid conflicts
|
||||
non_const_decl->add_method (sm_destroyed ("_destroyed?"));
|
||||
}
|
||||
|
||||
if (name_map.find (std::make_pair ("is_const_object", false)) == name_map.end ()) {
|
||||
// deprecate "is_const"
|
||||
non_const_decl->add_method (sm_is_const ("_is_const_object?|#is_const_object?"));
|
||||
} else {
|
||||
// fallback name is "_is_const" to avoid conflicts
|
||||
non_const_decl->add_method (sm_is_const ("_is_const_object?"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// finally merge the new classes into the existing ones
|
||||
if (! mp_class_collection) {
|
||||
mp_class_collection = new class_collection ();
|
||||
}
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
||||
gsi::ClassBase *non_const_decl = const_cast<gsi::ClassBase *> (c.operator-> ());
|
||||
mp_class_collection->push_back (non_const_decl);
|
||||
}
|
||||
mp_new_class_collection->clear ();
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -536,45 +573,33 @@ bool has_class (const std::string &name)
|
|||
return class_by_name_no_assert (name) != 0;
|
||||
}
|
||||
|
||||
namespace
|
||||
static void add_class_to_map (const gsi::ClassBase *c)
|
||||
{
|
||||
|
||||
struct type_info_compare
|
||||
{
|
||||
bool operator() (const std::type_info *a, const std::type_info *b) const
|
||||
{
|
||||
return a->before (*b);
|
||||
if (c->declaration () != c) {
|
||||
// only consider non-extensions
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const std::type_info *ti = c->adapted_type_info ();
|
||||
if (! ti) {
|
||||
ti = &c->type ();
|
||||
}
|
||||
if (ti && c->is_of_type (*ti) && !s_ti_to_class.insert (std::make_pair (ti, c)).second) {
|
||||
// Duplicate registration of this class
|
||||
tl::error << "Duplicate registration of class " << c->name () << " (type " << ti->name () << ")";
|
||||
tl_assert (false);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: thread-safe? Unlikely that multiple threads access this member -
|
||||
// we do a initial scan and after this no more write access here.
|
||||
static std::map<const std::type_info *, const ClassBase *, type_info_compare> s_ti_to_class;
|
||||
|
||||
const ClassBase *class_by_typeinfo_no_assert (const std::type_info &ti)
|
||||
{
|
||||
if (s_ti_to_class.empty ()) {
|
||||
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
|
||||
if (c->declaration () != c.operator-> ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::type_info *ti = c->adapted_type_info ();
|
||||
if (! ti) {
|
||||
ti = &c->type ();
|
||||
}
|
||||
if (ti && c->is_of_type (*ti) && !s_ti_to_class.insert (std::make_pair (ti, c.operator-> ())).second) {
|
||||
// Duplicate registration of this class
|
||||
tl::error << "Duplicate registration of class " << c->name () << " (type " << ti->name () << ")";
|
||||
tl_assert (false);
|
||||
}
|
||||
|
||||
add_class_to_map (c.operator-> ());
|
||||
}
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_new_classes (); c != gsi::ClassBase::end_new_classes (); ++c) {
|
||||
add_class_to_map (c.operator-> ());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::map<const std::type_info *, const ClassBase *, type_info_compare>::const_iterator c = s_ti_to_class.find (&ti);
|
||||
|
|
|
|||
|
|
@ -220,6 +220,23 @@ public:
|
|||
return collection ().end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterates all freshly registered classes (begin)
|
||||
* This collection is emptied on "merge_declarations".
|
||||
*/
|
||||
static class_iterator begin_new_classes ()
|
||||
{
|
||||
return new_collection ().begin ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterates all freshly registered classes (begin)
|
||||
*/
|
||||
static class_iterator end_new_classes ()
|
||||
{
|
||||
return new_collection ().end ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterates the methods (begin)
|
||||
*/
|
||||
|
|
@ -557,6 +574,7 @@ public:
|
|||
|
||||
protected:
|
||||
static const class_collection &collection ();
|
||||
static const class_collection &new_collection ();
|
||||
|
||||
const tl::weak_collection<ClassBase> &subclasses () const
|
||||
{
|
||||
|
|
@ -587,7 +605,7 @@ private:
|
|||
mutable std::auto_ptr<PerClassClientSpecificData> mp_data[ClientIndex::MaxClientIndex];
|
||||
|
||||
static class_collection *mp_class_collection;
|
||||
static unsigned int m_class_count;
|
||||
static class_collection *mp_new_class_collection;
|
||||
|
||||
// No copying
|
||||
ClassBase (const ClassBase &other);
|
||||
|
|
|
|||
|
|
@ -1073,15 +1073,10 @@ private:
|
|||
void GSI_PUBLIC
|
||||
initialize_expressions ()
|
||||
{
|
||||
// Allow duplicate initialization without any effect
|
||||
static bool s_is_initialized = false;
|
||||
if (s_is_initialized) {
|
||||
return;
|
||||
}
|
||||
s_is_initialized = true;
|
||||
|
||||
// just in case this did not happen yet ...
|
||||
gsi::initialize ();
|
||||
|
||||
// Go through all classes (maybe again)
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
|
||||
// install the method table:
|
||||
|
|
|
|||
|
|
@ -2355,7 +2355,7 @@ PythonModule::python_doc (const gsi::MethodBase *method)
|
|||
}
|
||||
|
||||
void
|
||||
PythonModule::make_classes ()
|
||||
PythonModule::make_classes (const char *mod_name)
|
||||
{
|
||||
PyObject *module = mp_module.get ();
|
||||
|
||||
|
|
@ -2407,6 +2407,11 @@ PythonModule::make_classes ()
|
|||
more_classes = false;
|
||||
for (gsi::ClassBase::class_iterator c = gsi::ClassBase::begin_classes (); c != gsi::ClassBase::end_classes (); ++c) {
|
||||
|
||||
if (mod_name && 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;
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ public:
|
|||
/**
|
||||
* @brief Creates the classes after init has been called
|
||||
*/
|
||||
void make_classes ();
|
||||
void make_classes (const char *mod_name = 0);
|
||||
|
||||
/**
|
||||
* @brief Gets the GSI class for a Python class
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ SOURCES = \
|
|||
|
||||
HEADERS += \
|
||||
|
||||
INCLUDEPATH += $$PYTHONINCLUDE $$TL_INC $$GSI_INC $$DB_INC $$GSI_INC $$PYA_INC
|
||||
DEPENDPATH += $$PYTHONINCLUDE $$TL_INC $$GSI_INC $$DB_INC $$GSI_INC $$PYA_INC
|
||||
LIBS += $$PYTHONLIBFILE -L$$LIBDIR -lklayout_tl -lklayout_gsi -lklayout_db -lklayout_gsi -lklayout_pya
|
||||
INCLUDEPATH += $$PYTHONINCLUDE $$TL_INC $$GSI_INC $$PYA_INC
|
||||
DEPENDPATH += $$PYTHONINCLUDE $$TL_INC $$GSI_INC $$PYA_INC
|
||||
LIBS += $$PYTHONLIBFILE -L$$LIBDIR -lklayout_tl -lklayout_gsi -lklayout_db -lklayout_pya
|
||||
|
||||
# Python is somewhat sloppy and relies on the compiler initializing fields
|
||||
# of strucs to 0:
|
||||
|
|
|
|||
|
|
@ -28,11 +28,13 @@
|
|||
static PyObject *module_init ()
|
||||
{
|
||||
gsi::initialize ();
|
||||
|
||||
// required for the tiling processor for example
|
||||
gsi::initialize_expressions ();
|
||||
|
||||
static pya::PythonModule module;
|
||||
module.init ("klayout.db", "KLayout core module (db)");
|
||||
module.make_classes ();
|
||||
module.make_classes ("db");
|
||||
|
||||
return module.module ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
LIBDIR = $$OUT_PWD/../..
|
||||
DESTDIR = $$LIBDIR/pymod
|
||||
TARGET = lay
|
||||
|
||||
include($$PWD/../../lib.pri)
|
||||
|
||||
SOURCES = \
|
||||
layMain.cc \
|
||||
|
||||
HEADERS += \
|
||||
|
||||
INCLUDEPATH += $$PYTHONINCLUDE $$TL_INC $$GSI_INC $$PYA_INC
|
||||
DEPENDPATH += $$PYTHONINCLUDE $$TL_INC $$GSI_INC $$PYA_INC
|
||||
LIBS += $$PYTHONLIBFILE -L$$LIBDIR -lklayout_tl -lklayout_db -lklayout_gsi -lklayout_pya -lklayout_lay -lklayout_laybasic
|
||||
|
||||
# Python is somewhat sloppy and relies on the compiler initializing fields
|
||||
# of strucs to 0:
|
||||
QMAKE_CXXFLAGS_WARN_ON += \
|
||||
-Wno-missing-field-initializers
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
/*
|
||||
|
||||
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 <Python.h>
|
||||
#include "pya.h"
|
||||
#include "gsi.h"
|
||||
#include "gsiExpression.h"
|
||||
|
||||
static PyObject *module_init ()
|
||||
{
|
||||
gsi::initialize ();
|
||||
|
||||
// required for the tiling processor for example
|
||||
gsi::initialize_expressions ();
|
||||
|
||||
static pya::PythonModule module;
|
||||
module.init ("klayout.lay", "KLayout core module (lay)");
|
||||
module.make_classes ("lay");
|
||||
|
||||
return module.module ();
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
PyMODINIT_FUNC
|
||||
DEF_INSIDE_PUBLIC
|
||||
initlay ()
|
||||
{
|
||||
module_init ();
|
||||
}
|
||||
#else
|
||||
PyMODINIT_FUNC
|
||||
DEF_INSIDE_PUBLIC
|
||||
PyInit_lay ()
|
||||
{
|
||||
return module_init();
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS = db
|
||||
SUBDIRS = \
|
||||
db \
|
||||
tl \
|
||||
lay \
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
LIBDIR = $$OUT_PWD/../..
|
||||
DESTDIR = $$LIBDIR/pymod
|
||||
TARGET = tl
|
||||
|
||||
include($$PWD/../../lib.pri)
|
||||
|
||||
SOURCES = \
|
||||
tlMain.cc \
|
||||
|
||||
HEADERS += \
|
||||
|
||||
INCLUDEPATH += $$PYTHONINCLUDE $$TL_INC $$GSI_INC $$PYA_INC
|
||||
DEPENDPATH += $$PYTHONINCLUDE $$TL_INC $$GSI_INC $$PYA_INC
|
||||
LIBS += $$PYTHONLIBFILE -L$$LIBDIR -lklayout_tl -lklayout_gsi -lklayout_pya
|
||||
|
||||
# Python is somewhat sloppy and relies on the compiler initializing fields
|
||||
# of strucs to 0:
|
||||
QMAKE_CXXFLAGS_WARN_ON += \
|
||||
-Wno-missing-field-initializers
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
/*
|
||||
|
||||
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 <Python.h>
|
||||
#include "pya.h"
|
||||
#include "gsi.h"
|
||||
#include "gsiExpression.h"
|
||||
|
||||
static PyObject *module_init ()
|
||||
{
|
||||
gsi::initialize ();
|
||||
|
||||
// required for the tiling processor for example
|
||||
gsi::initialize_expressions ();
|
||||
|
||||
static pya::PythonModule module;
|
||||
module.init ("klayout.tl", "KLayout core module (tl)");
|
||||
module.make_classes ("tl");
|
||||
|
||||
return module.module ();
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
PyMODINIT_FUNC
|
||||
DEF_INSIDE_PUBLIC
|
||||
inittl ()
|
||||
{
|
||||
module_init ();
|
||||
}
|
||||
#else
|
||||
PyMODINIT_FUNC
|
||||
DEF_INSIDE_PUBLIC
|
||||
PyInit_tl ()
|
||||
{
|
||||
return module_init();
|
||||
}
|
||||
#endif
|
||||
Loading…
Reference in New Issue