Compiling a SWIG Python wrapper for a static library?
Question: This is a noob question. I'm trying to learn how to use SWIG to make a python
interface for a C++ library. The library is a proprietary 3rd party library;
it comes to me in the form of a header file (foo.h) and a static archive
(libfoo.a).

To simplify matters, I've cooked up an example which I think has the same
pathology. Same error messages anyways.

    
    
    /* foo.hpp */
    class TC {
        public:
           TC();
           int i;
        private:
    };
    

For reference, here's foo.c. I only have the header and archive files for the
real 3rd party library.

    
    
    /*foo.cxx */
    #include "foo.hpp"
    TC::TC() {
        i = 0;
    }
    

I made this library by typing `g++ -c foo.cxx && ar rcs libfoo.a foo.o`

My SWIG interface file is as follows:

    
    
    /* foo.i */ 
    %module foo
    %{
    #include "foo.hpp"
    %}
    %include "foo.hpp"
    

I generate foo_wrap.cxx by typing

    
    
    swig -python -c++ foo.i
    

and then compile.

    
    
    g++ -c -fPIC -I/usr/include/python2.6 foo_wrap.cxx 
    g++ -shared -L. -lfoo -lpython2.6 -Wl,-soname,_foo.so foo_wrap.o -o _foo.so
    

The compilation succeeds, but when I run Python and `import foo`, I get an
undefined symbol error.

    
    
    >>> import foo
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
      File "foo.py", line 25, in <module>
        _foo = swig_import_helper() 
      File "foo.py", line 21, in swig_import_helper
        _mod = imp.load_module('_foo', fp, pathname, description)
    ImportError: ./_foo.so: undefined symbol: _ZN2TCC1Ev
    

What's going on here? The problem seems to be that the linking step isn't
finding the definition of the constructor TC::TC.

Note: If I alter the linking step to

    
    
    g++ -shared -L. -lfoo -lpython2.6 -Wl,-soname,_foo.so foo_wrap.o -o _foo.so
    

then everything works. But is this an option for my real problem, where I
don't have the raw source code? Can one extract a .o from a .a? Presumably one
can do this by hand, but shouldn't there be some automated way of doing it?


Answer: I'm not really sure if it's the case for you but in general the order of
object files and static libraries matters. The order defines the order of
initialisation.

You have to put the most general objects and/or static archives as last
parameters. The objects/archives with the most dependencies have to be placed
at the beginning.

An example. The object file A.o offer the fucntion A(). The object B.o uses
the function A(). You have to write `ld -o libmy.so B.o A.o` (the most general
file A.o as last parameter).

You can also check with `objdump -x _foo.so` if the symbol exists in the file.

The right call would be: `g++ -shared -L. -lpython2.6 -Wl,-soname,_foo.so
foo_wrap.o -lfoo -o _foo.so`

Do not be confused with -lpython2.6, it's a dynamic library _linked_ at
_runtime_.

