~ chicken-core (chicken-5) /manual/Extensions


  1[[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]]
Trap