OpenSSL может понадобиться к примеру в HTTP клиенте, чтобы установить защищенное соединение.
OpenSSL это открытая свободная библиотека на C, которая не является частью Qt библиотек.
Примечание: тут описывается старая версия openssl 1.0.0.1 с TLS1.0. Подключение TLSv1.2 смотрите здесь openssl 1.0.2 под Qt Creator 2.4.1.
То есть хотя в исходниках QtSources и есть подкаталог с некоторыми исходниками для openssl , но они ссылаются на другие файлы , которых в поставке исходников QtSources нет. Например :
d:\qtsdk1.2.1\qtsources\4.8.1\src\network\ssl\qsslsocket_openssl_p.h:66: error: C1083: Cannot open include file: 'openssl/asn1.h': No such file or directory.
asn1.h например находится в исходниках свободного проекта OpenSSL.
Наша задача скачать OpenSSL, собрать статически библиотеки под тулчейном msvc2010 и подключить их к QT.
Нам понадобится NASM , Perl и MSVC2010.
NASM (Netwide Assembler) — свободный (LGPL и лицензия BSD) ассемблер для архитектуры Intel x86.
Perl вариант Strawberry подошел нормально.
Исходники openSSL те, что openssl-1.0.0d .
Далее запускаем самописный cmd файл для создания makefile:
@set path=D:\PROG\NASM;%PATH%
cd D:\OpenSSL\openssl-1.0.0d
perl Configure VC-WIN32 --prefix=D:\OpenSSL\1_0_0_1
pause
ms\do_ms
pause
И если первый этап без ошибок прошел потом запускаем второй cmd файл:
@set path=D:\PROG\NASM;%PATH%
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
cd D:\OpenSSL\openssl-1.0.0d
nmake -f ms\ntdll.mak
nmake -f ms\ntdll.mak install
pause
ntdll.mak - это Makefile с вариантом динамики
nt.mak - это Makefile с вариантом статики
Важно чтобы в nt.mak и ntdll.mak были указаны разные каталоги сборки, иначе последняя сборка затрет предыдущую.
Например для ntdll.mak:
INSTALLTOP=d:\OpenSSL\1_0_0_1dll
OPENSSLDIR=d:\OpenSSL\1_0_0_1dll\ssl
Например для nt.mak:
INSTALLTOP=d:\OpenSSL\1_0_0_1_static
OPENSSLDIR=d:\OpenSSL\1_0_0_1d_static\ssl
Если все прошло правильно в D:\OpenSSL\1_0_0_1\lib у нас появятся две lib библиотеки libeay32.lib и ssleay32.lib . Заголовочные файлы к ним будут в каталоге D:\OpenSSL\1_0_0_1_static\include.
В результате выполнения ntdll.mak в D:\OpenSSL\1_0_0_1dll\bin у нас появятся две dll библиотеки libeay32.dll и ssleay32.dll . Заголовочные файлы к ним будут в каталоге D:\OpenSSL\1_0_0_1dll\include . И еще в каталоге D:\OpenSSL\1_0_0_1dll\lib появятся файлы libeay32.lib , ssleay32.lib - это lib-ы в дополнение к динамическим dll.
Примечание: после выполнения ms\do_ms создаются Makefile-ы :
nt.mak - это с ключом комиляции -MT (static)
ntdll.mak - это с ключом комиляции -MD (dll)
Переходим к нашему Qt проекту
Далее вызываем config.exe для qt исходников:
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
configure.exe -opensource -release -mp -platform win32-msvc2010 -nomake examples -nomake demos -no-qt3support -no-scripttools -no-opengl -no-phonon -no-style-motif -no-style-cde -no-style-cleanlooks -no-style-plastique -no-sql-sqlite -qt-libjpeg -qt-zlib -qt-libpng -fast -static -openssl -openssl-linked OPENSSL_LIBS="-lcrypto -lssl" -I D:\OpenSSL\1_0_0_1\include -L D:\OpenSSL\1_0_0_1\lib
Примечание: В последних версиях openSSL файлы библиотек имеют другие названия libcrypto.lib и libssl.lib .
Обратите внимание на нашу ошибку OPENSSL_LIBS="-lcrypto -lssl" . При этом исходники самого Qt (каталог src) собираются нормально, так как им надо только -I D:\OpenSSL\1_0_0_1_static\include -L D:\OpenSSL\1_0_0_1_static\lib. А вот вашему проекту вложенному в src придется при линковке получить ошибку cannot open input file 'ssl.lib'. Хотя упоминания в вашем проекте о ssl.lib нигде нет...
Примечание: глобальная переменная OPENSSL_LIBS используется в исходниках Qt 4.8.1 только в файле ssl.pri :
LIBS_PRIVATE = $$OPENSSL_LIBS
Примечание: openssl-linked это похоже для подключения в качестве dll . То есть его не используем.
В результате выполнения config.exe в конце запускается некая утилита syncqt. Интересно что она делает ? Running syncqt....
При отсутствии ключа -dont-process (у config.exe) syncqt проходится по вложенным каталогам и изменяет содержание Makefile на примерно такое , лучше бы он этого не делал. Он создаёт Makefile-ы для каждого каталога с pro файлом. В результате исходники Qt придется пересобирать заново:
Тут написано как работать с configure.exe , практическое использование.
all:
D:\QtSDK1.2.1\QtSources\4.8.1\bin\qmake D:/QtSDK1.2.1/QtSources/4.8.1/src\_MY_\http\http.pro -o Makefile -spec win32-msvc2010
"$(MAKE)" -$(MAKEFLAGS) -f Makefile
first: all
qmake:
D:\QtSDK1.2.1\QtSources\4.8.1\bin\qmake D:/QtSDK1.2.1/QtSources/4.8.1/src\_MY_\http\http.pro -o Makefile -spec win32-msvc2010
Примечание: config.exe как результат своей работы создает две специальных файла .qmake.cache и configure.cache, Qt Creator будет их искать выше каталога своего текущего собираемого проекта. Просто отметим это , так как в конце эти два файла нам пригодятся для решения одной проблемы.
Далее когда вы зайдете в Qt Creator и сделаете run qmake , то Makefile опять будет изменен уже в соответствии с идеалогией Qt Creator. Это не надо забывать.
После того как Creator заново создаст Makefile при run qmake , примечательно что в результирующей папки для собираемых библиотек qt появятся файлы *.prl . Вот содержание одного из них :
QMAKE_PRL_BUILD_DIR = D:/QtSDK1.2.1/QtSources/4.8.1/src/network
QMAKE_PRO_INPUT = network.pro
QMAKE_PRL_TARGET = QtNetwork
QMAKE_PRL_DEFINES = QT_THREAD_SUPPORT
QMAKE_PRL_CONFIG = include_source_dir lex yacc warn_on uic resources incremental_off windows release ReleaseBuild Release build_pass qt warn_on release incremental flat link_prl precompile_header autogen_precompile_source copy_dir_files debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe release static msvc_mp stl exceptions rtti mmx 3dnow sse sse2 minimal-config small-config medium-config large-config full-config release incremental msvc_mp create_prl link_prl depend_includepath QTDIR_build release release ReleaseBuild Release build_pass openssl qt_install_headers qt warn_on depend_includepath qmake_cache target_qt debug_and_release static release ReleaseBuild Release build_pass no_autoqmake staticlib static moc thread
QMAKE_PRL_VERSION = 4
QMAKE_PRL_LIBS = ws2_32.lib /LIBPATH:D:\\OpenSSL\\1_0_0_1\\lib d:\\QtSDK1.2.1\\QtSources\\4.8.1\\lib\\QtCore.lib kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib libeay32.lib ssleay32.lib
Тут примечательно содержание QMAKE_PRL_LIBS . Похоже здесь находится расширенная информация о собранной библиотеке.
Похоже , что если вы будете использовать далее эту библиотеку (на этом же ПК), то Qt creator будет знать где лежат зависимые библиотеки (например наши openssl ), смотрите :
/LIBPATH:D:\\OpenSSL\\1_0_0_1_static\\lib
libeay32.lib ssleay32.lib
Теперь если мы создаем свою программу в дереве src , то есть внутри srс каталога, то нам в общем-то и не надо подключать библиотек libeay32.lib ssleay32.lib к своему проекту. То есть они будет подключены по результату работы config.exe , а потом по результату создания Makefile утилитой qmake. А именно в Makefile появятся примерно такие записи :
d:\QtSDK1.2.1\QtSources\4.8.1\lib\QtGui.prl \
d:\QtSDK1.2.1\QtSources\4.8.1\lib\QtNetwork.prl \
d:\QtSDK1.2.1\QtSources\4.8.1\lib\QtCore.prl
Теперь если взять ваш проект и вынести из дерева src, например перенести на другой диск, то результат работы qmake в Qt Creator будет другой, а именно выше приведенных строчек с prl не будет и вы нормально соберете проект, но есть нюанс: останется зависимость от Qt*****.dll , то есть проект похоже соберётся не статически. При запуске программы не найдена будет QtGui4.dll и т.д.
Если попытаться запустить config.exe с таким же параметрами в новом месте размещения вашего проекта, то это выдаст ошибку:
Invalid option "win32-msvc2010" for -platform.
Может показаться ,что ситуацию исправит добавление в pro файл вашего проекта этого, но это не влияет:
INCLUDEPATH = d:\OpenSSL\1_0_0_1_static\include\openssl
LIBS = -LD:\OpenSSL\1_0_0_1_static\lib -llibeay32 -lssleay32
Но оказывается есть способ сделать второй вариант вашего проекта статическим. Поскольку config.exe мы здесь не можем выполнить , но вот перенести .qmake.cache и configure.cache нам никто не запрещает?...
Смотрим и изучаем какие строчки файла .qmake.cache влияют на сборку статически:
LIBS = -LD:\\OpenSSL\\1_0_0_1_static\\lib
OBJECTS_DIR = tmp\\obj\\release_static
MOC_DIR = tmp\\moc\\release_static
RCC_DIR = tmp\\rcc\\release_static
INCLUDEPATH = D:\\OpenSSL\\1_0_0_1_static\\include
OPENSSL_LIBS=-llibeay32 -lssleay32
styles = windows windowsxp windowsvista
CONFIG = minimal-config small-config medium-config large-config full-config release incremental msvc_mp create_prl link_prl depend_includepath QTDIR_build
QT_BUILD_PARTS = libs tools docs translations
QMAKESPEC = D:\\QtSDK1.2.1\\QtSources\\4.8.1\\mkspecs\\win32-msvc2010
ARCH = windows
QT_BUILD_TREE = D:\\QtSDK1.2.1\\QtSources\\4.8.1
QT_SOURCE_TREE = D:\\QtSDK1.2.1\\QtSources\\4.8.1
QMAKE_MOC = $$QT_BUILD_TREE\\bin\\moc.exe
QMAKE_UIC = $$QT_BUILD_TREE\\bin\\uic.exe
QMAKE_UIC3 = $$QT_BUILD_TREE\\bin\\uic3.exe
QMAKE_RCC = $$QT_BUILD_TREE\\bin\\rcc.exe
QMAKE_DUMPCPP = $$QT_BUILD_TREE\\bin\\dumpcpp.exe
QMAKE_INCDIR_QT = $$QT_BUILD_TREE\\include
QMAKE_LIBDIR_QT = $$QT_BUILD_TREE\\lib
Оказывается влияют только две ниже приведенные строчки файла .qmake.cache:
QT_BUILD_TREE = D:\\QtSDK1.2.1\\QtSources\\4.8.1
QMAKE_INCDIR_QT = $$QT_BUILD_TREE\\include
configure.cache в данном вопросе не влияет.
Ну и наконец в чем отличие сборок получается : отличите в линковке в самом конце . Какой вариант собирает статику думаю очевиден :
link /LIBPATH:"d:\QtSDK1.2.1\Desktop\Qt\4.8.1\msvc2010\lib" ......
link /LIBPATH:"d:\QtSDK1.2.1\QtSources\4.8.1\lib" ......
Просто тупо используется разные пути к библиотекам , их как видно как минимум два варианта. Причем в *.lib варианте библиотек для
d:\QtSDK1.2.1\Desktop\Qt\4.8.1\msvc2010\lib число 4 на конце : QtCore4.lib
А в статике почему-то вариант QtCore.lib (без 4 на конце)? Может в этом есть какой-то сокральный смысл?...
Остается интересный вопрос как в среде Qt Creator где-то иметь возможность установить нужный QMAKE_INCDIR_QT и т.д.
Оказывается , что в pro файле где-то в начале можно прописать инструкции из файла .qmake.cache и все соберется статически :
.....
QT_BUILD_TREE = D:\\QtSDK1.2.1\\QtSources\\4.8.1
QMAKE_MOC = $$QT_BUILD_TREE\\bin\\moc.exe
QMAKE_UIC = $$QT_BUILD_TREE\\bin\\uic.exe
QMAKE_UIC3 = $$QT_BUILD_TREE\\bin\\uic3.exe
QMAKE_RCC = $$QT_BUILD_TREE\\bin\\rcc.exe
QMAKE_DUMPCPP = $$QT_BUILD_TREE\\bin\\dumpcpp.exe
QMAKE_INCDIR_QT = $$QT_BUILD_TREE\\include
QMAKE_LIBDIR_QT = $$QT_BUILD_TREE\\lib
......
Выводы : наконец-то становится понятно примерно где искать проблемы при статической сборке.
Примечание: на самом деле libeay32.dll и ssleay32.dll могут лежать не одном , а даже в нескольких общедоступных папках. Вы будете думать , что собрали статически, а на самом деле ваша программа будет находить libeay32.dll, ssleay32.dll , грузить в память и использовать.
У нас на ПК например эти библиотеки найдены примерно в таких папках:
C:\Windows\SysWOW64 - общая
C:\QtSDK1.2.1 look disk D\Desktop\Qt\4.8.1\mingw\bin
C:\QtSDK1.2.1 look disk D\QtCreator\bin
.....