mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-28 16:00:22 +02:00
188 lines
7 KiB
Text
188 lines
7 KiB
Text
Random notes about dynamic linking for Guile. I will update this file
|
|
as I go along. Comments are very welcome. I can be reached at
|
|
mvo@zagadka.ping.de (Marius Vollmer).
|
|
|
|
The dynamic linking support is mostly untested. I can't test it
|
|
because I don't have all the different platforms, of course. Please
|
|
try it out.
|
|
|
|
To enable support for dynamic linking in libguile, give the
|
|
|
|
--enable-dynamic-linking
|
|
|
|
option to configure. It is disabled by default because it will
|
|
probably cause lots of problems in its present state. Currently there
|
|
is support for -ldld, -ldl, HP-UX (and VMS, but not really).
|
|
|
|
Files affected:
|
|
|
|
dynl* new
|
|
configure.in add --enable-dynamic-linking option and checking for
|
|
system dependencies
|
|
Makefile.am include dynl* in build and dist.
|
|
init.c initialize dynamic linking support
|
|
|
|
Here is my plan with indications of progress.
|
|
|
|
- port "dynl.c" and maybe some parts of "Link.scm" from SCM to
|
|
Guile. This should not be difficult, maybe I can even squeeze the
|
|
VMS code into the "dynl:link", "dyn:call" interface.
|
|
|
|
* Mostly done, except VMS, and almost completely untested. The -dl
|
|
support should work, but the rest has not even been compiled.
|
|
|
|
The code is in the "dynl*" files. "dynl.c" is the system independent
|
|
portion and includes the appropriate system dependent file, either
|
|
"dynl-dld.c", "dynl-dl.c" or "dynl-shl.c".
|
|
|
|
I have renamed the SCM names of the functions, because they didnn't
|
|
fit very well into Guile, the semantics are mostly the same:
|
|
|
|
SCM name Guile name
|
|
|
|
dynl:link dynamic-link FILENAME
|
|
dynl:call dynamic-call SYMBOL DYNOBJ
|
|
dynl:main-call dynamic-args-call SYMBOL DYNOBJ STRING-LIST
|
|
dynl:unlink dynamic-unlink DYNOBJ
|
|
|
|
I plan to generalise dynamic-call and dynamic-args-call to work with
|
|
arbitrary arguments, so these names are likely to change.
|
|
|
|
* There's now one new function
|
|
|
|
dynamic-func SYMB DYNOBJ
|
|
|
|
It determines the address of a function in a dynamic object. The
|
|
result of this function can be used with `dynamic-call' and
|
|
`dynamic-args-call' as the SYMBOL.
|
|
|
|
PROBLEMS:
|
|
|
|
Can tsort cope with blank lines? This situation arises when
|
|
configure substitutes nothing for @xtra_PLUGIN_guile_libs@.
|
|
|
|
You may need to link your application in a special way to make
|
|
dynamic linking work. For example, on Linux and a statically linked
|
|
libguile.a, you need -rdynamic to make the libguile symbols
|
|
available for dynamic linking. The solution is probably to build
|
|
libguile as a shared library on the systems that support it. Libtool
|
|
seems to be the right solution.
|
|
|
|
* Libguile is now build using libtool and it works fine for me.
|
|
|
|
|
|
- see how to couple dynamic linking with the module system. Dynamic
|
|
objects should have a way to specify the module they want to add
|
|
their bindings to. Extend this to statically linked parts of
|
|
guile. (i.e. posix could be put into a module and initialized on
|
|
demand)
|
|
|
|
* Maybe it will suffice to have scm_make_gsubr, etc to honor the
|
|
current scm_top_level_lookup_closure and do all the module switching
|
|
from Scheme.
|
|
|
|
* I now have modified scm_sysintern to use the lookup procedure when
|
|
there is one. This is a temporal hack while waiting for the module
|
|
system to be accessible from C.
|
|
|
|
|
|
- use gtcltk as a test case for the above, so that TCL/Tk capabilities
|
|
can be added to guile at runtime.
|
|
|
|
* Works.
|
|
|
|
When you link libgtcltk into your application and initialize it with
|
|
|
|
scm_init_gtcl ();
|
|
scm_init_gtk ();
|
|
|
|
you get the old behaviour. If you initialize it with
|
|
|
|
scm_init_ice_9_gtcltk_module ();
|
|
|
|
the TCL/Tk functions are made available in a module called
|
|
#/ice-9/gtcltk.
|
|
|
|
When you don't link libgtcltk into your application but put it
|
|
somewhere in your %load-path, it will be linked dynamically upon the
|
|
first `:use-module #/ice-9/gtcltk'. Using the %load-path for this
|
|
is probably not very smart.
|
|
|
|
From boot-9:
|
|
|
|
;;; Dynamic linking of modules
|
|
|
|
;; Initializing a module that is written in C is a two step process.
|
|
;; First the module's `module init' function is called. This function
|
|
;; is expected to call `scm_register_module_xxx' to register the `real
|
|
;; init' function. Later, when the module is referenced for the first
|
|
;; time, this real init function is called in the right context. See
|
|
;; gtcltk-lib/gtcltk-module.c for an example.
|
|
;;
|
|
;; The code for the module can be in a regular shared library (so that
|
|
;; the `module init' function will be called when libguile is
|
|
;; initialized). Or it can be dynamically linked.
|
|
;;
|
|
;; You can safely call `scm_register_module_xxx' before libguile
|
|
;; itself is initialized. You could call it from an C++ constructor
|
|
;; of a static object, for example.
|
|
;;
|
|
;; To make your Guile extension into a dynamic linkable module, follow
|
|
;; these easy steps:
|
|
;;
|
|
;; - Find a name for your module, like #/ice-9/gtcltk
|
|
;; - Write a function with a name like
|
|
;;
|
|
;; scm_init_ice_9_gtcltk_module
|
|
;;
|
|
;; This is your `module init' function. It should call
|
|
;;
|
|
;; scm_register_module_xxx ("ice-9 gtcltk", scm_init_gtcltk);
|
|
;;
|
|
;; "ice-9 gtcltk" is the C version of the module name. Slashes are
|
|
;; replaced by spaces, the rest is untouched. `scm_init_gtcltk' is
|
|
;; the real init function that executes the usual initilizations
|
|
;; like making new smobs, etc.
|
|
;;
|
|
;; - Make a shared library with your code and a name like
|
|
;;
|
|
;; ice-9/libgtcltk.so
|
|
;;
|
|
;; and put it somewhere in %load-path.
|
|
;;
|
|
;; - Then you can simply write `:use-module #/ice-9/gtcltk' and it
|
|
;; will be linked automatically.
|
|
;;
|
|
;; This is all very experimental.
|
|
|
|
|
|
- see how G-Wrap and libffi can work together and extend dyn:call to
|
|
functions taking arbitrary arguments. Something along the lines
|
|
|
|
(define XOpenDisplay (make-foreign-function X11-lib 'XOpenDisplay
|
|
.. whatever args ..))
|
|
|
|
* I have received Guile libffi glue code from Anthony Green but I have
|
|
yet to try it out.
|
|
|
|
I have no ideas how to support the development of packages for Guile
|
|
that can be dynamically linked into a running application. Maybe
|
|
automake can be used to automate most of the issues.
|
|
|
|
One nice thing is, however, that developers and users of Guile
|
|
packages have already installed Guile. So we might able to use Scheme
|
|
to describe and handle the build process. I would like that much more
|
|
than the arcane shell based implementations of autoconf, automake,
|
|
etc.
|
|
|
|
One more random thought about packages: I think it would be an
|
|
advantage if the configuration informations are not contained in a
|
|
bunch of files (like the PLUGIN stuff, or like tclConfig.sh) that have
|
|
to be found and analyzed, but rather can be accessed via a small
|
|
program that can be assumed to be in the PATH. That program (probably
|
|
a shell script, but not necessarily) can be queried about several
|
|
interesting things like prefix and exec_prefix of libguile or told to
|
|
do some tasks like installing a new module (and constructing a new
|
|
guile executable if that is necessary). It might even be used for such
|
|
generic things as uninstalling Guile (or downloading, configuring,
|
|
building and installing the latest version of Guile...)
|