summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-04-11 22:19:25 +0200
committerRobin Gareus <robin@gareus.org>2016-04-11 22:19:25 +0200
commit8002b2d26e0191ec562fe2f5f2f42f51b03e9c30 (patch)
tree809a2cda6bf4adb7c535ab9cb31fc948ca4d4519
parent4eba3869feab704aaacbc3aee30407beedb128f2 (diff)
special case luabridge for windows/MSVC
luabridge uses static fn addresses to identify classes. Windows uses different addresses for *identical* static functions in libardour.dll and ardour.exe This solves the issue by moving the all functions from a header-only implementation into libardour.
-rw-r--r--libs/ardour/luabindings.cc92
-rw-r--r--libs/lua/LuaBridge/detail/ClassInfo.h10
-rw-r--r--libs/lua/LuaBridge/detail/Userdata.h4
-rwxr-xr-xtools/luadevel/wscript13
4 files changed, 112 insertions, 7 deletions
diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc
index cf429ea5d7..a475416c19 100644
--- a/libs/ardour/luabindings.cc
+++ b/libs/ardour/luabindings.cc
@@ -38,6 +38,7 @@
#include "ardour/interthread_info.h"
#include "ardour/lua_api.h"
#include "ardour/luabindings.h"
+#include "ardour/luaproc.h"
#include "ardour/meter.h"
#include "ardour/midi_track.h"
#include "ardour/midi_port.h"
@@ -55,6 +56,96 @@
#include "LuaBridge/LuaBridge.h"
+#ifdef PLATFORM_WINDOWS
+/* luabridge uses addresses of static functions/variables to identify classes.
+ *
+ * Static symbols on windows (even identical symbols) are not
+ * mapped to the same address when mixing .dll + .exe.
+ * So we need a single point to define those static functions.
+ * (normally they're header-only in libs/lua/LuaBridge/detail/ClassInfo.h)
+ *
+ * Really!! A static function with a static variable in a library header
+ * should never ever be replicated, even if it is a template.
+ * But then again this is windows... what else can go wrong.
+ */
+
+template <class T>
+void const*
+luabridge::ClassInfo<T>::getStaticKey ()
+{
+ static char value;
+ return &value;
+}
+
+template <class T>
+void const*
+luabridge::ClassInfo<T>::getClassKey ()
+{
+ static char value;
+ return &value;
+}
+
+template <class T>
+void const*
+luabridge::ClassInfo<T>::getConstKey ()
+{
+ static char value;
+ return &value;
+}
+
+void*
+luabridge::getIdentityKey ()
+{
+ static char value;
+ return &value;
+}
+
+/* ...and this is the ugly part of it.
+ *
+ * We need to foward declare classes from gtk2_ardour.
+ * This is needed because some of the classes use objects from libardour
+ * as function parameters and the .exe would re-create symbols for libardour
+ * objects.
+ *
+ * Classes which don't use libardour symbols could be moved to
+ * gtk2_ardour/luainstance.cc, but keeping this here reduces code
+ * duplication and does not give the compiler a chance to even think
+ * about replicating the symbols.
+ */
+
+#define CLASSKEYS(CLS) \
+ template void const* luabridge::ClassInfo< CLS >::getStaticKey(); \
+ template void const* luabridge::ClassInfo< CLS >::getClassKey(); \
+ template void const* luabridge::ClassInfo< CLS >::getConstKey();
+
+#define CLASSINFO(CLS) \
+ class CLS; \
+ template void const* luabridge::ClassInfo< CLS >::getStaticKey(); \
+ template void const* luabridge::ClassInfo< CLS >::getClassKey(); \
+ template void const* luabridge::ClassInfo< CLS >::getConstKey();
+
+CLASSINFO(MarkerSelection);
+CLASSINFO(TrackSelection);
+CLASSINFO(TrackViewList);
+CLASSINFO(TimeSelection);
+CLASSINFO(RegionSelection);
+CLASSINFO(PublicEditor);
+CLASSINFO(Selection);
+CLASSINFO(ArdourMarker);
+
+namespace Cairo {
+ class Context;
+}
+CLASSKEYS(Cairo::Context);
+CLASSKEYS(std::vector<double>);
+CLASSKEYS(std::list<ArdourMarker*>);
+CLASSKEYS(std::bitset<47ul>); // LuaSignal::LAST_SIGNAL
+CLASSKEYS(ArdourMarker*);
+CLASSKEYS(ARDOUR::RouteGroup);
+CLASSKEYS(ARDOUR::LuaProc);
+
+#endif // end windows special case
+
/* Some notes on Lua bindings for libardour and friends
*
* - Prefer factory methods over Contructors whenever possible.
@@ -582,7 +673,6 @@ LuaBindings::common (lua_State* L)
.addFunction ("output_map", (ARDOUR::ChanMapping (PluginInsert::*)(uint32_t) const)&PluginInsert::output_map)
.addFunction ("set_input_map", &PluginInsert::set_input_map)
.addFunction ("set_output_map", &PluginInsert::set_output_map)
-
.endClass ()
.deriveWSPtrClass <AutomationControl, PBD::Controllable> ("AutomationControl")
diff --git a/libs/lua/LuaBridge/detail/ClassInfo.h b/libs/lua/LuaBridge/detail/ClassInfo.h
index 8639dbec52..2a0ab001fd 100644
--- a/libs/lua/LuaBridge/detail/ClassInfo.h
+++ b/libs/lua/LuaBridge/detail/ClassInfo.h
@@ -36,6 +36,15 @@ template <class T>
class ClassInfo
{
public:
+#ifdef PLATFORM_WINDOWS
+ /* static symbols on windows (even identical symbols) are not
+ * mapped to the same address when mixing .dll + .exe.
+ * the implementation is moved to libardour/gtk2_ardour.
+ */
+ static void const* getStaticKey ();
+ static void const* getClassKey ();
+ static void const* getConstKey ();
+#else
/** Get the key for the static table.
The static table holds the static data members, static properties, and
@@ -69,5 +78,6 @@ public:
static char value;
return &value;
}
+#endif
};
diff --git a/libs/lua/LuaBridge/detail/Userdata.h b/libs/lua/LuaBridge/detail/Userdata.h
index c7ee3bac3e..a0bbf720d4 100644
--- a/libs/lua/LuaBridge/detail/Userdata.h
+++ b/libs/lua/LuaBridge/detail/Userdata.h
@@ -51,11 +51,15 @@
6. Our metatables have "__metatable" set to a boolean = false.
7. Our lightuserdata is unique.
*/
+#ifdef PLATFORM_WINDOWS
+extern void* getIdentityKey ();
+#else
inline void* getIdentityKey ()
{
static char value;
return &value;
}
+#endif
/**
Interface to a class pointer retrievable from a userdata.
diff --git a/tools/luadevel/wscript b/tools/luadevel/wscript
index 5f5b46b5d1..3190380091 100755
--- a/tools/luadevel/wscript
+++ b/tools/luadevel/wscript
@@ -33,13 +33,14 @@ def build(bld):
if bld.is_defined('WINDOWS_VST_SUPPORT') and bld.env['build_target'] != 'mingw':
return
+ if bld.env['build_target'] != 'mingw':
# TEST/DEVEL TOOL #######################
- obj = bld (features = 'cxx c cxxprogram')
- obj.source = 'devel.cc'
- obj.target = 'devel'
- obj.uselib = ['SIGCPP', 'READLINE']
- obj.use = ['liblua']
- obj.install_path = None
+ obj = bld (features = 'cxx c cxxprogram')
+ obj.source = 'devel.cc'
+ obj.target = 'devel'
+ obj.uselib = ['SIGCPP', 'READLINE']
+ obj.use = ['liblua']
+ obj.install_path = None
#########################################
# commandline luasession wrapper