1
0
Fork 0
cl-sites/ecl.common-lisp.dev/static/manual/System-building.html
2024-12-24 19:15:49 +01:00

870 lines
41 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<!-- Created by GNU Texinfo 7.0.3, https://www.gnu.org/software/texinfo/ -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>System building (ECL Manual)</title>
<meta name="description" content="System building (ECL Manual)">
<meta name="keywords" content="System building (ECL Manual)">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="index.html" rel="start" title="Top">
<link href="Indexes.html" rel="index" title="Indexes">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="Extensions.html" rel="up" title="Extensions">
<link href="Operating-System-Interface.html#Operating-System-Interface" rel="next" title="Operating System Interface">
<style type="text/css">
<!--
/* colors */
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
div.example {margin-left: 3.2em}
span.r {font-family: initial; font-weight: normal; font-style: normal}
span:hover a.copiable-link {visibility: visible}
strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
ul.mark-bullet {list-style-type: disc}
@media (prefers-color-scheme: dark) {
/* dark theme */
html { color: seashell;
background: #1A1A1A; }
body { background: #1A1A1A; }
th { border-bottom: 2px solid lightgray; }
h1, h2, h3, h4, h5 { background-image: linear-gradient(to left, #202020, #3A3A3A); }
code, var, code a { color: darkorange;
background: #2A2A2A; }
a { color: seashell; }
pre { background: #2A2A2A;
color: seashell;
/* mark longer code block with stripe on the left */
border-left: 5px solid darkorange;
padding-left: 10px; }
pre.screen { background: #2A2A2A;
border: 1px solid lightgray; }
pre.programlisting { background: #2A2A2A;
border-left: 1px solid lightgray;
border-top: 1px solid lightgray; }
/* we need a light background in order for the images to be readable */
img { background: white }
}
@media (prefers-color-scheme: light) {
/* light theme */
html { background: white }
body { background: white }
th { border-bottom: 2px solid gray; }
h1, h2, h3, h4, h5 { background: lightgray; }
code, var, code a { color: darkred;
background: whitesmoke; }
a { color: #000; }
pre { background: whitesmoke;
color: black;
/* mark longer code block with stripe on the left */
border-left: 5px solid darkred;
padding-left: 10px; }
pre.screen { background: #EEE;
border: 1px solid black; }
pre.programlisting { background: #EEEEEE;
border-left: 1px solid black;
border-top: 1px solid black; }
}
body {
margin: 1em 125px 0 10%;
line-height: 1.5em;
padding: 0 2em 1em 2em;
font: 13px Verdana,Arial, sans-serif
}
ul, dd, dl, dt { margin-top: 0; margin-bottom: 0; }
p, code, td, dl, dt {
line-height: 1.5em;
}
table {
font: inherit;
border-collapse: collapse;
}
th, td {
vertical-align: top;
}
h1, h2, h3 { padding-left: 15px; }
h4, h5 { padding-left: 5px; }
code, pre {
font-size: 1em;
font-family: monospace;
}
var {
font-size: 1em;
}
/* links inside code appear the same as the code itself */
code a {
font-weight: normal;
text-decoration: none;
}
/* but get an underline when hovering */
code a:hover {
text-decoration: underline;
}
/* ordinary links appear in bold */
a { font-weight: bold; }
pre.verbatim {
margin: 0 0 0 0;
}
pre {
overflow: auto;
}
pre.screen {
font-weight: bold;
padding: 0.5em;
}
pre.programlisting {
padding: 0.5em;
}
div p { padding: 0 2em }
li p { padding: 0; margin: 0 }
hr { display: none; }
div.funcsynopsis p {
text-indent: -2em;
}
div.variablelist {
padding: 0 2em;
}
.type, .funcsynopsis, .symbol {
font-family: monospace;
}
.type, .symbol, .replaceable {
white-space: nowrap;
}
-->
</style>
</head>
<body lang="en">
<div class="section-level-extent" id="System-building">
<div class="nav-panel">
<p>
Next: <a href="Operating-System-Interface.html#Operating-System-Interface" accesskey="n" rel="next">Operating System Interface</a>, Up: <a href="Extensions.html" accesskey="u" rel="up">Extensions</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h3 class="section" id="System-building-1">3.1 System building</h3>
<a class="index-entry-id" id="index-System-building"></a>
<a class="index-entry-id" id="index-Creating-executables-and-libraries"></a>
<ul class="mini-toc">
<li><a href="System-building.html#Compiling-with-ECL" accesskey="1">Compiling with ECL</a></li>
<li><a href="System-building.html#Compiling-with-ASDF" accesskey="2">Compiling with ASDF</a></li>
<li><a href="System-building.html#C-compiler-configuration" accesskey="3">C compiler configuration</a></li>
</ul>
<hr>
<div class="subsection-level-extent" id="Compiling-with-ECL">
<div class="nav-panel">
<p>
Next: <a href="System-building.html#Compiling-with-ASDF" accesskey="n" rel="next">Compiling with ASDF</a>, Up: <a href="System-building.html#System-building" accesskey="u" rel="up">System building</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Compiling-with-ECL-1">3.1.1 Compiling with ECL</h4>
<p>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 <a class="ref" href="Foreign-Function-Interface.html#Foreign-Function-Interface">Foreign Function Interface</a>. We explain file types
generated by some compilation approaches. For the examples,
a GNU/Linux system and gcc as a development environment are assumed.
</p>
<p>You can generate the following files with ECL:
</p>
<ol class="enumerate">
<li> Portable FASL file (.fasc)
</li><li> Native FASL file (.fas, .fasb)
</li><li> Object file (.o)
</li><li> Static library
</li><li> Shared library
</li><li> Executable file
</li></ol>
<p>Relations among them are depicted below:
</p>
<div class="float" id="fig_003afile_005ftypes">
<img class="image" src="figures/file-types.png" alt="figures/file-types">
<div class="caption"><p><strong class="strong">Figure 3.1: </strong>Build file types</p></div></div>
<ul class="mini-toc">
<li><a href="System-building.html#Portable-FASL-_0028fasc_0029" accesskey="1">Portable FASL</a></li>
<li><a href="System-building.html#Native-FASL" accesskey="2">Native FASL</a></li>
<li><a href="System-building.html#Object-file" accesskey="3">Object file</a></li>
<li><a href="System-building.html#Static-library" accesskey="4">Static library</a></li>
<li><a href="System-building.html#Shared-library" accesskey="5">Shared library</a></li>
<li><a href="System-building.html#Executable" accesskey="6">Executable</a></li>
<li><a href="System-building.html#Summary" accesskey="7">Summary</a></li>
</ul>
<hr>
<div class="subsubsection-level-extent" id="Portable-FASL-_0028fasc_0029">
<div class="nav-panel">
<p>
Next: <a href="System-building.html#Native-FASL" accesskey="n" rel="next">Native FASL</a>, Up: <a href="System-building.html#Compiling-with-ECL" accesskey="u" rel="up">Compiling with ECL</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Portable-FASL">3.1.1.1 Portable FASL</h4>
<a class="index-entry-id" id="index-Portable-FASL"></a>
<p>ECL provides two compilers (bytecodes compiler, and C/C++
compiler). Portable FASL files are built from source lisp files by the
bytecodes compiler. Generally FASC files are portable across
architectures and operating systems providing a 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.
</p>
<a class="index-entry-id" id="index-Building-Portable-FASL-file"></a>
<div class="example lisp">
<pre class="lisp-preformatted">;; install bytecodes compiler
(ext:install-bytecodes-compiler)
;; compile hello.lisp file to hello.fasc
(compile-file &quot;hello1.lisp&quot;)
(compile-file &quot;hello2.lisp&quot;)
;; reinitialize C/C++ compiler back
(ext:install-c-compiler)
;; FASC file may be loaded dynamically from lisp program
(load &quot;hello1.fasc&quot;)
;; ... concatenated into a bundle with other FASC
(with-open-file (output &quot;hello.fasc&quot;
:direction :output
:if-exists :supersede)
(ext:run-program
&quot;cat&quot; '(&quot;hello1.fasc&quot; &quot;hello2.fasc&quot;) :output output))
;; ... and loaded dynamically from lisp program
(load &quot;hello.fasc&quot;)
</pre></div>
<hr>
</div>
<div class="subsubsection-level-extent" id="Native-FASL">
<div class="nav-panel">
<p>
Next: <a href="System-building.html#Object-file" accesskey="n" rel="next">Object file</a>, Previous: <a href="System-building.html#Portable-FASL-_0028fasc_0029" accesskey="p" rel="prev">Portable FASL</a>, Up: <a href="System-building.html#Compiling-with-ECL" accesskey="u" rel="up">Compiling with ECL</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Native-FASL-1">3.1.1.2 Native FASL</h4>
<a class="index-entry-id" id="index-Native-FASL"></a>
<a class="index-entry-id" id="index-DLOPEN"></a>
<a class="index-entry-id" id="index-_002d_002denable_002dshared-_005bYES_007cno_005d"></a>
<p>If you want to make a library which is loaded dynamically from a lisp
program, you should choose the fasl file format. Under the hood native fasls
are just shared library files.
</p>
<p>This means you can load fasl files with <code class="code">dlopen</code> and initialize it
by calling a init function from C programs, but this is not an intended
usage. The recommended usage is to load fasl files by calling the load lisp
function. To work with <em class="emph">Native FASL files</em> ECL has to be compiled
with <code class="code">--enable-shared</code> configure option (enabled by default).
</p>
<p>Creating a fasl file from one lisp file is very easy.
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(compile-file &quot;hello.lisp&quot;)
</pre></div>
<p>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
<code class="code">c:build-fasl</code>.
</p>
<a class="index-entry-id" id="index-Building-native-FASL"></a>
<div class="example lisp">
<pre class="lisp-preformatted">;; generates hello.o
(compile-file &quot;hello.lisp&quot; :system-p t)
;; generates goodbye.o
(compile-file &quot;goodbye.lisp&quot; :system-p t)
;; generates hello-goodbye.fas
(c:build-fasl &quot;hello-goodbye&quot;
:lisp-files '(&quot;hello.o&quot; &quot;goodbye.o&quot;))
;; fasls may be built from mix of objects and libraries (both shared and
;; static)
(c:build-fasl &quot;mixed-bundle&quot;
:lisp-files '(&quot;hello1.o&quot; &quot;hello2.a&quot; &quot;hello3.so&quot;))
</pre></div>
<hr>
</div>
<div class="subsubsection-level-extent" id="Object-file">
<div class="nav-panel">
<p>
Next: <a href="System-building.html#Static-library" accesskey="n" rel="next">Static library</a>, Previous: <a href="System-building.html#Native-FASL" accesskey="p" rel="prev">Native FASL</a>, Up: <a href="System-building.html#Compiling-with-ECL" accesskey="u" rel="up">Compiling with ECL</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Object-file-1">3.1.1.3 Object file</h4>
<p>Object files work as an intermediate file format. If you want to compile
more than two lisp files, you might better to compile with a
<code class="code">:system-p t</code> option, which generates object files (instead of a
fasl).
</p>
<p>On linux systems, ECL invokes <code class="code">gcc -c</code> to generate object files.
</p>
<p>An object file consists of some functions in C:
</p>
<ul class="itemize mark-bullet">
<li>Functions corresponding to Lisp functions
</li><li>The initialization function which registers defined functions on the lisp environment
</li></ul>
<p>Consider the example below.
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(defun say-hello ()
(print &quot;Hello, world&quot;))
</pre></div>
<a class="index-entry-id" id="index-Object-file-internal-layout"></a>
<p>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:
</p>
<ul class="itemize mark-bullet">
<li><code class="code">static cl_object L1say_hello</code>:
&rsquo;say-hello&rsquo; function
</li><li><code class="code">ECL_DLLEXPORT void _eclwm2nNauJEfEnD_CLSxi0z(cl_object flag)</code>:
initialization function
</li></ul>
<p>In order to use these object files from your C program, you have to call
initialization functions before using lisp functions (such as
<code class="code">say-hello</code>). 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.
</p>
<p>ECL provides other user-friendly ways to generate compiled lisp programs
(as static/shared libraries or executables), and in each approach, object
files act as intermediate files.
</p>
<hr>
</div>
<div class="subsubsection-level-extent" id="Static-library">
<div class="nav-panel">
<p>
Next: <a href="System-building.html#Shared-library" accesskey="n" rel="next">Shared library</a>, Previous: <a href="System-building.html#Object-file" accesskey="p" rel="prev">Object file</a>, Up: <a href="System-building.html#Compiling-with-ECL" accesskey="u" rel="up">Compiling with ECL</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Static-library-1">3.1.1.4 Static library</h4>
<p>ECL can compile lisp programs to static libraries, which can be linked
with C programs. A static library is created by
<code class="code">c:build-static-library</code> with some compiled object files.
</p>
<a class="index-entry-id" id="index-Building-static-library"></a>
<div class="example lisp">
<pre class="lisp-preformatted">;; generates hello.o
(compile-file &quot;hello.lsp&quot; :system-p t)
;; generates goodbye.o
(compile-file &quot;goodbye.lsp&quot; :system-p t)
;; generates libhello-goodbye.a
(c:build-static-library &quot;hello-goodbye&quot;
:lisp-files '(&quot;hello.o&quot; &quot;goodbye.o&quot;)
:init-name &quot;init_hello_goodbye&quot;)
</pre></div>
<p>When you use a static/shared library, you have to call its init function. The
name of this function is specified by the <code class="code">:init-name</code> option. In this
example, it is then <code class="code">init_hello_goodbye</code>. The usage of this function is
shown below:
</p>
<a class="anchor" id="ecl_005finit_005fmodule"></a><a class="index-entry-id" id="index-ecl_005finit_005fmodule"></a>
<a class="index-entry-id" id="index-Initializing-static_002fshared-library-in-C_002fC_002b_002b"></a>
<div class="example">
<pre class="verbatim">#include &lt;ecl/ecl.h&gt;
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 ecl_init_module */
ecl_init_module(NULL, init_hello_goodbye);
/* ... */
/* shutdown the lisp runtime */
cl_shutdown();
return 0;
}
</pre></div>
<p>Because the program itself does not know the type of the init function,
a prototype declaration is inserted. After booting up the lisp
environment, it invokes <code class="code">init_hello_goodbye</code> via
<code class="code"><a class="ref" href="System-building.html#ecl_005finit_005fmodule">ecl_init_module</a></code>. <code class="code">init_hello_goodbye</code> takes an argument,
and <code class="code"><a class="ref" href="System-building.html#ecl_005finit_005fmodule">ecl_init_module</a></code> supplies an appropriate one. Now that the
initialization is finished, we can use functions and other stuff defined
in the library.
</p>
<p><strong class="strong">DEPRECATED</strong> <code class="code">read_VV</code> - equivalent to <code class="code"><a class="ref" href="System-building.html#ecl_005finit_005fmodule">ecl_init_module</a></code>
</p>
<hr>
</div>
<div class="subsubsection-level-extent" id="Shared-library">
<div class="nav-panel">
<p>
Next: <a href="System-building.html#Executable" accesskey="n" rel="next">Executable</a>, Previous: <a href="System-building.html#Static-library" accesskey="p" rel="prev">Static library</a>, Up: <a href="System-building.html#Compiling-with-ECL" accesskey="u" rel="up">Compiling with ECL</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Shared-library-1">3.1.1.5 Shared library</h4>
<p>Almost the same as with a static library. The user has to use
<code class="code">c:build-shared-library</code>:
</p>
<a class="index-entry-id" id="index-Building-shared-library"></a>
<div class="example lisp">
<pre class="lisp-preformatted">;; generates hello.o
(compile-file &quot;hello.lsp&quot; :system-p t)
;; generates goodbye.o
(compile-file &quot;goodbye.lsp&quot; :system-p t)
;; generates libhello-goodbye.so
(c:build-shared-library &quot;hello-goodbye&quot;
:lisp-files '(&quot;hello.o&quot; &quot;goodbye.o&quot;)
:init-name &quot;init_hello_goodbye&quot;)
</pre></div>
<hr>
</div>
<div class="subsubsection-level-extent" id="Executable">
<div class="nav-panel">
<p>
Next: <a href="System-building.html#Summary" accesskey="n" rel="next">Summary</a>, Previous: <a href="System-building.html#Shared-library" accesskey="p" rel="prev">Shared library</a>, Up: <a href="System-building.html#Compiling-with-ECL" accesskey="u" rel="up">Compiling with ECL</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Executable-1">3.1.1.6 Executable</h4>
<p>ECL supports the generation of executable files. To create a standalone
executable from a lisp program, compile all lisp files to object
files. After that, calling <code class="code">c:build-program</code> creates the
executable:
</p>
<a class="index-entry-id" id="index-Building-executable"></a>
<div class="example lisp">
<pre class="lisp-preformatted">;; generates hello.o
(compile-file &quot;hello.lsp&quot; :system-p t)
;; generates goodbye.o
(compile-file &quot;goodbye.lsp&quot; :system-p t)
;; generates hello-goodbye
(c:build-program &quot;hello-goodbye&quot;
:lisp-files '(&quot;hello.o&quot; &quot;goodbye.o&quot;))
</pre></div>
<p>Like with native FASL, the program may be built also from libraries.
</p>
<hr>
</div>
<div class="subsubsection-level-extent" id="Summary">
<div class="nav-panel">
<p>
Previous: <a href="System-building.html#Executable" accesskey="p" rel="prev">Executable</a>, Up: <a href="System-building.html#Compiling-with-ECL" accesskey="u" rel="up">Compiling with ECL</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Summary-1">3.1.1.7 Summary</h4>
<p>In this section, some file types that can be compiled with ECL were
introduced. Each file type has an adequate purpose:
</p>
<ul class="itemize mark-bullet">
<li>Object file: intermediate file format for others
</li><li>Fasl files: loaded dynamically via the <code class="code">load</code> lisp function
</li><li>Static library: linked with and used from C programs
</li><li>Shared library: loaded dynamically and used from C programs
</li><li>Executable: standalone executable
</li></ul>
<p>ECL provides a high-level interface <code class="code">c:build-*</code> for each native
format. In case of <em class="emph">Portable FASL</em> the bytecodes compiler is needed.
</p>
<hr>
</div>
</div>
<div class="subsection-level-extent" id="Compiling-with-ASDF">
<div class="nav-panel">
<p>
Next: <a href="System-building.html#C-compiler-configuration" accesskey="n" rel="next">C compiler configuration</a>, Previous: <a href="System-building.html#Compiling-with-ECL" accesskey="p" rel="prev">Compiling with ECL</a>, Up: <a href="System-building.html#System-building" accesskey="u" rel="up">System building</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Compiling-with-ASDF-1">3.1.2 Compiling with ASDF</h4>
<p>For larger systems involving more complex file dependencies, or for systems
that are portable across different Common Lisp implementations, it may be
better to define systems using <a class="uref" href="https://common-lisp.net/project/asdf/">asdf</a>.
</p>
<p>ECL provides a useful extension for asdf called <code class="code">asdf:make-build</code>, which
offers an abstraction for building libraries directly from system definitions.
Note that this extension is only available in the ASDF that is shipped with
ECL; it may not be available from an ASDF installed from the system or from
Quicklisp.
</p>
<p>To download dependencies you may use
<a class="uref" href="https://www.quicklisp.org">Quicklisp</a> to load your system (with
dependencies defined). Make sure you can successfully load and run your
library in the ECL REPL (or <code class="code">*slime-repl*</code>). Don&rsquo;t worry about
other libraries loaded in your image ECL will only build and pack
libraries your project depends on (that is, all dependencies you put in
your <code class="code">.asd</code> file, and their dependencies - nothing more, despite
the fact that other libraries may be loaded).
</p>
<ul class="mini-toc">
<li><a href="System-building.html#Example-code-to-build" accesskey="1">Example code to build</a></li>
<li><a href="System-building.html#Build-it-as-an-single-executable" accesskey="2">Build it as an single executable</a></li>
<li><a href="System-building.html#Build-it-as-shared-library-and-use-in-C" accesskey="3">Build it as shared library and use in C</a></li>
<li><a href="System-building.html#Build-it-as-static-library-and-use-in-C" accesskey="4">Build it as static library and use in C</a></li>
</ul>
<hr>
<div class="subsubsection-level-extent" id="Example-code-to-build">
<div class="nav-panel">
<p>
Next: <a href="System-building.html#Build-it-as-an-single-executable" accesskey="n" rel="next">Build it as an single executable</a>, Up: <a href="System-building.html#Compiling-with-ASDF" accesskey="u" rel="up">Compiling with ASDF</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Example-code-to-build-1">3.1.2.1 Example code to build</h4>
<p>An example project is included in the ECL source distribution in the
<code class="code">examples/asdf_with_dependence/</code> directory.
</p>
<p>This project depends on the <code class="code">alexandria</code> library and consists of a system
definition (<code class="code">example-with-dep.asd</code>), package definition
(<code class="code">package.lisp</code>), and the actual library code (<code class="code">example.lisp</code>).
</p>
<p>Before following the steps below, you must
<a class="uref" href="https://asdf.common-lisp.dev/asdf/Configuring-ASDF-to-find-your-systems.html">configure ASDF to find your systems</a>.
You can either copy or symlink the example directory in one of the standard
ASDF locations, or push the path of the example directory to your
<code class="code">asdf:*central-registry*</code>, for example:
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(push &quot;./&quot; asdf:*central-registry*)
</pre></div>
<hr>
</div>
<div class="subsubsection-level-extent" id="Build-it-as-an-single-executable">
<div class="nav-panel">
<p>
Next: <a href="System-building.html#Build-it-as-shared-library-and-use-in-C" accesskey="n" rel="next">Build it as shared library and use in C</a>, Previous: <a href="System-building.html#Example-code-to-build" accesskey="p" rel="prev">Example code to build</a>, Up: <a href="System-building.html#Compiling-with-ASDF" accesskey="u" rel="up">Compiling with ASDF</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Build-it-as-an-single-executable-1">3.1.2.2 Build it as an single executable</h4>
<p>Use this in the REPL to make an executable:
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(asdf:make-build :example-with-dep
:type :program
:move-here #P&quot;./&quot;
:epilogue-code '(progn (example:test-function 5)
(si:exit)))
</pre></div>
<p>Here the <code class="code">:epilogue-code</code> is executed after loading our library;
we can use arbitrary Lisp forms here. You can also put this code in
your Lisp files and directly build them without this
<code class="code">:epilogue-code</code> option to achieve the same result. Running the
program in a console will display the following and exit:
</p>
<div class="example">
<pre class="example-preformatted">Factorial of 5 is: 120
</pre></div>
<hr>
</div>
<div class="subsubsection-level-extent" id="Build-it-as-shared-library-and-use-in-C">
<div class="nav-panel">
<p>
Next: <a href="System-building.html#Build-it-as-static-library-and-use-in-C" accesskey="n" rel="next">Build it as static library and use in C</a>, Previous: <a href="System-building.html#Build-it-as-an-single-executable" accesskey="p" rel="prev">Build it as an single executable</a>, Up: <a href="System-building.html#Compiling-with-ASDF" accesskey="u" rel="up">Compiling with ASDF</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Build-it-as-shared-library-and-use-in-C-1">3.1.2.3 Build it as shared library and use in C</h4>
<p>Use this in the REPL to make a shared library:
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(asdf:make-build :example-with-dep
:type :shared-library
:move-here #P&quot;./&quot;
:monolithic t
:init-name &quot;init_dll_example&quot;)
</pre></div>
<p>Here <code class="code">:monolithic t</code> means that ECL will compile the library and
all its dependencies into a single library named
<code class="code">example-with-dep--all-systems.so</code>. The <code class="code">:move-here</code>
parameter is self-explanatory. <code class="code">:init-name</code> sets the name of the
initialization function. Each library linked from C/C++ code must be
initialized, and this is a mechanism to specify the initialization
function&rsquo;s name.
</p>
<p>To use it, we write a simple C program:
</p>
<div class="example">
<pre class="verbatim">/* test.c */
#include &lt;ecl/ecl.h&gt;
extern void init_dll_example(cl_object);
int main (int argc, char **argv) {
cl_boot(argc, argv);
ecl_init_module(NULL, init_dll_example);
/* do things with the Lisp library */
cl_eval(c_string_to_object(&quot;(example:test-function 5)&quot;));
cl_shutdown();
return 0;
}
</pre></div>
<p>Compile the file using a standard C compiler (note we&rsquo;re linking to
<code class="code">libecl.so</code> with <code class="code">-lecl</code>, which provides the lisp
runtime<a class="footnote" id="DOCF3" href="System-building.html#FOOT3"><sup>3</sup></a>):
</p>
<div class="example">
<pre class="example-preformatted">gcc test.c example-with-dep--all-systems.so -o test -lecl
</pre></div>
<p>If ECL is installed in a non-standard location you may need to provide
flags for the compiler and the linker. You may read them with:
</p>
<div class="example">
<pre class="example-preformatted">ecl-config --cflags
ecl-config --libs
</pre></div>
<p>Since our shared object is not in the standard location, you need to
provide <code class="code">LD_LIBRARY_PATH</code> pointing to the current directory to
run the application:
</p>
<div class="example">
<pre class="example-preformatted">LD_LIBRARY_PATH=`pwd` ./test
</pre></div>
<p>This will show:
</p>
<div class="example">
<pre class="example-preformatted">Factorial of 5 is: 120
</pre></div>
<p>You can also build all dependent libraries separately as a few
<code class="code">.so</code> files and link them together. For example, if you are
building a library called <code class="code">complex-example</code>, that depends on
<code class="code">alexandria</code> and <code class="code">cl-fad</code>, you can do the following (in the
REPL):
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(asdf:make-build :complex-example
:type :shared-library
:move-here #P&quot;./&quot;
:init-name &quot;init_example&quot;)
(asdf:make-build :alexandria
:type :shared-library
:move-here #P&quot;./&quot;
:init-name &quot;init_alexandria&quot;)
(asdf:make-build :cl-fad
:type :shared-library
:move-here #P&quot;./&quot;
:init-name &quot;init_fad&quot;)
(asdf:make-build :bordeaux-threads
:type :shared-library
:move-here #P&quot;./&quot;
:init-name &quot;init_bt&quot;)
</pre></div>
<p>Note that we haven&rsquo;t specified <code class="code">:monolithic t</code>, so we need to build
<code class="code">bordeaux-threads</code> as well because <code class="code">cl-fad</code> depends on it. The
building sequence doesn&rsquo;t matter and the resultant <code class="code">.so</code> files can
also be used in your future programs if these libraries are not
modified.
</p>
<p>We need to initialize all these modules using <code class="code"><a class="ref" href="System-building.html#ecl_005finit_005fmodule">ecl_init_module</a></code>
in the correct order. (<code class="code">bordeaux-threads</code> must be initialized
before <code class="code">cl-fad</code>; <code class="code">cl-fad</code> and <code class="code">alexandria</code> must be
initialized before <code class="code">complex-ecample</code>.)
</p>
<p>Here is a code snippet (not a full program):
</p>
<div class="example">
<pre class="example-preformatted">extern void init_fad(cl_object);
extern void init_alexandria(cl_object);
extern void init_bt(cl_object);
extern void init_example(cl_object);
/* call these *after* cl_boot(argc, argv);
if B depends on A, you should first init A then B. */
ecl_init_module(NULL, init_bt);
ecl_init_module(NULL, init_fad);
ecl_init_module(NULL, init_alexandria);
ecl_init_module(NULL, init_example);
</pre></div>
<hr>
</div>
<div class="subsubsection-level-extent" id="Build-it-as-static-library-and-use-in-C">
<div class="nav-panel">
<p>
Previous: <a href="System-building.html#Build-it-as-shared-library-and-use-in-C" accesskey="p" rel="prev">Build it as shared library and use in C</a>, Up: <a href="System-building.html#Compiling-with-ASDF" accesskey="u" rel="up">Compiling with ASDF</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Build-it-as-static-library-and-use-in-C-1">3.1.2.4 Build it as static library and use in C</h4>
<p>To build a static library, use:
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(asdf:make-build :example-with-dep
:type :static-library
:move-here #P&quot;./&quot;
:monolithic t
:init-name &quot;init_example&quot;)
</pre></div>
<p>This will generate <code class="code">example-with-dep--all-systems.a</code> in the
current directory which we need to initialize with the
<code class="code">init_example</code> function. Compile it using:
</p>
<div class="example">
<pre class="example-preformatted">gcc test.c example-with-dep--all-systems.a -o test-static -lecl
</pre></div>
<p>Then run it:
</p>
<div class="example">
<pre class="example-preformatted">./test-static
</pre></div>
<p>This will show:
</p>
<div class="example">
<pre class="example-preformatted">Factorial of 5 is: 120
</pre></div>
<p>Note we don&rsquo;t need to pass the current path in <code class="code">LD_LIBRARY_PATH</code>
here, since our Lisp library is statically bundled with the executable.
The result is the same as the shared library example above. You can also
build all dependent libraries separately as static libraries.
</p>
<hr>
</div>
</div>
<div class="subsection-level-extent" id="C-compiler-configuration">
<div class="nav-panel">
<p>
Previous: <a href="System-building.html#Compiling-with-ASDF" accesskey="p" rel="prev">Compiling with ASDF</a>, Up: <a href="System-building.html#System-building" accesskey="u" rel="up">System building</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="C-compiler-configuration-1">3.1.3 C compiler configuration</h4>
<p>ECL provides some global variables to customize which C compiler and
compiler options to use:
</p>
<ul class="mini-toc">
<li><a href="System-building.html#Compiler-flags" accesskey="1">Compiler flags</a></li>
<li><a href="System-building.html#Compiler-_0026-Linker-programs" accesskey="2">Compiler &amp; Linker programs</a></li>
</ul>
<div class="subsubsection-level-extent" id="Compiler-flags">
<h4 class="subsubsection">3.1.3.1 Compiler flags</h4>
<p>It is not required to surround the compiler flags with quotes or use
slashes before special characters.
</p>
<dl class="first-deftypevr first-deftypevar-alias-first-deftypevr">
<dt class="deftypevr deftypevar-alias-deftypevr" id="index-c_003a_002auser_002dcc_002dflags_002a"><span class="category-def">Variable: </span><span><code class="def-type">string</code> <strong class="def-name">c:*user-cc-flags*</strong><a class="copiable-link" href='System-building.html#index-c_003a_002auser_002dcc_002dflags_002a'> &para;</a></span></dt>
<dd><p>Flags and options to be passed to the C compiler when building FASL,
shared libraries and standalone programs.
</p></dd></dl>
<dl class="first-deftypevr first-deftypevar-alias-first-deftypevr">
<dt class="deftypevr deftypevar-alias-deftypevr" id="index-c_003a_002auser_002dlinker_002dflags_002a"><span class="category-def">Variable: </span><span><code class="def-type">string</code> <strong class="def-name">c:*user-linker-flags*</strong><a class="copiable-link" href='System-building.html#index-c_003a_002auser_002dlinker_002dflags_002a'> &para;</a></span></dt>
<dd><p>Flags for options (e.g. <code class="code">-Wl,foo</code> flags, usually in the
<code class="code">$LDFLAGS</code> variable in autoconf) to be passed to the linker when
building FASL, shared libraries and standalone programs.
</p></dd></dl>
<dl class="first-deftypevr first-deftypevar-alias-first-deftypevr">
<dt class="deftypevr deftypevar-alias-deftypevr" id="index-c_003a_002auser_002dlinker_002dlibs_002a"><span class="category-def">Variable: </span><span><code class="def-type">string</code> <strong class="def-name">c:*user-linker-libs*</strong><a class="copiable-link" href='System-building.html#index-c_003a_002auser_002dlinker_002dlibs_002a'> &para;</a></span></dt>
<dd><p>Flags for libraries (e.g. <code class="code">-lfoo</code> flags, usually in the
<code class="code">$LIBS</code> variable in autoconf) to be passed to the linker when
building FASL, shared libraries and standalone programs.
</p></dd></dl>
<dl class="first-deftypevr first-deftypevar-alias-first-deftypevr">
<dt class="deftypevr deftypevar-alias-deftypevr" id="index-c_003a_002acc_002doptimize_002a"><span class="category-def">Variable: </span><span><code class="def-type">string</code> <strong class="def-name">c:*cc-optimize*</strong><a class="copiable-link" href='System-building.html#index-c_003a_002acc_002doptimize_002a'> &para;</a></span></dt>
<dd><p>Optimize options to be passed to the C compiler.
</p></dd></dl>
<dl class="first-deftypevr first-deftypevar-alias-first-deftypevr">
<dt class="deftypevr deftypevar-alias-deftypevr" id="index-c_003a_002auser_002dld_002dflags_002a"><span class="category-def">Variable: </span><span><code class="def-type">string</code> <strong class="def-name">c:*user-ld-flags*</strong><a class="copiable-link" href='System-building.html#index-c_003a_002auser_002dld_002dflags_002a'> &para;</a></span></dt>
<dd><p><strong class="strong">DEPRECATED</strong> Flags and options to be passed to the linker when
building FASL, shared libraries and standalone programs.
</p></dd></dl>
</div>
<div class="subsubsection-level-extent" id="Compiler-_0026-Linker-programs">
<h4 class="subsubsection">3.1.3.2 Compiler &amp; Linker programs</h4>
<dl class="first-deftypevr first-deftypevar-alias-first-deftypevr">
<dt class="deftypevr deftypevar-alias-deftypevr" id="index-c_003a_003a_002acc_002a"><span class="category-def">Variable: </span><span><code class="def-type">string</code> <strong class="def-name">c::*cc*</strong><a class="copiable-link" href='System-building.html#index-c_003a_003a_002acc_002a'> &para;</a></span></dt>
<dd><p>This variable controls how the C compiler is invoked by ECL. One can
set the variable appropriately adding for instance flags which the C
compiler may need to exploit special hardware features (e.g. a
floating point coprocessor).
</p></dd></dl>
<dl class="first-deftypevr first-deftypevar-alias-first-deftypevr">
<dt class="deftypevr deftypevar-alias-deftypevr" id="index-c_003a_003a_002ald_002a"><span class="category-def">Variable: </span><span><code class="def-type">string</code> <strong class="def-name">c::*ld*</strong><a class="copiable-link" href='System-building.html#index-c_003a_003a_002ald_002a'> &para;</a></span></dt>
<dd><p>This variable controls the linker which is used by ECL.
</p></dd></dl>
<dl class="first-deftypevr first-deftypevar-alias-first-deftypevr">
<dt class="deftypevr deftypevar-alias-deftypevr" id="index-c_003a_003a_002aranlib_002a"><span class="category-def">Variable: </span><span><code class="def-type">string</code> <strong class="def-name">c::*ranlib*</strong><a class="copiable-link" href='System-building.html#index-c_003a_003a_002aranlib_002a'> &para;</a></span></dt>
<dd><p>Name of the &lsquo;ranlib&rsquo; program on the hosting platform.
</p></dd></dl>
<dl class="first-deftypevr first-deftypevar-alias-first-deftypevr">
<dt class="deftypevr deftypevar-alias-deftypevr" id="index-c_003a_003a_002aar_002a"><span class="category-def">Variable: </span><span><code class="def-type">string</code> <strong class="def-name">c::*ar*</strong><a class="copiable-link" href='System-building.html#index-c_003a_003a_002aar_002a'> &para;</a></span></dt>
<dd><p>Name of the &lsquo;ar&rsquo; program on the hosting platform.
</p></dd></dl>
<dl class="first-deftypevr first-deftypevar-alias-first-deftypevr">
<dt class="deftypevr deftypevar-alias-deftypevr" id="index-c_003a_003a_002aecl_002dinclude_002ddirectory_002a"><span class="category-def">Variable: </span><span><code class="def-type">string</code> <strong class="def-name">c::*ecl-include-directory*</strong><a class="copiable-link" href='System-building.html#index-c_003a_003a_002aecl_002dinclude_002ddirectory_002a'> &para;</a></span></dt>
<dd><p>Directory where the ECL header files for the target platform are located.
</p></dd></dl>
<dl class="first-deftypevr first-deftypevar-alias-first-deftypevr">
<dt class="deftypevr deftypevar-alias-deftypevr" id="index-c_003a_003a_002aecl_002dlibrary_002ddirectory_002a"><span class="category-def">Variable: </span><span><code class="def-type">string</code> <strong class="def-name">c::*ecl-library-directory*</strong><a class="copiable-link" href='System-building.html#index-c_003a_003a_002aecl_002dlibrary_002ddirectory_002a'> &para;</a></span></dt>
<dd><p>Directory where the ECL library files for the target platform are located.
</p></dd></dl>
</div>
</div>
</div>
<div class="footnotes-segment">
<hr>
<h4 class="footnotes-heading">Footnotes</h4>
<h5 class="footnote-body-heading"><a id="FOOT3" href="System-building.html#DOCF3">(3)</a></h5>
<p>You may also link ECL runtime statically. That is not
covered in this walkthrough.</p>
</div>
<hr>
<div class="nav-panel">
<p>
Next: <a href="Operating-System-Interface.html#Operating-System-Interface" accesskey="n" rel="next">Operating System Interface</a>, Up: <a href="Extensions.html" accesskey="u" rel="up">Extensions</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
</body>
</html>