Update the documentation for new runtime type linking.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@6389 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
John Lenz 2004-10-12 22:06:47 +00:00
commit 02cffc8047
5 changed files with 47 additions and 166 deletions

View file

@ -9,10 +9,9 @@
<!-- INDEX -->
<ul>
<li><a href="#Modules_nn2">The SWIG runtime code</a>
<li><a href="#Modules_nn3">Compiling Multiple SWIG modules</a>
<li><a href="#Modules_nn4">A word of caution about static libraries</a>
<li><a href="#Modules_nn5">References</a>
<li><a href="#Modules_nn6">Reducing the wrapper file size</a>
<li><a href="#Modules_nn3">A word of caution about static libraries</a>
<li><a href="#Modules_nn4">References</a>
<li><a href="#Modules_nn5">Reducing the wrapper file size</a>
</ul>
<!-- INDEX -->
@ -44,12 +43,10 @@ have no need for a SWIG runtime. All the dynamically typed / interpreted
languages rely on the SWIG runtime.
<p>
By default, the runtime functions are private to each SWIG-generated
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. 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
@ -57,116 +54,21 @@ relationships that cross module boundaries.
</p>
<p>
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.
</p>
<H2><a name="Modules_nn3"></a>15.2 Compiling Multiple SWIG modules</H2>
Suppose that you have three SWIG interface files A.i, B.i, and C.i
and suppose that these modules interact with each other. To make this work,
there are two approaches you can take:
<p>
<b>Option 1:</b> Designate one module to provide the runtime code
To solve the problem of sharing information across modules, a pointer to the
type information is stored in a global variable in the target language namespace.
During module initialization, type information is loaded into the global data
structure of type information from all modules.
</p>
<p>
With this option, one of the modules is designated as providing the runtime
environment. This is done with the <tt>-runtime</tt> option like this:
This can present a problem with threads. If two modules try and load at the same
time, the type information can become corrupt. SWIG currently does not provide any
locking, and if you use threads, you must make sure that modules are loaded serially.
Be careful if you use threads and the automatic module loading that some scripting
languages provide. One solution is to load all modules before spawning any threads.
</p>
<blockquote>
<pre>
% swig -runtime -c++ -python A.i
</pre>
</blockquote>
The other modules are then compiled without runtime support. This is done by
supplying the <tt>-noruntime</tt> option like this:
<blockquote>
<pre>
% swig -noruntime -c++ -python B.i
% swig -noruntime -c++ -python C.i
</pre>
</blockquote>
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 get unresolved symbols.
<p>
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.
</p>
<p>
<b>Option 2: Build a runtime library</b>
</p>
<p>
The second way to work with multiple modules is to create a special runtime library module.
To do this, you first need to create an empty SWIG interface file, say swigrun.i, containing
just the %module directive, for example:
</p>
<blockquote>
<pre>
%module swigrun
</pre>
</blockquote>
Next, build a runtime library like this:
<blockquote>
<pre>
% 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
</pre>
</blockquote>
Now, you compile all of the normal SWIG modules using the <tt>-noruntime</tt> option:
<blockquote>
<pre>
% swig -noruntime -c++ -python A.i
% swig -noruntime -c++ -python B.i
% swig -noruntime -c++ -python C.i
</pre>
</blockquote>
Finally, when linking the dynamically loadable modules, you need to link again the special
runtime library above. For example (Linux) :
<blockquote>
<pre>
% 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
</pre>
</blockquote>
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 (DLL) and
you need to link all of the modules against that library.
<p>
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.
</p>
<H2><a name="Modules_nn4"></a>15.3 A word of caution about static libraries</H2>
<H2><a name="Modules_nn3"></a>15.2 A word of caution about static libraries</H2>
When working with multiple SWIG modules, you should take care not to use static
@ -175,13 +77,13 @@ of SWIG modules with that library, each module will get its own private copy of
into it. This is very often <b>NOT</b> what you want and it can lead to unexpected or bizarre program
behavior. When working with dynamically loadable modules, you should try to work exclusively with shared libaries.
<H2><a name="Modules_nn5"></a>15.4 References</H2>
<H2><a name="Modules_nn4"></a>15.3 References</H2>
Due to the complexity of working with shared libraries and multiple modules, it might be a good idea to consult
an outside reference. John Levine's "Linkers and Loaders" is highly recommended.
<H2><a name="Modules_nn6"></a>15.5 Reducing the wrapper file size</H2>
<H2><a name="Modules_nn5"></a>15.4 Reducing the wrapper file size</H2>
<p>