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...)