自定义库编译正常但链接时出现未定义引用错误求助
问题:静态库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)'
原因分析
- 静态库特性限制:静态库只是自身目标文件的集合,不会自动将依赖的第三方库(如Crypto++)代码合并进来。应用链接MYCrypto时,链接器需要找到MYCrypto中调用的Crypto++函数实现,否则会触发未定义引用错误。
- CMake依赖传递缺失:原MYCrypto的CMake配置中,
target_link_libraries(MYCrypto libcrypto++.a)未指定PUBLIC属性,导致下游应用无法自动继承对Crypto++的依赖。 - 代码语法错误: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
相关产品推荐
相关产品推荐

