Четверг, 02.05.2024, 12:45
Приветствую Вас Гость | RSS
_nast
Главная | Каталог статей | Регистрация | Вход
Форма входа

Меню сайта
Категории раздела
Длинная арифметика [2]
CUDA [6]
OpenCL [4]
СТАТЕЙКИ [3]
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Поиск
Друзья сайта
  • Природа Орловщины
  • Главная » Статьи » СТАТЕЙКИ

    mongodb C++ driver MinGW

     Пролог

    В общем  встала задача собрать C++ драйвер для MongoDB в Win(в моем случае Win 7 32-bit) с помощью MinGW. Чего-то гугл не очень помог или я плохо старался(((. Если кто знаетс способ попроще, пожалуйста отпишитесь!!!

    Что имеем:

    1. MinGW(содержит MSYS) который с mingw.org – здесь используется только MSYS, расположен по адресу C:\MinGW
    2. MinGW который отсюда - здесь используем только gcc – 4.7.1, расположен по адресу d:\mingw
    3. Boost – версии 1.51, расположен по адресу C:\MinGW\msys\1.0\home\den\boost. Собирался так:

      b2 --prefix=/home/den/boost --layout=system toolset=gcc variant=release link=static  threading=multi runtime-link=static

    4. Python - версия 2.7.3, надо только установить scons, я скачал msi (кстати scons и для 3-го питона есть) 
    5. mongodb-linux-x86_64-v2.2-latest

    Возникшие проблемы:

    1. Т.к у меня boost установлен, не в очень стандартное место (обычно что-то вроде C:\boost) – scons не смог его найти
    2. В файле boost/filesystem/config.hpp есть такая строчка

      #error Compiling Filesystem version 3 file with BOOST_FILESYSTEM_VERSION defined != 3

      А в файле из исходник драйвера mongo/pch.h

      #define BOOST_FILESYSTEM_VERSION 2

      Результат ошибка компиляции

    3. SConstruct настроен для VS
    4. В файле из исходник драйвера util/time_support.h
      #if defined(MONGO_BOOST_TIME_UTC_HACK) || (BOOST_VERSION >= 105000)
              #define MONGO_BOOST_TIME_UTC boost::TIME_UTC_
      #else
              #define MONGO_BOOST_TIME_UTC boost::TIME_UTC
      #endif

      Компилятор ругается на TIME_UTC - мол не знаю чего это значит
    5. Хотя в path есть путь к gcc – 4.7.1, но scons все равно хочет gcc из c:\mingw (его в path Нет)
    6. Ну и куча мелочей связанных с "некоторыми" различиями между стандартными библиотеками С++  из gcc и VS

    Как решались эти проблемы:

    1. Добавляем в SConstruct:
      boost_path=ARGUMENTS.get('boost_path',None) 
      if (boost_path):
              env.Append(CPPPATH = [os.path.join(boost_path, "include")])
              env.Append(LIBPATH = [os.path.join(boost_path, "lib")])
      т.е. если для сборки драйвера мы просто вызывали scons то теперь вызываем scons с аргументом boost_path
    2. Меняем в mongo/pch.h
      #define BOOST_FILESYSTEM_VERSION 2
      На
      #if BOOST_VERSION >= 105000
              #define BOOST_FILESYSTEM_VERSION 3
      #else
              #define BOOST_FILESYSTEM_VERSION 2
      #endif

      Warning: Кстати к чему это приведет я не знаю
    3. В SConstruct: к окружению добавляем TOOLS – mingw
    4. В SConstruct добавляем:
      MONGO_BOOST_TIME_UTC_HACK=ARGUMENTS.get('MONGO_BOOST_TIME_UTC_HACK',0)
      if (MONGO_BOOST_TIME_UTC_HACK):
              env.Append(CPPDEFINES=[ "_SCONS", "MONGO_BOOST_TIME_UTC_HACK" ]) #for boost>=1.5
      т.е. если у вас boost старше 1.49 добавляем аргумент к вызову scons - MONGO_BOOST_TIME_UTC_HACK=1
    5. В Sconstruct:
      if (gcc_path):
              env.Replace(AR = [os.path.join(gcc_path, "ar")])
              env.Replace(AS = [os.path.join(gcc_path, "as")])
              env.Replace(CXX = [os.path.join(gcc_path, "g++")])
              env.Replace(RANLIB = [os.path.join(gcc_path, "ranlib")])
    6. Эти и оставшиеся изменения более конкретнее описаны в файле mingw.diff

     Примечание:

    1. Добавлена опция компиляции BOOST_THREAD_USE_LIB, без нее декорируются имена (добавляется imp к вызову)
    2. Чем заменить эти строки в mongo/util/util.cpp
      __try {
              RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
      }
      __except(EXCEPTION_EXECUTE_HANDLER) {
      }

      Я не знаю
    3. Зачем эти объявления функций без определений (файл mongo/util/time_support.h) я не понял (линкер ругается)
      char *asctime(const struct tm *tm);
      char *ctime(const time_t *timep);
      struct tm *gmtime(const time_t *timep);
      struct tm *localtime(const time_t *timep);
      struct tm *localtime(const time_t *timep);
    4.  boost иногда "рвет мозг" -  порядок линковки это важно, иначе будет undefined reference boost::..., т.е. -lboost_thread -lboost_chrono - это верно, а  -lboost_chrono  -lboost_thread ошибка

      Эпилог 

    Итак, переходим в каталог с драйвером и вводим команду

    scons boost_path="C:\MinGW\msys\1.0\home\den\boost" gcc_path="d:\mingw\bin" MONGO_BOOST_TIME_UTC_HACK=1

    если все ОК, то в паке build будет создан файл libmongoclient.a

    Давайте попробуем компилировать что-нибудь из примеров, пусть это будет mongo/client/examples/first.cpp. Создадим Makefile, у меня получилось как-то так

    first: first.o
             g++ first.o -L/home/den/mongo-cxx-driver-v2.2/build -lmongoclient -L/home/den/boost/lib -lws2_32 -lboost_system -lboost_thread -lboost_chrono -lboost_filesystem -lboost_program_options -o first.exe 
    first.o: first.cpp
             g++ -c first.cpp -I/home/den/mongo-cxx-driver-v2.2/src -I/home/den/mongo-cxx-driver-v2.2/src/mongo -I/home/den/boost/include -DBOOST_THREAD_USE_LIB

    clean:
            rm *.o
            rm *.exe

    Вот вроде и все, надеюсь мне получилось помочь не только себе. Если у вас получилось что-то сделать лучше/проще, пожалуйсто отпишитесь

    Категория: СТАТЕЙКИ | Добавил: _nast (09.10.2012)
    Просмотров: 2631 | Комментарии: 3 | Рейтинг: 0.0/0
    Всего комментариев: 1
    1 PavelIgorevich  
    0
    Здравствуйте, очень помогла Ваша статья - хотя бы с пониманием сложившейся ситуации. Все изменения настроек проводил вручную исходя из приложенного diff-файла. До этого скомпилил буст, все библиотеки в точности, как Ваши - версии те же. Во время сборки драйвера scons выдал ошибку:
    mongo/util/log.cpp warning: 'thread' attribute directive ignored [-Wattributes]
    mongo/util/log.cpp error: specializing member 'mongo::TSP<mongo::Logstream>::reset' requires 'template<>' syntax

    Все это относится к строке 57 файла log.cpp, где выполняется код TSP_DEFINE(Logstream,Logstream_tsp);

    Не встречалось ли у Вас такой проблемы? Logstream из кода вроде шаблонный... Помогите, пожалуйста решить этот вопрос.

    И еще один вопрос: как был сгенерирован diff-файл = я так понимаю какой-нибудь системой контроля версий. Тогда можно ли используя Ваш файл провести изменения на оригинальном коде драйвера автоматически?

    Большое спасибо за статью!

    Имя *:
    Email *:
    Код *:
    Copyright MyCorp © 2024
    Конструктор сайтов - uCoz