Использование статической библиотеки Crypto++ в проекте QT
Я статически построил cryptopp в моей системе, он также проходит все тесты. Это предупреждение, хотя я получаю во время испытаний
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.
Теперь я связываю это в моем файле проекта 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?
1 ответ
Я статически построил cryptopp в моей системе, он также проходит все тесты. Это предупреждение, хотя я получаю во время испытаний
ВНИМАНИЕ: CRYPTOPP_NO_UNALIGNED_DATA_ACCESS не определен в config.h. ВНИМАНИЕ: CRYPTOPP_INIT_PRIORITY не определен в config.h. ВНИМАНИЕ: CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 определен в config.h. ВНИМАНИЕ: Вы должны внести эти изменения в config.h, а не в CXXFLAGS. ВНИМАНИЕ: Вы можете 'mv config.recommend config.h', но это нарушает управление версиями. ПРЕДУПРЕЖДЕНИЕ. См. http://cryptopp.com/wiki/config.h для получения более подробной информации.
Я могу прокомментировать это предупреждение. Вы должны выполнить шаги, которые он говорит:
mv config.recommend config.h
config.recommend
ставит библиотеку в лучшую конфигурацию, полностью избегая известного неопределенного поведения, которое не может быть удалено без нарушения контроля версий. Поскольку у вас нет проблем с версиями (например, Fedora или Debian), вы можете выполнить этот шаг.
Теперь я связываю это в моем файле проекта QT как
TEMPLATE = app LIBS += -L/usr/lib/libcryptopp.a #LIBS += -lcryptopp CONFIG += console c++11 ...
При сборке Crypto++ вы должны использовать один и тот же компилятор и флаги для библиотеки и приложения. Я предлагаю следующее.
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
Также смотрите GNUmakefile | Сборка библиотеки на 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*)' ...
Это из источника (*.cpp
) файлы. Я предполагаю (и это чисто предположение) одну из двух проблем:
- C++ 03 против C++11 вызывает пропущенные символы
- QT Creator не использует
libcryptopp.a
использование nm
осматривать символы. Что-то вроде следующего (буква "Т" говорит вам, что она определена и в текстовом разделе):
$ 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++, смотрите что-то вроде добавления внешней библиотеки в проект Qt Creator.
Из комментариев:
-lcryptopp
работает, но я не знаю почему-L/usr/lib/libcryptopp.a
не делает.... Потому что, если у человека были статические и динамические библиотеки, я до сих пор не знаю, как принудительно связывать статические библиотеки.
Архив, как libcryptopp.a
, это коллекция объектных файлов. Вы добавляете это к OBJECTS
не LIBS
так что вы хотите что-то вроде:
# main.pro file
OBJECTS += /usr/lib/libcryptopp.a
Ты используешь -L
указать путь к библиотеке для компоновщика. Это не имеет большого смысла -L/usr/lib/libcryptopp.a
так как его использовали для путей.
Дополнительное замечание: когда присутствовали статические и динамические библиотеки, он автоматически связывал динамическую библиотеку. Знаете ли вы, как заставить статические ссылки?
В Linux вы можете принудительно установить статическое связывание одним из следующих способов: (1) -Bstatic -lcryptopp
; или (2) непосредственно указав /usr/lib/libcryptopp.a
, Тестовая программа Crypto++ использует метод (2):
g++ main.cpp /usr/lib/libcryptopp.a -o main.exe
В OS X компоновщик всегда ссылается на динамический объект. Это даже происходит в iOS, где пользовательскому пространству обычно не разрешается загружать динамические объекты. Чтобы избежать динамического связывания, либо (1) переместите, либо переименуйте *.dylib
; или (2) непосредственно указав /usr/lib/libcryptopp.a
, Тестовая программа Crypto++ использует метод (2):
g++ main.cpp /usr/lib/libcryptopp.a -o main.exe