readme.org: add language fixes by tomek

This commit is contained in:
Daniel Kochmański 2017-07-25 08:53:28 +02:00
parent 3e19d40d40
commit 6a5dea524d

View file

@ -1,33 +1,34 @@
#+TITLE: Build an asdf system with dependencies #+TITLE: Build an asdf system with dependencies
#+AUTHOR: Bo Yao <icerove@gmail.com> #+AUTHOR: Bo Yao <icerove@gmail.com>
Besides the simple situation that we write Lisp without depending on First, let's disregard the simple situation in which we write Lisp
any other Lisp libraries. A more practical example is to build a without depending on any other Lisp libraries. A more practical
library which depends on other asdf systems. ECL provides a useful example is to build a library that depends on other asdf systems. ECL
extension for asdf called ~asdf:make-build~, which provides provides a useful extension for asdf called ~asdf:make-build~, which
abstraction for building libraries direclty from system offers an abstraction for building libraries directly from system
definitions. definitions.
To download dependencies you may use Quicklisp to load your system To download dependencies you may use Quicklisp to load your system
(with dependencies defined). Make sure you can successfully load and (with dependencies defined). Make sure you can successfully load and
run your library in ECL REPL (or ~*slime-repl*~). Don't worry about run your library in ECL REPL (or ~*slime-repl*~). Don't worry about
other libraries loaded in your image ECL will only build and pack other libraries loaded in your image ECL will only build and pack
libraries your project depends on (that is, all dependence you put in libraries your project depends on (that is, all dependencies you put
your ~.asd~ file, and their dependencies - nothing more, despite the in your ~.asd~ file, and their dependencies - nothing more, despite
fact that other libraries may be loaded). the fact that other libraries may be loaded).
** Example code to build ** Example code to build
We use a simple project depends on ~alexandria~ to demonstrate the We use a simple project that depends on ~alexandria~ to demonstrate
interface. Example consists of ~example-with-dep.asd~, ~package.lisp~ the interface. The example consists of ~example-with-dep.asd~,
and ~example.lisp~ (included in ~examples/asdf_with_dependence/~ ~package.lisp~ and ~example.lisp~ (included in the
directory in ECL source tree). Before any kind of build you need to ~examples/asdf_with_dependence/~ directory in the ECL source tree).
push full path of this directory to ~asdf:*central-registry*~ (or link Before any kind of build you need to push the full path of this
it in the location already recognized by ASDF). directory to ~asdf:*central-registry*~ (or link it in a location
already recognized by ASDF).
** Build it as an single executable ** Build it as a single executable
Use this in REPL to make a executable: Use this in REPL to make an executable:
#+BEGIN_SRC common-lisp #+BEGIN_SRC common-lisp
(asdf:make-build :example-with-dep (asdf:make-build :example-with-dep
@ -37,11 +38,11 @@ Use this in REPL to make a executable:
(si:exit))) (si:exit)))
#+END_SRC #+END_SRC
Here the ~:epilogue-code~ is what to do after loading our library, we Here the ~:epilogue-code~ is executed after loading our library; we
can use arbitrary Lisp forms here. You can also write this code in can use arbitrary Lisp forms here. You can also put this code in
your Lisp files and directly build them without this ~:epilogue-code~ your Lisp files and directly build them without this ~:epilogue-code~
option to have the same effect. Run the program in console will option to achieve the same result. Running the program in a console
display the following and exit: will display the following and exit:
#+BEGIN_SRC shell #+BEGIN_SRC shell
Factorial of 5 is: 120 Factorial of 5 is: 120
@ -59,13 +60,13 @@ Use this in REPL to make a shared library:
#+END_SRC #+END_SRC
Here ~:monolithic t~ means that ECL will compile the library and all Here ~:monolithic t~ means that ECL will compile the library and all
its dependencies into one library named its dependencies into a single library named
~example-with-dep--all-systems.so~. ~:move-here~ parameter is ~example-with-dep--all-systems.so~. The ~:move-here~ parameter is
self-explanatory. ~:init-name~ gives the name for initialization self-explanatory. ~:init-name~ sets the name of the initialization
function. Each library if linked from C/C++ code must be initialized function. Each library linked from C/C++ code must be initialized,
and this is a mechanism to specify the initialization function name. and this is a mechanism to specify the initialization function's name.
To use it, we use a simple C program: To use it, we write a simple C program:
#+BEGIN_SRC c #+BEGIN_SRC c
/* test.c */ /* test.c */
@ -86,14 +87,14 @@ int main (int argc, char **argv) {
#+END_SRC #+END_SRC
Compile file using standard C compiler (note linking to ~libecl.so~ Compile the file using a standard C compiler (note we're linking to
with ~-lecl~ which provides lisp runtime[fn:1]): ~libecl.so~ with ~-lecl~, which provides the lisp runtime[fn:1]):
#+BEGIN_SRC shell #+BEGIN_SRC shell
gcc test.c example-with-dep--all-systems.so -o test -lecl gcc test.c example-with-dep--all-systems.so -o test -lecl
#+END_SRC #+END_SRC
If ECL is installed in non-standard location you may need to provide 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: flags for the compiler and the linker. You may read them with:
#+BEGIN_SRC shell #+BEGIN_SRC shell
@ -102,7 +103,7 @@ ecl-config --libs
#+END_SRC #+END_SRC
Since our shared object is not in the standard location, you need to Since our shared object is not in the standard location, you need to
provice ~LD_LIBRARY_PATH~ pointing and the current directory to run provide ~LD_LIBRARY_PATH~ pointing to the current directory to run
the application: the application:
#+BEGIN_SRC shell #+BEGIN_SRC shell
@ -142,14 +143,15 @@ library called ~complex-example~, that depends on ~alexandria~ and
:init-name "init_bt") :init-name "init_bt")
#+END_SRC #+END_SRC
Note that we haven't specified ~:monolithic t~ so we need to build Note that we haven't specified ~:monolithic t~, so we need to build
~bordeaux-threads~ as well, because ~cl-fad~ depends on it. The ~bordeaux-threads~ as well because ~cl-fad~ depends on it. The
building sequence doesn't matter and the result ~.so~ files can also building sequence doesn't matter and the resultant ~.so~ files can
be used in your future program if these libraries are not modified. also be used in your future programs if these libraries are not
modified.
We need to initialize all these modules using ~ecl_init_module~ in the We need to initialize all these modules using ~ecl_init_module~ in the
correct order (~bordeaux-threads~ must be initialized before ~cl-fad~, correct order. (~bordeaux-threads~ must be initialized before ~cl-fad~;
~cl-fad~ and ~alexandria~ must be initialized before ~complex-ecample~). ~cl-fad~ and ~alexandria~ must be initialized before ~complex-ecample~.)
Here is a code snippet (not a full program): Here is a code snippet (not a full program):
#+BEGIN_SRC c #+BEGIN_SRC c
@ -166,7 +168,7 @@ ecl_init_module(NULL, init_alexandria);
ecl_init_module(NULL, init_example); ecl_init_module(NULL, init_example);
#+END_SRC #+END_SRC
** Build it as static library and use in C ** Build it as a static library and use in C
To build a static library, use: To build a static library, use:
#+BEGIN_SRC common-lisp #+BEGIN_SRC common-lisp
@ -177,9 +179,9 @@ To build a static library, use:
:init-name "init_example") :init-name "init_example")
#+END_SRC #+END_SRC
That will generate a ~example-with-dep--all-systems.a~ in current This will generate ~example-with-dep--all-systems.a~ in the current
directory and we need to initialize it with ~init_example~ directory which we need to initialize with the ~init_example~
function. And compile it using: function. Compile it using:
#+BEGIN_SRC shell #+BEGIN_SRC shell
gcc test.c example-with-dep--all-systems.a -o test-static -lecl gcc test.c example-with-dep--all-systems.a -o test-static -lecl
@ -197,10 +199,10 @@ This will show:
Factorial of 5 is: 120 Factorial of 5 is: 120
#+END_SRC #+END_SRC
Note we don't need to give current path in ~LD_LIBRARY_PATH~ here, Note we don't need to pass the current path in ~LD_LIBRARY_PATH~ here,
since our Lisp library is statically bundled to the executable. The since our Lisp library is statically bundled with the executable. The
result is same as the shared library example above. You can also build result is the same as the shared library example above. You can also
all dependent libraries separately to static libraries. build all dependent libraries separately as static libraries.
* Footnotes * Footnotes