It is possible to embed saved-states into an executable. Together with static linking, this gives an all-in-one executable, an executable that does not depend on external SICStus files.
In the simplest case, creating an all-in-one executable main.exe
from a saved state main.sav
can be done with a command like
% spld --output=main.exe --static main.sav
This will automatically embed the saved state, any foreign resources needed by the saved state as well the SICStus run-time and its run-time saved state.
The keys to this feature are:
sprt311.dll
(Windows) or libsprt311.so
(UNIX). Note that, as
of SICStus 3.9, static linking is supported under Windows.
If the application needs foreign resources (predicates
written in C code), as used for example by library(system)
and
library(clpfd)
, then these foreign resources can be linked
statically with the application as well.
The remaining component is the Prolog code itself; see the next item.
An application needs two saved-states:
sprt.sav
).
This is added automatically when spld
is invoked with the
--static
(or -S
) option unless the spld
-option
--no-embed-rt-sav
is specified. It can also be added explicitly
with the option --embed-rt-sav
.
This saved-state is typically created by loading all
application code using compile/1
and then creating the
saved-state with save_program/2
.
Data resources are added by specifying their internal name and the
path to a file as part of the comma separated list of resources passed with
the spld
option --resources
. Each data resource is
specified as file=name where file is the path
to the
file containing the data (it must exist during the call to spld
)
and name is the name used to access the content of file
during run-time. A typical choice of name would be the base name,
i.e. without directories, of file, preceded by a slash
(/
).
name should begin with a slash (/
) and
look like an ordinary lowercase file path made up of /
-separated,
non-empty,
names consisting of a
to z
, underscore (_
, period
(.
), and digits.
Typically, you would use spld --main=restore
, which will
automatically restore the first .sav
argument. To manually
restore an embedded saved-state you should use the syntax
URL:x-sicstus-resource:
name, e.g.
SP_restore("URL:x-sicstus-resource:/main.sav")
.
An example will make this clearer. Suppose we create a run-time system
that consists of a single file main.pl
that looks like:
% main.pl:- use_module(library(system)). :- use_module(library(clpfd)). % This will be called when the application starts: user:runtime_entry(start) :- %% You may consider putting some other code here... write('hello world'),nl, write('Getting host name:'),nl, host_name(HostName), % from system write(HostName),nl, ( all_different([3,9]) -> % from clpfd write('3 != 9'),nl ; otherwise -> write('3 = 9!?'),nl ).
Then create the saved-state main.sav
, which will contain
the compiled code of main.pl
as well as the Prolog code of
library(system)
and library(clpfd)
and other Prolog
libraries needed by library(clpfd)
.
% sicstus -i -f SICStus 3.11.2 ... Licensed to SICS | ?- compile(main). % compiling .../main.pl... % ... loading several library modules | ?- save_program('main.sav'). % .../main.sav created in 201 msec | ?- halt.
Finally, tell spld
to build an executable statically linked
with the SICStus run-time and the foreign resources needed by
library(system)
and library(clpfd)
. Also, embed the Prolog
run-time saved-state and the application specific
saved-state just created. Note that the random
foreign
resource is needed since it is used by library(clpfd)
.
As noted above, it is possible to build the all-in-one executable with the command line
% spld --output=main.exe --static main.savbut for completeness the example below uses all options as if no options were added automatically.
The example is using Cygwin bash
(http://www.cygwin.com)
under Windows but would look much the same on other platforms. The command
should be given on a single line; it is broken up here for better
layout.
% spld --output=main.exe --static --embed-rt-sav --main=restore --resources=main.sav=/main.sav,clpfd,system,random
The arguments are as follows:
--output=main.exe
spld
where to put the resulting executable.
--static
system
and clpfd
in this case).
--embed-rt-sav
.sav
file
(sprt.sav
). This option is not needed since it is added
automatically by --static
.
--main=restore
user:runtime_entry(start)
. This is not strictly needed in the above
example since it is the default if any file with extension .sav
or a data resource with a name with extension .sav
is
specified.
--resources=...
main.sav=/main.sav
spld
to make the content (at the time spld
is
invoked) of the file main.sav
available at run-time in a data
resource named /main.sav
. That is, the data resource
name corresponding to "URL:x-sicstus-resource:/main.sav"
.
Alternatively, spld
can create a default data resource
specification when passed a .sav
file argument and the option
--embed-sav-file
(which is the default with
--static
).
clpfd
system
random
spld
to link with the foreign resources (that
is, C-code) associated with library(system)
,
library(clpfd)
and library(random)
.
Since --static
was specified the static
versions of these foreign resources will be used.
Alternatively, spld
can extract the information about the
required foreign resources from the saved-state
(main.sav
). This feature is enabled by adding the option
--resources-from-sav
(which is the default with
--static
). Using --resources-from-sav
instead of an
explicit list of foreign resources is preferred since it is hard to know
what foreign resources are used by the SICStus libraries.
Since both --embed-sav-file
and --resources-from-sav
are the default when --static
is used the example can be built
simply by doing
% spld --output=main.exe --static main.sav
Finally, we may run this executable on any machine, even if SICStus is not installed:
bash-2.04$ ./main.exe hello world Getting host name: EOWYN 3 != 9 bash-2.04$