itsnevertoobadtoaskforhelp itsnevertoobadtoaskforhelp - 3 months ago 53
C++ Question

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.


I now link this in my QT project file as

TEMPLATE = app

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

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

SOURCES += main.cpp \
hashdata.cpp

HEADERS += \
hashdata.hpp


But when I compile this I get all undefined errors.

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>'
...


I have seen a similar problem previously when I searched in google, but the solution isn't clear. Could it be because of C++11 flags ?

jww jww
Answer

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.

I can comment on this warning. You should perform the steps it says:

mv config.recommend config.h

config.recommend puts the library is a better configuration by completely avoiding known undefined behavior that could not be removed without breaking versioning. Since you don't appear to have versioning issues (like say, Fedora or Debian), then you can perform the move.


I now link this in my QT project file as

TEMPLATE = app

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

CONFIG += console c++11
...

When you build Crypto++, you should use the same compiler and flags for the library and app. I suggest the following.

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

Also see GNUmakefile | Building the Library on the Crypto++ wiki.


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*)'
...

These are coming from source (*.cpp) files. I'm guessing (and its purely a guess) one of two problems:

  • C++03 vs C++11 is causing missing symbols
  • QT Creator is not using libcryptopp.a

Use nm to inspect the symbols. Something like the following (the ' T " tells you its defined and in the text section):

$ 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)

If the symbols are present by QT Creator is not finding the Crypto++ library, then see something like Adding external library into Qt Creator project.


From Comments:

The link says for QT the correct way is LIBS +=-L/"PATH" -lcrptopp ...

An archive, like libcrypto.a, is a collection of object files. You add it to OBJECTS, not LIBS, so you want something like:

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

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

On Linux, you can force static linking by either (1) -Bstatic -lcryptopp; or (2) directly specifying /usr/lib/libcryptopp.a. The Crypto++ test program uses method (2):

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

On OS X, the linker always links to the dynamic object. It even does so on iOS, where userland is usually not allowed to load dynamic objects. To avoid dynamic linking, either (1) move or rename the *.dylib; or (2) directly specifying /usr/lib/libcryptopp.a. The Crypto++ test program uses method (2):

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