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. * There is now some code at http//www-nt.e-technik.uni-dortmund.de/m_mvo/guile-ffi-970501.tar.gz but it doesn't address G-Wrap.