~ chicken-core (master) /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 its code and some special
 86files in a directory named after the desired name of the egg. 
 87For example, if your
 88egg is called {{foo}}, create a directory called {{foo}}
 89and put the egg code there.
 90 
 91Eggs need an egg description file {{<egg name>.egg}}.  This file
 92indicates how the egg is to be compiled and provides some information
 93about the egg (author, license, dependencies etc).
 94
 95The format of these files is described in full in the chapter entitled
 96"[[Egg specification format]]".  Below we'll give a few brief
 97examples of simple eggs.
 98
 99
100=== Examples for extensions
101
102==== A simple library
103
104The simplest case is a single file that does not export any syntax.
105For example
106
107<enscript highlight=scheme>
108;;;; hello.scm
109
110(define (hello name)
111  (print "Hello, " name " !") )
112</enscript>
113
114We need an {{.egg}} file to build and install our nifty extension:
115
116<enscript highlight=scheme>
117;;;; hello.egg
118
119((author "Me")
120 (synopsis "A cool hello-world library")
121 (license "GPLv3")
122 (components (extension hello)))
123</enscript>
124
125After entering
126
127 $ chicken-install
128
129at the shell prompt (and in the same directory where the two files
130exist), the file {{hello.scm}} will be compiled into a dynamically
131loadable library and a statically linkable object.
132If the compilation succeeds, {{hello.so}} and {{hello.o}} will
133be stored in the repository, together with a file named
134{{hello.egg-info}} containing an a-list with metadata (what
135you stored above in {{hello.egg}} plus some additional metadata).
136If no extension name is given to {{chicken-install}}, it will simply
137process any files with the {{.egg}} extension it can find.
138
139Use it like any other CHICKEN extension:
140
141 $ csi -q
142 #;1> (require-library hello)
143 ; loading /usr/local/lib/chicken/8/hello.so ...
144 #;2> (hello "me")
145 Hello, me!
146 #;3>
147
148==== An application
149
150Here we create a simple application:
151
152<enscript highlight=scheme>
153;;;; hello2.scm
154(import scheme chicken.format chicken.process-context)
155(print "Hello, ")
156(for-each (lambda (x) (printf "~A " x)) (command-line-arguments))
157(print "!")
158</enscript>
159
160We also need an egg file:
161
162<enscript highlight=scheme>
163;;;; hello2.egg
164((author "Me")
165 (synopsis "A cool hello-world application")
166 (license "proprietary")
167 (components (program hello2)))
168</enscript>
169
170To use it, just run {{chicken-install}} in the same directory:
171
172 $ chicken-install
173
174(Here we omit the extension name)
175
176Now the program {{hello2}} will be installed in the same location as
177the other CHICKEN tools (like {{chicken}}, {{csi}}, etc.), which will
178normally be {{/usr/local/bin}}.  Note that you need write-permissions
179for those locations and may have to run {{chicken-install}} with
180administrative rights or use the {{-sudo}} option.
181
182The extension can be used from the command line:
183
184 $ hello2 one two three
185 Hello,
186 one two three !
187
188De-installation is just as easy - use the {{chicken-uninstall}}
189program to remove one or more extensions from the local repository:
190
191 $ chicken-uninstall hello2
192
193==== A module exporting syntax
194
195The hello module was just a shared library, and not a module.
196
197To create an extension that exports syntax see the chapter on
198[[Modules]].  We will show a simple example here: a module {{my-lib}}
199that exports one macro ({{prog1}}) and one procedure ({{my-sum}}):
200
201<enscript highlight=scheme>
202;;; my-lib.scm
203
204(module my-lib
205  *
206  (import scheme (chicken base))
207
208(define-syntax prog1
209  (syntax-rules ()
210    ((_ e1 e2 ...)
211     (let ((result e1))
212       (begin e2 ...)
213       result))))
214
215(define my-sum
216  (lambda (numbers)
217    (prog1
218      (apply + numbers)
219      (display "my-sum used one more time!")
220      (newline))))
221
222)
223</enscript>
224
225The {{prog1}} macro is similar to Common Lisp's {{prog1}}: it
226evaluates a list of forms, but returns the value of the first form.
227
228The egg file:
229
230<enscript highlight=scheme>
231;;; my-lib.egg
232
233((components (extension my-lib))
234 (version 1.0)
235 (license "BSD")
236 (author "Me again")
237 (synopsis "My own cool libraries"))
238</enscript>
239
240Running {{chicken-install}} on the same directory will install the extension.
241
242Next, it should be possible to load the library:
243
244 $ csi -q
245 #;1> (import my-lib)
246 ; loading /usr/local/lib/chicken/6/my-lib.import.so ...
247 ; loading /usr/local/lib/chicken/6/scheme.import.so ...
248 ; loading /usr/local/lib/chicken/6/chicken.import.so ...
249 ; loading /usr/local/lib/chicken/6/my-lib.so ...
250 #;2> (my-sum '(10 20 30))
251 my-sum used one more time!
252 60
253 #;3> (my-sum '(-1 1 0))
254 my-sum used one more time!
255 0
256 #;4> (prog1 (+ 2 2) (print "---"))
257 ---
258 4
259
260To query the list of currently installed extensions, use
261{{chicken-status}}. It can list what extensions are installed and
262what files belong to a particular installed extension.
263
264For more information about the available tools and the various options
265they provide, consult the [[Extension tools]] chapter.  Again, for a
266full list of allowed declarations in the {{.egg}} file, see the
267[[Egg specification format]] chapter.
268
269---
270Previous: [[Declarations]]
271
272Next: [[Extension tools]]
Trap