【问题标题】:Linking Crypto++ fails when building a C++ project using CMake使用 CMake 构建 C++ 项目时链接 Crypto++ 失败
【发布时间】:2020-10-13 11:24:19
【问题描述】:

我的项目结构如下:

myexec/
|-main.cpp
|-hashing.cpp
|-hashing.h
|-CMakeLists.txt

我的小软件需要Crypto++,我在这个路径下构建的最新版本:

C:\Users\myuser\cryptopp

CMakeLists.txt 是:

cmake_minimum_required (VERSION 3.8)

project ("MyExec")

add_executable(MyExec "main.cpp", "hashing.h", "hashing.cpp")

find_library(CRYPTOPP_LIB cryptopp "C:/Users/myuser/cryptopp/Win32/DLL_Output/Debug")
target_link_libraries(MyExec PUBLIC "${CRYPTOPP_LIB}")

target_include_directories(MyExec PUBLIC "C:/Users/myuser/cryptopp")

hashing.cpp 是:

#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 // Needed to use MD5 in Crypto++

#include <cryptlib.h>
#include <md5.h>

#include "Hashing.h"

using namespace CryptoPP;

std::string get_hash(const std::string& str)
{
    std::string digest;
    Weak::MD5 hash;

    hash.Update((const byte*)(str.data()), str.size());
    digest.resize(hash.DIGESTSIZE);
    hash.Final((byte*)&digest[0]);

    return digest;
}

问题

当我在我的 Win10 x64 机器上的 VS 2019 社区中编译这个时,我得到这个链接错误:

C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\Hashing.cpp.obj : error LNK2019: unresolved external symbol "public: __cdecl CryptoPP::Algorithm::Algorithm(bool)" (??0Algorithm@CryptoPP@@QEAA@_N@Z) referenced in function "public: __cdecl CryptoPP::HashTransformation::HashTransformation(void)" (??0HashTransformation@CryptoPP@@QEAA@XZ)
C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\Hashing.cpp.obj : error LNK2001: unresolved external symbol "public: virtual bool __cdecl CryptoPP::HashTransformation::TruncatedVerify(unsigned char const *,unsigned __int64)" (?TruncatedVerify@HashTransformation@CryptoPP@@UEAA_NPEBE_K@Z)
C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\Hashing.cpp.obj : error LNK2019: unresolved external symbol "public: virtual void __cdecl CryptoPP::IteratedHashBase<unsigned int,class CryptoPP::HashTransformation>::Update(unsigned char const *,unsigned __int64)" (?Update@?$IteratedHashBase@IVHashTransformation@CryptoPP@@@CryptoPP@@UEAAXPEBE_K@Z) referenced in function "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl get_hash(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?get_hash@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBV34@@Z)
C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\Hashing.cpp.obj : error LNK2001: unresolved external symbol "public: virtual unsigned char * __cdecl CryptoPP::IteratedHashBase<unsigned int,class CryptoPP::HashTransformation>::CreateUpdateSpace(unsigned __int64 &)" (?CreateUpdateSpace@?$IteratedHashBase@IVHashTransformation@CryptoPP@@@CryptoPP@@UEAAPEAEAEA_K@Z)
C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\Hashing.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl CryptoPP::IteratedHashBase<unsigned int,class CryptoPP::HashTransformation>::Restart(void)" (?Restart@?$IteratedHashBase@IVHashTransformation@CryptoPP@@@CryptoPP@@UEAAXXZ)
C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\Hashing.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl CryptoPP::IteratedHashBase<unsigned int,class CryptoPP::HashTransformation>::TruncatedFinal(unsigned char *,unsigned __int64)" (?TruncatedFinal@?$IteratedHashBase@IVHashTransformation@CryptoPP@@@CryptoPP@@UEAAXPEAE_K@Z)
C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\Hashing.cpp.obj : error LNK2001: unresolved external symbol "protected: virtual unsigned __int64 __cdecl CryptoPP::IteratedHashBase<unsigned int,class CryptoPP::HashTransformation>::HashMultipleBlocks(unsigned int const *,unsigned __int64)" (?HashMultipleBlocks@?$IteratedHashBase@IVHashTransformation@CryptoPP@@@CryptoPP@@MEAA_KPEBI_K@Z)
C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\Hashing.cpp.obj : error LNK2019: unresolved external symbol "public: static void __cdecl CryptoPP::Weak1::MD5::InitState(unsigned int *)" (?InitState@MD5@Weak1@CryptoPP@@SAXPEAI@Z) referenced in function "protected: virtual void __cdecl CryptoPP::IteratedHashWithStaticTransform<unsigned int,struct CryptoPP::EnumToType<enum CryptoPP::ByteOrder,0>,64,16,class CryptoPP::Weak1::MD5,0,0>::Init(void)" (?Init@?$IteratedHashWithStaticTransform@IU?$EnumToType@W4ByteOrder@CryptoPP@@$0A@@CryptoPP@@$0EA@$0BA@VMD5@Weak1@2@$0A@$0A@@CryptoPP@@MEAAXXZ)
C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\Hashing.cpp.obj : error LNK2019: unresolved external symbol "public: static void __cdecl CryptoPP::Weak1::MD5::Transform(unsigned int *,unsigned int const *)" (?Transform@MD5@Weak1@CryptoPP@@SAXPEAIPEBI@Z) referenced in function "protected: virtual void __cdecl CryptoPP::IteratedHashWithStaticTransform<unsigned int,struct CryptoPP::EnumToType<enum CryptoPP::ByteOrder,0>,64,16,class CryptoPP::Weak1::MD5,0,0>::HashEndianCorrectedBlock(unsigned int const *)" (?HashEndianCorrectedBlock@?$IteratedHashWithStaticTransform@IU?$EnumToType@W4ByteOrder@CryptoPP@@$0A@@CryptoPP@@$0EA@$0BA@VMD5@Weak1@2@$0A@$0A@@CryptoPP@@MEAAXPEBI@Z)
C:\Users\myuser\cryptopp\Win32\DLL_Output\Debug\cryptopp.lib : warning LNK4272: library machine type 'x86' conflicts with target machine type 'x64'
C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\myexec.exe : fatal error LNK1120: 9 unresolved externals
  ninja: build stopped: subcommand failed.

我在这里做错了什么?


编辑

在得到@botje 和@nelsonsule 的良好反馈后,我修复了x64 问题:

find_library(CRYPTOPP_LIB cryptopp "C:/Users/myuser/cryptopp/x64/DLL_Output/Release")

这会导致拱形不匹配警告消失,但我会收到 2 个链接错误:

C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\Hashing.cpp.obj : error LNK2019: unresolved external symbol "public: static void __cdecl CryptoPP::Weak1::MD5::InitState(unsigned int *)" (?InitState@MD5@Weak1@CryptoPP@@SAXPEAI@Z) referenced in function "protected: virtual void __cdecl CryptoPP::IteratedHashWithStaticTransform<unsigned int,struct CryptoPP::EnumToType<enum CryptoPP::ByteOrder,0>,64,16,class CryptoPP::Weak1::MD5,0,0>::Init(void)" (?Init@?$IteratedHashWithStaticTransform@IU?$EnumToType@W4ByteOrder@CryptoPP@@$0A@@CryptoPP@@$0EA@$0BA@VMD5@Weak1@2@$0A@$0A@@CryptoPP@@MEAAXXZ)
C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\Hashing.cpp.obj : error LNK2019: unresolved external symbol "public: static void __cdecl CryptoPP::Weak1::MD5::Transform(unsigned int *,unsigned int const *)" (?Transform@MD5@Weak1@CryptoPP@@SAXPEAIPEBI@Z) referenced in function "protected: virtual void __cdecl CryptoPP::IteratedHashWithStaticTransform<unsigned int,struct CryptoPP::EnumToType<enum CryptoPP::ByteOrder,0>,64,16,class CryptoPP::Weak1::MD5,0,0>::HashEndianCorrectedBlock(unsigned int const *)" (?HashEndianCorrectedBlock@?$IteratedHashWithStaticTransform@IU?$EnumToType@W4ByteOrder@CryptoPP@@$0A@@CryptoPP@@$0EA@$0BA@VMD5@Weak1@2@$0A@$0A@@CryptoPP@@MEAAXPEBI@Z)
C:\Users\myuser\Documents\myexec\out\build\x64-Debug (default)\myexec.exe : fatal error LNK1120: 2 unresolved externals

【问题讨论】:

  • "C:\Users\myuser\cryptopp\Win32\DLL_Output\Debug\cryptopp.lib : 警告 LNK4272: 库机器类型 'x86' 与目标机器类型 'x64' 冲突" 你正在尝试将 x86 cryptopp 库链接到 x64 MyExec 二进制文件
  • 这是一个警告......真的是这个问题的原因吗?
  • 这就是原因。
  • 好吧,我明白了,我之前的评论实际上很愚蠢......我没有看到警告,我知道拱门不同显然是一个问题......我想我需要重建图书馆
  • @Andry LNK2019 错误表示“CryptoPP::Weak1::MD5”命名空间(可能是单独的头文件)中定义了一些在库文件(lib )。由于您现在肯定链接到该库,因此请检查您是否使用了与该库对应的正确头文件。

标签: c++ cmake crypto++


【解决方案1】:

C:\Users\myuser\cryptopp\Win32\DLL_Output\Debug\cryptopp.lib : warning LNK4272: library machine type 'x86' conflicts with target machine type 'x64'

您的问题似乎来自这里。您在更高的操作系统架构 (x64) 上运行,同时链接到为 32 位的较低操作系统架构 (x86) 设计的加密库。考虑链接到为 x64 设计的 cyrpto 库

【讨论】:

  • 我仍然收到该错误,但我可以看到它使用的是旧路径。 CMake 是否缓存了 CMakeLists 文件中的内容?
  • 我应用了您的建议并针对 x64 重新构建了 Crypto++。警告现在消失了,但仍然存在两个链接错误...
【解决方案2】:

好的,我已经设法构建了一个最小的可重现示例。

下载https://github.com/weidai11/cryptopp并解压到E:\__experiments\cryptopp\cryptopp-master

在 Visual Studio 中打开 cryptest.sln,选择 x64 配置并构建。

目录 E:__experiments\cryptopp\testprog:

build\
src\main.cpp
CMakeLists.txt

CMakeLists.txt:

cmake_minimum_required (VERSION 3.15)

# this enables the MSVC_RUNTIME_LIBRARY property for slightly older CMake versions
cmake_policy(SET CMP0091 NEW)

project ("MD5test")

add_executable(MD5test "src/main.cpp")

# this is equivalent to setting C/C++ -> Code Generation -> Runtime Library in the Visual Studio project property pages
set_property(TARGET MD5test 
             PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

find_library(CRYPTOPP_LIB cryptlib.lib HINTS E:/__experiments/cryptopp/cryptopp-master/x64/Output/*)

target_link_libraries(MD5test PUBLIC "${CRYPTOPP_LIB}")

target_include_directories(MD5test PUBLIC "E:/__experiments/cryptopp/cryptopp-master")

src\main.cpp:

#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 // Needed to use MD5 in Crypto++

#include <cryptlib.h>
#include <md5.h>
#include <string>
#include <iostream>

#define byte unsigned char

using std::string;

string get_hash(const string& str)
{
    string digest;
    CryptoPP::Weak::MD5 hash;

    hash.Update((const byte*)(str.data()), str.size());
    digest.resize(hash.DIGESTSIZE);
    hash.Final((byte*)&digest[0]);

    return digest;
}


int main (int argc, char** argv)
{
    string hash = get_hash("coconuts");
    std::cout << hash << std::endl;
    return 0;

打开“VS2019 的开发人员命令提示符”并导航到 testprog 目录,然后输入:

del build
mkdir build
cd build
cmake  -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ..
cmake --build .

Debug\MD5test.exe

或者在测试根目录中编写一个批处理文件do_build.bat,这样您就可以使用普通的命令提示符窗口:

call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat"
cd .
del /F /Q build
rd /S /Q build
mkdir build
cd build
cmake  -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON ..
cmake --build .
cd ..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-30
    • 2019-09-04
    相关资源
    最近更新 更多