diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2012-02-16 16:42:58 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2012-02-20 09:56:45 +0100 |
commit | 51967dab002323b62f4f8f635052ab12ceb2b2ad (patch) | |
tree | 7a85a7a2359184185c73cd5ff4ca63f6b931e91d | |
parent | 19903d30def0a2bf63357031e56b18b5c4abea78 (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.mk | 43 | ||||
-rw-r--r-- | pyuno/source/module/pyuno_dlopenwrapper.c | 79 |
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: */ |