The default search path of the dynamic loader can easily be changed
by having a file named .xsb/xsbrc.P
in the user's home directory.
The .xsb/xsbrc.P
file, which is automatically consulted by the
XSB interpreter, might look like the following:
:- assert(library_directory('./')). :- assert(library_directory('~/')). :- assert(library_directory('~my_friend')). :- assert(library_directory('/usr/lib/sbprolog')).After loading the module of the above example, the current working directory is searched first (as opposed to the default action of searching it last). Also, XSB's system library directories ( lib, syslib, and cmplib), will now be searched after searching the user's, my_friend's and the "/usr/lib/sbprolog/" directory.
In fact, XSB also uses library_directory/1 for internal purposes.
For instance, before the user's .xsb/xsbrc.P
is consulted,
XSB puts the packages directory and the directory
.xsb/config/$CONFIGURATIONon the library search path. The directory
.xsb/config/$CONFIGURATION
is used to store user
libraries that are machine or OS dependent. ($CONFIGURATION
for a
machine is something that looks like sparc-sun-solaris2.6 or
pc-linux-gnu, and is selected by XSB automatically at run time).
Note that the file .xsb/xsbrc.P
is not limited to setting the
library search path. In fact, arbitrary Prolog code can go there.
We emphasize that in the presense of a .xsb/xsbrc.P
file
it is the user's responsibility to avoid module name clashes
with modules in XSB's system library directories.
Such name clashes can cause the system to behave strangely since these
modules will probably have different semantics from that expected
by the XSB system code. The list of module names in
XSB's system library directories can be found in
appendix C.
Apart from the user libraries, XSB now has a simple packaging system.
A package is an application consisting of one or more files that
are organized in a subdirectory of one of the XSB system or user libraries.
The system directory $XSB_DIR/packages
has several examples
of such packages. Packages are convenient as a means of organizing
large XSB applications, and for simplifying user interaction with such
applications. User-level packaging is implemented through the predicate
bootstrap_userpackage(+LibraryDir, +PackageDir, +PackageName).which must be imported from the packaging module.
To illustrate, suppose you wanted to create a package, foobar, inside your own library, my_lib. Here is a sequence of steps you can follow:
~/my_lib/foobar
and organize all the
package files there. Designate one file, say, foo.P, as the
entry point, i.e., the application file that must be loaded first.~/my_lib/foobar.P
with the
following content:
:- bootstrap_userpackage('~/my_lib', 'foobar', foobar), [foo].The interface program and the package directory do not need to have the same name, but it is convenient to follow the above naming schema.
[foobar].
at the XSB prompt. This is because both and
~/my_lib/foobar
have already been automatically added to the
library search path.~/my_lib/foobar.P
import all
these predicates, renaming them, and then exporting them. This provides a
uniform interface to the foobar module, since all the package
predicates are can now be imported from just one module, foobar.bootstrap_userpackage/3
also adds information to the
predicate package_configuration/3
, so that other applications could
query the information about loaded packages.
Packages can also be unloaded using the predicate
unload_package/1
. For instance,
:- unload_package(foobar).removes the directory
~/my_lib/foobar
from the library search path
and deletes the associated information from package_configuration/3
.