summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2012-02-16 16:42:58 +0100
committerStephan Bergmann <sbergman@redhat.com>2012-02-20 09:56:45 +0100
commit51967dab002323b62f4f8f635052ab12ceb2b2ad (patch)
tree7a85a7a2359184185c73cd5ff4ca63f6b931e91d
parent19903d30def0a2bf63357031e56b18b5c4abea78 (diff)
Reintroduce pyuno.so wrapper around libpyuno.so
...it was cleaned away by a09ce46818fd4d5e08b3af9a478501cd8ef5b4fe "Port PyUno to support Python 3" but is still needed to make sure libpyuno.so is loaded RTLD_GLOBAL (Python apparently loads its modules RTLD_LOCAL). At least with pre 4.5 GCC this can cause problems with C++ exception handling, see the mail thread starting at <http://lists.freedesktop.org/archives/libreoffice/2012-February/025166.html> "LibO 3.5RC2: terminate called after throwing an instance of 'com::sun::star::registry::InvalidRegistryException'" for details. (cherry picked from commit 0b1be1ce0e0ac7b34c4b73d53f4bf32ec5df7290) ...plus... Adapt pyuno.so wrapper to Python 3 support (cherry picked from commit 1bb0d979b5ac5ed0cd831c6c8c0ab55dc2621eba) Signed-off-by: Michael Meeks <michael.meeks@suse.com>
-rw-r--r--pyuno/source/module/makefile.mk43
-rw-r--r--pyuno/source/module/pyuno_dlopenwrapper.c79
2 files changed, 86 insertions, 36 deletions
diff --git a/pyuno/source/module/makefile.mk b/pyuno/source/module/makefile.mk
index f72e1c3031fe..714a120de58d 100644
--- a/pyuno/source/module/makefile.mk
+++ b/pyuno/source/module/makefile.mk
@@ -50,6 +50,9 @@ EXTRA_FRAMEWORK_FLAG=-framework Python
.ENDIF # .IF "$(EXTRA_CFLAGS)"!=""
.IF "$(GUI)" == "UNX"
+# python expects modules without the lib prefix
+# pyuno.so even on Mac OS X, because it is a python module
+PYUNO_MODULE=$(DLLDEST)$/pyuno.so
PYUNORC=pyunorc
.ELSE
.IF "$(CROSS_COMPILING)" != "YES"
@@ -109,6 +112,7 @@ DEFLIB1NAME=$(TARGET)
ALLTAR : \
$(DLLDEST)/uno.py \
$(DLLDEST)/unohelper.py \
+ $(PYUNO_MODULE) \
$(MISC)/$(PYUNORC) \
$(LB)/lib$(TARGET).a
@@ -116,17 +120,10 @@ $(LB)/lib$(TARGET).a: $(MISC)/$(TARGET).def
$(DLLTOOL) --dllname $(TARGET)$(DLLPOST) --input-def=$(MISC)/$(TARGET).def --kill-at --output-lib=$(LB)/lib$(TARGET).a
.ELSE
-.IF "$(GUI)"!="WNT"
-# For some reason the build breaks on Windows if this is listed in the
-# prerequisite list of ALLTAR, but pyuno.pyd still gets produced. Go
-# figure. But we need it on non-Windows.
-targetdll=$(LB)/$(TARGET)$(DLLPOST)
-.ENDIF
-
ALLTAR : \
$(DLLDEST)/uno.py \
$(DLLDEST)/unohelper.py \
- $(targetdll) \
+ $(PYUNO_MODULE) \
$(MISC)/$(PYUNORC)
.ENDIF
.ENDIF
@@ -141,6 +138,29 @@ $(MISC)/framework_link :
$(COMMAND_ECHO)ln -sf $(SOLARLIBDIR)/OOoPython.framework $(LB)/OOoPython.framework
@touch $@
+.IF "$(GUI)" == "UNX"
+$(PYUNO_MODULE) : $(SLO)$/pyuno_dlopenwrapper.obj
+.IF "$(OS)" == "LINUX"
+ @echo $(LINK) $(LINKFLAGS) $(LINKFLAGSRUNPATH_OOO) $(LINKFLAGSSHLCUI) -ldl -o $@ $(SLO)$/pyuno_dlopenwrapper.o > $(MISC)$/$(@:b).cmd
+.ELIF "$(OS)" == "SOLARIS"
+ @echo ld -G -ldl -o $@ $(SLO)$/pyuno_dlopenwrapper.o > $(MISC)$/$(@:b).cmd
+.ELIF "$(OS)" == "FREEBSD"
+ @echo ld -shared -o $@ $(SLO)$/pyuno_dlopenwrapper.o > $(MISC)$/$(@:b).cmd
+.ELIF "$(OS)" == "NETBSD"
+ @echo $(LINK) $(LINKFLAGSSHLCUI) -o $@ $(SLO)$/pyuno_dlopenwrapper.o > $(MISC)$/$(@:b).cmd
+.ELIF "$(OS)" == "OPENBSD"
+ @echo ld -shared -o $@ $(SLO)$/pyuno_dlopenwrapper.o > $(MISC)$/$(@:b).cmd
+.ELIF "$(OS)" == "DRAGONFLY"
+ @echo ld -shared -o $@ $(SLO)$/pyuno_dlopenwrapper.o > $(MISC)$/$(@:b).cmd
+.ELIF "$(OS)" == "MACOSX"
+ @echo $(CC) -bundle -ldl -o $@ $(SLO)$/pyuno_dlopenwrapper.o $(EXTRA_LINKFLAGS) $(EXTRA_FRAMEWORK_FLAG) > $(MISC)$/$(@:b).cmd
+.ELSE
+ @echo $(LINK) $(LINKFLAGSSHLCUI) -o $@ $(SLO)$/pyuno_dlopenwrapper.o > $(MISC)$/$(@:b).cmd
+.ENDIF
+ cat $(MISC)$/$(@:b).cmd
+ @+source $(MISC)$/$(@:b).cmd
+.ENDIF
+
$(MISC)/$(PYUNORC) : pyuno
-rm -f $@
cat pyuno > $@
@@ -149,11 +169,4 @@ $(MISC)/pyuno.flt : pyuno.flt
-rm -f $@
cat $? > $@
-.IF "$(DLLPRE)"!=""
-# python does not accept the "lib" prefix in the module library
-$(LB)/$(TARGET)$(DLLPOST) : $(LB)/$(DLLPRE)$(TARGET)$(DLLPOST)
- -rm -f $@
- ln -s $? $@
-.ENDIF
-
.ENDIF # L10N_framework
diff --git a/pyuno/source/module/pyuno_dlopenwrapper.c b/pyuno/source/module/pyuno_dlopenwrapper.c
index 1ace0442ced6..3bdc912f95bd 100644
--- a/pyuno/source/module/pyuno_dlopenwrapper.c
+++ b/pyuno/source/module/pyuno_dlopenwrapper.c
@@ -26,38 +26,75 @@
*
************************************************************************/
-#include <rtl/string.h>
+/* make Python.h go first as a hack to work around _POSIX_C_SOURCE redefinition
+ warnings: */
+#include "Python.h"
+
+#include "sal/config.h"
#include <stdlib.h>
#include <string.h>
-#ifdef LINUX
-# ifndef __USE_GNU
-# define __USE_GNU
-# endif
+#if defined LINUX && !defined __USE_GNU
+#define __USE_GNU
#endif
#include <dlfcn.h>
-void initpyuno ()
-{
- Dl_info dl_info;
- void (*func)(void);
+#include "rtl/string.h"
- if (dladdr((void*)&initpyuno, &dl_info) != 0) {
- void* h = 0;
- size_t len = strrchr(dl_info.dli_fname, '/') - dl_info.dli_fname + 1;
- char* libname = malloc(len + RTL_CONSTASCII_LENGTH( SAL_DLLPREFIX "pyuno" SAL_DLLEXTENSION ) + 1);
- strncpy(libname, dl_info.dli_fname, len);
- strcpy(libname + (len), SAL_DLLPREFIX "pyuno" SAL_DLLEXTENSION);
+/* A wrapper around libpyuno.so, making sure the latter is loaded RTLD_GLOBAL
+ so that C++ exception handling works with old GCC versions (that determine
+ RTTI identity by comparing string addresses rather than string content).
+*/
- h = dlopen (libname, RTLD_NOW | RTLD_GLOBAL);
+static void * load(void * address, char const * symbol) {
+ Dl_info dl_info;
+ char * slash;
+ size_t len;
+ char * libname;
+ void * h;
+ void * func;
+ if (dladdr(address, &dl_info) == 0) {
+ abort();
+ }
+ slash = strrchr(dl_info.dli_fname, '/');
+ if (slash == NULL) {
+ abort();
+ }
+ len = slash - dl_info.dli_fname + 1;
+ libname = malloc(
+ len + RTL_CONSTASCII_LENGTH(SAL_DLLPREFIX "pyuno" SAL_DLLEXTENSION)
+ + 1);
+ if (libname == 0) {
+ abort();
+ }
+ strncpy(libname, dl_info.dli_fname, len);
+ strcpy(libname + len, SAL_DLLPREFIX "pyuno" SAL_DLLEXTENSION);
+ h = dlopen(libname, RTLD_NOW | RTLD_GLOBAL);
free(libname);
- if( h )
- {
- func = (void (*)())dlsym (h, "initpyuno");
- (func) ();
- }
+ if (h == NULL) {
+ abort();
}
+ func = dlsym(h, symbol);
+ if (func == NULL) {
+ abort();
+ }
+ return func;
}
+#if PY_MAJOR_VERSION >= 3
+
+PyObject * PyInit_pyuno(void) {
+ return
+ ((PyObject * (*)(void)) load((void *) &PyInit_pyuno, "PyInit_pyuno"))();
+}
+
+#else
+
+void initpyuno(void) {
+ ((void (*)(void)) load((void *) &initpyuno, "initpyuno"))();
+}
+
+#endif
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */