[PATCH] Reintroduce pyuno.so wrapper around libpyuno.so
Stephan Bergmann
sbergman at redhat.com
Thu Feb 16 07:42:58 PST 2012
...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)
---
pyuno/source/module/makefile.mk | 43 +++++++++++------
pyuno/source/module/pyuno_dlopenwrapper.c | 76 +++++++++++++++++++++--------
2 files changed, 83 insertions(+), 36 deletions(-)
diff --git a/pyuno/source/module/makefile.mk b/pyuno/source/module/makefile.mk
index f72e1c3..714a120 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 1ace044..487665b 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: */
--
1.7.7.6
--------------050306020205000408010304--
More information about the LibreOffice
mailing list