For example, we can include the bootstrap data into an embedded executable using the steps below. The advantage of this approach is that it is fully supported by any OS and you obtain a single file executable.
% swipl -o state -c file.pl ...
% xxd -i state > state.h
#include <SWI-Prolog.h> #include "state.h" int main(int argc, char **argv) { if ( !PL_set_resource_db_mem(state, state_len) || !PL_initialise(argc, argv) ) PL_halt(1); return PL_toplevel(); }
Alternative to xxd, it is possible to use inline assembler,
e.g. the gcc incbin
instruction. Code for
gcc was provided by Roberto Bagnara on the SWI-Prolog
mailinglist. Given the state in a file state
, create the
following assembler program:
.globl _state .globl _state_end _state: .incbin "state" _state_end:
Now include this as follows:
#include <SWI-Prolog.h> #if __linux #define STATE _state #define STATE_END _state_end #else #define STATE state #define STATE_END state_end #endif extern unsigned char STATE[]; extern unsigned char STATE_END[]; int main(int argc, char **argv) { if ( !PL_set_resource_db_mem(STATE, STATE_END - STATE) || !PL_initialise(argc, argv) ) PL_halt(1); return PL_toplevel(); }
As Jose Morales pointed at https://github.com/graphitemaster/incbin, which contains a portability layer on top of the above idea.