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
-Sand-Wflags can be combined.- If the
-Soption is used, the-LDoption 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.libneeds to be created. The trailingsis significant (see below);qldassumes 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
-Soption is used, when processing a library dependencyqldwill first search for the library with ansappended to its name, for examplelibqps.libfor the Embedding Layer, and if not found it tries the original name.