TL;DR
I'm attempting to build a go project that uses this dependency: https://github.com/mqu/openldap, which in turn externally links lldap and llber libraries, which in turn uses lgnutls, which uses lnettle, which is where I'm stuck.
The go build
produces a long list of undefined references and the build fails. Here's a sample:
/usr/lib/x86_64-linux-gnu/libgnutls.a(sha-x86-ssse3.o): In function `_ctx_init':
(.text+0x468): undefined reference to `nettle_sha256_digest'
/usr/lib/x86_64-linux-gnu/libgnutls.a(sha-x86-ssse3.o): In function `_ctx_init':
(.text+0x476): undefined reference to `nettle_sha224_init'
/usr/lib/x86_64-linux-gnu/libgnutls.a(sha-x86-ssse3.o): In function `_ctx_init':
(.text+0x494): undefined reference to `nettle_sha256_init'
/usr/lib/x86_64-linux-gnu/libgnutls.a(sha-x86-ssse3.o): In function `_ctx_init':
(.text+0x4b8): undefined reference to `nettle_sha256_digest'
/usr/lib/x86_64-linux-gnu/libgnutls.a(sha-x86-ssse3.o): In function `_ctx_init':
(.text+0x4c6): undefined reference to `nettle_sha256_init'
/usr/lib/x86_64-linux-gnu/libgnutls.a(sha-x86-ssse3.o):(.data.rel.ro+0x18): undefined reference to `nettle_sha256_init'
/usr/lib/x86_64-linux-gnu/libgnutls.a(sha-x86-ssse3.o):(.data.rel.ro+0x28): undefined reference to `nettle_sha256_digest'
/usr/lib/x86_64-linux-gnu/libgnutls.a(sha-x86-ssse3.o):(.data.rel.ro+0x58): undefined reference to `nettle_sha224_init'
/usr/lib/x86_64-linux-gnu/libgnutls.a(sha-x86-ssse3.o):(.data.rel.ro+0x68): undefined reference to `nettle_sha224_digest'
/usr/lib/x86_64-linux-gnu/libgnutls.a(sha-x86-ssse3.o):(.data.rel.ro+0x98): undefined reference to `nettle_sha1_init'
/usr/lib/x86_64-linux-gnu/libgnutls.a(sha-x86-ssse3.o):(.data.rel.ro+0xa8): undefined reference to `nettle_sha1_digest'
And my go build
command:
CC=/usr/local/musl/bin/musl-gcc \
GOOS=linux go build \
-o /bin/activedirectory \
-ldflags '-linkmode external -extldflags "-static -L/usr/lib/x86_64-linux-gnu -lnettle -lp11 -lsasl2 -lgnutls -ltasn1"'
I have tried resolving this by installing libnettle4
, nettle-dev
, libghc-nettle-dev
, nettle-bin
. I have made sure to include -lnettle
in the ldflags. No luck.
More context
The openldap library is linking the ldap
and lber
libs in the code:
package openldap
/*
#define LDAP_DEPRECATED 1
#include <stdlib.h>
#include <ldap.h>
static inline char* to_charptr(const void* s) { return (char*)s; }
static inline LDAPControl** to_ldapctrlptr(const void* s) {
return (LDAPControl**) s;
}
*/
// #cgo CFLAGS: -DLDAP_DEPRECATED=1
// #cgo linux CFLAGS: -DLINUX=1
// #cgo LDFLAGS: -lldap -llber
This has required me to install and include in the ldflags all the libraries you see in my build command.
So the dependency chain, in short, goes like this:
lldap -> lgnutls -> lnettle.
I added lgnutls and that resolved my gnutls dependency issues, but I'm unable to resolve my nettle depencency issues.
My question
What am I doing wrong in my attempts to fix these nettle dependency issues?
Bonus question
Is there a best practice for resolving these ld linker dependencies? Right now my flow looks like this:
nettle_sha1_digest
= nettle package)I guess I'm wondering if there's a magic bullet that can install all dependencies for me? :)
From the looks of it you're linking your dependent libraries in the wrong order (see Why does the order in which libraries are linked sometimes cause errors in GCC? for more context).
With statically linked libraries the linker attempts to resolve symbols in the order that the libraries were specified in. If a relied-upon symbol comes up as undefined then the linker looks to see if it's defined in the subsequent libraries specified. Since in your build invocation -lnettle
is specified before -lgnutls
the gnutls library can't resolve the symbols it needs from nettle.
What this means is that (at minimum) you'll have to move your reference to -lnettle
to after -lgnutls
. Not sure this will solve all of your problems since I'm not familiar with all of the linking dependencies you have listed, but it should at least solve your current errors running go build
.