@c =================================================================== @c
@c    serrano/prgm/project/bigloo/manuals/library.texi                 @c
@c    ------------------------------------------------------------     @c
@c    Author      :  Manuel Serrano                                    @c
@c    Creation    :  Mon Jun 15 15:00:35 1998                          @c
@c    Last change :  Tue Nov 13 06:13:38 2001 (serrano)                @c
@c    ------------------------------------------------------------     @c
@c    Bigloo libraries                                                 @c
@c =================================================================== @c

@c ------------------------------------------------------------------- @c
@c    Libraries                                                        @c
@c ------------------------------------------------------------------- @c
@node Bigloo Libraries, Extending the Runtime System, Java Interface, Top
@comment  node-name,  next,  previous,  up
@chapter Bigloo Libraries
@cindex libraries

Bigloo libraries are collections of global bindings (global variables and
global functions). Bigloo libraries are built on the top of the host
operating system (e.g. Unix) libraries. Because Bigloo uses modules, a
library is not only a bundle of compiled codes and memory locations. A
Bigloo library is split into several files:

@itemize @bullet
@item one @emph{heap} that describes the variables and functions of the library.
@item several host library files (safe and unsafe versions of the compilation
and also @emph{eval libraries} that contain the code that binds the
variables and functions to the evaluator).
@item possibly, C header files.
@item possibly, an initialization file.
@end itemize

Let's consider, for example, a library that implements the
@code{format} Common Lisp facility. Let's suppose we name this library
@code{bformat} and that the library number is
@code{1.0}. Using a Unix machine, the Bigloo library will consist of
the following files:

@itemize @bullet
@item @code{bformat.heap}: the heap file.
@item @code{bformat.init}: the initialization file.
@item @code{libbformat_s-1.0.a}, @code{libbformat_s-1.0.so}, 
 @code{libbformat_u-1.0.a}, @code{libbformat_u-1.0.so},
 @code{libbformat_eu-1.0.so}, and @code{libbformat_es-1.0.so}::
the Unix library files. The file names with a @code{_u} are libraries compiled 
in @emph{unsafe} and @emph{optimized} mode. By convention the library using
the @code{_s} suffix are @emph{safe} libraries, @code{_p} are profiling
libraries, @code{_d} debug libraries, @code{_es} and @code{_eu} eval libraries.
@item @code{bformat.h}: an include file.
@end itemize

@c ------------------------------------------------------------------- @c
@c    Compiling and linking with a library                             @c
@c ------------------------------------------------------------------- @c
@section Compiling and linking with a library
@cindex compiling and linking with a library
From the user standpoint, using a library can be made two ways:

@itemize @bullet
@item Using the Bigloo @code{-library @var{lib-name}} option where 
@var{lib-name} is the name of the Bigloo library (not the name of one 
of the Unix files implementing the library). The name of the library
must be @emph{lower case}. For instance:

@display
$ bigloo foo.scm -library bformat
@end display

@item Using the module clause @code{library}. This second solution avoids
using a special compilation option. For instance, this module will
automatically compile and link with the @code{bformat} library:

@smalllisp
(module foo
   (library bformat))

...
(format ...)
@end smalllisp
@end itemize

When a Bigloo library @code{@var{lib}} is used, Bigloo automatically
searches for a file called @code{@var{lib}.init} (the "init file").
If such a file exits, it is loaded at @emph{compile-time}. For instance, the init file
may be used to specify compilation flags or to define macros used by
the compiler. The initialization file may affect any of the global
parameters of the Bigloo compiler.  For instance, a Bigloo library
supporting SSL connections would likely need a native
library. Setting the compiler variable @code{*ld-post-options*} has
this effect. For instance, one may define an initialization file such
as:

@smalllisp
(cond-expand
   (bigloo-compile
    (set! *ld-post-options* (string-append "-lssl " *ld-post-options*)))
   (bigloo-eval
    #unspecified))
@end smalllisp

When a Bigloo library @code{lib} is used, the Bigloo linker
automatically looks at a library to be linked against the
application. The name of the file containing the library depends on
the operating system and the back-end used. For instance, under Unix,
for a library called @emph{NAME}, the Bigloo linker searches for a
file called @code{lib@emph{NAME}_[s|u]-@emph{VERSION}.a} or
@code{lib@emph{NAME}_[s|u]-@emph{VERSION}.@emph{DYNLIB-SUFFIX}} in the
compilation linker path when using the native back-end. It searches
for a file @code{@emph{NAME}_[s|u]-@emph{VERSION}.zip} when the JVM
back-end is used.

This default @emph{NAME} can be overridden in the initialization
file. The function @code{declare-library!} associates a
Bigloo library name and a system name. 

@deffn {library procedure} declare-library! ident [attributes]
All the attributes are optional.

@itemize @bullet
@item @code{version:} the version number of the library. This defaults
to the Bigloo version number.
@item @code{basename:} the base of the filename containing the library.
This defaults to the library name.
@item @code{srfi:} a list of symbols denoting the SRFI 0 features implemented
 by this library. Registered SRFIs may be tested by the @code{cond-expand} 
 form (@pxref{SRFIs}). This defaults to an empty list.
@item @code{dlopen-init:} a function to be invoked when the library is 
 dynamically loaded using the function @code{dynamic-load}. This defaults
to @code{#f}.
@item @code{module-init:} a module to be initialized when the library is
 loaded. This defaults to @code{#f}.
@item @code{eval-init:} a module to be initialized for binding the library
 exports in the interpreter. This defaults to @code{#f}.
@item @code{class-init:} the JVM or .NET class name containing the module
 to be initialized. This defaults to @code{#f}.
@item @code{eval-init:} the JVM or .NET class name containing the module
 to be initialized for eval. This defaults to @code{#f}.
@item @code{init:} a function to be invoked when a library is loaded.
 This defaults to @code{#f}.
@item @code{eval:} a function to be invoked when a library is loaded by
 the interpreter. This defaults to @code{#f}.
@item @code{eval:} a function to be invoked when a library is loaded by
 the interpreter. This defaults to @code{#f}.
@end itemize

Examples:

@itemize @bullet
@item The following declares a library named @code{foo}. When loaded,
the Bigloo runtime system will seek file named @code{libfoo_s-3.4a.so}, 
@code{libfoo_u-3.4a.so}, @code{libfoo_es-3.4a.so}, and @code{libfoo_eu-3.4a.so}.
@smalllisp
(declare-library! 'foo) 
@end smalllisp

@item The following declares a library named @code{pthread}. When loaded,
the Bigloo runtime system will seek a file named
@code{libbigloopth_s-1.1a.so}, @code{libbigloopth_u-1.1a.so},
@code{libbigloopth_es-1.1a.so}, @code{libbigloopth_eu-1.1a.so}. Once
the library loaded, the SRFI-0 features @code{pthread} and
@code{srfi-18} will be bound. When loading the library, the two
modules @code{__pth_thread} and @code{__pth_makelib} will be
initialized. In the JVM version these modules are compiled in the
classes @code{"bigloo.pthread.pthread"} and
@code{"bigloo.pthread.make_lib"}.

@smalllisp
(declare-library! 'pthread 
                  :basename "bigloopth" 
                  :version "1.1a"
                  :srfi '(pthread srfi-18)
                  :module-init '__pth_thread
                  :module-eval '__pth_makelib
                  :class-init "bigloo.pthread.pthread"
		  :class-eval "bigloo.pthread.make_lib")
@end smalllisp

@end itemize

@end deffn


@deffn {library procedure} library-translation-table-add! ident name
@deffnx {library procedure} library-translation-table-add! ident name version
@deffnx {library procedure} library-translation-table-add! ident name version :dlopen-init initsym

The function @code{library-translation-table-add!} is obsolete. It should
no longer be used in new code. It is totally subsumed by
@code{declare-library!}. The function @code{library-translation-table-add!}
is still documented for enabling readers to understand old Bigloo source
code.

This function registers a @var{name} for the library @var{id}. An optional
@var{version} can be specified. The optional named argument @code{dlopen-init}
gives the base name of the initialization entry point of a library.

Imagine that we would like to name our @code{bformat} library
@code{bigloobformat}. This can be achieved by adding the following
expression in the initialization file.

@smalllisp
(library-translation-table-add! 'bformat "bigloobformat")
@end smalllisp

Using this translation, on a Unix platform, the library used during
the linking will be named:
@code{libbigloobformat_s-<BIGLOO-VERSION>.a}. In order to change the
@code{<BIGLOO-VERSION>} to another suffix, such as @code{1.0}, one may use:

@smalllisp
(library-translation-table-add! 'bformat "bigloobformat" "1.0")
@end smalllisp

In such a case, the library searched will be named
@code{libbigloobformat_s-1.0.a}.

Specifying a @code{#f} prevents the insertion of any suffix. Hence,

@smalllisp
(library-translation-table-add! 'bformat "bigloobformat" #f)
@end smalllisp

instructs the compiler to look at a library named
@code{libbigloobformat_s.a}.

@end deffn

@c ------------------------------------------------------------------- @c
@c    Library and inline functions                                     @c
@c ------------------------------------------------------------------- @c
@section Library and inline functions
@cindex Library and inline functions

It is illegal for libraries to include inline functions that make use of
new foreign types. By "new foreign type", we mean foreign types that are
defined inside the library. A library may contain inline functions but
these inline functions must not call functions using foreign types in
their prototypes. Including inline functions making use of foreign C
types will make the compiler fail when compiling user code, prompting
type errors. A library may contains non-inline
functions that make use of new foreign types.

@c ------------------------------------------------------------------- @c
@c    library and eval                                                 @c
@c ------------------------------------------------------------------- @c
@section library and eval
@cindex library and eval

The function @code{library-load} loads a library in the interpreter.

@deffn {library procedure} library-multithread-set!
Multi-threaded and single-threaded cannot be mixed. An application must
use exclusively one kind of library. This function forces
the specie of library to load dynamically. Normally this is set automatically
and this function should be used only on exceptional situations.
@end deffn

@deffn {library procedure} library-exists? ident . path
Checks if the library @var{ident} exists for the current back-end.

The regular Bigloo library paths are scanned unless optional @var{path}s
are sent to the function.
@end deffn

@deffn {library procedure} bigloo-library-path
@deffnx {library procedure} bigloo-library-path-set!
These functions get and set the default path (a list of strings)
for loading libraries. 
@end deffn

@deffn {library procedure} library-load ident . path
Loads a library in the interpreter. In addition to dynamically loading
the library, this function tries to load the @code{_es} version of the library if it is linked
against the safe Bigloo library version or the
@code{_eu} version if it is linked against the unsafe
version of the Bigloo library.

Searches for libraries occur in the regular Bigloo library paths
unless optional @var{path}s are sent to the function.

This version may be used for automatically exporting bindings to the
interpreter. In general, the @code{_es} and @code{_eu} libraries are
simple libraries that contain only one module, the module that is used
to build the heap-file. For instance, let's consider an implementation
of a library for SSL programming. This library is composed of a single
implementation module @code{__ssl_ssl}. The library is build using a
heap file:

@smalllisp
(module __ssl_makelib
   (import __ssl_ssl))
@end smalllisp

Changing this file for:

@smalllisp
(module __ssl_makelib
   (import __ssl_ssl)
   (eval   (export-all)))
@end smalllisp

enables the construction of the @code{_es} and @code{_eu} libraries.

When the system loads a dynamic library, it @emph{initializes} it. 
For that it expects to find @emph{initialization entry points} in the dynamic
libraries that are named after the library's name. More precisely, for
the @code{LIB_s} library, the loader seeks the entry point named
@code{"LIB_s"} and for the @code{LIB_es}, it seeks @code{"LIB_es"}.
The name of the initialization entry of a library can be changed using
the @code{declare-library!} function. If that named is changed,
one module of the library must contain an @code{option} module clause
that sets the variable @code{*dlopen-init*} with the name of the initialization
entry point.

Since Bigloo 3.1a, the runtime system supports a better way for
initializing libraries. @emph{Initialization} modules can be associated
with a library. When loaded, these modules are automatically initialized.
This new method fits harmoniously with the Bigloo initialization process
and it relieves users from any requirement to annotate the source code of the library.
@c I don't really understand the original sentence.  This is my best guess. #c

For instance, if a library initialization file contains the following
declaration:

@smalllisp
(declare-library! 'foo :module-init 'foo)
@end smalllisp

Then, the library must implement the @code{foo} module.

@smalllisp
(module foo
  (import ...)
  ...)
@end smalllisp

In addition if the library binds variables, functions, or classes in the
interpreter then, an @code{eval-init} clause must be added to the
class declaration:

@smalllisp
(declare-library! 'foo :module-init 'foo :eval-init 'foo-eval)
@end smalllisp

Then, the module @code{foo-eval} must be implemented in the 
@code{libfoo_es} and @code{libfoo_eu} libraries.

@smalllisp
(module foo-eval
  (import ...)
  (eval (export-all)))
@end smalllisp
@end deffn

The standard distribution contains examples of such constructions. In
particular, the multi-threading libraries @code{pthread} and
@code{fthread} use this facility.

@c ------------------------------------------------------------------- @c
@c    library and repl                                                 @c
@c ------------------------------------------------------------------- @c
@section library and repl
@cindex library and repl

It is possible to implement a "read-eval-print-loop" that is extended
with the facilities implemented inside a library. In order to make
the variables, functions, and classes of a library visible from the
interpreter, the eval @code{library} module clause has to be used.
(@pxref{Module Declaration}) For instance, here is a module that 
implements a "repl" with the @code{format} facility available:

@smalllisp
(module format-repl
   (eval (library bformat))
   (library bformat))

;; a dummy reference to a facility of the format library
(let ((dummy format))
   (repl))
@end smalllisp


Alternatively, libraries can be explicitly loaded using the 
@code{library-load}@ function such as:

@smalllisp
(module format-repl)

;; a dummy reference to a facility of the format library
(let ((dummy format))
   (eval '(library-load 'bformat))
   (repl))
@end smalllisp


@c ------------------------------------------------------------------- @c
@c    Build a library                                                  @c
@c ------------------------------------------------------------------- @c
@section Building a library
@cindex Building a library

Build Bigloo libraries require several steps that are explained in
this section. This section shows how to create @emph{static} and
@emph{dynamic} (or @emph{shared}) libraries. However not that creating
a dynamic library highly dependent on the host operating system. Users
willing to create dynamic libraries on other operating systems should
use the @code{api} directory of the Bigloo source code tree as an
example.

@itemize @bullet
@item The first step is to build a @emph{library heap}. This is achieved
 using a special compilation mode: @code{-mkaddheap -mkaddlib -addheap -heap-library <ident>}. 
 That is, for your library you have to create a heap associated source file 
 that imports all the binding you want in your library. The heap source file
 must be @emph{excluded} from the source files that will be used to build
 the host library.

Suppose we have a unique source file, @code{bformat.scm} for our
library. The module clause of this source file is:

@smalllisp
(module __bformat
   (export (bformat fmt::bstring . args)
           bformat:version))

(define (bformat fmt . args)
   (apply format (string-replace fmt #\% #\~) args))

(define bformat:version 1.0)
@end smalllisp

Prior to compiling the library, we have to create the heap associated file
(let's name it @code{make_lib.scm}). This file could be:

@smalllisp
(module __make_lib
   (import (__bformat "bformat.scm"))
   (eval (export-all)))
@end smalllisp

Building it is simple:

@display
bigloo -unsafe -safee -q -mkaddheap -mkaddlib -heap-library bformat \
     make_lib.scm -addheap bformat.heap
@end display

The options @code{-mkaddheap} and @code{-mkaddlib} tell Bigloo that it 
is compiling an heap associated file. The option @code{-addheap} tells 
Bigloo the name of the heap file to be produced. The option 
@code{-heap-library} instructs the compiler for the library name to be 
included inside the heap file. This name is used for checking versions 
at run-time.

@item The second step is to compile all the library source file. These
compilation must be done using the @code{-mkaddlib} compilation mode. 
For example:

@display
bigloo -O3 -unsafe -safee -mkaddlib       \
   -cc gcc -fsharing -q -rm               \
   -unsafev bformat.scm -o bformat_u.o -c
bigloo -O3 -mkaddlib -g -cg -cc gcc       \
   -fsharing -q -rm                       \
   -unsafev bformat.scm -o bformat.o -c
@end display

The first compilation produces the @emph{unsafe} version the second the 
produced the @emph{debugging} version.

@item The third step is to build the host operating system libraries. There
is no portable way to do this. This operation may looks like:

@display
ar qcv libbigloobformat_s-1.0.a bformat.o
ranlib libbigloobformat_s-1.0.a
ld -G -o libbigloobformat_s-1.0.so bformat.o -lm -lc
ar qcv libbigloobformat_u-1.0.a bformat_u.o
ranlib libbigloobformat_u-1.0.a
ld -G -o libbigloobformat_u-1.0.so bformat_u.o -lm -lc
@end display

@item The fourth step consist in creating the @code{bformat_es} and 
@code{bformat_eu} libraries
for eval. For the unsafe version we use:

@display
bigloo -O3 -unsafe -safee -mkaddlib       \
   -cc gcc -fsharing -q -rm               \
   -unsafev make_lib.scm -o make_lib.o -c
ld -G -o libbigloobformat_eu-1.0.so make_lib.o -lm -lc
ar qcv libbigloobformat_eu-1.0.a make_lib.o
ranlib libbigloobformat_eu-1.0.a
@end display

For the safe version we do:

@display
bigloo -O3 -mkaddlib              \
   -cc gcc -fsharing -q -rm               \
   -unsafev make_lib.scm -o make_lib.o -c
ld -G -o libbigloobformat_es-1.0.so make_lib.o -lm -lc
ar qcv libbigloobformat_es-1.0.a make_lib.o
ranlib libbigloobformat_es-1.0.a
@end display


@item The last step is to create an initialization file @code{bformat.init}:

@smalllisp
(declare-library! 'bformat 
   :version "1.0"
   :srfi '(bformat)
   :basename "bigloobformat"
   :module-init '__bformat
   :module-eval '__make_lib
   :class-init "bigloo.bformat.__bformat"
   :class-eval "bigloo.bformat.__make_lib")
@end smalllisp

@end itemize

At this time, you are ready to use your library. For that, let's assume
the file @code{foo.scm}:

@smalllisp
(module foo
   (library bformat))

(bigloo-library-path-set! (cons (pwd) (bigloo-library-path)))
(print (bformat "Library path: %a" (bigloo-library-path)))

(eval '(library-load 'bformat))
(repl)
@end smalllisp

It can be compiled and executed with:

@display
bigloo foo.scm -L . -copt -L.
LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./a.out
@end display

The Bigloo distribution contains library exemplars that should probably
considered as a departure point for new libraries.

@c ------------------------------------------------------------------- @c
@c    Library and modules                                              @c
@c ------------------------------------------------------------------- @c
@section Library and modules
@cindex Library and modules

A Bigloo library may be composed of several Bigloo modules (even if in
our example only one module was used). The modules composing the library
are free to import each other. Nevertheless, someone designing a Bigloo
library should be aware that Bigloo importation creates dependences
between modules. A module @code{mod1} that imports a module @code{mod2}
depends on @code{mod2} because @code{mod1} requires @code{mod2} to be
initialized (i.e. @code{mod1} calls to the initialization function of
@code{mod2}). The result is that using @code{import} clauses inside
modules composing a library may create a lot of dependencies between the
object files that are used to build the associated Unix
library. Dependencies should be avoided because they make the Unix
linkers unable to produce small stand-alone programs. Instead of
@code{import} clauses, @code{use} clauses should be
preferred. @code{Use} clauses do not create dependencies because a
module @code{mod1} that @code{use}s a second module @code{mod2} does not
require @code{mod2} to be initialized. Of course, it may happen
situations where the initialization is mandatory and thus, the
@code{import} must not be replaced with a @code{use} clause. The source
code of the Bigloo library makes use of @code{import} and @code{use}
clauses. The Bigloo standard library should be studied as an example.

@c ------------------------------------------------------------------- @c
@c    Library and macros                                               @c
@c ------------------------------------------------------------------- @c
@section Library and macros
@cindex Library and macros

Bigloo libraries can export macros, expanders, and syntaxes but these
must be handled carefully. Macros (these also applies to expanders and
syntaxes) exported by modules are not visible by client code. Exported
macros have to be placed inside the initialization file. For instance,
if we change the definition of @code{bformat.init} file for:

@smalllisp
(declare-library! 'bformat 
   :version "1.0"
   :srfi '(bformat)
   :basename "bigloobformat"
   :module-init '__bformat
   :module-eval '__make_lib
   :class-init "bigloo.bformat.__bformat"
   :class-eval "bigloo.bformat.__make_lib")

(define-expander BFORMAT
   (lambda (x e)
      (match-case x
         ((?- (? (lambda (s) (and (string? s) (not (string-index s #\%))))) . ?a
)
          `(string-append ,@@(cdr x)))
         (else
          `(bformat ,@@(map (lambda (x) (e x e)) (cdr x)))))
@end smalllisp

At compile time the macro BFORMAT will be declared. Hence, we can change
the definition of @code{foo.scm} for:

@smalllisp
(module foo
   (library bformat))

(bigloo-library-path-set! (cons (pwd) (bigloo-library-path)))
(print (BFORMAT "library path: %a" (bigloo-library-path)))

(eval '(library-load 'bformat))
(repl)
@end smalllisp

@c ------------------------------------------------------------------- @c
@c    A complete library example                                       @c
@c ------------------------------------------------------------------- @c
@section A complete library example
@cindex A complete library example

For the means of an example let's suppose we want to design a Bigloo
library for 2d points. That library is made of three implementation
files: two C files, @code{cpoint.h} and @code{cpoint.c} and one Scheme
file @code{spoint.scm}. Here are defined the three files:

@noindent @code{cpoint.h}:
@smalllisp
struct point_2d @{
   double x, y;
@};
@end smalllisp

@noindent @code{cpoint.c}:
@smalllisp
#include <stdio.h>
#include "cpoint.h"

int print_point_2d( struct point_2d *pt ) @{
   printf( "<point-2d: %g, %g>", pt->x, pt->y );
@}
@end smalllisp

@noindent @code{spoint.scm}:
@smalllisp
(module __point
   (include "spoint.sch")
   (extern  (include "cpoint.h"))
   (export  (make-point::s-point_2d* ::double ::double)
            (print-point ::s-point_2d*)
            (point? ::obj)))

(define (make-point::s-point_2d* x::double y::double)
   (s-point_2d* x y))

(define (print-point p::s-point_2d*)
   (print_point_2d p))

(define (point? obj::obj)
   (s-point_2d*? obj)
   obj)
@end smalllisp

@noindent @code{makelib.scm}:

We want our library to be composed of the whole exported Scheme
functions. Thus the file to build the heap library could look like:

@smalllisp
(module __point_makelib
   (import __point)
   (eval (export-all)))
@end smalllisp


@noindent @code{point.init}:
Let's suppose that the @code{point} library requires the @code{libposix}
library. This means that any file linked with the @code{point} library
needs to be also linked with the @code{posix} library. Furthermore, 
programs making use of the @code{point} library needs to include the
@code{point.sch} file. That Scheme file needs in turn the C file 
@code{point.h} otherwise the produced C files won't compile. The need
for the @code{libposix} library and for the @code{point.h} file may be
specified inside the @code{point.init} file. For our current library,
the @code{point.init} file could look like:

@smalllisp
(declare-library! 'point 
                  :basename "point" 
                  :srfi '(point)
                  :eval-init '__point_makelib)

(set! *ld-options*
      (string-append "-L/usr/lib " *ld-options*))

(set! *bigloo-user-lib*
      (cons "-lm" *bigloo-user-lib*))

(set! *additional-include-foreign*
      (cons "cpoint.h" *additional-include-foreign*))
      
(define-macro (point x y)
   `(make-point ,x ,y))
@end smalllisp

This file updates some compilation variables (@code{*ld-options*},
@code{*bigloo-user-lib*}, @code{*additional-include-foreign*}) and
defines a macro: @code{point}. Because the @code{point.init} file will
be loaded each time a compilation require the @code{point} library is
spawned, user code are allowed to use the @code{point} macro. Here is an
example file making use of the @code{point} library:

@noindent @code{example.scm}
@smalllisp
(module example)

(let ((p (point 2.9 3.5)))
   (print "point?: " (point? p))
   (print "point?: " (point? 4))
   (print-point p)
   (print "done..."))
@end smalllisp

To conclude that example here is the @code{Makefile} used to compile
the @code{point} library, heap file and one example.

@display
# bigloo flags
BIGLOO          = bigloo
RELEASE		= `$(BIGLOO) -eval '(begin (print *bigloo-version*) (exit 0))'`
BHEAPFLAGS      = -unsafe -q -mkaddheap -mkaddlib -v2 -heap-library point
BCOMMONFLAGGS   = -mkaddlib -fsharing -q $(VERBOSE)        \
                  -copt '$(CCOMMONFLAGS)' -cc $(CC)
BSAFEFLAGS      = $(BCOMMONFLAGGS) -cg -O3 -g -cg -unsafev \
                  -eval '(set! *indent* 4)' -rm
BUNSAFEFLAGS    = $(BCOMMONFLAGS) -O4 -unsafe

# cigloo flags
CIGLOO          = cigloo

# cflags
CC              = gcc
CCOMMONFLAGS    = -I.
CSAFEFLAGS      = $(CCOMMONFLAGS)
CUNSAFEFLAGS    = $(CCOMMONFLAGS) -O2

# library objects
SAFE_OBJECT     = olib/spoint.o olib/cpoint.o
UNSAFE_OBJECT   = olib_u/spoint.o olib_u/cpoint.o

all: .afile heap lib example

.afile: spoint.scm makelib.scm
	bglafile $^ > $@@

heap: point.heap

point.heap: spoint.sch spoint.scm
	$(BIGLOO) $(BHEAPFLAGS) makelib.scm -addheap point.heap

lib: lib_u lib.a

lib.a: olib $(SAFE_OBJECT)
	ar qcv libpoint_s-$(RELEASE).a $(SAFE_OBJECT) 

lib_u: olib_u $(UNSAFE_OBJECT)
	ar qcv libpoint_u-$(RELEASE).a $(UNSAFE_OBJECT) 

olib:
	mkdir olib

olib_u:
	mkdir olib_u

olib_u/spoint.o olib/spoint.o: spoint.scm
	$(BIGLOO) $(BSAFEFLAGS) $(<F) -o $*.o -c

olib_u/cpoint.o olib/cpoint.o: cpoint.c
	$(CC) $(CSAFEFLAGS) $(<F) -o $*.o -c

spoint.sch: cpoint.h cpoint.c
	cigloo $^ > $@@

example: heap lib
	$(BIGLOO) -v2 -L . -library point \
            -static-bigloo example.scm -o example

clean:
	-/bin/rm -f point.heap
	-/bin/rm -f spoint.sch spoint.c
	-/bin/rm -fr olib olib_u
	-/bin/rm -f example example.c example.o
	-/bin/rm -f libpoint_s-$(RELEASE).a libpoint_u-$(RELEASE).a
@end display




