【发布时间】:2022-12-07 06:16:58
【问题描述】:
我目前正在使用 cmake 和 crypto++ 构建一个库。虽然库编译得很好,但引用它的代码却没有。
库的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)
我的密码.hpp
#ifndef MYCrypto
#define MYCrypto
#include <string>
namespace MYCrypto
{
std::string hashSha256(std::string);
std::string hashMd5(std::string);
}
#endif
密码.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)
存档.hpp
#ifndef Archive
#define Archive
#include <string>
#include <unordered_set>
namespace Archive
{
std::string getImportPath(std::string);
bool fileExistsInDatabase(std::string, std::string);
}
#endif
存档.cpp
#include "MYCrypto.hpp"
#include "Archive.hpp"
using namespace std;
string Archive::getImportPath(string path)
{
return MYCrypto::hashSha256(Path);
}
当我尝试编译我的第二个 cmake progject 时,出现这样的错误
[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++。
我如何编译第二个项目?
【问题讨论】:
-
encrypt在命名空间MYCrypto中声明,然后在全局命名空间中定义了encrypt。 -
@463035818_is_not_a_number 恐怕我不明白你在说什么。
encrypt未在声明命名空间的 MYCrypto.hpp 中的任何位置定义。我只在全球范围内声明过encrypt。是否需要放入 MYCrypto 命名空间才能看到? -
你在链接cryptopp吗?在第二个项目中,我的意思是。 cryptopp 不是仅包含标头的库,因此您甚至需要在第二个项目上链接它。您的第一个项目不会包含任何关于 cryptopp 代码的内容(内联代码除外)。这两个项目必须使用相同版本的 cryptopp obv 否则你会看到地狱
-
静态链接仅对应用程序有意义。语言中有“一个定义规则”,如果您链接
liba和libb库都定义了foo(即使它是相同的并且通过过渡依赖定义),您仍然应该从链接器收到多重定义警告 -通常不提供符号隔离(Windows 上的 DLL 需要完全解析所有依赖关系,但 Linux 上不需要,静态库只是目标文件的存档)。通常有特定于链接器的方法来强制合并静态库,但它会导致多次链接库的麻烦。 -
是的。此外,您可以通过 cmake export 您的库,它会在使用时自动链接依赖项,例如通过
find_package。
标签: c++ cmake static-libraries static-linking crypto++