-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Crystal depends upon linking a number of libraries in the embedded/lib
directory.
However, system libraries included via the Link()
annotation may depend on -L/usr/lib
, which can contain conflicting libraries. This error is happening on Linux when -L/usr/lib
is passed (via -L
pg_config --libdir``) for the Postgres Driver. The result is obscure errors involving missing symbols while linking.
A solution that seems to work only on Linux is to use the colonized form (-l:
) of the linker flag to avoid resolving libary path directives when linking Crystal-internal libraries, for example:
@[Link(ldflags: "-lpq -l:/opt/crystal/embedded/lib/libatomic_ops.a -l:/opt/crystal/embedded/lib/libatomic_ops_gpl.a -l:/opt/crystal/embedded/lib/libcord.a -l:/opt/crystal/embedded/lib/libevent.a -l:/opt/crystal/embedded/lib/libevent_core.a -l:/opt/crystal/embedded/lib/libevent_extra.a -l:/opt/crystal/embedded/lib/libevent_openssl.a -l:/opt/crystal/embedded/lib/libevent_pthreads.a -l:/opt/crystal/embedded/lib/libgc.a -l:/opt/crystal/embedded/lib/libpcl.a -l:/opt/crystal/embedded/lib/libpcre.a -l:/opt/crystal/embedded/lib/libpcrecpp.a -l:/opt/crystal/embedded/lib/libpcreposix.a -l:/opt/crystal/embedded/lib/libunwind.a -l:/opt/crystal/embedded/lib/libunwind-coredump.a -l:/opt/crystal/embedded/lib/libunwind-generic.a -l:/opt/crystal/embedded/lib/libunwind-ptrace.a -l:/opt/crystal/embedded/lib/libunwind-setjmp.a -l:/opt/crystal/embedded/lib/libunwind-x86_64.a")]
@will reproduced this on Heroku, and the Trusty EC2 image on AWS after installing libpq-dev
, so, regretfully, it is difficult to use libpq
in common situations, though we suspect this applies to any C library with transitive dependencies.
Notably, Crystal will append -levent -lrt -lpcl -lpcre -lm -lgc -lpthread -lunwind
to the call to cc
, so there is a limited opportunity play with various orders in intermixing -L
and -l
flags. We did try a number of orders of -L
and -l
without success.
We first suspected libary path precedence orders played an important role in this because installing a new libpcl
into /usr/lib
worked, without having to add those -l:
expressions to ldflags
.
One might think one could include the library of choice, e.g. "libpq", with -l:/usr/lib/libpq.a
, except libpq optionally supports a number of authentication methods that is determined by the operating system. For example, on Debian, it supports GSSAPI and uses a libary to do so, so having /usr/lib
in the library path is necessary.