mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-23 04:52:42 -08:00
newdoc: add chapter about building
Covers c::build-* functions.
This commit is contained in:
parent
e7122e49e9
commit
0caefbabcd
2 changed files with 286 additions and 2 deletions
284
src/doc/new-doc/extensions/building.txi
Normal file
284
src/doc/new-doc/extensions/building.txi
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
|
||||
@node System building
|
||||
@section System building
|
||||
|
||||
@menu
|
||||
* Compiling with ECL::
|
||||
@c * Compiling with Matroska::
|
||||
@c * Compiling with ASDF::
|
||||
@end menu
|
||||
|
||||
@cindex System building
|
||||
@cindex Creating executables and libraries
|
||||
|
||||
@node Compiling with ECL
|
||||
@subsection Compiling with ECL
|
||||
|
||||
In this section we will introduce topics on compiling Lisp programs. ECL
|
||||
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
|
||||
@ref{Foreign Function Interface}. We explain file types generated by
|
||||
some compilation approaches. GNU/Linux system and gcc as a development
|
||||
environment are assumed.
|
||||
|
||||
You can generate following files with ECL.
|
||||
|
||||
@enumerate
|
||||
@item Portable FASL file (.fasc)
|
||||
@item Native FASL file (.fas, .fasb)
|
||||
@item Object file (.o)
|
||||
@item Static library
|
||||
@item Shared library
|
||||
@item Executable file
|
||||
@end enumerate
|
||||
|
||||
Relations among them are depicted below:
|
||||
|
||||
@float Figure,fig:file_types
|
||||
@caption{Build file types}
|
||||
@image{figures/file-types}
|
||||
@end float
|
||||
|
||||
@node Portable FASL (fasc)
|
||||
@subsubsection Portable FASL
|
||||
@cindex Portable FASL
|
||||
|
||||
ECL provides two compilers (bytecodes compiler, and C/C++
|
||||
compieler). Portable FASL files are build from source lisp files by the
|
||||
bytecodes compiler. Generally FASC files are portable across
|
||||
architectures and operating systems providing convenient way of shipping
|
||||
portable modules. Portable FASL files may be concatenated, what leads to
|
||||
bundles. FASC files are faster to compile, but generally slower to run.
|
||||
|
||||
@exindex Building Portable FASL file
|
||||
@lisp
|
||||
;; install bytecodes compiler
|
||||
(ext:install-bytecodes-compiler)
|
||||
|
||||
;; compile hello.lisp file to hello.fasc
|
||||
(compile-file "hello1.lisp")
|
||||
(compile-file "hello2.lisp")
|
||||
|
||||
;; reinitialize C/C++ compiler back
|
||||
(ext:install-c-compiler)
|
||||
|
||||
;; FASC file may be loaded dynamically from lisp program
|
||||
(load "hello1.fasc")
|
||||
|
||||
;; ... concatenated into a bundle with other FASC
|
||||
(with-open-file (output "hello.fasc"
|
||||
:direction :output
|
||||
:if-exists :supersede)
|
||||
(ext:run-program
|
||||
"cat" '("hello1.fasc" "hello2.fasc") :output output))
|
||||
|
||||
;; ... and loaded dynamically from lisp program
|
||||
(load "hello.fasc")
|
||||
@end lisp
|
||||
|
||||
@node Native FASL
|
||||
@subsubsection Native FASL
|
||||
|
||||
@cindex Native FASL
|
||||
@ftindex DLOPEN
|
||||
@cfindex --enable-shared [YES|no]]
|
||||
|
||||
|
||||
If you want to make a library which is loaded dynamically from lisp
|
||||
program, you should choose fasl file format. Under the hood native fasls
|
||||
are just a shared library files.
|
||||
|
||||
This means you can load fasl files with @code{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. To work with @emph{Native FASL files} ECL has to be compiled
|
||||
with @code{--enable-shared} configure option (enabled by default).
|
||||
|
||||
Creating a fasl file from one lisp file is very easy.
|
||||
|
||||
@lisp
|
||||
(compile-file "hello.lisp")
|
||||
@end lisp
|
||||
|
||||
To create a fasl file from more lisp files, firstly you have to compile
|
||||
each lisp file into an object file, and then combine them with
|
||||
c:build-fasl.
|
||||
|
||||
@exindex Building native FASL
|
||||
@lisp
|
||||
;; generates hello.o
|
||||
(compile-file "hello.lisp" :system-p t)
|
||||
;; generates goodbye.o
|
||||
(compile-file "goodbye.lisp" :system-p t)
|
||||
|
||||
;; generates hello-goodbye.fas
|
||||
(c:build-fasl "hello-goodbye"
|
||||
:lisp-files '("hello.o" "goodbye.o"))
|
||||
|
||||
;; fasls may be built from mix of objects and libraries (both shared and
|
||||
;; static)
|
||||
(c:build-fasl "mixed-bundle"
|
||||
:lisp-files '("hello1.o" "hello2.a" "hello3.so"))
|
||||
@end lisp
|
||||
|
||||
@node Object file
|
||||
@subsubsection Object file
|
||||
|
||||
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 (instead of a fasl).
|
||||
|
||||
On linux systems, ECL invokes gcc -c for generating object files.
|
||||
|
||||
An object file consists of some functions in C:
|
||||
|
||||
@itemize
|
||||
@item Functions corresponding to Lisp functions
|
||||
@item The initialization function which registers defined functions on the lisp environment
|
||||
@end itemize
|
||||
|
||||
Consider the example below.
|
||||
|
||||
@lisp
|
||||
(defun say-hello ()
|
||||
(print "Hello, world"))
|
||||
@end lisp
|
||||
|
||||
@cindex Object file internal layout
|
||||
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:
|
||||
|
||||
@itemize
|
||||
|
||||
@item @code{static cl_object L1say_hello}:
|
||||
'say-hello' function
|
||||
|
||||
@item @code{ECL_DLLEXPORT void _eclwm2nNauJEfEnD_CLSxi0z(cl_object flag)}:
|
||||
initialization function
|
||||
|
||||
@end itemize
|
||||
|
||||
In order to use these object files from your C program, you have to call
|
||||
initialization functions before using lisp functions (such as
|
||||
@code{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 other user-friendly ways to generate compiled lisp programs
|
||||
(as static/shared libraries or executable), and in each approach, object
|
||||
files act as intermediate files.
|
||||
|
||||
@node Static library
|
||||
@subsubsection 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.
|
||||
|
||||
@exindex Building static library
|
||||
@lisp
|
||||
;; generates hello.o
|
||||
(compile-file "hello.lsp" :system-p t)
|
||||
;; generates goodbye.o
|
||||
(compile-file "goodbye.lsp" :system-p t)
|
||||
|
||||
;; generates libhello-goodbye.a
|
||||
(c:build-static-library "hello-goodbye"
|
||||
:lisp-files '("hello.o" "goodbye.o")
|
||||
:init-name "init_hello_goodbye")
|
||||
@end lisp
|
||||
|
||||
When you use static/shared library, you have to call init functions. The
|
||||
name of the function is specified by @code{:init-name} option. In this
|
||||
example, @code{init_hello_goodbye} is it. The usage of this function is
|
||||
shown below:
|
||||
|
||||
@exindex Initializing static/shared library in C/C++
|
||||
@example
|
||||
@verbatim
|
||||
#include <ecl/ecl.h>
|
||||
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;
|
||||
}
|
||||
@end verbatim
|
||||
@end example
|
||||
|
||||
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 @code{init_hello_goodbye} via
|
||||
@code{read_VV}. @code{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.
|
||||
|
||||
@node Shared library
|
||||
@subsubsection Shared library
|
||||
|
||||
Almost the same as the case of static library. User has to use
|
||||
@code{c:build-shared-library}:
|
||||
|
||||
@exindex Building shared library
|
||||
@lisp
|
||||
;; generates hello.o
|
||||
(compile-file "hello.lsp" :system-p t)
|
||||
;; generates goodbye.o
|
||||
(compile-file "goodbye.lsp" :system-p t)
|
||||
|
||||
;; generates libhello-goodbye.so
|
||||
(c:build-shared-library "hello-goodbye"
|
||||
:lisp-files '("hello.o" "goodbye.o")
|
||||
:init-name "init_hello_goodbye")
|
||||
@end lisp
|
||||
|
||||
@node Executable
|
||||
@subsubsection Executable
|
||||
|
||||
ECL supports executable file generation. To create a standalone
|
||||
executable from lisp programs, compile all lisp files to object
|
||||
files. After that, calling @code{c:build-program} creates the
|
||||
executable.
|
||||
|
||||
@exindex Building executable
|
||||
@lisp
|
||||
;; generates hello.o
|
||||
(compile-file "hello.lsp" :system-p t)
|
||||
;; generates goodbye.o
|
||||
(compile-file "goodbye.lsp" :system-p t)
|
||||
|
||||
;; generates hello-goodbye
|
||||
(c:build-program "hello-goodbye"
|
||||
:lisp-files '("hello.o" "goodbye.o"))
|
||||
@end lisp
|
||||
|
||||
Like native FASL, program may be built also from libraries.
|
||||
|
||||
@node Summary
|
||||
@subsubsection Summary
|
||||
|
||||
In this post, some file types that can be compiled to with ECL were introduced. Each file type has adequate purpose:
|
||||
|
||||
@itemize
|
||||
@item Object file: intermediate file format for others
|
||||
@item Fasl files: loaded dynamically via load lisp function
|
||||
@item Static library: linked with and used from C programs
|
||||
@item Shared library: loaded dynamically and used from C programs
|
||||
@item Executable: standalone executable
|
||||
@end itemize
|
||||
|
||||
ECL provides a high-level interface @code{c:build-*} for each native
|
||||
format. In case of @emph{Portable FASL} bytecodes compiler is needed.
|
||||
|
|
@ -23,8 +23,8 @@
|
|||
* CDR Extensions::
|
||||
@end menu
|
||||
|
||||
@node System building
|
||||
@section System building
|
||||
@ System building
|
||||
@include extensions/building.txi
|
||||
|
||||
@node Operating System Interface
|
||||
@section Operating System Interface
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue