It is relatively easy to create distributions of Scheme projects that have been compiled to C. The runtime system of CHICKEN consists of only two handcoded C files (runtime.c and chicken.h). All other modules of the runtime system and the extension libraries are just compiled Scheme code.
An example:
Consider these two source files:
;;; foo.scm (declare (uses bar)) (say-hello)
and
;;; bar.scm (declare (unit bar) (uses posix)) (define (say-hello) (print "Hello, " (nth-value 0 (user-information (current-user-id)))) )
Compiling them yields two C files:
% chicken foo.scm -quiet % chicken bar.scm -quiet -explicit-use
The makefile for generating the executable foo would look like this:
CC = gcc CFLAGS = -I. -O3 -fomit-frame-pointer -fstrict-aliasing foo : foo.o bar.o libchicken.a libsrfi-chicken.a libstuffed-chicken.a gcc -s -L. foo.o bar.o -o $@ -lchicken -lsrfi-chicken -lstuffed-chicken foo.o : foo.c chicken.h bar.o : bar.c chicken.h libchicken.a : runtime.o library.o eval.o syntax-case.o ar rus $@ $^ libsrfi-chicken.a : srfi-1.o srfi-4.o srfi-13.o srfi-14.o scheduler.o srfi-18.o srfi-25.o srfi-37.o ar rus $@ $^ libstuffed-chicken.a : extras.o format.o match-support.o lolevel.o regex.o posix.o script-utils.o tcp.o ar rus $@ $^ runtime.o : runtime.c chicken.h eval.o : eval.c chicken.h library.o : library.c chicken.h extras.o : extras.c chicken.h srfi-1.o : srfi-1.c chicken.h srfi-4.o : srfi-4.c chicken.h match-support.o : match-support.c chicken.h syntax-case.o : syntax-case.c chicken.h srfi-18.o : srfi-18.c chicken.h scheduler.o : scheduler.c chicken.h format.o : format.c chicken.h tinyclos.o : tinyclos.c chicken.h srfi-13.o : srfi-13.c chicken.h srfi-14.o : srfi-14.c chicken.h srfi-25.o : srfi-25.c chicken.h srfi-37.o : srfi-37.c chicken.h lolevel.o : lolevel.c chicken.h regex.o : regex.c chicken.h posix.o : posix.c chicken.h script-utils.o : script-utils.c chicken.h tcp.o : tcp.c chicken.h
If CHICKEN was properly installed, then the C files needed can be found in the directory $(CHICKEN_HOME)/src (or just take them from the original tar archive). Don't forget chicken.h.
Some of the libraries created during the build process might not be needed. In this case it is safe to remove the associated rules from the makefile. Most of the time not all library units are needed for a given application. For the example above, a minimal makefile would look like this:
CC = gcc CFLAGS = -I. -O3 -fomit-frame-pointer -fstrict-aliasing foo : foo.o bar.o libchicken0.a libstuffed-chicken0.a gcc -s -L. foo.o bar.o -o $@ -lchicken0 -lstuffed-chicken0 foo.o : foo.c chicken.h bar.o : bar.c chicken.h libchicken0.a : runtime.o library.o eval.o ar rus $@ $^ libstuffed-chicken0.a : posix.o regex.o extras.o script-utils.o ar rus $@ $^ runtime.o : runtime.c chicken.h eval.o : eval.c chicken.h library.o : library.c chicken.h posix.o : posix.c chicken.h regex.o : regex.c chicken.h extras.o : extras.c chicken.h script-utils.o : script-utils.c chicken.h
Most library units can be used independently. Here is a table that shows library units that depend on other library units:
format | extras |
srfi-13 | srfi-14 |
lolevel | extras |
tinyclos | extras |
posix | extras regex script-utils |
script-utils | extras regex |
srfi-18 | scheduler |
tcp | extras scheduler |
In the example above bar uses posix. The units library and eval are used by foo (these are used by default). The file runtime.c is needed in any case.