diff --git a/src/doc/new-doc/extensions/building.txi b/src/doc/new-doc/extensions/building.txi new file mode 100644 index 000000000..52cef44bb --- /dev/null +++ b/src/doc/new-doc/extensions/building.txi @@ -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 +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. diff --git a/src/doc/new-doc/extensions/index.txi b/src/doc/new-doc/extensions/index.txi index 65f209004..67625893c 100644 --- a/src/doc/new-doc/extensions/index.txi +++ b/src/doc/new-doc/extensions/index.txi @@ -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