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 presence 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 by looking through the directories $XSB_DIR/{syslib,cmplib,lib}.
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, many of which are documented in Volume 2 of this
manual. 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
predicate 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
.
Finally, if you developed and tested a package that you think is generally useful and you would like to distribute it with XSB, please contact xsb-development@sourceforge.net.