Next: Setting up the C compiler on Windows, Previous: Customizing spld, Up: The Application Builder [Contents][Index]
It is possible to embed saved states into an executable (or shared object). Together with static linking, this gives an all-in-one executable, an executable (or shared object) 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 runtime and its runtime saved state.
Creating a shared object is similar, e.g.
% spld --output=main.dll --shared --static main.sav
but the following examples cover the more common case of creating an ordinary executable.
The keys to this feature are:
If the application needs foreign resources (predicates
written in C code), as used for example by library(random)
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 runtime. 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 runtime system that consists of a single file main.pl that looks like:
% main.pl
:- use_module(library(random)). :- 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 a random value:'),nl, random(1,10,R), % from random writeq(R),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(random)
and library(clpfd)
and other Prolog
libraries needed by library(clpfd)
:
% sicstus -i -f SICStus 4.9.0 … 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 runtime and the foreign resources needed by
library(random)
and library(clpfd)
. Also, embed the Prolog
runtime saved state and the application specific
saved state just created.
As noted above, it is possible to build the all-in-one executable with the command line:
% spld --output=main.exe --static main.sav
but 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,random
The arguments in the example are as follows:
This tells spld
where to put the resulting executable.
Link statically with the SICStus runtime and foreign resources
(clpfd
and random
, in this case).
This option embeds the SICStus runtime ‘.sav’ file (sprt.sav). This option is not needed since it is added automatically by --static.
Start the application by restoring the saved state and calling
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 where the extension is ‘.sav’ is
specified.
This is followed by comma-separated resource specifications:
main.sav=/main.sav
This tells spld
to make the content (at the time spld
is
invoked) of the file main.sav available at runtime 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
random
These tell spld
to link with the foreign resources (that
is, C-code) associated with
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 a random value: 4 3 != 9 bash-2.04$