Is it possible to create static binaries with nim?
I found a tutorial using musl-gcc, but my example doesn't work when I try it like that:
I import std/db_postgres. When trying to execute the static build I get
$ ./test
could not load: libpq.so(.5|)
(compile with -d:nimDebugDlOpen for more information)
$
So I tried the option:
$ ./test
Dynamic loading not supported
Dynamic loading not supported
could not load: libpq.so(.5|)
$
The library seems to be locatable:
$ ld -lpq --verbose | grep pq
attempt to open /usr/x86_64-pc-linux-gnu/lib64/libpq.so failed
attempt to open /usr/x86_64-pc-linux-gnu/lib64/libpq.a failed
attempt to open /usr/lib/libpq.so succeeded
/usr/lib/libpq.so
libssl.so.1.1 needed by /usr/lib/libpq.so
libcrypto.so.1.1 needed by /usr/lib/libpq.so
libgssapi_krb5.so.2 needed by /usr/lib/libpq.so
libldap.so.2 needed by /usr/lib/libpq.so
libc.so.6 needed by /usr/lib/libpq.so
ld: warning: cannot find entry symbol _start; not setting start address
d@doti ~/tu/data mgmt/ue/static (git)-[master]
$
Is it possible to statically link libc, but include a loader so libpq.so can be found?
As @archnim said, std/db_postgres is an impure lib. So Nim tries to link to it dynamically by default.
If you want to build a static binary with that library, you need to first build static version of that library.
As a example, see https://github.com/kaushalmodi/hello_musl/blob/master/config.nims that has the recipes for building static objects of pcre, openssl and libressl libraries.
You'll need to figure out a similar recipe for libpq.
I think this is as minimal as it gets...:
import std/db_postgres
let fake = open("","","","")
fake.close
compile with
nim --gcc.exe:musl-gcc --gcc.linkerexe:musl-gcc --passL:-static c test.nim
That's why I said that it should be normally possible.
But this is what you are actually trying to do:
As @yardanico said, it is impossible. And that is not Nim-specific.
It's too late to edit the above post, here's some other ideas. Supply a bundled libc and link to that:
https://stackoverflow.com/questions/847179/multiple-glibc-libraries-on-a-single-host
Or possibly write a script so it builds easily on the target system, or if it was practical, break the app into 2 parts, so the main part is statically built and a small libpq section isn't and was written in something that will work in both instances and interface through a (RAM, tmpfs?)file, signal, socket or something.