You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义库编译正常但链接时出现未定义引用错误求助

问题:静态库MYCrypto依赖Crypto++,应用链接时出现未定义引用错误

问题背景

使用CMake构建自定义静态库MYCrypto,依赖Crypto++,库本身编译正常,但依赖它的应用编译时出现未定义引用错误。

MYCrypto库的CMake配置

add_library(MYCrypto Crypto.cpp)
target_link_libraries(MYCrypto libcrypto++.a)
set_target_properties(MYCrypto PROPERTIES PUBLIC_HEADER "includes/MYCrypto.hpp")
install(TARGETS File MYCrypto ARCHIVE DESTINATION ~/.local/dev-bin/bin PUBLIC_HEADER DESTINATION ~/.local/dev-bin/includes)

MYCrypto核心代码

MYCrypto.hpp

#ifndef MYCrypto
#define MYCrypto
#include <string>
namespace MYCrypto
{
    std::string hashSha256(std::string);
    std::string hashMd5(std::string);
}
#endif

Crypto.cpp

#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include <cryptopp/iterhash.h>
#include <cryptopp/cryptlib.h>
#include <cryptopp/sha.h>
#include <cryptopp/md5.h>
#include <sstream>
#include <iomanip>
#include "MYCrypto.hpp"

using namespace std;

template<typename T>
string encrypt(string data, T hasher)
{
    stringstream output;
    CryptoPP::byte* digest;

    hasher.Update((const CryptoPP::byte*)data.c_str(),data.size());
    digest = new CryptoPP::byte[hasher.DigestSize()];
    hasher.Final(digest);

    for (int i=0; i < hasher.DigestSize(); i++) output << hex << setw(2) << setfill('0') << (int)digest[i];
    delete[] digest;

    return output.str();
}

string MYCrypto::hashSha256(string data)
{
    return encrypt(data, CryptoPP::SHA256());
}

string MYCrypto::hashMd5(string data)
{
    return encrypt(data, CryptoPP::Weak1::MD5());
}

依赖应用的CMake配置

cmake_minimum_required(VERSION 3.0.0)
project(TEST VERSION 0.1.0)

include(CTest)

include_directories(~/.local/dev-bin/includes)
link_directories(~/.local/dev-bin/bin)

add_library(Archive Archive.cpp)
target_link_libraries(Archive MYCrypto)

应用核心代码

Archive.hpp

#ifndef Archive
#define Archive
#include <string>
#include <unordered_set>
namespace Archive
{
   std::string getImportPath(std::string);
   bool fileExistsInDatabase(std::string, std::string);
}
#endif

Archive.cpp

#include "MYCrypto.hpp"
#include "Archive.hpp"

using namespace std;

string Archive::getImportPath(string path)
{
    return MYCrypto::hashSha256(Path);
}

编译错误信息

[build] /usr/bin/ld: /home/user/.local/dev-bin/bin/libMYCrypto.a(Crypto.cpp.o):(.data.rel.ro._ZTVN8CryptoPP5Weak13MD5E[_ZTVN8CryptoPP5Weak13MD5E]+0x38): undefined reference to `CryptoPP::IteratedHashBase<unsigned int, CryptoPP::HashTransformation>::Update(unsigned char const*, unsigned long)'

原因分析

  1. 静态库特性限制:静态库只是自身目标文件的集合,不会自动将依赖的第三方库(如Crypto++)代码合并进来。应用链接MYCrypto时,链接器需要找到MYCrypto中调用的Crypto++函数实现,否则会触发未定义引用错误。
  2. CMake依赖传递缺失:原MYCrypto的CMake配置中,target_link_libraries(MYCrypto libcrypto++.a)未指定PUBLIC属性,导致下游应用无法自动继承对Crypto++的依赖。
  3. 代码语法错误:Archive.cpp中存在变量名大小写错误(Path应为path),虽不是链接错误直接原因,但会导致编译异常。

解决方案

1. 修正MYCrypto的CMake配置

将Crypto++的链接改为PUBLIC,让下游应用自动继承该依赖,同时修正install命令中的多余File目标:

add_library(MYCrypto Crypto.cpp)
# 使用PUBLIC传递Crypto++依赖给所有链接MYCrypto的目标
target_link_libraries(MYCrypto PUBLIC libcrypto++.a)
set_target_properties(MYCrypto PROPERTIES PUBLIC_HEADER "includes/MYCrypto.hpp")
# 移除多余的File目标
install(TARGETS MYCrypto ARCHIVE DESTINATION ~/.local/dev-bin/bin PUBLIC_HEADER DESTINATION ~/.local/dev-bin/includes)

2. 重新安装MYCrypto库

重新执行编译安装流程:

cd path/to/MYCrypto/build
cmake ..
make
make install

3. 修正应用代码中的变量名错误

修改Archive.cpp中的参数引用:

string Archive::getImportPath(string path)
{
    return MYCrypto::hashSha256(path);
}

4. 应用CMake无需额外修改(可选优化)

当前配置下,仅链接MYCrypto即可,PUBLIC属性会自动传递Crypto的依赖。若追求更规范的管理,可使用find_package查找Crypto并配置依赖。

关键说明

静态链接时,应用需要所有被调用的函数实现都能被链接器找到。MYCrypto作为静态库仅包含自身代码,依赖的Crypto++代码并未被打包。通过CMake的PUBLIC关键字,可将MYCrypto的依赖传递给下游应用,避免手动重复添加链接项。

内容的提问来源于stack exchange,提问作者Cryos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 02:25:21