This chapter describes the problem of using SWIG in programs where you want to create a collection of modules.
By default, the runtime functions are private to each SWIG-generated module. That is, the runtime functions are declared with "static" linkage and are visible only to the wrapper functions defined in that module. If two completely different SWIG modules are loaded, this presents no problem---each module uses its own private runtime code. The only problem with this approach is that when more than one SWIG module is used in the same application, those modules often need to share type information. This is especially true for C++ programs where SWIG must collect and share information about inheritance relationships that cross module boundaries.
To solve the problem of sharing information across modules, the SWIG runtime functions need to be exposed in a way that allows data to be shared between modules. The next section describes how to do that.
Option 1: Designate one module to provide the runtime code
With this option, one of the modules is designated as providing the runtime environment. This is done with the -runtime option like this:
The other modules are then compiled without runtime support. This is done by supplying the -noruntime option like this:% swig -runtime -c++ -python A.i
To use the modules, you compile and link everything as before, but you need to make sure that module A is loaded before all of the other modules are used---otherwise you will unresolved symbols.% swig -noruntime -c++ -python B.i % swig -noruntime -c++ -python C.i
Now, the bad news: This approach may or may not work depending on the platform you are using, what target language you are using, and the way that shared libraries work on the system. On many systems, the symbols contained in dynamically loaded modules are private. Therefore, even though module A provides the runtime code, the other modules won't be able to find it. You'll know if this is the case if you try to load the other modules and you get errors about unresolved SWIG_* functions.
Option 2: Build a runtime library
The second way to work with multiple modules is to create a special runtime library module. To do this, you first build a runtime library like this:
Now, you compile all of the normal SWIG modules using the -noruntime option:% swig -runtime -python swigrun.i % # Build a shared library --- this is different on every machine! (shown for Linux) % gcc -fpic swigrun_wrap.c -o swigrun_wrap.o % gcc -shared swigrun_wrap.o -o libswigrunpy.so
Finally, when linking the dynamically loadable modules, you need to link again the special runtime library above. For example (Linux) :% swig -noruntime -c++ -python A.i % swig -noruntime -c++ -python B.i % swig -noruntime -c++ -python C.i
Again, all of the details will vary depending on what compiler you use, the platform, target language, and so forth. The key point is that the runtime needs to be contained in a shared/dynamic library and you need to link all of the modules against that library.% g++ -shared A_wrap.o -L. -lswigrunpy -o _A.so % g++ -shared B_wrap.o -L. -lswigrunpy -o _B.so % g++ -shared C_wrap.o -L. -lswigrunpy -o _C.so
When you use the modules created using this technique, the runtime code will be automatically loaded when the modules are imported. Moreover, since all of the modules are linked against the same runtime library, they will share that code.