2

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
  • 97,681
  • 90
  • 411
  • 885
  • Crypto++ has some headers to include in your project. Add something like `HEADERS += path/to/cryptopps/headers/you/are/using.hpp` in your project file. – ForceBru Aug 11 '16 at 10:17
  • my hashdata.hpp has `"cryptopp/filters.h" ` and QT doesnt complain file not found. Adding it to `HEADER += ` will just copy these files to my project. But I will try anyway. – itsnevertoobadtoaskforhelp Aug 11 '16 at 10:21
  • do you have the command line which is generated ? – Bhaal22 Aug 11 '16 at 10:41
  • ok I was doing nonsense maybe. my commented out section -lcryptopp works. I had dynamic libraries first and I wanted to be sure I was choosing the static one while compiling. Now I deleted my dynamic libs and kept just the static and -lcryptopp works. – itsnevertoobadtoaskforhelp Aug 11 '16 at 10:42
  • though I have a question is `-L/usr/lib/libcryptopp.a` wrong way ? I thought -lcryptopp should do the same thing. – itsnevertoobadtoaskforhelp Aug 11 '16 at 10:45
  • @itsnevertoobadtoaskforhelp - You should provide an answer to your question to help others in the future. Its OK to answer your own question. – jww Aug 11 '16 at 20:16
  • @jww as I said -lcryptopp works, but I don't know why -L/usr/lib/libcryptopp.a doesn't. I don't want to provide a misguided answer. Because if a person had both static and dynamic libraries, I still don't know how to force linking static ones. – itsnevertoobadtoaskforhelp Aug 12 '16 at 07:29
  • @itsnevertoobadtoaskforhelp - Use `OBJECTS += /usr/lib/libcryptopp.a`. An archive is a collection of object files. Just specify it like you would any other object file. – jww Aug 12 '16 at 21:13

1 Answers1

2

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:

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

An archive, like libcryptopp.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

You use -L to specify a library path to a linker. It does not make much sense to -L/usr/lib/libcryptopp.a since its used for paths.


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 ?

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
Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
  • Additional comments to this answer. I tried checking for missing symbols and there aren't any. The link says for QT the correct way is `LIBS +=-L/"PATH" -lcrptopp` is the correct way to linking in QT. Since it is in the DEFAULT_PATH anyway the path isn't required. 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 ? – itsnevertoobadtoaskforhelp Aug 12 '16 at 07:38