~ chicken-core (chicken-5) /manual/Extensions
Trap1[[tags: manual]]
2[[toc:]]
3
4== Introduction to extensions
5
6=== Extension libraries
7
8Extension libraries (''eggs'') are extensions to the core
9functionality provided by the basic CHICKEN system, to be built and
10installed separately. The mechanism for loading compiled extensions
11is based on dynamically loadable code and as such is only available on
12systems on which loading compiled code at runtime is
13supported. Currently these are most UNIX-compatible platforms that
14provide the {{libdl}} functionality like Linux, Solaris, BSD, Mac OS X
15and Windows using Cygwin.
16
17On systems where dynamic loading is not available, extensions can
18still be built and linked as static object files.
19
20Note: eggs may also be normal applications or shell scripts, but
21are usually libraries.
22
23Extensions are technically nothing but dynamically loadable compiled
24files with added meta-data that describes dependencies to other
25eggs, version information and things like the author/maintainer
26of the egg. Three tools provide an easy to use interface for
27installing eggs, removing them and querying the current
28status of installed eggs.
29
30
31=== Installing eggs
32
33To install an egg, run the {{chicken-install}} program
34with the egg name as argument. The egg archive is
35downloaded, its contents extracted and the contained egg description
36file is analyzed and the appropriate commands executed.
37This file is an abstract description of the contents of
38the egg and
39will be translated by {{chicken-install}} into build- and installation
40scripts for the current platform. After running these scripts (and
41if all goes well), the egg is installed and will be available
42like a built-in library. The format and meaning
43of the file will be described below.
44
45Installation will copy
46a number of given files into the local egg repository or in the
47path where the CHICKEN executables are located (in the case of
48executable programs or scripts). Additionally the list of installed
49files, and user-defined metadata is stored in the repository.
50
51If no egg name is given on the command-line, then all {{.egg}}
52files in the current directory are processed, including all {{.egg}}
53files in a subdirectory {{chicken}} (if such a directory exists),
54in some arbitrary
55order, unless the egg descriptions specify dependencies.
56
57==== Installing eggs that use libraries
58
59Sometimes an egg requires a C library to compile. Compilation
60can fail when your system has this library in a nonstandard
61location. Normally the C compiler searches in the default locations
62{{/usr}} and {{/usr/local}}, and in the prefix where CHICKEN itself
63was installed. Sometimes this is not enough, so you'll need to supply
64{{chicken-install}} with some extra hints to the C compiler/linker. Here's
65an example:
66
67 CSC_OPTIONS='-I/usr/pkg/include/mysql -L/usr/pkg/lib/mysql -L -R/usr/pkg/lib/mysql' chicken-install mysql
68
69This installs the mysql egg with the extra compiler options -I and -L
70to set the include path and the library search path. The second -L
71switch passes the -R option directly to the linker, which causes the
72library path to get hardcoded into the resulting extension file (for
73systems that do not use {{ld.so.conf}}).
74
75The environment variables {{CHICKEN_C_INCLUDE_PATH}} and {{CHICKEN_C_LIBRARY_PATH}}
76can also be used to override include- and linker-paths. Each of these variables
77may contain one or more directory names, separated by {{:}} or {{;}} and will
78be passed using {{-I}} and {{-L}} to the C compiler.
79
80Finally, you can use the {{custom-build}} egg file property to use a
81custom script to compile your extension's code. See below for more information.
82
83=== Creating eggs
84
85An egg can be created by placing the code and some special
86files in a directory of its own.
87For example, if your egg is called {{foo}}, create a directory called {{foo}}
88and put the egg code there (the directory's name is not actually important).
89
90Eggs need an egg description file {{<egg name>.egg}}. This file
91indicates how the egg is to be compiled and provides some information
92about the egg (author, license, dependencies etc).
93
94The format of these files is described in full in the chapter entitled
95"[[Egg specification format]]". Below we'll give a few brief
96examples of simple eggs.
97
98
99=== Examples for extensions
100
101==== A simple library
102
103The simplest case is a single file that does not export any syntax.
104For example
105
106<enscript highlight=scheme>
107;;;; hello.scm
108
109(define (hello name)
110 (print "Hello, " name " !") )
111</enscript>
112
113We need an {{.egg}} file to build and install our nifty extension:
114
115<enscript highlight=scheme>
116;;;; hello.egg
117
118((author "Me")
119 (synopsis "A cool hello-world library")
120 (license "GPLv3")
121 (components (extension hello)))
122</enscript>
123
124After entering
125
126 $ chicken-install
127
128at the shell prompt (and in the same directory where the two files
129exist), the file {{hello.scm}} will be compiled into a dynamically
130loadable library and a statically linkable object.
131If the compilation succeeds, {{hello.so}} and {{hello.o}} will
132be stored in the repository, together with a file named
133{{hello.egg-info}} containing an a-list with metadata (what
134you stored above in {{hello.egg}} plus some additional metadata).
135If no extension name is given to {{chicken-install}}, it will simply
136process any files with the {{.egg}} extension it can find.
137
138Use it like any other CHICKEN extension:
139
140 $ csi -q
141 #;1> (require-library hello)
142 ; loading /usr/local/lib/chicken/8/hello.so ...
143 #;2> (hello "me")
144 Hello, me!
145 #;3>
146
147==== An application
148
149Here we create a simple application:
150
151<enscript highlight=scheme>
152;;;; hello2.scm
153(import scheme chicken.format chicken.process-context)
154(print "Hello, ")
155(for-each (lambda (x) (printf "~A " x)) (command-line-arguments))
156(print "!")
157</enscript>
158
159We also need an egg file:
160
161<enscript highlight=scheme>
162;;;; hello2.egg
163((author "Me")
164 (synopsis "A cool hello-world application")
165 (license "proprietary")
166 (components (program hello2)))
167</enscript>
168
169To use it, just run {{chicken-install}} in the same directory:
170
171 $ chicken-install
172
173(Here we omit the extension name)
174
175Now the program {{hello2}} will be installed in the same location as
176the other CHICKEN tools (like {{chicken}}, {{csi}}, etc.), which will
177normally be {{/usr/local/bin}}. Note that you need write-permissions
178for those locations and may have to run {{chicken-install}} with
179administrative rights or use the {{-sudo}} option.
180
181The extension can be used from the command line:
182
183 $ hello2 one two three
184 Hello,
185 one two three !
186
187De-installation is just as easy - use the {{chicken-uninstall}}
188program to remove one or more extensions from the local repository:
189
190 $ chicken-uninstall hello2
191
192==== A module exporting syntax
193
194The hello module was just a shared library, and not a module.
195
196To create an extension that exports syntax see the chapter on
197[[Modules]]. We will show a simple example here: a module {{my-lib}}
198that exports one macro ({{prog1}}) and one procedure ({{my-sum}}):
199
200<enscript highlight=scheme>
201;;; my-lib.scm
202
203(module my-lib
204 *
205 (import scheme (chicken base))
206
207(define-syntax prog1
208 (syntax-rules ()
209 ((_ e1 e2 ...)
210 (let ((result e1))
211 (begin e2 ...)
212 result))))
213
214(define my-sum
215 (lambda (numbers)
216 (prog1
217 (apply + numbers)
218 (display "my-sum used one more time!")
219 (newline))))
220
221)
222</enscript>
223
224The {{prog1}} macro is similar to Common Lisp's {{prog1}}: it
225evaluates a list of forms, but returns the value of the first form.
226
227The egg file:
228
229<enscript highlight=scheme>
230;;; my-lib.egg
231
232((components (extension my-lib))
233 (version 1.0)
234 (license "BSD")
235 (author "Me again")
236 (synopsis "My own cool libraries"))
237</enscript>
238
239Running {{chicken-install}} on the same directory will install the extension.
240
241Next, it should be possible to load the library:
242
243 $ csi -q
244 #;1> (import my-lib)
245 ; loading /usr/local/lib/chicken/6/my-lib.import.so ...
246 ; loading /usr/local/lib/chicken/6/scheme.import.so ...
247 ; loading /usr/local/lib/chicken/6/chicken.import.so ...
248 ; loading /usr/local/lib/chicken/6/my-lib.so ...
249 #;2> (my-sum '(10 20 30))
250 my-sum used one more time!
251 60
252 #;3> (my-sum '(-1 1 0))
253 my-sum used one more time!
254 0
255 #;4> (prog1 (+ 2 2) (print "---"))
256 ---
257 4
258
259To query the list of currently installed extensions, use
260{{chicken-status}}. It can list what extensions are installed and
261what files belong to a particular installed extension.
262
263For more information about the available tools and the various options
264they provide, consult the [[Extension tools]] chapter. Again, for a
265full list of allowed declarations in the {{.egg}} file, see the
266[[Egg specification format]] chapter.
267
268---
269Previous: [[Declarations]]
270
271Next: [[Extension tools]]