[Ecls-list] Compile Flags

Juan Jose Garcia-Ripoll juanjose.garciaripoll at googlemail.com
Sun Jul 31 11:13:04 UTC 2011

On Thu, Jul 28, 2011 at 12:50 AM, Mark McCurry <mark.d.mccurry at gmail.com>wrote:

> Well, I had no luck digging through the mailing list and the wiki is vague.
> I have managed to get the linking working after playing around for a bit.
> The process I used to link the static lisp code "F-NAME.lisp" was:
> 1) Run ecl script to:
> (compile-file F-NAME.lisp :system-p t)
> (c:build-static-library F-NAME :lisp-files '(F-NAME.o))
> 2) In C file to be linked:
> cl_boot(argc, argv);
> void init_lib_F_NAME(cl_object);
> read_VV(OBJNULL, init_lib_F_NAME);
> cl_funcall(...);
> 3) Compile C with static library
> Is this the 'right' way to embed a static piece of lisp code into a C
> program?

There is no single right way to do it. Possibilities are many and I would
favor some that many people do not like.

*TYPE I: ECL in control*

* Compile all your C code into a statically or dynamically linked library,
say libc_extensions.a.

* Organize your program in the lisp part, including the lisp code that is to
be executed at startup. Say the "startup" function is MY-PACKAGE:ENTRY-POINT

* Compile each file using the flag :SYSTEM-P T and link all the resulting
files into a program using C:BUILD-PROGRAM

   (let ((list-of-files '("mylisp1.lisp" "mylisp2.lisp" ... ))
         (compiled-files (mapcar (lambda (x) (compile-file x :system-p t))
     (c:build-static-library "lisp_extension"
                             :lisp-files compiled-files
                             :ld-flags '("-lc_extension")
                             :epilogue-code '(MY-PACKAGE:ENTRY-POINT)

I very much prefer this way because it hides from you the link flags and
also the initialization of ECL. It is also much simpler to capture and
handle exceptions from lisp code than from C.

Note that you need not use :epilogue-code or the function
MY-PACKAGE;ENTRY-POINT, because on startup _all_ lisp code will be executed

*TYPE II: Your code in control*

* Organize your lisp code in a set of lisp files, with certain public
functions that are to be called from C perfectly identified by name.

* Compile and build everything into a statically or dynamically linked
library (that itself depends on libecl.so or ecl.dll!)

   (let ((list-of-files '("mylisp1.lisp" "mylisp2.lisp" ... ))
         (compiled-files (mapcar (lambda (x) (compile-file x :system-p t))
     (c:build-static-library "lisp_extension"
                             :lisp-files compiled-files))

* Compile your C program as usual and add your lisp library as a dependency.
In this case you would have to add -llisp_extension and -lecl when linking
the program and you have to code your main program to initialize the lisp

int main(int argc, char **argv)
  cl_boot(argc, argv);
  extern cl_object init_LIB_LISP_EXTENSION(cl_object);

This is more or less what you did but you have to make sure that both your
lisp code and ECL's library is included in the dependencies of your program,
otherwise it will fail to link. I do not like it very much, except for very
large projects where somehow ECL has to be integrated by hand. It has the
severe disadvantage that you have to know how to create lisp objects, find
lisp symbols and call lisp functions in C, and use some interfaces (read_VV)
which may change in the near future.

There are detailed examples about how to build libraries and programs using
ECL as a linker and including external C code in examples/build and
examples/asdf (they have been updated in CVS because some files had
disappeared) When organizing and building your code I very much recommend
http://ecls.sourceforge.net/new-manual/ch16.html) instead of compiling your
files manually.


Instituto de Física Fundamental, CSIC
c/ Serrano, 113b, Madrid 28006 (Spain)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/ecl-devel/attachments/20110731/8aae1c0c/attachment.html>

More information about the ecl-devel mailing list