• 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

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.


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:


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.

   1  (defun say-hello ()
   2    (print "Hello, world"))

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.

   1  (compile-file "hello.lsp")

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.

   1  ;; generates hello.o
   2  (compile-file "hello.lsp" :system-p t)
   3  ;; generates goodbye.o
   4  (compile-file "goodbye.lsp" :system-p t)
   6  ;; generates hello-goodbye.fas
   7  (c:build-fasl "hello-goodbye"
   8                :lisp-files '("hello.o" "goodbye.o"))

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.

   1  ;; generates hello.o
   2  (compile-file "hello.lsp" :system-p t)
   3  ;; generates goodbye.o
   4  (compile-file "goodbye.lsp" :system-p t)
   6  ;; generates libhello-goodbye.a
   7  (c:build-static-library "hello-goodbye"
   8                :lisp-files '("hello.o" "goodbye.o")
   9                :init-name "init_hello_goodbye")

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, "init_hello_goodbye" is it. The usage of this function is shown below:

   1  #include <ecl/ecl.h>
   2  extern void init_hello_goodbye(cl_object cblock);
   4  int
   5  main(int argc, char **argv)
   6  {
   7      // setup the lisp runtime
   8      cl_boot(argc, argv);
  10      // call the init function via read_VV
  11      read_VV(OBJNULL, init_hello_goodbye);
  13      ...
  15      // shutdown the lisp runtime
  16      cl_shutdown();
  18      return 0;
  19  }

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.

   1  ;; generates hello.o
   2  (compile-file "hello.lsp" :system-p t)
   3  ;; generates goodbye.o
   4  (compile-file "goodbye.lsp" :system-p t)
   6  ;; generates hello-goodbye
   7  (c:build-program "hello-goodbye"
   8                :lisp-files '("hello.o" "goodbye.o"))


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. Enjoy!


posted by Png hayamiz on Mon 26 Oct 2009 at 00:09


or Preview
Social Bookmarks
  • Delicious
  • B_entry1649
  • Clip_16_12_w
Services from s21g