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.

### Simple executables

The simplest form of deployment is the single executable. The runtime library (`libchicken.so` 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.5 => /home/felix/chicken/core/lib/libchicken.so.5 (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

Linking your application statically will include the runtime library in the executable, but this will increase its size substantially:

     % ls myprogram
     -rwxr-xr-x 1 felix felix 3566656 2010-02-22 20:30 myprogram

Programs distributed this way can only use Extensions if these extensions get linked in statically, which is basically supported but not available for all extensions.

### Self contained applications

The solution to many of these problems is creating an application directory that contains the executable, the runtime libraries, extensions and additional support files needed by the program. The executable has to be linked specially to make sure the correct included runtime library is used. You do this by using the `-deploy` options provided by the compiler driver, `csc`:

     % csc -deploy myprogram.scm
     % ls -l myprogram
     -rwxr-xr-x 1 felix felix 7972753 2010-02-22 20:19 libchicken.so.5
     -rwxr-xr-x 1 felix felix   34839 2010-02-22 20:19 myprogram
     % ldd myprogram
             linux-gate.so.1 =>  (0xb806a000)
             libchicken.so.5 => /home/felix/tmp/myprogram/libchicken.so.5 (0xb7c30000)
             libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7bfa000)
             libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7bf5000)
             libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7a92000)
             /lib/ld-linux.so.2 (0xb806b000)

As can be seen here, `myprogram` is prepared to load the contained `libchicken`, not any installed in the system that happens to have the same name.

You can even install extensions inside the application directory:

     % chicken-install -deploy -p $PWD/myprogram defstruct
     ...
     % ls -l myprogram
     -rwxr-xr-x 1 felix felix   82842 2010-02-22 20:24 defstruct.import.so
     -rw-r--r-- 1 felix felix     182 2010-02-22 20:24 defstruct.setup-info
     -rwxr-xr-x 1 felix felix   11394 2010-02-22 20:24 defstruct.so
     -rwxr-xr-x 1 felix felix 7972753 2010-02-22 20:19 libchicken.so.5
     -rwxr-xr-x 1 felix felix   34839 2010-02-22 20:19 myprogram

We can check with ldd that those compiled extension libraries are linked with the correct library:

     % ldd myprogram/*.so
     /home/felix/tmp/myprogram/defstruct.import.so:
             linux-gate.so.1 =>  (0xb7f4f000)
             libchicken.so.5 => /home/felix/tmp/myprogram/libchicken.so.5 (0xb7b08000)
             libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7ad2000)
             libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7acd000)
             libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb796a000)
             /lib/ld-linux.so.2 (0xb7f50000)
     /home/felix/tmp/myprogram/defstruct.so:
             linux-gate.so.1 =>  (0xb80c9000)
             libchicken.so.5 => /home/felix/tmp/myprogram/libchicken.so.5 (0xb7c8c000)
             libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7c56000)
             libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7c51000)
             libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7aee000)
             /lib/ld-linux.so.2 (0xb80ca000)

The `-deploy` option passed to `csc` when compiling `myprogram.scm` has taken care of setting up the application directory as the "repository" for extensions that the program will use at runtime:

     % myprogram/myprogram -:d
     [debug] application startup...
     [debug] heap resized to 500000 bytes
     [debug] stack bottom is 0xbfdbdf60.
     [debug] entering toplevel toplevel...
     [debug] stack resized to 131072 bytes
     [debug] entering toplevel library_toplevel...
     [debug] entering toplevel eval_toplevel...
     [debug] entering toplevel expand_toplevel...
     [debug] loading compiled module `/home/felix/tmp/myprogram/defstruct.so' (handle is 0x886ce98)
     ...

There is one restriction that you should be aware of: you cannot `chicken-install -deploy` an uninstalled extension, e.g. directly from an SVN checkout. You must first install it on your build system normally with `chicken-install`, so that `csc` can find its import library in the system-wide repository (or in a custom one if you have set `CHICKEN_REPOSITORY`). This is only needed while you are deploying the extension into the application directory; once deployed, of course, it's totally self-contained.

You can execute the program from its location, or you can install a symbolic link pointing to it - it will find the correct directory where the actual executable is located.

The application directory 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 hunt them down yourself and place them in the application directory. If these again have dependencies, things will get complicated and will involve things like patching binaries or writing "trampoline" shell scripts to run your application.

Deployment is fully compatible with "cross CHICKENs" (see Cross development).

#### Platform-specific notes

##### Linux

Deployment is fully supported on Linux

##### 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

On the Macintosh, passing the `-gui` option to `csc` will result in a true GUI application bundle (named `<your-program>.app`).

Invoking

     % otool -L <yourprogram>

will list dynamic libraries that your application needs.

##### Other UNIX flavors

Setting up the application executable to load runtime libraries from the same directory is supported on FreeBSD, NetBSD, OpenBSD and Solaris.

Under NetBSD, you must invoke the binary using its full absolute path (or via `$PATH`), otherwise it will give you an error message:

     execname not specified in AUX vector: No such file or directory

On AIX, deployment is currently not fully supported as the runtime linker will only load libraries from paths hardcoded at link time.

### Deploying source code

An alternative to deploying binaries is deployment as compiled C sources.

See the corresponding section in Using the compiler.

Previous: Extensions

Next: Cross development