<?xml version="1.0" encoding="UTF-8"?>
<articles type="array">
  <article>
    <body>From this post, I will introduce topics on compiling Lisp programs
with ECL, Embeddable Common Lisp. ECL is an implementation of Common
Lisp, and it is especially powerful on combining lisp programs with C
programs. You can embed ECL as a lisp engine in C programs, or call C
functions via ffi. In a series of posts, several ways to compile lisp
programs and use them from C programs are introduced. As a starter, I
explain file types generated by some compilation approaches.
I suppose GNU/Linux system and gcc as a development environment.

## Overview

You can generate following files with ECL.

- Object file (.o)
- Fasl file (.fas)
- Static library (.a)
- Shared library (.so)
- Executable file

Relations among them are depicted below:

![file-type-relations.png](http://blog.s21g.com/blobs/19fe98df859c51142fa7ebba5e31afe9/file-type-relations.png)

## Object file

As you can see, object file works as an intermediate file format. If
you want to compile more than two lisp files, you might better to
compile with a `:system-p t` option, which generates object files.

On linux systems, ECL invokes `gcc -c` for generating object files.

An object file consists of some functions in C:

* Functions corresponding to Lisp functions
* The initialization function which registers defined functions on the lisp environment

Consider the example below.

lisp&gt;&gt;
(defun say-hello ()
  (print &quot;Hello, world&quot;))
&lt;&lt;--

During compilation, This simple lisp program is translated into the C
program, and then compiled into the object file. The C program contains two functions:

- `static cl_object L1say_hello`: corresponding to 'say-hello' function
- `ECL_DLLEXPORT void _eclwm2nNauJEfEnD_CLSxi0z(cl_object flag)`: initialization function

In order to use these object files from your C program, you have to call initialization functions before using lisp functions (such like 'say-hello'). However the name of an init function is seemed to be randomized and not user-friendly. This is because object files are not intended to be used directly. ECL provides some user-friendly ways to generate compiled lisp programs(as static/shared libraries or executable), and in each approach, object files act as intermediate files.

## Fasl file

If you want to make a library which is loaded dynamically from lisp program, you should choose fasl file format.

In current ECL(9.10.2), a fasl file is just a shared library file. This means you can load fasl files with `dlopen` and initialize it by calling a init function from C programs, but this is not an intended usage. Recommended usage is loading fasl files by calling `load` lisp function.

Creating a fasl file from one lisp file is very easy.

lisp&gt;&gt;
(compile-file &quot;hello.lsp&quot;)
&lt;&lt;--

To create a fasl file from some lisp files, firstly you have to compile each lisp file into object file, and then combine them with `c:build-fasl`.

lisp&gt;&gt;
;; generates hello.o
(compile-file &quot;hello.lsp&quot; :system-p t)
;; generates goodbye.o
(compile-file &quot;goodbye.lsp&quot; :system-p t)

;; generates hello-goodbye.fas
(c:build-fasl &quot;hello-goodbye&quot;
              :lisp-files '(&quot;hello.o&quot; &quot;goodbye.o&quot;))
&lt;&lt;--

## Static library

ECL can compile lisp programs to static libraries, which can be linked with
 C programs. A static library is created by `c:build-static-library` with some compiled object files.

lisp&gt;&gt;
;; generates hello.o
(compile-file &quot;hello.lsp&quot; :system-p t)
;; generates goodbye.o
(compile-file &quot;goodbye.lsp&quot; :system-p t)

;; generates libhello-goodbye.a
(c:build-static-library &quot;hello-goodbye&quot;
              :lisp-files '(&quot;hello.o&quot; &quot;goodbye.o&quot;)
              :init-name &quot;init_hello_goodbye&quot;)
&lt;&lt;--

When you use static/shared library, you have to call init functions. The name of the function is specified by `:init-name` option. In this example, &quot;init_hello_goodbye&quot; is it. The usage of this function is shown below:

c&gt;&gt;
#include &lt;ecl/ecl.h&gt;
extern void init_hello_goodbye(cl_object cblock);

int
main(int argc, char **argv)
{
    // setup the lisp runtime
    cl_boot(argc, argv);
    
    // call the init function via read_VV
    read_VV(OBJNULL, init_hello_goodbye);
    
    ...
        
    // shutdown the lisp runtime
    cl_shutdown();

    return 0;
}
&lt;&lt;--

Because the program itself does not know the type of the init
function, a prototype declaration is inserted. After booting up the
lisp environment, invoke `init_hello_goodbye` via
`read_VV`. `init_hello_goodbye` takes a argument, and `read_VV`
supplies an appropriate one. Now that the initialization is finished, we can use functions and other stuffs defined in the library.

## Shared library

Almost the same as the case of static library.

## Executable file

Some of you might want to create a standalone executable from lisp
programs. ECL supports executable file generation. First, compile all
lisp files to object files. After that, calling `c:build-program` does
the job.

lisp&gt;&gt;
;; generates hello.o
(compile-file &quot;hello.lsp&quot; :system-p t)
;; generates goodbye.o
(compile-file &quot;goodbye.lsp&quot; :system-p t)

;; generates hello-goodbye
(c:build-program &quot;hello-goodbye&quot;
              :lisp-files '(&quot;hello.o&quot; &quot;goodbye.o&quot;))
&lt;&lt;--

## Summary

In this post, some file types that can be compiled to with ECL were introduced. Each file type has adequate purpose:

* Object file: intermediate file format for others
* Fasl file: loaded dynamically via `load` lisp function
* Static library: linked with and used from C programs
* Shared library: loaded dynamically and used from C programs
* Executable: standalone executable

ECL provides a high-level interface `c:build-*` for each format. If you want to use them, you can find detailed description in the [manual](http://ecls.sourceforge.net/new-manual/). Enjoy!

## References

- [ECL: Embeddable Common Lisp](http://ecls.sourceforge.net/resources.html)
</body>
    <cached-tag-list>ECL</cached-tag-list>
    <comments-count type="integer">0</comments-count>
    <created-at type="datetime">2009-10-26T00:09:14+00:00</created-at>
    <daily-archive-id type="integer">1283</daily-archive-id>
    <filter-type>blue_stole</filter-type>
    <id type="integer">1649</id>
    <monthly-archive-id type="integer">197</monthly-archive-id>
    <pdf-digest nil="true"></pdf-digest>
    <permalink nil="true"></permalink>
    <published-at type="datetime">2009-10-26T09:10:00+00:00</published-at>
    <secret>5101ad38-43ca-460c-ac77-cfe40f507117</secret>
    <title>Compiling with ECL (1): File types</title>
    <updated-at type="datetime">2009-10-26T00:09:14+00:00</updated-at>
    <user-id type="integer">104</user-id>
  </article>
  <article>
    <body>This is the first post on this blog.</body>
    <cached-tag-list></cached-tag-list>
    <comments-count type="integer">0</comments-count>
    <created-at type="datetime">2009-10-16T09:25:40+00:00</created-at>
    <daily-archive-id type="integer">1276</daily-archive-id>
    <filter-type>blue_stole</filter-type>
    <id type="integer">1642</id>
    <monthly-archive-id type="integer">197</monthly-archive-id>
    <pdf-digest nil="true"></pdf-digest>
    <permalink>/articles/1642</permalink>
    <published-at type="datetime">2009-10-16T09:24:00+00:00</published-at>
    <secret>6b600886-7a36-42cc-8c2e-da9a642ad5b6</secret>
    <title>My first post</title>
    <updated-at type="datetime">2009-10-16T09:25:42+00:00</updated-at>
    <user-id type="integer">104</user-id>
  </article>
</articles>
