在 QT 项目中使用 Crypto++ 静态库

Using Crypto++ static library in a QT project

I have built cryptopp statically on my system it passes all tests too. These are the warning though I get during tests

WARNING: CRYPTOPP_NO_UNALIGNED_DATA_ACCESS is not defined in config.h.
WARNING: CRYPTOPP_INIT_PRIORITY is not defined in config.h.
WARNING: CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 is defined in config.h.
WARNING: You should make these changes in config.h, and not CXXFLAGS.
WARNING: You can 'mv config.recommend config.h', but it breaks versioning.
WARNING: See http://cryptopp.com/wiki/config.h for more details.

我现在 link 在我的 QT 项目文件中

TEMPLATE = app

LIBS += -L/usr/lib/libcryptopp.a
#LIBS += -lcryptopp

CONFIG += console c++11
CONFIG += staticlib

SOURCES += main.cpp \
hashdata.cpp

HEADERS += \
hashdata.hpp

但是当我编译这个时,我得到了所有未定义的错误。

hashdata.o: In function `hashdata::hashfunction(std::string)':
hashdata.cpp:(.text+0x1fb): undefined reference to `CryptoPP::Algorithm::Algorithm(bool)'
hashdata.cpp:(.text+0x270): undefined reference to `CryptoPP::SHA512::InitState(unsigned long long*)'
hashdata.cpp:(.text+0x29a): undefined reference to `CryptoPP::Algorithm::Algorithm(bool)'
hashdata.cpp:(.text+0x2a1): undefined reference to `vtable for CryptoPP::StringSinkTemplate<std::string>'
hashdata.cpp:(.text+0x30b): undefined reference to `CryptoPP::Filter::Filter(CryptoPP::BufferedTransformation*)'
hashdata.cpp:(.text+0x312): undefined reference to `vtable for CryptoPP::Grouper'
hashdata.cpp:(.text+0x35e): undefined reference to `CryptoPP::Filter::Detach(CryptoPP::BufferedTransformation*)'
hashdata.cpp:(.text+0x375): undefined reference to `CryptoPP::Filter::Filter(CryptoPP::BufferedTransformation*)'
hashdata.cpp:(.text+0x37c): undefined reference to `vtable for CryptoPP::BaseN_Encoder'
hashdata.cpp:(.text+0x3d3): undefined reference to `CryptoPP::Filter::Detach(CryptoPP::BufferedTransformation*)'
hashdata.cpp:(.text+0x3e5): undefined reference to `CryptoPP::ProxyFilter::ProxyFilter(CryptoPP::BufferedTransformation*, unsigned long, unsigned long, CryptoPP::BufferedTransformation*)'
hashdata.cpp:(.text+0x3ec): undefined reference to `vtable for CryptoPP::HexEncoder'
hashdata.cpp:(.text+0x452): undefined reference to `vtable for CryptoPP::AlgorithmParametersTemplate<int>'
hashdata.cpp:(.text+0x4af): undefined reference to `vtable for CryptoPP::AlgorithmParametersTemplate<CryptoPP::ConstByteArrayParameter>'
...

之前在google搜索的时候也看到过类似的问题,但是解决方案不清楚。可能是因为 C++11 标志?

I have built cryptopp statically on my system it passes all tests too. These are the warning though I get during tests

WARNING: CRYPTOPP_NO_UNALIGNED_DATA_ACCESS is not defined in config.h. WARNING: CRYPTOPP_INIT_PRIORITY is not defined in config.h. WARNING: CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 is defined in config.h. WARNING: You should make these changes in config.h, and not CXXFLAGS. WARNING: You can 'mv config.recommend config.h', but it breaks versioning. WARNING: See http://cryptopp.com/wiki/config.h for more details.

我可以对此警告发表评论。您应该执行它所说的步骤:

mv config.recommend config.h

config.recommend 通过完全避免在不破坏版本控制的情况下 无法 删除的已知未定义行为,使库成为更好的配置。由于您似乎没有版本控制问题(例如 Fedora 或 Debian),因此您可以执行迁移。


I now link this in my QT project file as

TEMPLATE = app

LIBS += -L/usr/lib/libcryptopp.a
#LIBS += -lcryptopp

CONFIG += console c++11
...

构建 Crypto++ 时,您应该为库和应用程序使用相同的编译器和标志。我建议如下。

加密++:

# Be sure to 'mv config.recommend config.h'
export CXXFAGS="-DNDEBUG -g2 -O3 -std=c++11"
make static dynamic test

Qt App

# main.pro file
QMAKE_CXXFLAGS += -DNDEBUG -g2 -O3

另请参阅 Crypto++ wiki 上的 GNUmakefile | Building the Library


hashdata.o: In function `hashdata::hashfunction(std::string)':
hashdata.cpp:(.text+0x1fb): undefined reference to `CryptoPP::Algorithm::Algorithm(bool)'
hashdata.cpp:(.text+0x270): undefined reference to `CryptoPP::SHA512::InitState(unsigned long long*)'
...

这些来自源 (*.cpp) 文件。我猜测(这纯粹是猜测)两个问题之一:

  • C++03 与 C++11 导致缺少符号
  • QT Creator 未使用 libcryptopp.a

使用nm检查符号。类似于以下内容(“ T ”在文本部分告诉您它的定义):

$ nm libcryptopp.a 2>/dev/null | c++filt | \
     grep 'Algorithm::Algorithm(bool)' | grep ' T '
0000000000000060 T CryptoPP::Algorithm::Algorithm(bool)
0000000000000070 T CryptoPP::Algorithm::Algorithm(bool)

如果 QT Creator 没有找到 Crypto++ 库,则可以看到类似 Adding external library into Qt Creator project.

的内容

来自评论:

-lcryptopp works, but I don't know why -L/usr/lib/libcryptopp.a doesn't. ... Because if a person had both static and dynamic libraries, I still don't know how to force linking static ones.

存档,如 libcryptopp.a,是目标文件的集合。您将其添加到 OBJECTS,而不是 LIBS,因此您 want something like:

# main.pro file
OBJECTS += /usr/lib/libcryptopp.a

您使用 -L 指定链接器的库路径。它对 -L/usr/lib/libcryptopp.a 没有多大意义,因为它用于路径。


Additional note is that when both the static and dynamic libs were present it was automatically linking the dynamic lib. Do you know how to force static linking ?

在 Linux 上,您可以通过 (1) -Bstatic -lcryptopp 强制静态链接;或 (2) 直接指定 /usr/lib/libcryptopp.a。加密++ test program uses method (2):

g++ main.cpp /usr/lib/libcryptopp.a -o main.exe

在 OS X 上,链接器总是链接到动态对象。它甚至在 iOS 上也是如此,其中通常不允许用户空间加载动态对象。为避免动态链接,(1) 移动或重命名 *.dylib;或 (2) 直接指定 /usr/lib/libcryptopp.a。加密++ test program uses method (2):

g++ main.cpp /usr/lib/libcryptopp.a -o main.exe