Commit | Line | Data |
---|---|---|
1edae076 | 1 | Random notes about dynamic linking for Guile. I will update this file |
e4bcd6d9 MV |
2 | as I go along. Comments are very welcome. I can be reached at |
3 | mvo@zagadka.ping.de (Marius Vollmer). | |
1edae076 MV |
4 | |
5 | The dynamic linking support is mostly untested. I can't test it | |
6 | because I don't have all the different platforms, of course. Please | |
7 | try it out. | |
8 | ||
9 | To enable support for dynamic linking in libguile, give the | |
10 | ||
11 | --enable-dynamic-linking | |
12 | ||
13 | option to configure. It is disabled by default because it will | |
14 | probably cause lots of problems in its present state. Currently there | |
15 | is support for -ldld, -ldl, HP-UX (and VMS, but not really). | |
16 | ||
17 | Files affected: | |
18 | ||
19 | dynl* new | |
20 | configure.in add --enable-dynamic-linking option and checking for | |
21 | system dependencies | |
22 | Makefile.am include dynl* in build and dist. | |
23 | init.c initialize dynamic linking support | |
24 | ||
25 | Here is my plan with indications of progress. | |
26 | ||
27 | - port "dynl.c" and maybe some parts of "Link.scm" from SCM to | |
28 | Guile. This should not be difficult, maybe I can even squeeze the | |
29 | VMS code into the "dynl:link", "dyn:call" interface. | |
30 | ||
31 | * Mostly done, except VMS, and almost completely untested. The -dl | |
32 | support should work, but the rest has not even been compiled. | |
33 | ||
34 | The code is in the "dynl*" files. "dynl.c" is the system independent | |
35 | portion and includes the appropriate system dependent file, either | |
36 | "dynl-dld.c", "dynl-dl.c" or "dynl-shl.c". | |
37 | ||
38 | I have renamed the SCM names of the functions, because they didnn't | |
08f3ac02 | 39 | fit very well into Guile, the semantics are mostly the same: |
1edae076 MV |
40 | |
41 | SCM name Guile name | |
42 | ||
08f3ac02 MV |
43 | dynl:link dynamic-link FILENAME |
44 | dynl:call dynamic-call SYMBOL DYNOBJ | |
45 | dynl:main-call dynamic-args-call SYMBOL DYNOBJ STRING-LIST | |
46 | dynl:unlink dynamic-unlink DYNOBJ | |
1edae076 MV |
47 | |
48 | I plan to generalise dynamic-call and dynamic-args-call to work with | |
49 | arbitrary arguments, so these names are likely to change. | |
50 | ||
08f3ac02 MV |
51 | * There's now one new function |
52 | ||
53 | dynamic-func SYMB DYNOBJ | |
54 | ||
55 | It determines the address of a function in a dynamic object. The | |
56 | result of this function can be used with `dynamic-call' and | |
57 | `dynamic-args-call' as the SYMBOL. | |
58 | ||
1edae076 MV |
59 | PROBLEMS: |
60 | ||
a2ce54ae MV |
61 | Can tsort cope with blank lines? This situation arises when |
62 | configure substitutes nothing for @xtra_PLUGIN_guile_libs@. | |
1edae076 MV |
63 | |
64 | You may need to link your application in a special way to make | |
65 | dynamic linking work. For example, on Linux and a statically linked | |
66 | libguile.a, you need -rdynamic to make the libguile symbols | |
67 | available for dynamic linking. The solution is probably to build | |
a2ce54ae MV |
68 | libguile as a shared library on the systems that support it. Libtool |
69 | seems to be the right solution. | |
1edae076 | 70 | |
08f3ac02 MV |
71 | * Libguile is now build using libtool and it works fine for me. |
72 | ||
1edae076 MV |
73 | |
74 | - see how to couple dynamic linking with the module system. Dynamic | |
75 | objects should have a way to specify the module they want to add | |
76 | their bindings to. Extend this to statically linked parts of | |
77 | guile. (i.e. posix could be put into a module and initialized on | |
78 | demand) | |
79 | ||
80 | * Maybe it will suffice to have scm_make_gsubr, etc to honor the | |
81 | current scm_top_level_lookup_closure and do all the module switching | |
82 | from Scheme. | |
83 | ||
08f3ac02 MV |
84 | * I now have modified scm_sysintern to use the lookup procedure when |
85 | there is one. This is a temporal hack while waiting for the module | |
86 | system to be accessible from C. | |
87 | ||
1edae076 MV |
88 | |
89 | - use gtcltk as a test case for the above, so that TCL/Tk capabilities | |
90 | can be added to guile at runtime. | |
91 | ||
08f3ac02 MV |
92 | * Works. |
93 | ||
94 | When you link libgtcltk into your application and initialize it with | |
95 | ||
96 | scm_init_gtcl (); | |
97 | scm_init_gtk (); | |
98 | ||
99 | you get the old behaviour. If you initialize it with | |
100 | ||
101 | scm_init_ice_9_gtcltk_module (); | |
102 | ||
103 | the TCL/Tk functions are made available in a module called | |
104 | #/ice-9/gtcltk. | |
105 | ||
106 | When you don't link libgtcltk into your application but put it | |
107 | somewhere in your %load-path, it will be linked dynamically upon the | |
108 | first `:use-module #/ice-9/gtcltk'. Using the %load-path for this | |
109 | is probably not very smart. | |
110 | ||
111 | From boot-9: | |
112 | ||
113 | ;;; Dynamic linking of modules | |
114 | ||
115 | ;; Initializing a module that is written in C is a two step process. | |
116 | ;; First the module's `module init' function is called. This function | |
117 | ;; is expected to call `scm_register_module_xxx' to register the `real | |
118 | ;; init' function. Later, when the module is referenced for the first | |
119 | ;; time, this real init function is called in the right context. See | |
120 | ;; gtcltk-lib/gtcltk-module.c for an example. | |
121 | ;; | |
122 | ;; The code for the module can be in a regular shared library (so that | |
123 | ;; the `module init' function will be called when libguile is | |
124 | ;; initialized). Or it can be dynamically linked. | |
125 | ;; | |
126 | ;; You can safely call `scm_register_module_xxx' before libguile | |
127 | ;; itself is initialized. You could call it from an C++ constructor | |
128 | ;; of a static object, for example. | |
129 | ;; | |
130 | ;; To make your Guile extension into a dynamic linkable module, follow | |
131 | ;; these easy steps: | |
132 | ;; | |
133 | ;; - Find a name for your module, like #/ice-9/gtcltk | |
134 | ;; - Write a function with a name like | |
135 | ;; | |
136 | ;; scm_init_ice_9_gtcltk_module | |
137 | ;; | |
138 | ;; This is your `module init' function. It should call | |
139 | ;; | |
140 | ;; scm_register_module_xxx ("ice-9 gtcltk", scm_init_gtcltk); | |
141 | ;; | |
142 | ;; "ice-9 gtcltk" is the C version of the module name. Slashes are | |
143 | ;; replaced by spaces, the rest is untouched. `scm_init_gtcltk' is | |
144 | ;; the real init function that executes the usual initilizations | |
145 | ;; like making new smobs, etc. | |
146 | ;; | |
147 | ;; - Make a shared library with your code and a name like | |
148 | ;; | |
149 | ;; ice-9/libgtcltk.so | |
150 | ;; | |
151 | ;; and put it somewhere in %load-path. | |
152 | ;; | |
153 | ;; - Then you can simply write `:use-module #/ice-9/gtcltk' and it | |
154 | ;; will be linked automatically. | |
155 | ;; | |
156 | ;; This is all very experimental. | |
157 | ||
158 | ||
1edae076 MV |
159 | - see how G-Wrap and libffi can work together and extend dyn:call to |
160 | functions taking arbitrary arguments. Something along the lines | |
161 | ||
162 | (define XOpenDisplay (make-foreign-function X11-lib 'XOpenDisplay | |
163 | .. whatever args ..)) | |
164 | ||
a2ce54ae MV |
165 | * I have received Guile libffi glue code from Anthony Green but I have |
166 | yet to try it out. | |
1edae076 MV |
167 | |
168 | I have no ideas how to support the development of packages for Guile | |
169 | that can be dynamically linked into a running application. Maybe | |
170 | automake can be used to automate most of the issues. | |
171 | ||
172 | One nice thing is, however, that developers and users of Guile | |
173 | packages have already installed Guile. So we might able to use Scheme | |
174 | to describe and handle the build process. I would like that much more | |
175 | than the arcane shell based implementations of autoconf, automake, | |
176 | etc. | |
a2ce54ae MV |
177 | |
178 | One more random thought about packages: I think it would be an | |
179 | advantage if the configuration informations are not contained in a | |
180 | bunch of files (like the PLUGIN stuff, or like tclConfig.sh) that have | |
181 | to be found and analyzed, but rather can be accessed via a small | |
182 | program that can be assumed to be in the PATH. That program (probably | |
183 | a shell script, but not necessarily) can be queried about several | |
184 | interesting things like prefix and exec_prefix of libguile or told to | |
185 | do some tasks like installing a new module (and constructing a new | |
186 | guile executable if that is necessary). It might even be used for such | |
187 | generic things as uninstalling Guile (or downloading, configuring, | |
188 | building and installing the latest version of Guile...) |