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

@ -19,23 +19,22 @@
<li><a href="#Guile_nn7">Native Guile Module Linkage</a>
<li><a href="#Guile_nn8">Old Auto-Loading Guile Module Linkage</a>
<li><a href="#Guile_nn9">Hobbit4D Linkage</a>
<li><a href="#Guile_nn10">General Remarks on Multiple SWIG Modules</a>
</ul>
<li><a href="#Guile_nn11">Underscore Folding</a>
<li><a href="#Guile_nn12">Typemaps</a>
<li><a href="#Guile_nn13">Representation of pointers as smobs</a>
<li><a href="#Guile_nn10">Underscore Folding</a>
<li><a href="#Guile_nn11">Typemaps</a>
<li><a href="#Guile_nn12">Representation of pointers as smobs</a>
<ul>
<li><a href="#Guile_nn14">GH Smobs</a>
<li><a href="#Guile_nn15">SCM Smobs</a>
<li><a href="#Guile_nn16">Garbage Collection</a>
<li><a href="#Guile_nn13">GH Smobs</a>
<li><a href="#Guile_nn14">SCM Smobs</a>
<li><a href="#Guile_nn15">Garbage Collection</a>
</ul>
<li><a href="#Guile_nn17">Exception Handling</a>
<li><a href="#Guile_nn18">Procedure documentation</a>
<li><a href="#Guile_nn19">Procedures with setters</a>
<li><a href="#Guile_nn20">GOOPS Proxy Classes</a>
<li><a href="#Guile_nn16">Exception Handling</a>
<li><a href="#Guile_nn17">Procedure documentation</a>
<li><a href="#Guile_nn18">Procedures with setters</a>
<li><a href="#Guile_nn19">GOOPS Proxy Classes</a>
<ul>
<li><a href="#Guile_nn21">Naming Issues</a>
<li><a href="#Guile_nn22">Linking</a>
<li><a href="#Guile_nn20">Naming Issues</a>
<li><a href="#Guile_nn21">Linking</a>
</ul>
</ul>
<!-- INDEX -->
@ -289,23 +288,7 @@ my/lib/libfoo.so.X.Y.Z and friends. This scheme is still very
experimental; the (hobbit4d link) conventions are not well understood.
</p>
<H3><a name="Guile_nn10"></a>18.3.6 General Remarks on Multiple SWIG Modules</H3>
If you want to use multiple SWIG modules, they have to share some
run-time data for the typing system.
At least one of your modules must be compiled with the <code>-runtime</code>
command line switch so that one of the modules contains the runtime code.
The remaining modules must be compiled with the
<code>-noruntime</code> commandline switch and linked with the module
with the runtime code. You could create an empty swig module and use that
to generate the runtime code instead of placing the runtime code into a
module with code that is being wrapped. See the
<a href="Modules.html#Modules">Working with Modules</a> chapter for further details.
<H2><a name="Guile_nn11"></a>18.4 Underscore Folding</H2>
<H2><a name="Guile_nn10"></a>18.4 Underscore Folding</H2>
<p>
@ -317,7 +300,7 @@ complained so far.
<code>%rename</code> to specify the Guile name of the wrapped
functions and variables (see CHANGES).
<H2><a name="Guile_nn12"></a>18.5 Typemaps</H2>
<H2><a name="Guile_nn11"></a>18.5 Typemaps</H2>
<p>
@ -383,7 +366,7 @@ In <code><var>body</var></code>, the first result of
</ul>
See also the "multivalue" example.
<H2><a name="Guile_nn13"></a>18.6 Representation of pointers as smobs</H2>
<H2><a name="Guile_nn12"></a>18.6 Representation of pointers as smobs</H2>
<p>
@ -404,7 +387,7 @@ representing the expected pointer type. See also
If the Scheme object passed was not a SWIG smob representing a compatible
pointer, a <code>wrong-type-arg</code> exception is raised.
<H3><a name="Guile_nn14"></a>18.6.1 GH Smobs</H3>
<H3><a name="Guile_nn13"></a>18.6.1 GH Smobs</H3>
<p>
@ -423,7 +406,7 @@ available. <code>SWIG_Guile_Init()</code> registers a smob type named
a table of all C pointer types seen so far, to which new types seen
are appended. The CDR stores the pointer value.
<H3><a name="Guile_nn15"></a>18.6.2 SCM Smobs</H3>
<H3><a name="Guile_nn14"></a>18.6.2 SCM Smobs</H3>
<p>The SCM interface (using the "-scm" argument to swig) uses common.swg.
@ -438,7 +421,7 @@ in the smob tag. If a generated GOOPS module has been loaded, smobs will be wra
GOOPS class.</p>
<H3><a name="Guile_nn16"></a>18.6.3 Garbage Collection</H3>
<H3><a name="Guile_nn15"></a>18.6.3 Garbage Collection</H3>
<p>Garbage collection is a feature of the new SCM interface, and it is automatically included
@ -452,7 +435,7 @@ is exactly like described in <a href="Customization.html#ownership">
Object ownership and %newobject</a> in the SWIG manual. All typemaps use an $owner var, and
the guile module replaces $owner with 0 or 1 depending on feature:new.</p>
<H2><a name="Guile_nn17"></a>18.7 Exception Handling</H2>
<H2><a name="Guile_nn16"></a>18.7 Exception Handling</H2>
<p>
@ -476,7 +459,7 @@ mapping:
The default when not specified here is to use "swig-error".
See Lib/exception.i for details.
<H2><a name="Guile_nn18"></a>18.8 Procedure documentation</H2>
<H2><a name="Guile_nn17"></a>18.8 Procedure documentation</H2>
<p>If invoked with the command-line option <code>-procdoc
@ -509,7 +492,7 @@ like this:
typemap argument <code>doc</code>. See <code>Lib/guile/typemaps.i</code> for
details.
<H2><a name="Guile_nn19"></a>18.9 Procedures with setters</H2>
<H2><a name="Guile_nn18"></a>18.9 Procedures with setters</H2>
<p>For global variables, SWIG creates a single wrapper procedure
@ -537,7 +520,7 @@ struct members, the procedures <code>(<var>struct</var>-<var>member</var>-get
pointer)</code> and <code>(<var>struct-member</var>-set pointer
value)</code> are <em>not</em> generated.
<H2><a name="Guile_nn20"></a>18.10 GOOPS Proxy Classes</H2>
<H2><a name="Guile_nn19"></a>18.10 GOOPS Proxy Classes</H2>
<p>SWIG can also generate classes and generic functions for use with
@ -665,7 +648,7 @@ before the definition of &lt;Foo&gt;. The generated GOOPS file would look like
Notice that &lt;Foo&gt; is used before it is defined. The fix is to just put the
<code>%import "foo.h"</code> before the <code>%inline</code> block.
<H3><a name="Guile_nn21"></a>18.10.1 Naming Issues</H3>
<H3><a name="Guile_nn20"></a>18.10.1 Naming Issues</H3>
<p>As you can see in the example above, there are potential naming conflicts. The default exported
@ -704,7 +687,7 @@ guile-modules. For example,</p>
<p>TODO: Renaming class name prefixes?</p>
<H3><a name="Guile_nn22"></a>18.10.2 Linking</H3>
<H3><a name="Guile_nn21"></a>18.10.2 Linking</H3>
<p>The guile-modules generated above all need to be linked together. GOOPS support requires

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>

View file

@ -64,7 +64,7 @@ For several years, the most stable version of SWIG has been release
been adopted. Odd version numbers (1.3, 1.5, etc.) represent
development versions of SWIG. Even version numbers (1.4, 1.6, etc.)
represent stable releases. Currently, developers are working to
create a stable SWIG-2.0 release (Maybe in 2003). Don't let the development status
create a stable SWIG-2.0 release. Don't let the development status
of SWIG-1.3 scare you---it is much more stable (and capable) than SWIG-1.1p5.
<H2><a name="Preface_nn5"></a>1.4 SWIG resources</H2>

View file

@ -1861,7 +1861,7 @@ types:
<H3><a name="Ruby_nn47"></a>27.8.1 Creating Multi-Module Packages</H3>
The chapter on <a href="Advanced.html#Advanced">Advanced Topics</a> discusses
The chapter on <a href="Modules.html">Working with Modules</a> discusses
the basics
of creating multi-module extensions with SWIG, and in particular
the considerations for sharing runtime type information among the
@ -1878,14 +1878,12 @@ a derived class:
<blockquote>
<pre>%module circle<br><br>%{<br>#include "Shape.h"<br>#include "Circle.h"<br>%}<br><br>// Import the base class definition from Shape module<br>%import shape.i<br><br>class Circle : public Shape {<br>protected:<br> double radius;<br>public:<br> Circle(double x, double y, double r);<br> double getRadius() const;<br>};<br></pre>
</blockquote>
Both of these modules should be compiled with SWIG's <tt>-c</tt>
option so that
the runtime library code is omitted from the wrapper files. We'll start
We'll start
by building
the <b>Shape</b> extension module:
<blockquote>
<pre>$ <b>swig -c++ -ruby -c shape.i</b>
<pre>$ <b>swig -c++ -ruby shape.i</b>
</pre>
</blockquote>
SWIG generates a wrapper file named <tt>shape_wrap.cxx</tt>. To
@ -1894,7 +1892,7 @@ into a dynamically loadable extension for Ruby, prepare an <tt>extconf.rb</tt>
script using this template:
<blockquote>
<pre>require 'mkmf'<br><br># Since the SWIG runtime support library for Ruby (libswigrb.so)<br># depends on the Ruby library, make sure it's in the list<br># of libraries.<br>$libs = append_library($libs, Config::CONFIG['RUBY_INSTALL_NAME'])<br><br># Now add the SWIG runtime support library<br>have_library('swigrb', 'SWIG_InitRuntime')<br><br># Create the makefile<br>create_makefile('shape')<br></pre>
<pre>require 'mkmf'<br><br># Since the SWIG runtime support library for Ruby<br># depends on the Ruby library, make sure it's in the list<br># of libraries.<br>$libs = append_library($libs, Config::CONFIG['RUBY_INSTALL_NAME'])<br><br># Create the makefile<br>create_makefile('shape')<br></pre>
</blockquote>
Run this script to create a <tt>Makefile</tt> and then type <tt>make</tt>
to
@ -1902,14 +1900,13 @@ build the shared library:
<blockquote>
<pre>$ <b>ruby extconf.rb</b>
checking for SWIG_InitRuntime() in -lswigrb... yes
creating Makefile
$ <b>make</b>
g++ -fPIC -g -O2 -I. -I/usr/local/lib/ruby/1.7/i686-linux \
-I. -c shape_wrap.cxx
gcc -shared -L/usr/local/lib -o shape.so shape_wrap.o -L. \
-lruby -lswigrb -lruby -lc
-lruby -lruby -lc
</pre>
</blockquote>
Note that depending on your installation, the outputs may be slightly

View file

@ -114,7 +114,6 @@ swig [ <em>options</em> ] filename
-I<em>dir</em> Add a directory to the file include path
-l<em>file</em> Include a SWIG library file.
-module <em>name</em> Set the name of the SWIG module
-noruntime Generate raw wrapper code (omit supporting code)
-o <em>outfile</em> Name of output file
-outdir <em>dir</em> Set language specific files output directory
-swiglib Show location of SWIG library