/usr/bin/ld: 未定义的静态库引用

Posted

技术标签:

【中文标题】/usr/bin/ld: 未定义的静态库引用【英文标题】:/usr/bin/ld: undefined reference to static library 【发布时间】:2020-05-29 08:46:52 【问题描述】:

我得到了以下 cmake 文件:

cmake_minimum_required(VERSION 3.17)
project(blsbench2)

set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES main.cpp)

INCLUDE_DIRECTORIES(../../Documents/projects/bls-signatures/src)
LINK_DIRECTORIES(../../Documents/projects/bls-signatures/build/src)
LINK_DIRECTORIES(../../Documents/projects/bls-signatures/build/object_blstmp)



INCLUDE_DIRECTORIES(/usr/local/include/relic/)
LINK_DIRECTORIES(/usr/local/lib/)

add_executable(blsbench2 $SOURCE_FILES)

TARGET_LINK_LIBRARIES(blsbench2 bls relic)

还有下面的程序

#include <iostream>
#include <bls.hpp>

using namespace bls;
using namespace std;

int main()

    std::cout << "Hello, World!" << std::endl;


    uint8_t seed[] = 0, 50, 6, 244, 24, 199, 1, 25, 52, 88, 192,
                      19, 18, 12, 89, 6, 220, 18, 102, 58, 209,
                      82, 12, 62, 89, 110, 182, 9, 44, 20, 254, 22;

    PrivateKey sk = PrivateKey::FromSeed(seed, sizeof(seed));
    PublicKey pk = sk.GetPublicKey();

    uint8_t msg[] = 100, 2, 254, 88, 90, 45, 23;

    Signature sig = sk.Sign(msg, sizeof(msg));


    return 0;

我正在使用 CLion,上面的设置允许我包含库并使用函数自动完成。

当我尝试开始运行程序时出现问题。

/usr/bin/ld: CMakeFiles/blsbench2.dir/main.cpp.o: in function `main':
/home/ray/CLionProjects/blsbench2/main.cpp:16: undefined reference to `bls::PrivateKey::FromSeed(unsigned char const*, unsigned long)'
/usr/bin/ld: /home/ray/CLionProjects/blsbench2/main.cpp:17: undefined reference to `bls::PrivateKey::GetPublicKey() const'
/usr/bin/ld: /home/ray/CLionProjects/blsbench2/main.cpp:21: undefined reference to `bls::PrivateKey::Sign(unsigned char const*, unsigned long) const'
/usr/bin/ld: /home/ray/CLionProjects/blsbench2/main.cpp:16: undefined reference to `bls::PrivateKey::~PrivateKey()'
/usr/bin/ld: /home/ray/CLionProjects/blsbench2/main.cpp:16: undefined reference to `bls::PrivateKey::~PrivateKey()'
/usr/bin/ld: CMakeFiles/blsbench2.dir/main.cpp.o: in function `bls::Signature::~Signature()':
/home/ray/CLionProjects/blsbench2/../../Documents/projects/bls-signatures/src/signature.hpp:101: undefined reference to `bls::AggregationInfo::~AggregationInfo()'
collect2: error: ld returned 1 exit status

我在互联网上搜索了一下,它在几个地方说这是由于缺少 .so 文件(可能在这里弄错了)。但是,该库构建一个 .a 文件就足够了。

【问题讨论】:

看起来bls实际上并没有定义给定的符号(构造函数、析构函数、方法)。您可以使用nm &lt;path-to-library-file&gt; --demangle 获取静态库中定义的符号列表(方法取自这里:***.com/a/2714330/3440745)。 bls-signatures 项目手动创建bls 库:src/CMakeLists.txt,这种方法可能有问题。 【参考方案1】:

这是由于bls 库是如何构建的。 bls::PrivateKey 类在 file 中实现,它是 blstmp 静态库的一部分。

您可以直接链接到blstmp 库而不是bls。这有效:您的程序运行良好。但这有点hacky。

这是由于 CMake 的一个问题:当您构建依赖于静态库 B 的库 A 时,库 B 的对象文件不会复制到库 A 中。因此,链接到 A 的程序也应该链接到B. 在 CMake 的邮件列表中有一个 discussion 关于它。

但这是 bls 库的问题,将其报告给维护者可能会很有用。

【讨论】:

好吧,这似乎让我更进一步,现在我收到以下错误:“bls.cpp:(.text+0x1a1): undefined reference to `core_set_thread_initializer'” 大约三种方法: core_set_thread_initializer, ep2_sub_projc, fp_inv_exgcd_bn 这些似乎确实与relic密切相关。 当我构建你的代码时,我必须链接到relic_s 而不是relic。这值得一试。您可以尝试的另一件事是直接使用 CMake 的 ExternalProjectadd_subdirectory 在您的项目中构建 bls(我尝试了第二个但没有成功)。 只添加relic_s又抛出了一批问题,同时添加relic_s和relic只会抛出我提到的4个。【参考方案2】:

正如答案中的另一位用户指出的那样,我追求图书馆维护者。

主要问题是他们 a) 运行经过大量修改的遗物版本。 b) 将其分布在 2 个文件夹中。

解决办法:

a) 正如 antoine 指出的那样,包括 blstmp 而不是 bls b) 包括 relic_s 而不是 relic c) 包括来自正确目录的遗物。

INCLUDE_DIRECTORIES(../../Documents/projects/bls-signatures/src)
LINK_DIRECTORIES(../../Documents/projects/bls-signatures/build/src)

LINK_DIRECTORIES(../../Documents/projects/bls-signatures/build/contrib/relic/lib)
INCLUDE_DIRECTORIES(../../Documents/projects/bls-signatures/build/contrib/relic/include)
INCLUDE_DIRECTORIES(../../Documents/projects/bls-signatures/contrib/relic/include)

add_executable(blsbench2 $SOURCE_FILES)

TARGET_LINK_LIBRARIES(blsbench2 blstmp relic_s)

【讨论】:

以上是关于/usr/bin/ld: 未定义的静态库引用的主要内容,如果未能解决你的问题,请参考以下文章

Bugfix系列/usr/bin/ld: cannot find -lxxx 的解决办法

静态库的未定义引用和奇怪的内容

解决遇到动态库链接静态库

未定义弱函数的引用(静态库+ GCC)

c ++对静态库函数的“未定义引用”[重复]

与代码块一起使用时,使用 Visual Studio 创建的静态库显示对 Myfunction 的未定义引用