How to make a saved state fully self-contained?

When I run ldd on my saved state (created using swipl --stand_alone=true --foreign=save -c), it reports the following libraries(*,**):

libtinfo5:amd64: /lib/x86_64-linux-gnu/libtinfo.so.5
zlib1g:amd64: /lib/x86_64-linux-gnu/libz.so.1
swi-prolog-nox: /usr/lib/swi-prolog/lib/x86_64-linux/libswipl.so.8
libgmp10:amd64: /usr/lib/x86_64-linux-gnu/libgmp.so.10

I was expecting these “DLLs” to be inside the saved state, even though they’d increase the size from 300KB to 2.3MB. But --foreign=save doesn’t seem to do anything. (Ideally I would like to specify that I don’t need gmp and tinfo, but that’s not terribly important.)

(*) The full command I used:
ldd my-saved-state | grep '=>' | cut -f3 -d' ' | sort | xargs -L1 dpkg-query -S | grep -v libc6:amd64

(**)

?- current_foreign_library(F, P), numbervars(F:P, 0, _), writeln(F:P), fail; true.
foreign(sha4pl):[crypto_hash:sha_hash(A,B,C),crypto_hash:sha_new_ctx(D,E),crypto_hash:sha_hash_ctx(F,G,H,I),crypto_hash:hmac_sha(J,K,L,M)]
foreign(json):[json:json_read_number(A,B,C),json:json_skip_ws(D,E,F),json:json_write_string(G,H),json:json_write_indent(I,J,K)]
foreign(memfile):[memory_file:new_memory_file(A),memory_file:free_memory_file(B),memory_file:size_memory_file(C,D),memory_file:size_memory_file(E,F,G),memory_file:open_memory_file(H,I,J),memory_file:open_memory_file(K,L,M,N),memory_file:atom_to_memory_file(O,P),memory_file:memory_file_to_atom(Q,R),memory_file:memory_file_to_codes(S,T),memory_file:memory_file_to_string(U,V),memory_file:memory_file_to_atom(W,X,Y),memory_file:memory_file_to_codes(Z,A1,B1),memory_file:memory_file_to_string(C1,D1,E1),memory_file:utf8_position_memory_file(F1,G1,H1),memory_file:insert_memory_file(I1,J1,K1),memory_file:delete_memory_file(L1,M1,N1),memory_file:memory_file_substring(O1,P1,Q1,R1,S1),memory_file:memory_file_line_position(T1,U1,V1,W1)]
foreign(readutil):[read_util:read_line_to_codes(A,B,C),read_util:read_line_to_codes(D,E),read_util:read_stream_to_codes(F,G,H),read_util:read_stream_to_codes(I,J)]
foreign(pcre4pl):[pcre:re_config(A),pcre:re_compile(B,C,D),pcre:re_match_(E,F,G),pcre:re_matchsub_(H,I,J,K),pcre:re_foldl_(L,M,N,O,P,Q)]
foreign(files):[files_ex:set_time_file(A,B,C),files_ex:link_file(D,E,F),files_ex:file_mode_(G,H),files_ex:chmod_(I,J)]
1 Like

They are the dependencies of the emulator (e.g., swipl). You can get rid of these using static linking. Using -DSWIPL_SHARED_LIB=OFF it avoids libswipl.so. gmp could be avoided using -DUSE_GMP=OFF. Currently the other two have no options to get rid of them, libtinfo could be made conditional, but zlib is needed to load the saved state. With some work in the CMake config files it should be possible to link these libraries statically.

Static linking doesn’t always play well with plugins (works on ELF/Linux I think, but on many platforms it doesn’t). So, for Linux you can probably achieve fully stand-alone executables, but it requires some work.

That said, many modern OSes have a lot of ways to package shared object dependencies. Think of snappy, flatpack, etc.