Using Crypto++ Static Library in a Qt Project

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

Using a static library in Qt Creator

LIBS += -L[path to lib] -l[name of lib]

Note! that filename of lib: lib[nameOfLib].a and you have to pass only original part -l[nameOfLib]

How to use static library in Qt 5.2?

You seem to have tried CONFIG+=static, but that is not meant for this use case. That is used when you would like to use build your library to be static after the end of the build.

This is not the case here because you already have static Qt libraries available, so what you wish instead, to link those statically against your executable.

You would need to use this in your qmake project file:

LIBS += -L/path/to/the/static/QtCore -lQtCore

You could also use, albeit this would make the build-system less portable across different platforms:

LIBS += /path/to/the/statis/QtCore/libQtCore.a

How do I build a static library and executable with Qt?

Filesystem layout:

MyProject
|_ myproject.pro
|_ core
|_ core.cpp
|_ core.h
|_ core.pro
|_ app
|_ main.cpp
|_ app.pro

myproject.pro:

TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = core \
app
app.depends = core

core.pro:

TEMPLATE = lib
CONFIG += staticlib
HEADERS = core.h
SOURCES = core.cpp

app.pro:

TEMPLATE = app
SOURCES = main.cpp
LIBS += -L../core -lcore
TARGET = ../app-exe # move executable one dire up

How to make Qt and Qtcreator link the libraries statically instead of dynamic?

You can use the CONFIG variable for this with qmake:

CONFIG += static

or

CONFIG += staticlib

However, you will need to make sure that you have all the libraries that you wish to bundle up, available as static.

This includes the Qt framework itself as well if you comply with the license to do so. The official installation only sets up dynamic libraries (.dll files), so you would need to build Qt on your own to accomplish this.

You could use the following commands to build Qt statically for your own purpose:

configure -developer-build -opensource -nomake examples -nomake tests -static
qmake -r
nmake

Note that in general when building third-party Qt softwares like yours, you better invoke qmake with the following parameter to pass your environment properly:

qmake -r -spec win32-msvc2010 

Please also noted that as Frank and ManuelH wrote in the comment, static linkage is not allowed if your application is not free licensed either a LGPL or at least compatible to LGPL, nor do you use commercial license for Qt. It is better to make sure about this before picking up your approach.

Once that is done, you can use the LIBS variable in the regular way, as in: pass the path of your static library to it along with the library name, so something like this:

LIBS += -L/path/to/the/static/library -lstaticlibraryname

Note that the static library name passed to the -l parameter should not contain the static library extension, for instance .lib on Windows.

As a fallback, you can always link other libraries statically, and put the Qt dll files beside the executable, and you deploy the folder as a "package". That is probably the easier way for you to go.



Related Topics



Leave a reply



Submit