Creating Prolog executables

I have recently been porting some of my GNU Prolog code to both SWI Prolog and SICStus Prolog.

Here is a simple attempt at synthesizing some of what I learnt from that experience, especially as far as building executables is concerned.

Indeed, neither SWI nor SICStus will allow you to do something like

$ gplc -o my_native_binary --min-fd-bips --strip -C -Wall some.pl source.pl files.pl

SWI Prolog

The magic formula is the following:

$ swipl -o my_executable --stand_alone=true --global=128000 -g my_main_predicate -O -q -c some.pl source.pl files.pl

This will load quietly (-q) all source files (and run their initialization if there is any), then create a saved state with a 128M global stack, optimized (-O) and that embeds the SWI interpreter (you will thus also need libswipl.so/dylib/dll to run the created executable, check for dynamic libraries with ldd/otool -L/…). When executed, it will start with my_main_predicate.

It is possible to produce executables for other target architectures by specifying another emulator image with the aptly named --emulator option.

SICStus Prolog

The process is very similar, but it seems that the two steps of creating the saved state and the executable cannot be merged. We thus go:

$ sicstus -f --nologo --noinfo -l some_source.pl --goal "save_program('my_saved'),halt."
$ spld --output my_executable --static my_saved.sav

Here we use a fast and quiet SICStus call to load one source file (if you need more, add them in the goal) and save the state.

Then we convert the saved state to a standalone and static executable that embeds a restricted interpreter and will run the goal called user:runtime_entry(start) on start. Once again, another SICStus executable can be used with --sicstus (but I think that it is used for more than embedding by spld, thus cross-building might not work…).