0

I have an application that statically links to libpython.a (2.7). From within the application's interpreter I try importing time module (time.so), which fails with:

ImportError: ./time.so: undefined symbol: PyExc_IOError

So, this module has unresolved symbols:

nm -D time.so | grep PyExc_IOError
         U PyExc_IOError

I figured that this symbol is discarded by the linker when linking the application. OK, I'm now linking libpython with all symbols:

... -Wl,-whole-archive -lpython -Wl,-no-whole-archive ...

The symbol is now there:

$ nm app | grep PyExc_IOError
8638348 D PyExc_IOError
08638ca0 d _PyExc_IOError

But I still get the same import error. Where is the problem?

Alex B
  • 82,554
  • 44
  • 203
  • 280

1 Answers1

2

Besides making sure all of libpython is included in your binary, you also need to make sure the symbols in the library are exposed to shared objects being loaded. When you're linking libpython (statically) into your main binary this means you need the --export-dynamic linker argument (so -Wl,--export-dynamic or -Xlinker --export-dynamic as the gcc argument.) When loading a shared object with libpython (say, when you embed libpython into a plugin for your app) this means you have to make sure the shared object is loaded with the RTLD_GLOBAL flag to dlopen().

Thomas Wouters
  • 130,178
  • 23
  • 148
  • 122