Показаны сообщения с ярлыком POCO. Показать все сообщения
Показаны сообщения с ярлыком POCO. Показать все сообщения

среда, 4 июля 2012 г.

MinGW + POCO. Часть 2

В очередной раз убеждаюсь что для того чтобы опенсорсовские исходники заработали, необходимо приложить "драчильный напильник".

Скачал пример HTTP сервера на POCO http://poco.roundsquare.net/downloads/HTTPServer.zip
И попытался скомпилировать на QT Creator + MinGW

Получил ошибку
D:/QtSDK/mingw/lib//libmingw32.a(main.o):main.c:(.text+0x104): undefined reference to `WinMain@16'


Угрохал 3 часа на выявления причин.

Оказалось что в файле ...\Foundation\include\Poco\Config.h
прописано явно

// Define to enable Windows Unicode (UTF-8) support
#define POCO_WIN32_UTF8

что приводит в ...\Util\include\Poco\Util\ServerApplication.h 
//
// Macro to implement main()
//
#if defined(_WIN32) && defined(POCO_WIN32_UTF8)
#define POCO_SERVER_MAIN(App) \
int wmain(int argc, wchar_t** argv) \
{ \
App app; \
return app.run(argc, argv); \
}
#elif defined(POCO_VXWORKS)
#define POCO_SERVER_MAIN(App) \
int pocoSrvMain(const char* appName, ...) \
{ \
std::vector<std::string> args; \
args.push_back(std::string(appName)); \
va_list vargs; \
va_start(vargs, appName); \
const char* arg = va_arg(vargs, const char*); \
while (arg) \
{ \
args.push_back(std::string(arg)); \
arg = va_arg(vargs, const char*); \
} \
va_end(vargs); \
App app; \
return app.run(args); \
}
#else
#define POCO_SERVER_MAIN(App) \
int main(int argc, char** argv) \
{ \
App app; \
return app.run(argc, argv); \
}
#endif

к формированию через POCO_SERVER_MAIN(...)

функции int wmain(int argc, wchar_t** argv) вместо int main(int argc, char** argv)которую MinGW упорно ожидает увидеть.


Решение проблемы
1) Закомментировать #define POCO_WIN32_UTF8 в Config.h и отключить -DUNICODE
т.к. все равно в ...\Foundation\include\Poco\Platform_WIN32.h стоит взведение POCO_WIN32_UTF8

// Unicode Support
#if defined(UNICODE) && !defined(POCO_WIN32_UTF8)
#define POCO_WIN32_UTF8
#endif
но если первое еще можно пережить, то второе может привести к непредсказуемым последствиям.


2) Резать (вернее вшивать) по живому ...\Util\include\Poco\Util\ServerApplication.h, что я и предлагаю сделать:

//
// Macro to implement main()
//
#if defined(_WIN32) && defined(POCO_WIN32_UTF8) && (!defined(__MINGW__) && !defined(__MINGW32__))
Нужно добавить то, что отмечено зеленым цветом, после чего проект собирается вполне адекватно.




Компиляция примеров POCO в QT Creator + MinGW

Для начала возьмем самое простое -- скомпилируем под  QT Creator+MinGW примеры POCO
(http://pocoproject.org/download/index.html)

Basic Edition
No external dependencies — start developing immediately


poco-1.4.3p1.zip │4176 K


содержит в себе следующие компоненты


║..                                    │readme
║build                                 │version
║contrib                               │
CppUnit                               │
║doc                                   │
Foundation                            │
Net                                   │
║patches                               │
Util                                  │
XML                                   │
║build_CE_vs90.cmd                     │
║build_vcexpress2008.cmd               │
║build_vcexpress2010.cmd               │
║build_vs100.cmd                       │
║build_vs71.cmd                        │
║build_vs80.cmd                        │
║build_vs90.cmd                        │
║buildvms.com                          │
║buildwin.cmd                          │
║changelog                             │
║components                            │
║configure                             │
║contributors                          │
║DLLVersion.rc                         │
║libversion                            │
║license                               │
║Makefile                              │
║manifest                              │
║news                                  │



Professional Edition
Includes additional powerful libraries and tools
Платный, поэтому по определению не интересует


Нас же интересует

Complete Edition
Requires OpenSSL, MySQL Client and ODBC


poco-1.4.3p1-all.zip │7003 K

..                       │libversion
build                    │license
contrib                  │Makefile
CppUnit                  │manifest
Crypto                   │news
Data                     │readme
doc                      │version
Foundation               │
Net                      │
NetSSL_OpenSSL           │
PageCompiler             │
patches                  │
Util                     │
XML                      │
Zip                      │
build_CE_vs90         cmd│
build_vcexpress2008   cmd│
build_vcexpress2010   cmd│
build_vs100           cmd│
build_vs71            cmd│
build_vs80            cmd│
build_vs90            cmd│
buildvms              com│
buildwin              cmd│
changelog                │
components               │
configure                │
contributors             │
DLLVersion            rc │

ГРАБЛИ №1


Как видем из списка файлов дистрибьютив не заточен под компиляцию в  QT Creator+MinGW.
Что же делать? Писать проекты/makefile в ручную?

Обратимся к мировому разуму:
http://gluescript.sourceforge.net/?q=node/22

Похожую проблему народ поборол используя Premake4 (http://industriousone.com/premake/download) и скрипт на lua (http://gluescript.svn.sourceforge.net/viewvc/gluescript/trunk/src/poco.zip?view=log)

Но проблему побороли не до конца и не на той версии POCO и как следствие скрипты оказались не совсем корректными.
Пришлось с бубном и матом, методом проб и ошибок писать свои скрипты: 
http://www.dymovoy.ru/download/premake4_lua_poco-1.4.3p1-all.rar


Потребуется:
http://sourceforge.net/projects/premake/files/Premake/4.3/premake-4.3-windows.zip/download
premake-4.3-windows.zip   │ 90861

в котором лежит
premake4.exe              │261632

и собственно сами новые скрипты lua http://www.dymovoy.ru/download/premake4_lua_poco-1.4.3p1-all.rar

кладем скрипты по директориям а дальше в корневой директории POCO запускаем
C:\premake4\premake4.exe gmake


В результате будут созданы файлы Makefile, которые и будут использоваться для начальной компиляции библиотеки.



ГРАБЛИ №2

Обратите внимание, что стоит в файлах lua
             "WINVER=0x0501",
Это означает что версия ОС у нас не ниже Windows XP.
Это реальный баг MinGW: по умолчанию переменная WINVER=0x0500 и как следствие Windows2000, а MinGW не умеет корректно работать со стеком в Windows2000.

Поэтому компиляцию нужно проводить из батника !build_mingw.bat

@echo off



setlocal

set OPENSSL_DIR=c:\openssl
set OPENSSL_INCLUDE=%OPENSSL_DIR%\include
set OPENSSL_LIB=%OPENSSL_DIR%\lib
set INCLUDE=%INCLUDE%;%OPENSSL_INCLUDE%
set LIB=%LIB%;%OPENSSL_LIB%

set POCO_BASE=%CD%
set PATH=D:\QtSDK\mingw\bin\;%POCO_BASE%\bin;%PATH%

set PLATFORM=Win32


set POCO_OS_FAMILY_WINDOWS=1
set Win32=0x0501
set MINGW32=0x0501
set POCO_VXWORKS=
set _WIN32_WINNT=0x0501


C:\premake4\premake4.exe gmake

mingw32-make.exe config=release
mingw32-make.exe

endlocal

в результате в директории ...\poco\lib\ должны появиться откомпилированные файлы *.a, которые я руками переименовал в *.lib (я это понял уже потом что нужно переименовать -- QT Creator не хотел их добавлять в проект)
libPoco_CppUnit_mt                          lib│216938
libPoco_CppUnit_mtd                         lib│216938
libPoco_Crypto_mt                           lib│382736
libPoco_Crypto_mtd                          lib│389834
libPoco_Data_mt                             lib│1360 K
libPoco_Data_mtd                            lib│1379 K
libPoco_Foundation_mt                       lib│4320 K
libPoco_Foundation_mtd                      lib│4411 K
libPoco_Net_mt                              lib│2791 K
libPoco_Net_mtd                             lib│2841 K
libPoco_NetSSL_mt                           lib│ 984 K
libPoco_NetSSL_mtd                          lib│1000 K
libPoco_PageCompiler_mt                     lib│151998
libPoco_PageCompiler_mtd                    lib│154900
libPoco_Util_mt                             lib│1537 K
libPoco_Util_mtd                            lib│1556 K
libPoco_XML_mt                              lib│1492 K
libPoco_XML_mtd                             lib│1531 K
libPoco_Zip_mt                              lib│1232 K
libPoco_Zip_mtd                             lib│1249 K





ГРАБЛИ №3


Компиляция самого примера это тоже не для слабонервных
Открываем в самом интерфейсе QT Creator файл проекта *.pro и добавляем библиотеки *.lib/*.a (правой кнопкой мышки) (помечено оранжевым цветом) и руками переменные (помечено синим цветом), затем дошкуриваем руками. Обратите внимание, что руками добавляются библиотеки POCO, WinSocket'а и библиотеки openssl. Как это сделать автоматом я так и не смог понять.





#-------------------------------------------------
#
# Project created by QtCreator 2012-07-03T16:48:27
#
#-------------------------------------------------


QT       += core


QT       -= gui


TARGET = sslprj02
CONFIG   += console
CONFIG   -= app_bundle


TEMPLATE = app


SOURCES += main.cpp


WINVER = 0x0501
_WIN32_WINNT = 0x0501


#-------------------------------------------------
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../poco/lib/ -llibPoco_NetSSL_mt
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../poco/lib/ -llibPoco_NetSSL_mtd


INCLUDEPATH += $$PWD/../poco/NetSSL_OpenSSL/include/
DEPENDPATH += $$PWD/../poco/NetSSL_OpenSSL/include/
#-------------------------------------------------




#-------------------------------------------------
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../poco/lib/ -llibPoco_Crypto_mt
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../poco/lib/ -llibPoco_Crypto_mtd


INCLUDEPATH += $$PWD/../poco/Crypto/include/
DEPENDPATH += $$PWD/../poco/Crypto/include/
#-------------------------------------------------


#-------------------------------------------------
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../poco/lib/ -llibPoco_Net_mt
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../poco/lib/ -llibPoco_Net_mtd


INCLUDEPATH += $$PWD/../poco/Net/include/
DEPENDPATH += $$PWD/../poco/Net/include/
#-------------------------------------------------


#-------------------------------------------------
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../poco/lib/ -llibPoco_Util_mt
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../poco/lib/ -llibPoco_Util_mtd


INCLUDEPATH += $$PWD/../poco/Util/include/
DEPENDPATH += $$PWD/../poco/Util/include/
#-------------------------------------------------




#-------------------------------------------------
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../poco/lib/ -llibPoco_XML_mt
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../poco/lib/ -llibPoco_XML_mtd


INCLUDEPATH += $$PWD/../poco/XML/include/
DEPENDPATH += $$PWD/../poco/XML/include/
#-------------------------------------------------




#-------------------------------------------------
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../poco/lib/ -llibPoco_Foundation_mt
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../poco/lib/ -llibPoco_Foundation_mtd


INCLUDEPATH += $$PWD/../poco/Foundation/include/
DEPENDPATH += $$PWD/../poco/Foundation/include/
#-------------------------------------------------


win32: LIBS += -LC:/openssl/lib/ -lssleay32
win32: LIBS += -LC:/openssl/lib/ -llibeay32


INCLUDEPATH += c:/openssl/include/
DEPENDPATH += c:/openssl/include/


win32: LIBS += -LD:/QtSDK/mingw/lib/ -lws2_32
win32: LIBS += -LD:/QtSDK/mingw/lib/ -liphlpapi


В файле *.cpp до #include вставляем строку

#define _WIN32_WINNT 0x0501
чтобы уж быть точно уверенным.

ГРАБЛИ №4

Перед запуском в отладке или просто так убедитесь, что у вас доступны DLL (прописана директория в переменной PATH или лежат в текущей директории) следующие файлы:

СКЗИ МагПро КриптоПакет он же openssl 0.9.8e
cryptoeay32-0.9.8.dll                        │1387 K


ssleay32-0.9.8.dll                           │330426
zlib1.dll                                    │ 73216





Основные куски библиотек MinGW

libgcc_s_dw2-1.dll                           │ 43008
mingwm10.dll                                 │ 11362


Основные библиотеки QT (большая часть не нужна, но на всякий случай положите в доступную папку)
phonon4.dll                                  │344576
QtCore4.dll                                  │2492 K
QtDeclarative4.dll                           │2995 K
QtGui4.dll                                   │9619 K
QtMultimedia4.dll                            │174080
QtNetwork4.dll                               │1181 K
QtOpenGL4.dll                                │912384
QtScript4.dll                                │2126 K
QtScriptTools4.dll                           │745984
QtSql4.dll                                   │271872
QtSvg4.dll                                   │373248
QtWebKit4.dll                                │  17 M
QtXml4.dll                                   │399360
QtXmlPatterns4.dll                           │3912 K



Обратите внимание, что при запуске откомпилированного в DEBUG режиме файла нужно чтобы были еще доступны соответствующие библиотеки с буковкой <d>.

Пример:
....
QtCored4.dll                                 │  30 M
QtGuid4.dll                                  │ 148 M
QtSvgd4.dll                                  │5475 K
QtNetworkd4.dll                              │  19 M
....


ГРАБЛИ №5

Под гостевой ОС Windows XP откомпилированный пример работает нормально, под основной ОС Windows 7 пример вываливается с ошибкой:
I/O error: Permission denied
Так что есть еще с чем бороться %)









Инструменты в работе

Долго размышлял, какие инструменты использовать.
В большей степени повлияло собственное мироощущение

C# -- очень удобно и быстро писать, но на мой взгляд портирование на платформы отличные от Windows приведет к непонятным глюкам на MONO (http://www.mono-project.com/)
Используется на сегодняшний момент в:
90% серверных компонентах (Cyberplat, DeltaPay, Лидер, X-Plat)
30% клиентских компонентах (Лидер, DeltaPay)


Java -- мне кажется что при объеме памяти меньше чем ОЧЕНЬ МНОГО сильно проигрывает нативным компиляторам. 
Используется на сегодняшний момент в:
7% серверных компонентах (ЕРЦ)
5% клиентских компонентах (e-port)



Python -- по отзывам друзей, за ним будущее, но я не готов сейчас заняться изучением нового языка. 


Delphi/Cylix -- хммм... Возможно но...

С/C++ -- старый сапог в бою надежнее. 

Так что будем писать на C/C++.

Дабы не убивать собственную машину (Corei3, Windows 7 Home Basic, 64-bit  (Build 7600) 6.1.7600 RAM2808 MB) решил вести разработку в двух виртуальных машинах под VirtualBox [https://www.virtualbox.org/http://download.virtualbox.org/virtualbox/4.1.18/VirtualBox-4.1.18-78361-Win.exe + патчи под операционные системы]
С учетом того, что параллельно я использую(-вал) VMware® Workstation 8.0.2 build-591240 [https://my.vmware.com/web/vmware/info/slug/desktop_end_user_computing/vmware_workstation/8_0](я ее установил, дабы можно было дома сделать (настроить образ ОС+ПО), затем скопировать образ виртуальной машины на DVD и быстренько подложить в VMware® vSphere на работе -- использовалась возможность "быстрой" миграции сложных систем позволяет задобрить сисадминов, которые напрочь отказываются что-либо делать самостоятельно), то могу высказать свое личное мнение: Только VirtualBox! Никакой VMware Workstation для реальной работы. Если падение скорости в гостевой ОС VirtualBox практически не заметно, то в гостевой ОС VMware Workstation я могу наблюдать как экран прорисовывается.

Как платформы для разработки решил использовать QT.
Скачал QT SDK [http://qt.nokia.com/downloads/sdk-windows-cpp-offline] но это было давно и многих граблей я уже не помню.

Итого я поимел:
Qt 4.7.4 (сейчас уже на сайте Qt 4.8.1)
Qt Creator 2.2.1 (сейчас уже на сайте Qt Creator 2.5.0)
MinGW 3.15.2 (что сейчас на сайте я пока не в курсе)
Для пониманию мой MinGW (..\QtSDK\mingw\manifest.txt):

binutils-2.19.1-mingw32-bin
mingwrt-3.15.2-mingw32-dev
mingwrt-3.15.2-mingw32-dll
w32api-3.13-mingw32-dev
gcc-core-4.4.0-mingw32-bin
gcc-core-4.4.0-mingw32-dll
gcc-c++-4.4.0-mingw32-bin
gcc-c++-4.4.0-mingw32-dll
gmp-4.2.4-mingw32-dll
libiconv-1.13-mingw32-dll-2
mingw32-make-3.81-20080326-3
mpfr-2.4.1-mingw32-dll
pthreads-w32-2.8.0-mingw32-dll
gdb and libexpat-1.dll

Библиотеки-обертки SSL


Для быстрого создания транспорта с шифрацией под SSL рассматривались следующие библиотеки

Первую не рассматривал, т.к. IMHO уж очень сильно привязана к продукции Borland
Последнюю не рассматривал, т.к. ПЛАТНАЯ.

Будем рассматривать QT, cURL и POCO как основные конкуренты для внедрения.
Задача определить какая из трех библиотек более производительная.


См. также
http://forum.kaimi.ru/viewtopic.php?id=153