我收到此错误:
CMakeFiles/Athena.dir/Startup/main.cpp.o: In function `CryptoPP::ClonableImpl<CryptoPP::BlockCipherFinal<(CryptoPP::CipherDir)0, CryptoPP::Rijndael::Enc>, CryptoPP::Rijndael::Enc>::ClonableImpl()':
/home/dev/workspace/Athena/lib/cryptopp/simple.h:26: undefined reference to `CryptoPP::Rijndael::Enc::Enc()'
collect2: error: ld returned 1 exit status
CMakeFiles/Athena.dir/build.make:434: recipe for target 'Athena'
当我尝试将CryptoPP链接到我的程序时。
这是我的CMakeLists.txt:
cmake_minimum_required(VERSION 3.8)
project(Athena)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -fpermissive -Wno-deprecated -Wno-int-to-pointer-cast -Wno-deprecated-declarations")
include_directories(lib/SQLiteCpp/include)
add_subdirectory(lib/SQLiteCpp)
include_directories(lib/cryptopp)
add_subdirectory(lib/cryptopp)
include_directories(lib/json/src)
add_subdirectory(lib/json)
set(SOURCE_FILES
Startup/main.cpp)
add_executable(Athena ${SOURCE_FILES})
target_link_libraries(Athena SQLiteCpp sqlite3 pthread dl cryptopp)
以下是我的包含:
#include "modes.h" // For CTR_Mode
#include "filters.h" //For StringSource
#include "aes.h" // For AES
我已经尝试通过find_library通过find_package链接cryptopp,我甚至尝试编写脚本来手动下载并制作cryptopp。我真的没有想法,我也很确定这不是我的代码(我在cryptopp wiki的一个例子中粘贴)。
答案 0 :(得分:1)
您的CMakeLists.txt
看起来不正确。你应该做两件事。首先,您应该复制GNUmakefile
用于目标的源文件的确切列表。其次,您应该使用GNUmakefile
使用的相同标记。您必须运行项目的makefile或msbuild文件才能获得这些文件。
您还应该考虑使用ExternalProject_Add
;并停止尝试让Cmake建立库。该库已经提供了一个Makefile和MSBuild文件,用于在它支持的所有平台上构建库,因此Cmake是多余的,不需要。没有理由让Cmake创建具有错误选项和标志的构建文件,因为我们已经为其提供了正确的选项。另请参阅Stack Overflow上的How to use CMake ExternalProject_Add or alternatives in a cross platform way?。
在Crypto ++中尝试支持Cmake一年后,我会说很多经验。另请参阅Crypto ++ wiki上的Cmake。
CMakeFiles/Athena.dir/Startup/main.cpp.o: In function `CryptoPP::ClonableImpl<CryptoPP::BlockCipherFinal<(CryptoPP::CipherDir)0, CryptoPP::Rijndael::Enc>, CryptoPP::Rijndael::Enc>::ClonableImpl()':
/home/dev/workspace/Athena/lib/cryptopp/simple.h:26: undefined reference to `CryptoPP::Rijndael::Enc::Enc()'
collect2: error: ld returned 1 exit status
CMakeFiles/Athena.dir/build.make:434: recipe for target 'Athena'
您应该显示用于构建库的命令行。这是Crypto ++取消对Cmake的支持的另一个原因 - 它隐藏了用于故障排除的必要信息,比如用于构建源文件的命令行。这导致了糟糕的错误报告。
Rijndael::Enc::Enc()
用于在未对齐的数据访问生效时使代码加强对侧通道攻击。构造函数本身没有使用;但它需要代码路径,因为它中设置了一些值。
如果查看rijndael.h
,当平台为IA-32,ARM或PowerPC时,您将看到构造函数已启用。但感兴趣的源文件实际上是rijndael.cpp
,在第1070行附近:
#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86
static inline bool AliasedWithTable(const byte *begin, const byte *end)
{
ptrdiff_t s0 = uintptr_t(begin)%4096, s1 = uintptr_t(end)%4096;
ptrdiff_t t0 = uintptr_t(Te)%4096, t1 = (uintptr_t(Te)+sizeof(Te))%4096;
if (t1 > t0)
return (s0 >= t0 && s0 < t1) || (s1 > t0 && s1 <= t1);
else
return (s0 < t1 || s1 <= t1) || (s0 >= t0 || s1 > t0);
}
struct Locals
{
word32 subkeys[4*12], workspace[8];
const byte *inBlocks, *inXorBlocks, *outXorBlocks;
byte *outBlocks;
size_t inIncrement, inXorIncrement, outXorIncrement, outIncrement;
size_t regSpill, lengthAndCounterFlag, keysBegin;
};
const size_t s_aliasPageSize = 4096;
const size_t s_aliasBlockSize = 256;
const size_t s_sizeToAllocate = s_aliasPageSize + s_aliasBlockSize + sizeof(Locals);
Rijndael::Enc::Enc() : m_aliasBlock(s_sizeToAllocate) { }
#endif // CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86
#if CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARM64 || CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64
// Do nothing
Rijndael::Enc::Enc() { }
#endif
你需要弄清楚为什么Cmake正在捣乱CRYPTOPP_BOOL_X86
,CRYPTOPP_BOOL_X64
和朋友的定义。为此,您需要查看命令行,但Cmake会将其隐藏起来。
相关的,我们测试C ++ 17,你应该对那个标志没问题。但是,根据经验,这可能会导致问题:set(CMAKE_CXX_STANDARD 17)
。 Cmake没有很好的C ++支持。我们无法执行简单的project(cryptopp, CXX)
。另请参阅Tell CMake to use C++ compiler for C files coming from CMake?。
我将研究删除所有构建的构造函数;并在m_aliasBlock
中设置UncheckedSetKey
。这可能有助于解决这个问题。但它只是一个更大的工程问题的创可贴。 Cmake创造的更大的工程问题是我们撤回对它的支持的原因。
答案 1 :(得分:0)
尝试
target_link_libraries(Athena SQLiteCpp sqlite3 cryptopp pthread ${CMAKE_DL_LIBS})
我想改变库的排序可能有所帮助。使用${CMAKE_DL_LIBS}
代替dl
不是强制性的,但使用便携式CMake定义是一种很好的做法。