A runtime system is a single executable program that should be easily
transferable to a different machine. By default, the executable built
by qld
will use dynamic libraries where it can, such as the dynamic C
library (-lc
under UNIX, /MD
under Windows).
This requires that a corresponding library exist on
the target machine on which the executable will be run.
Under UNIX,
you may encounter problems if libraries included in your executable are
not installed in "standard places" -- e.g. in /usr/lib
-- on the target
machine. For example, if you specify -lX11
, but the corresponding file
libX11.so.4.2
resides in /usr/local/lib/X11
.
Typically, a user has to set the LD_LIBRARY_PATH
environment variable to
find libraries in non-standard places, although another option at
installation time might be to add a call to ldconfig(8)
in /etc/rc.local
to include the directory containing a shared library into the system-wide
list of "standard places" to find shared libraries. The ldd(1)
command
lists the dynamic dependencies of an executable and whether or not
these can be found.
The problem exists under Windows but the details are different. In
particular Windows shared libraries are looked for in the folders
specified by the PATH
environment variable and in some further
"standard places". Consult the Windows documentation for details.
In addition to shared libraries, your executable may contain shared
object files, specified in calls to load_foreign_executable/1
.
qld
passes the absolute file paths for these files to the linker,
which results
in the dependencies for these shared object files being stored in the
runtime system executable as absolute filenames. Note that this problem
can arise even if you have no foreign code of your own, if you are using
the Quintus Prolog library or X interfaces.
A solution to the shared object files problem is to use the -S
option with qld
, which tries to substitute archive files
for shared object files where they exist. If
the shared object files have dependencies on other shared libraries
then those libraries need to be explicitly listed in the qld
command, as qld
does not track these dependencies. This makes
your executable file larger, as the library code is stored within the
executable rather than linked in at start-up time. Each shared object
file provided in the Quintus libraries has an equivalent archive
file that can be substituted by the qld -S
command.
For example, under UNIX,
building a runtime system from the file in (A) with the command (B)
produces an a.out
file, which prints the date and time, as in (C).
test.pl:- use_module(library(date)). (A) runtime_entry(start) :- datime(X), portray_date(X), nl.
% qpc test.pl (B)
% ./a.out (C) 2:10:09 PM 1-Feb-91
This a.out
file has a dependency on the Prolog library as well as on
the C library, as shown by the ldd(1)
command:
% ldd a.out /usr/local/quintus/generic/qplib3.5/library/sun4-5/libpl.so libc.so.1 => /usr/lib/libc.so.1.8
Under Windows, the example would be almost the same, with the difference
that the default name of the executable produced by qpc
is
a.exe
rather than a.out
. To view dependencies you can type
dumbin /DEPENDENTS a.exe.
Hence this runtime system will not work on a machine where Quintus Prolog is not installed. To build a runtime system that does not have this dependency, it is necessary to call qld -S explicitly, rather than just calling qpc test.pl as shown above. Under UNIX, the necessary command sequence is:
% qpc -c test.pl % qld -Sd test.qof
That is, qpc
is called with the -c
option so that it stops after producing
a .qof
file, rather than calling qld
. Then
qld
is called with the -S
option so that it substitutes libpl.a
for
libpl.so
. The result is an executable that depends only on the C shared
library:
% ldd a.out ilbc.so.1 => /usr/lib/libc.so.1.8
This executable should run without problem on a different machine.
Under Windows, the linker does not automatically add all needed OS libraries. These need to be added explicitly as follows:
C:\> qpc -c test.pl C:\> qld -Sd test.qof -LD qpconsoles.lib user32.lib gdi32.lib comdlg32.lib
Windows notes:
- The
-S
and-W
flags can be combined.- If the
-S
option is used, the-LD
option must also be used, together with the library referencesqpconsoles.lib
,user32.lib
,gdi32.lib
, andcomdlg32.lib
.- If the Prolog code has a foreign executable dependency on
myforeignex
, a static librarymyforeignexs.lib
needs to be created. The trailings
is significant (see below);qld
assumes this naming convention. Here is an example of the necessary sequence of commands to create a static executablemyforeignex.exe
:C:\> cl /c /MD myforeignex.c C:\> link /lib /OUT:myforeignexs.lib myforeignex.obj C:\> qpc -c myprog.pl C:\> qld -Sdvo myprog.exe myprog.qof -LD \ user32.lib comdlg32.lib qpconsoles.lib gdi32.libThe above command produces an executable that uses the static version of the Runtime Kernel and has no DLL dependencies. Statically linked applications can still dynamically load foreign code DLLs, provided these DLLs do not call any of the Quintus Prolog C API functions.
In order to distinguish static libraries from DLL import libraries in foreign dependencies, the following naming convention has been chosen. If the
-S
option is used, when processing a library dependencyqld
will first search for the library with ans
appended to its name, for examplelibqp
s.lib
for the Embedding Layer, and if not found it tries the original name.