如何修复对`nettle_sha256_digest`的未定义引用?

时间:2017-11-15 22:35:27

标签: gcc go ld nettle

TL; DR

我正在尝试构建一个使用此依赖项的go项目:https://github.com/mqu/openldap,它依次外部链接lldap和llber库,后者又使用lgnutls,它使用lnettle,这是我被卡住的地方

go build生成一长串未定义的引用,构建失败。这是一个示例:

/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'

我的go build命令:

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"'

我尝试通过安装libnettle4nettle-devlibghc-nettle-devnettle-bin来解决此问题。我已确保在ldflags中包含-lnettle。没有运气。

更多背景

openldap库链接代码中的ldaplber库:

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

这要求我在ldflags中安装并包含你在我的构建命令中看到的所有库。

简而言之,依赖关系链是这样的:

lldap - &gt; lgnutls - &gt; lnettle。

我添加了lgnutls,这解决了我的gnutls依赖问题,但我无法解决我的荨麻依赖性问题。

我的问题

在尝试解决这些荨麻依赖问题时,我做错了什么?

加分问题

是否有解决这些ld链接器依赖项的最佳实践?现在我的流程看起来像这样:

  1. 运行构建
  2. 注意“未定义参考”错误
  3. 通过Google搜索错误或查看引用的名称(例如nettle_sha1_digest = nettle package)来确定丢失了哪个包
  4. 安装该软件包
  5. 重复
  6. 我想我想知道是否有可以安装所有依赖项的神奇子弹? :)

1 个答案:

答案 0 :(得分:1)

从它的外观来看,您以错误的顺序链接您的依赖库(有关更多上下文,请参阅Why does the order in which libraries are linked sometimes cause errors in GCC?)。

使用静态链接库,链接器会尝试按照指定库的顺序解析符号。如果依赖符号出现为未定义,则链接器会查看是否在后续库中定义了符号指定。由于在您的构建调用中{<1}}在 -lnettle之前指定了 ,因此gnutls库无法从nettle中解析所需的符号。

这意味着(至少)您必须将-lgnutls的引用移至-lnettle之后。不确定这会解决您的所有问题,因为我不熟悉您列出的所有链接依赖项,但至少应该解决当前运行-lgnutls的错误。