| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In this chapter we describe how you can use ECL to build programs and loadable extensions that you can later on distribute to other people.
2.1 What can ECL do? 2.2 Compiling files 2.3 Building standalone executables 2.4 Building libraries 2.5 File names 2.6 Compiler examples
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Some day for some reasons you will be in the need to distribute code that has been developed using ECL. In the following sections we will describe the means that ECL offers you to do so. Basically, these are the alternatives
In several of these options, we have mentioned the possibility to include C/C++ code. Even if this is possible, you cannot use ordinary C/C++ compilers and makefiles to build ECL extensions, let it be programs or libraries. Briefly, you have to organize your code as follows
mymain(), in which the initialization phase
for your library is performed.
#include <ecl.h> at the beginning.
mymain() in the example above). These means
are explained in the following sections.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ECL supports two types of compilation. One is bytecodes compilation. This process is performed on-the-fly, as you load source files with lisp code. This leads to a series of bytes for each instruction, the so called "bytecodes". These bytecodes are interpreted in a virtual machine, which is written in C and which is reasonably fast.
The other type of compilation is the so-called "native" compilation. This process consists on translating the lisp source file to C language. The intermediate file is later compiled using a C compiler. The result is an object file which may have different purposes.
compile-file. These object files typically have
the `.fas' extension, and can be loaded with load. They cannot be used
to build libraries nor standalone executable programs.
compile-file with the keyword argument
:system-p
extension. It cannot be loaded with load, but it can be used to build
libraries, standalone executable programs, or larger FASL files.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To build an executable you need a working ECL image with the compiler. The function to build customized images is c::build-program. The description of this function is as follows.
This function builds a lisp image up from the core lisp library, plus all components listed in lisp-files. Each component is either:
prologue-code and epilogue-code are used to customize the initialization process of the lisp image. In order to build the executable, c:build-program first writes down a piece of C code which initializes the lisp environment. You can customize the initialization process by suppling code to be executed before (prologue-code) or after (epilogue-code) setting up the lisp environment. Typically prologue-code defaults to an empty string, while epilogue-code invokes the classical lisp top-level.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To build a library you proceed more or less the same way as with standalone executables. There are two different functions depending on whether you need to build static or shared libraries.
This function builds a library file up from the object files listed in
lisp-files. Each of the arguments to lisp-file must name a single
object file produced with compile-file.
library-name is the physical pathname corresponding to the library. The
value of library-name must follow some system-specific conventions. To
make your program portable, library-name should be built using the
output of compile-file-pathname.
prologue-code and epilogue-code are strings with C code to be executed before and after initializing the library, respectively. For dynamically linked libraries you can also provide a list of strings in ld-flags. These strings are additional parameters for the linker and their purpose is to link C/C++ extensions into the library.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When compiling lisp files, creating libraries, etc, a number of files are
produced which are of interest for the user or programmer. However, the name
of these files will change from system to system. The purpose of the function
compile-file-pathname is to query the compiler about the name of the
different files that it can produce. Possible values of the type
argument include:
load.
c:build-static-library.
c:build-shared-library.
c:build-program.
The output of this function is system specific. For example, under FreeBSD
> (compile-file-pathname "/this/path/mylib" :type :lib) #P"/this/path/libmylib.a" > (compile-file-pathname "/this/path/mylib" :type :dll) #P"/this/path/libmylib.so" > (compile-file-pathname "/this/path/mycode") #P"/this/path/mycode.fas" |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
(princ "Hello world!") (terpri) (quit) |
"Hello world!" message and the interpreter will be closed.
ECL (Embeddable Common-Lisp) 0.9d
Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
Copyright (C) 1993 Giuseppe Attardi
Copyright (C) 2000 Juan J. Garcia-Ripoll
ECL is free software, and you are welcome to redistribute it
under certain conditions; see file 'Copyright' for details.
Type :h for Help. Top level.
> (load "hello.lisp")
;;; Loading "hello.lisp"
Hello World!
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Type :h for Help. Top level.
> *features*
(:IEEE-FLOATING-POINT :IBM-PC :I386 :BSD :UNIX :DLOPEN :ANSI-CL :CLOS
:BOEHM-GC :ECL :COMMON)
|
In this example we build a loadable extension which prints the "Hello
world!" message. First you need to create a the `hello.lisp' file. Next
you have to enter the ECL environment and type (compile-file
"hello.lisp"). This produces a loadable object file.
Type :h for Help. Top level. > (compile-file "hello.lisp") ;;; Loading #P"/usr/lib/ecl/cmp.fas" ;;; Loading #P"/usr/lib/ecl/sysfun.lsp" ;;; Compiling hello.lisp. ;;; End of Pass 1. ;;; Calling the C compiler... ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl//h" -w -c "hello.c" -o "hello.o" ;;; Invoking external command: gcc -o "hello.fas" -L"/usr/lib/ecl/" "hello.o" -Wl,--rpath,/usr/lib/ecl/ -shared -lecl -lgmp -lgc -ldl -lm ;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3 ;;; Finished compiling hello.lisp. #P"hello.fas" Top level. > (load "hello") ;;; Loading #P"hello.fas" Hello World! |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
"Hello
world!" message and does nothing else. First you must create the
`hello.lisp' file shown above. Next you have to enter the ECL
environment and type (compile-file "hello.lisp" :system-p t). This
produces an object file that can be linked against the ECL core image.
Type :h for Help. Top level. > (compile-file "hello.lisp" :system-p t) ;;; Loading #P"/usr/lib/ecl/cmp.fas" ;;; Loading #P"/usr/lib/ecl/sysfun.lsp" ;;; Compiling hello.lisp. ;;; End of Pass 1. ;;; Calling the C compiler... ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl//h" -w -c "hello.c" -o "hello.o" ;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3 ;;; Finished compiling hello.lisp. #P"hello.o" |
The final step is to build the executable using the c:build-program
instruction.
> (c:build-program "myecl" :lisp-files '("hello.o"))
;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl//h" -w -c "myecl.c" -o "myecl.o"
;;; Invoking external command: gcc -o "myecl" -L"/usr/lib/ecl/" "myecl.o" "hello.o" -Wl,--rpath,/usr/lib/ecl/ -lecl -lgmp -lgc -ldl -lm
#P"myecl"
Top level.
|
% ./myecl Hello world! |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
"Hello world!" message and does nothing
else. First you must create the `hello.lisp' file shown above. Next you
have to enter the ECL environment and type (compile-file "hello.lisp"
:system-p t). This produces an object file that can be linked to form a loadable
library.
Type :h for Help. Top level. > (compile-file "hello.lisp" :system-p t) ;;; Loading #P"/usr/lib/ecl/cmp.fas" ;;; Loading #P"/usr/lib/ecl/sysfun.lsp" ;;; Compiling hello.lisp. ;;; End of Pass 1. ;;; Calling the C compiler... ;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl//h" -w -c "hello.c" -o "hello.o" ;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3 ;;; Finished compiling hello.lisp. #P"hello.o" |
The final step is to build the library using the c:build-shared-library
instruction.
> (c:build-shared-library "myecl" :lisp-files '("hello.o"))
;;; Invoking external command: gcc -O2 -march=i686 -pipe -fomit-frame-pointer -fPIC -fstrict-aliasing -Dlinux -O "-I/usr/lib/ecl//h" -w -c "myecl.c" -o "myecl.o"
;;; Invoking external command: gcc -o "libmyecl.so" -L"/usr/lib/ecl/" "myecl.o" "hello.o" -Wl,--rpath,/usr/lib/ecl/ -shared -lecl -lgmp -lgc -ldl -lm
#P"libmyecl.so"
|
c:build-program.
<<<<<<<< THIS EXAMPLE IS WRONG?! >>>>>>>>> > (load "myecl") ;;; Loading myecl.fas Hello world! Bye. |
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |