FAQ
I know that this may be quite a common question, but since I was unable to
find the answer, I ask :

I try to build a Python plugin for an application. The plugin is a shared
library (.so) loaded at runtime by the main program using dlopen. The
plugin is used to interpret Python scripts for the main application.
So I wrote the following Makefile:

OBJECTS = plugin_python.o

INCLUDE = -I./include -I../include -I/usr/include -I/usr/include/python2.0
CC = gcc
FLAGS = $(INCLUDE) -Wall -g -fPIC

all : plugin_python

clean :
rm -rf *.o core plugin_python.so.0.1

install :
cp plugin_python.so.0.1 /home/gros/games/share/crossfire/plugins

plugin_python : $(OBJECTS)
$(CC) $(FLAGS) -shared -Wl,-soname,plugin_python.so.0 $(OBJECTS)
../common/libcross.a /usr/lib/python2.0/config/libpython2.0.a -lpthread
-lutil -ldmalloc -o plugin_python.so.0.1

plugin_python.o : plugin_python.c
$(CC) $(FLAGS) -c plugin_python.c

The plugin/application duo works fine, but when I try to run that script
for example:

import shelve

maildb_file = '/tmp/crossfiremail.db'
maildb = shelve.open(maildb_file)
maildb.close()

I get the following error:
ImportError: /usr/lib/python2.0/lib-dynload/structmodule.so: undefined
symbol: PyString_Type

Following my searches, it seems that I need to tell the linker to export
all symbols of the dynamic symbol table, so I tried to add -export-dynamic
(or -E) in the main making line, but it does not work. What should I do ?
Anyone has an idea ?

Chachkoff Y.

Search Discussions

  • Ignacio Vazquez-Abrams at Aug 28, 2001 at 8:16 pm

    On Tue, 28 Aug 2001, Chachkoff Yann wrote:

    I know that this may be quite a common question, but since I was unable to
    find the answer, I ask :

    [snip]

    I get the following error:
    ImportError: /usr/lib/python2.0/lib-dynload/structmodule.so: undefined
    symbol: PyString_Type

    Following my searches, it seems that I need to tell the linker to export
    all symbols of the dynamic symbol table, so I tried to add -export-dynamic
    (or -E) in the main making line, but it does not work. What should I do ?
    Anyone has an idea ?

    Chachkoff Y.
    Section 5.2 of the Extending and Embedding the Python Interpreter says:

    "The problem is that some entry points are defined by the Python runtime
    solely for extension modules to use. If the embedding application does not use
    any of these entry points, some linkers will not include those entries in the
    symbol table of the finished executable. Some additional options are needed to
    inform the linker not to remove these symbols.

    Determining the right options to use for any given platform can be quite
    difficult, but fortunately the Python configuration already has those values.
    To retrieve them from an installed Python interpreter, start an interactive
    interpreter and have a short session like this:
    import distutils.sysconfig
    distutils.sysconfig.get_config_var('LINKFORSHARED')
    '-Xlinker -export-dynamic'

    The contents of the string presented will be the options that should be used.
    If the string is empty, there's no need to add any additional options. The
    LINKFORSHARED definition corresponds to the variable of the same name in
    Python's top-level Makefile."

    The '-Xlinker' tells gcc to pass '-export-dynamic' to ld. gcc itself seems to
    ignore it otherwise.

    --
    Ignacio Vazquez-Abrams <ignacio at openservices.net>
  • Chachkoff Yann at Aug 29, 2001 at 3:00 am

    Le Mardi 28 Ao?t 2001 16:16, vous avez ?crit :
    I get the following error:
    ImportError: /usr/lib/python2.0/lib-dynload/structmodule.so: undefined
    symbol: PyString_Type

    Following my searches, it seems that I need to tell the linker to export
    all symbols of the dynamic symbol table, so I tried to add
    -export-dynamic (or -E) in the main making line, but it does not work.
    What should I do ? Anyone has an idea ?
    Section 5.2 of the Extending and Embedding the Python Interpreter says: <snip>
    The '-Xlinker' tells gcc to pass '-export-dynamic' to ld. gcc itself seems
    to ignore it otherwise.
    I of course tried this first (I always read manuals before working). It does
    not work. I tried the following one:

    $(CC) $(FLAGS) -shared -Wl,-soname,plugin_python.so.0 $(OBJECTS)
    ../common/libcross.a -Xlinker -export-dynamic
    /usr/lib/python2.0/config/libpython2.0.a -lpthread -lutil -ldmalloc -o
    plugin_python.so.0.1

    Maybe I'm completely wrong or simply dumb. But I passed the correct options
    to gcc and it simply does not solve the problem. (Thanx for trying to help
    anyway)

    Chachkoff Y.
  • Ignacio Vazquez-Abrams at Aug 28, 2001 at 9:43 pm

    On Tue, 28 Aug 2001, Chachkoff Yann wrote:
    Le Mardi 28 Ao?t 2001 16:16, vous avez ?crit :
    Section 5.2 of the Extending and Embedding the Python Interpreter says: <snip>
    The '-Xlinker' tells gcc to pass '-export-dynamic' to ld. gcc itself seems
    to ignore it otherwise.
    I of course tried this first (I always read manuals before working). It does
    not work. I tried the following one:

    $(CC) $(FLAGS) -shared -Wl,-soname,plugin_python.so.0 $(OBJECTS)
    ../common/libcross.a -Xlinker -export-dynamic
    /usr/lib/python2.0/config/libpython2.0.a -lpthread -lutil -ldmalloc -o
    plugin_python.so.0.1

    Maybe I'm completely wrong or simply dumb. But I passed the correct options
    to gcc and it simply does not solve the problem. (Thanx for trying to help
    anyway)

    Chachkoff Y.
    Sorry, in tests that I did gcc silently ignored '-export-dynamic' when passed
    to it, so I thought that that might have been the problem.

    OTOH...
    From the ld man page:
    "
    --whole-archive
    For each archive mentioned on the command line af?
    ter the --whole-archive option, include every ob?
    ject file in the archive in the link, rather than
    searching the archive for the required object
    files. This is normally used to turn an archive
    file into a shared library, forcing every object to
    be included in the resulting shared library.
    "

    If I understand correctly, you may need to add '-Xlinker --whole-archive'
    before python2.0.a.

    --
    Ignacio Vazquez-Abrams <ignacio at openservices.net>
  • Chachkoff Yann at Aug 30, 2001 at 1:00 pm

    The '-Xlinker' tells gcc to pass '-export-dynamic' to ld. gcc itself
    seems to ignore it otherwise.
    I of course tried this first (I always read manuals before working). It
    does not work. I tried the following one:

    $(CC) $(FLAGS) -shared -Wl,-soname,plugin_python.so.0 $(OBJECTS)
    ../common/libcross.a -Xlinker -export-dynamic
    /usr/lib/python2.0/config/libpython2.0.a -lpthread -lutil -ldmalloc -o
    plugin_python.so.0.1
    Sorry, in tests that I did gcc silently ignored '-export-dynamic' when
    passed to it, so I thought that that might have been the problem.
    I think I need to apologize myself... Your idea was good indeed, and I had
    been unclear in my terms. I thank you for your support.
    OTOH...

    From the ld man page:

    "
    --whole-archive
    For each archive mentioned on the command line af?
    ter the --whole-archive option, include every ob?
    ject file in the archive in the link, rather than
    searching the archive for the required object
    files. This is normally used to turn an archive
    file into a shared library, forcing every object to
    be included in the resulting shared library.
    "

    If I understand correctly, you may need to add '-Xlinker --whole-archive'
    before python2.0.a.
    That's an idea I didn't tried before, so I did.
    Unfortunately, it does not seemed to solve the problem - I always get the
    same error.
    I did some new variations around; I replaced the "gcc" command with direct
    calls to "ld". I tried numerous combinations using --whole-archive, -E (and
    others too; for example, I tried to link in more than one line using -r to be
    able to "fine-tune" options for each linked library).
    Whatever I did, the problem stayed the same.
    I ask now a new question: has anyone already tried to make a shared library
    dynamically loaded with the Python interpreter ? Is it even possible (I
    suppose it is, but I do not know how) ? If yes, can you tell me where I am
    wrong ?

    Chachkoff Y.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedAug 28, '01 at 8:16p
activeAug 30, '01 at 1:00p
posts5
users2
websitepython.org

People

Translate

site design / logo © 2022 Grokbase