在VSCode中用MinGW编译CryptoPP 8.7.0时的链接错误求助
问题描述
我下载了CryptoPP 8.7.0,尝试在VSCode中使用MinGW编译。编译参数为:
A:\msys64\mingw64\bin\g++.exe -g A:\Andrey_dev\AES256_GSM_C++\test.cpp -static -static-libgcc -static-libstdc++ -lcrypto++ -o A:\Andrey_dev\AES256_GSM_C++\test.exe
编译时出现错误:找不到-lcrypto++(使用-lcryptopp也报错)。尝试在tasks.json中添加-L ${fileDirname}\cryptopp后,又出现大量未定义引用错误。后来通过MSYS2安装CryptoPP后,大部分问题解决,但又出现libcryptopp.a中std::istream::seekg等未定义引用,测试代码如下:
#include "cryptopp/cryptlib.h" #include "cryptopp/rijndael.h" #include "cryptopp/modes.h" #include "cryptopp/files.h" #include "cryptopp/osrng.h" #include "cryptopp/hex.h" #include <iostream> #include <string> #include <windows.h> using namespace std; int main(int argc, char *argv[]) { using namespace CryptoPP; AutoSeededRandomPool prng; HexEncoder encoder(new FileSink(std::cout)); SecByteBlock key(AES::DEFAULT_KEYLENGTH); SecByteBlock iv(AES::BLOCKSIZE); prng.GenerateBlock(key, key.size()); prng.GenerateBlock(iv, iv.size()); std::string plain = "CBC Mode Test"; std::string cipher, recovered; std::cout << "plain text: " << plain << std::endl; /********************************* \*********************************/ try { CBC_Mode<AES>::Encryption e; e.SetKeyWithIV(key, key.size(), iv); StringSource s(plain, true, new StreamTransformationFilter(e, new StringSink(cipher)) // StreamTransformationFilter ); // StringSource } catch (const Exception &e) { std::cerr << e.what() << std::endl; exit(1); } /********************************* \*********************************/ std::cout << "key: "; encoder.Put(key, key.size()); encoder.MessageEnd(); std::cout << std::endl; std::cout << "iv: "; encoder.Put(iv, iv.size()); encoder.MessageEnd(); std::cout << std::endl; std::cout << "cipher text: "; encoder.Put((const BYTE *)&cipher[0], cipher.size()); encoder.MessageEnd(); std::cout << std::endl; /********************************* \*********************************/ try { CBC_Mode<AES>::Decryption d; d.SetKeyWithIV(key, key.size(), iv); StringSource s(cipher, true, new StreamTransformationFilter(d, new StringSink(recovered)) // StreamTransformationFilter ); // StringSource std::cout << "recovered text: " << recovered << std::endl; } catch (const Exception &e) { std::cerr << e.what() << std::endl; exit(1); } return 0; }
解决办法
1. 修复库文件找不到的问题
- MSYS2安装的CryptoPP库默认存放在
/mingw64/lib,MinGW会自动搜索该路径,无需手动添加-L参数。注意必须使用MSYS2自带的MinGW终端编译,而非系统CMD,否则g++无法识别MSYS2的库路径。 - 正确的链接参数是
-lcryptopp,而非-lcrypto++——MSYS2安装的包名为mingw-w64-x86_64-cryptopp,对应库文件是libcryptopp.a或libcryptopp.dll.a。
2. 解决静态编译时的标准库符号未定义问题
你使用了-static全静态编译,但MSYS2默认安装的CryptoPP库依赖动态标准库,直接全静态链接会缺失std::istream相关符号,可通过两种方式解决:
方式一:改用半静态编译(推荐)
保留动态链接CryptoPP,仅静态链接gcc和stdc++,去掉-static参数:
A:\msys64\mingw64\bin\g++.exe -g A:\Andrey_dev\AES256_GSM_C++\test.cpp -static-libgcc -static-libstdc++ -lcryptopp -o A:\Andrey_dev\AES256_GSM_C++\test.exe
方式二:自行编译静态CryptoPP库
若必须全静态编译,需手动从源码构建静态库:
- 打开MSYS2的MinGW64终端,进入CryptoPP 8.7.0源码目录
- 执行
make static编译静态库 - 执行
make install将库文件和头文件安装到/mingw64路径 - 再用
-static -lcryptopp参数编译你的代码
3. VSCode tasks.json配置参考
确保tasks.json使用MSYS2的g++,并配置正确参数:
{ "version": "2.0.0", "tasks": [ { "label": "build", "type": "shell", "command": "A:/msys64/mingw64/bin/g++.exe", "args": [ "-g", "${file}", "-static-libgcc", "-static-libstdc++", "-lcryptopp", "-o", "${fileDirname}/${fileBasenameNoExtension}.exe" ], "group": { "kind": "build", "isDefault": true }, "problemMatcher": ["$gcc"] } ] }
内容的提问来源于stack exchange,提问作者reExecute_IV
相关产品推荐
相关产品推荐

