Chicken » Deployment

## Deployment

CHICKEN generates fully native binaries that can be distributed like normal C/C++ programs. There are various methods of deployment, depending on platform, linkage, external dependencies and whether the application should be built from sources or precompiled and whether the CHICKEN runtime-libraries are expected on the destination system or if the application should be completely self-contained.

There are several options for distributing software written in CHICKEN for use on other machines or by other people:

- Distribute source code, which requires that the target system has a compatible version of CHICKEN installed
- Distribute C files generated from Scheme source code and compile them to binaries on the target system - this also requires a matching CHICKEN installation on the target
- Distribute compiled binaries, either statically linked or built in such a way that all required extensions and libraries are included in the distribution

The rest of this chapter addresses the third option, for which several options exist, depending on your needs and how self-contained you want your deployed binary to be.

The simplest form of deployment is the single executable. The runtime library (`libchicken.so`, `libchicken.dylib` or `libchicken.dll`) is required for these programs to run, unless you link your application statically:

     % csc myprogram.scm
     % ldd myprogram               # on linux
               linux-gate.so.1 =>  (0xb805c000)
               libchicken.so.9 => /home/felix/chicken/core/lib/libchicken.so.9 (0xb7c22000)
               libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7bec000)
               libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7be7000)
               libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7a84000)
               /lib/ld-linux.so.2 (0xb805d000)
     % ls -l myprogram
     -rwxr-xr-x 1 felix felix   34839 2010-02-22 20:19 x

### Static linking

Linking your application statically will include the runtime library in the executable:

     % csc -static myprogram.scm
     % ldd myprogram
               linux-gate.so.1 =>  (0xb805c000)
               libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7bec000)
               libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7be7000)
               libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7a84000)
               /lib/ld-linux.so.2 (0xb805d000)

Extensions are transparently linked in statically, if you provide the `-static` option to `csc`, provided the extension is avaiable as a static object file (this applies to most extensions by default).

### Shipping the runtime library

An alternate way of distributing compiled code is to ship the runtime library `libchicken.so` together with the executable, possibly including any extensions that you use. To make this work, any runtime linker paths compiled into binary objects need to be deleted or changed by using a tool like `chrpath(1)` or `patchelf(1)`, to a value that indicates that the library lookup should start in the same location as the main program. (e.g. `$ORIGIN` on Linux). Don't forget to copy any extensions from the extension repository (`$PREFIX/lib/chicken/$BINARYVERSION`).

Alternatively start your program through a separate script that sets `LD_LIBRARY_PATH` (or `DYLD_LIBRARY_PATH` on MacOS X). For more details, consult the documentation of the operating system that you use to build your deployed binaries.

A directory containing all binaries is fully "portable" in the sense that it will run directly from an USB-stick or any other removable media. At runtime the program can find out its location by invoking the `repository-path` procedure, which will return the full pathname in which the application is located.

Should the program depend on more libraries which are not available by default on the intended target systems, and which you would like to include in your application, you will have to track them down yourself and place them in the application directory.

### Distributing compiled C files

It is possible 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`), plus the files `chicken-config.h` and `buildtag.h`, which are generated by the build process. All other modules of the runtime system and the extension libraries are just compiled Scheme code. The following example shows a minimal application, which should run without changes on most operating systems, like Windows, Linux or FreeBSD (note however that static binaries are not supported on Mac OS X).

Take the following "Hello World" program:

    ; hello.scm

    (print "Hello, world!")

     % csc -t hello.scm -optimize-level 3 -output-file hello.c

Compiled to C, we get `hello.c`. We need the files `chicken.h`, `chicken-config.h`, `buildtag.h` and `runtime.c`, which contain the basic runtime system, plus the library files `build-version.c`, `chicken-syntax.c`, `eval.c`, `expand.c`, `internal.c`, `library.c` and `modules.c`, which contain the same functionality as the library that is linked into plain CHICKEN-compiled applications:

     % cd /tmp
     % echo '(print "Hello World.")' > hello.scm
     % csc -t hello.scm
     % cp $CHICKEN_BUILD/build-version.c .
     % cp $CHICKEN_BUILD/chicken-syntax.c .
     % cp $CHICKEN_BUILD/eval.c .
     % cp $CHICKEN_BUILD/expand.c .
     % cp $CHICKEN_BUILD/internal.c .
     % cp $CHICKEN_BUILD/library.c .
     % cp $CHICKEN_BUILD/modules.c .
     % cp $CHICKEN_BUILD/runtime.c .
     % cp $CHICKEN_BUILD/chicken.h .
     % cp $CHICKEN_BUILD/chicken-config.h .
     % cp $CHICKEN_BUILD/buildtag.h .
     % gcc -Os -fomit-frame-pointer -DHAVE_CHICKEN_CONFIG_H hello.c \
       build-version.c chicken-syntax.c eval.c expand.c internal.c \
       library.c modules.c runtime.c \
       -o hello -lm

Once we have all the files together, we can create a tarball:

    % tar czf hello.tar.gz hello.c build-version.c chicken-syntax.c eval.c \
      expand.c internal.c library.c modules.c runtime.c chicken.h \
      chicken-config.h buildtag.h

This is naturally rather simplistic. Things like enabling dynamic loading and selecting supported features of the host system would need more configuration- and build-time support. All this can be addressed using more elaborate build-scripts, makefiles or by using autoconf/automake.

The `chicken-config.h` file may contain incorrect settings for your deployment target. Especially when the architecture is different. In that case you will have to adjust the values as needed.

For more information, study the CHICKEN source code and/or ask on the CHICKEN mailing lists to understand the implications and difficulties of this deployment method in more detail.

### Platform specific notes

#### Windows

Deployment is fully supported on Windows. Since Windows looks up dynamic link libraries in the programs original location by default, adding third-party libraries to the application directory is no problem. The freely available Dependency Walker tool is helpful to find out what DLLs your application depends on.

#### MacOS X

The `otool(1)` program will show you dynamic libraries that your application requires. `DYLD_LIBRARY_PATH` can be set to override runtime linker paths and `install_name_tool(1)` is available to patch runtime linker paths directly. All of these tools require the Xcode command-line tools too be installed.

Previous: Units and linking model

Next: Cross development