For Vicare releases in the series 0.4
I have done a full overhauling of
the libraries infrastructure, along with code reorganisation. I have been working on
this for some time and procrastinating the end of the restructuring for weeks; now I
have whipped myself into finalising at least some of it. But there are still some
design decisions to be made, so more entries will follow on this subject. This
section is about what’s currently in the master branch, not the latest
Vicare release.
Some of the changes are backwards incompatible. Here is a quick list:
(ikarus)
and the libraries in the hierarchy
(ikarus system ---)
do not exist anymore. The core library is now only
(vicare)
and all the libraries are in the hierarchy (vicare ---)
.
(vicare)
has a version number, too; the full library name is:
(vicare (0 4 ?year ?month ?day))
where ?year, ?month and ?day are fixnums representing the date of the last build.
make all
from the build directory of
Vicare packages: the Scheme libraries are compiled; the Makefiles will be written
in such a way to allow parallel builds; on my system with Intel Core i5 I do:
$ make -j4 all && make -j4 check
all the time, and it speeds up building significantly.
.vicare-32bit-fasl .vicare-64bit-fasl
there is now a single fasl file extension: .fasl
.
$(prefix)/lib/vicare-scheme
and 64-bit fasl files under:
$(prefix)/lib64/vicare-scheme
(vicare libraries)
exports an api to perform library–related
operations.
Now some topic discussion.
Since the days of the Ikarus code base, there has been support for caching compiled libraries; other Scheme implementations have this feature (Guile, Mosh, Sagittarius, Ypsilon). It worked like this: we install source libraries in a system directory, for example:
and import them as usual:
(import (prefix (vicare posix) px.))
the first time we import a library: Vicare loads the source file and stores a compiled version in the cache directory, for example:
the second time we import a library Vicare loads the compiled file from the cache directory. Seems fine, but:
Back when I started getting the hang of preparing packages for Ikarus, I started including a Makefile rule to precompile all the installed source libraries in the cache; then I started to install both the source and binary files in system directories, side by side.
I nuked all of this. Starting with Vicare releases in the series 0.4
caching of compiled libraries will not be supported anymore. It is possible to
reintroduce it using the api exported by the library (vicare libraries)
,
but Vicare does not offer it anymore.
The library (vicare libraries)
is defined by Vicare’s boot image and
exports an api to allow the customisation of the library loading process. Here is
an overview:
import
clause/syntax used in the source code instructs Vicare to
search a library whose r6rs name matches the given r6rs library reference.
find-library-by-reference
, which first searches the library in the
internal collection of already–interned libraries, then searches for a matching
library in some external repository.
find-library-by-reference
makes use of the parameter
current-library-loader
. The function default-library-loader
is the
default value of the parameter current-library-loader
.
default-library-loader
makes use of: the library locator
referenced by the parameter current-library-locator
; the source library loader
referenced by the parameter current-source-library-loader
; the binary library
loader referenced by the parameter current-binary-library-loader
.
current-library-locator
is usually initialised to
one of the functions:
run-time-library-locator compile-time-library-locator source-library-locator
either by default, or by direct selection with the command line option --library-locator. The library locators search the file system for a library file pathname matching a specified r6rs library reference.
default-source-library-loader
is the default value for the
parameter current-source-library-loader
. Given a textual input port: it reads
from it a library
symbolic expression; it verifies that its version
reference conforms to the library reference; using the expander procedure referenced
by current-library-expander
: loads and interns all its dependency libraries;
expands it; compiles it; interns it.
default-binary-library-loader
is the default value for the
parameter current-binary-library-loader
. Given a binary input port: it reads
from it a serialised library; verifies that its library name conforms to the library
reference; interns it along with all its dependency libraries.
Every parameter can be used to introduce some customisation in the process. The library locators need some discussion.
The run–time library locator is the default; it can be selected explicitly with the
command line option --library-locator run-time
or by setting the parameter
current-library-locator
to run-time-library-locator
; it is meant to be
used by an installation of Vicare to run applications. The run–time locator
scans the search path for compiled libraries in search of a matching binary file; if
a matching compiled library is not found: it scans the search path for source
libraries in search of a matching source file.
The reference scenario for the run–time library locator is this:
/usr/local/lib/vicare-scheme/vicare/posix.fasl
/usr/local/lib/vicare-scheme/vicare/something.fasl
(library-binary-search-path) ⇒ (... "/usr/local/lib/vicare-scheme" ...)
(current-library-binary-search-path-scanner default-library-binary-search-path-scanner)
which will scan the search path returned by (library-binary-search-path)
.
(import (vicare) (prefix (vicare posix) px.) (vicare something))
and we execute it selecting the run–time library locator:
$ vicare --library-locator run-time --r6rs-script demo.sps
the command line option --library-locator will put
run-time-library-locator
in the parameter current-library-locator
. The
run–time locator is the default, so we can just do:
$ vicare --r6rs-script demo.sps
The compile–time library locator must be selected explicitly with the command line
option --library-locator compile-time
or by setting the parameter
current-library-locator
to compile-time-library-locator
; it is meant to
be used from the build directory of a package while compiling libraries for
development or future installation. The compile–time locator does the following:
compiled-libraries-build-directory
:
when using this locator we instruct the compiler to put compiled libraries in the build directory.
The reference scenario for the compile–time library locator is this:
/usr/local/lib/vicare-scheme/vicare/posix.fasl
/usr/local/lib/vicare-scheme/vicare/something.fasl
$(srcdir)/lib/vicare/this.sls $(srcdir)/lib/vicare/that.sls
we want to compile them under the build directory:
$(builddir)/lib/vicare/this.fasl $(builddir)/lib/vicare/that.fasl
and then install them in a system directory:
/usr/local/lib/vicare-scheme/vicare/this.fasl /usr/local/lib/vicare-scheme/vicare/that.fasl
This is the gist: in the package’s building infrastructure (for example a Makefile
managed by the gnu Autotools) we need to write appropriate invocations of
vicare
to build the libraries locally and pick the appropriate source
libraries and compiled libraries.
(library (vicare this) (export) (import (vicare) (vicare that)) ---) (library (vicare that) (export) (import (vicare) (prefix (vicare posix) px.) (vicare something)) ---)
/usr/local/lib/vicare-scheme/vicare/this.fasl /usr/local/lib/vicare-scheme/vicare/that.fasl
we want the libraries under $(builddir)/lib
to take precedence over the
libraries under /usr/local/lib/vicare-scheme. It may be that there
exist installed source libraries:
/usr/local/lib/vicare-scheme/vicare/this.sls /usr/local/lib/vicare-scheme/vicare/that.sls
we want the libraries under $(srcdir)/lib
to take precedence over the
libraries under /usr/local/lib/vicare-scheme.
At the Scheme level we want the following:
(library-source-search-path) ⇒ ("$(srcdir)/lib")
(library-binary-search-path) ⇒ (... "/usr/local/lib/vicare-scheme" ...)
(compiled-libraries-build-directory) ⇒ "$(builddir)/lib
(current-library-binary-search-path-scanner default-library-binary-search-path-scanner)
which will scan the search path returned by (library-binary-search-path)
.
(current-library-source-search-path-scanner default-library-source-search-path-scanner)
which will scan the search path returned by
(library-source-search-path)
.
(current-library-locator compile-time-library-locator)
which implements the appropriate policy.
Assuming Makefiles generated by gnu Automake: to achieve the desired result, we have two options:
lib/vicare/that.fasl: lib/vicare/that.sls VICARE_SOURCE_PATH=; export VICARE_SOURCE_PATH; \ vicare --library-locator compile-time \ --library-path /usr/local/lib/vicare-scheme \ --source-path $(srcdir)/lib \ --build-directory $(builddir)/lib \ -o $@ -c $< lib/vicare/this.fasl: lib/vicare/this.sls lib/vicare/that.fasl VICARE_SOURCE_PATH=; export VICARE_SOURCE_PATH; \ vicare --library-locator compile-time \ --library-path /usr/local/lib/vicare-scheme \ --source-path $(srcdir)/lib \ --build-directory $(builddir)/lib \ -o $@ -c $<
this is the solution to prefer, because it allows parallel builds.
(import (only (vicare that)) (only (vicare this)))
we write a single Makefile rule that compiles in the build directory all the dependencies of the script:
.PHONY: vfasl vfasl: VICARE_SOURCE_PATH=; export VICARE_SOURCE_PATH; \ vicare --library-locator compile-time \ --library-path /usr/local/lib/vicare-scheme \ --source-path $(srcdir)/lib \ --build-directory $(builddir)/lib \ --compile-dependencies compile-all.sps
The source library locator must be selected explicitly with the command line option
--library-locator source
or by setting the parameter
current-library-locator
to source-library-locator
; it is meant to be
used to search for source libraries first and then for compiled ones.
The reference scenario for the source library locator is this:
/usr/local/lib/vicare-scheme/vicare/posix.fasl
/usr/local/lib/vicare-scheme/vicare/something.fasl
$(srcdir)/lib/vicare/this.sls $(srcdir)/lib/vicare/that.sls
we want to compile them under the build directory:
$(builddir)/lib/vicare/this.fasl $(builddir)/lib/vicare/that.fasl
and then install them in a system directory:
/usr/local/lib/vicare-scheme/vicare/this.fasl /usr/local/lib/vicare-scheme/vicare/that.fasl
In the package’s building infrastructure (for example a Makefile managed by the
gnu Autotools) we need to write appropriate invocations of vicare
to
build the libraries locally and pick the appropriate source libraries and compiled
libraries.
This is the gist: we want to automatically generate an include Makefile holding the compilation and installation recipes correctly describing the dependencies among libraries. For this we need to load all the source libraries in the package’s source tree.
(library (vicare this) (export) (import (vicare) (vicare that)) ---) (library (vicare that) (export) (import (vicare) (prefix (vicare posix) px.) (vicare something)) ---)
/usr/local/lib/vicare-scheme/vicare/this.fasl /usr/local/lib/vicare-scheme/vicare/that.fasl
we want these installed libraries to be ignored. It may be that there exist installed source libraries:
/usr/local/lib/vicare-scheme/vicare/this.sls /usr/local/lib/vicare-scheme/vicare/that.sls
we want the libraries under $(srcdir)/lib
to take precedence over the
libraries under /usr/local/lib/vicare-scheme.
At the Scheme level we want the following:
(library-source-search-path) ⇒ ("$(srcdir)/lib")
(library-binary-search-path) ⇒ (... "/usr/local/lib/vicare-scheme" ...)
(current-library-binary-search-path-scanner default-library-binary-search-path-scanner)
which will scan the search path returned by (library-binary-search-path)
.
(current-library-source-search-path-scanner default-library-source-search-path-scanner)
which will scan the search path returned by (library-source-search-path)
.
(current-library-locator source-library-locator)
which implements the appropriate policy.
To achieve the desired result, in the Makefile we write rules as follows:
.PHONY: dependencies DEPSCRIPT = $(srcdir)/scripts/build-makefile-rules.sps dependencies: VICARE_SOURCE_PATH=; export VICARE_SOURCE_PATH; \ vicare --library-locator source \ --library-path /usr/local/lib/vicare-scheme \ --source-path $(srcdir)/lib \ --r6rs-script $(DEPSCRIPT) -- \ $(slsdir)/libraries.scm >$(slsdir)/dependencies.make
where the executed Scheme script generates the Makefile rules automatically. The package Vicare Scheme comes with a script build-makefile-rules.sps that does exactly that to generate the dependencies among libraries; the extension packages will use the same script with the same Makefile rule.