Apache Thrift и C++ для Visual Studio 2013 (2015) на Windows инструкция

Thrift — язык описания интерфейсов, который используется для определения и создания служб под разные языки программирования.
Для большинства языков можно использовать готовые собранные бинарники Thrift или, без каких-либо шаманств, собрать и подключить поставляющиеся в архиве исходники.
Те, кто использует thrift для C++, сталкиваются с большим количеством шагов по предварительной подготовке зависимостей (скачивание, сборка, подключение). При выполнении всех этих действий часто возникает множество ошибок, и кажется непонятным, как вообще оно всё должно работать вместе и в какую сторону отлаживать Программу. Потому и возникает необходимость в эталонной рабочей версии, а, соответственно, и инструкции по её созданию.

Заранее предупреждаю, инструкция длинная и выполняется достаточно долго. Для полноценного понимания желательно также:

  1. ознакомиться с тем, как пишутся .thrift-файлы, какие типы можно использовать, и что .thrift-файл является Интерфейсом или объявлением (аналог интерфейсов в C#), содержащим методы и структуры данных будущего сервиса;
  2. ознакомиться с простейшим работающим примером сервера с одним методом, который возвращает текущее время, и клиента, который получает его, здесь.

Итак, приступим.

Обычно Thrfit на C++ собирают на Linux, по инструкции, описанной на сайте thrift (сам не проверял, но те, кто
это делает, говорят, что всё заводится с полпинка). Но вот, к сожалению, официальная инструкция по сборке Thrift под Windows не позволяет взять thrift как есть и использовать на C++.
На данный момент мне известны две стабильные рабочие версии thrift на языке C++: пример на 0.7.0 (опять же, сам не проверял, но так сообщают источники в интернете) и 0.9.2 — под неё, собственно, и пишется инструкция.
(Крайняя версия thrift на сегодня — 0.9.3, но я не нашёл способа, как заставить её работать или хотя бы запустить пример, — даже при том, что бинарники thrift этой версии собираются без ошибок, при запуске примера возникает множество ошибок линковки; темы по этому вопросу: thrift-jira_№3832, на cyberforum.ru, на prog.org.ru).

Короткая инструкция:
\\В ПРОЦЕССЕ

Короткая инструкция для последней версии:
(скорее всего окажется нерабочей)
\\В ПРОЦЕССЕ

Подробная инструкция:

I. Среда разработки:

  • Windows 7 64bit.
  • Microsoft Visual Studio 2013 (также протестировано на VS2015+Windows 10 64bit).
  • Apache Thrift 0.9.2.
  • Boost 1.59.0.
  • Libevent 2.0.22.
  • OpenSSL 1.0.2h.

II. Подготовка к сборке:

  1. Скачать Apache Thrift 0.9.2: Компилятор, Исходники бинарников c примерами (другие версии можно скачать с сайта Thrift в разделе Apache Thrift Archive).
  2. Скачать заранее собранные бинарники библиотеки Boost 1.59.0, x32, для Visual Studio 2013  ( или, при желании, — для других версий); именование происходит следующим образом:
    • версия boost (в нашем случае это 1.59.0)
    • версия студии 12 (для Visual Studio 2013 — версия 12; для Visual Studio 2015 — версия 14; для другой версии — см. меню Справка-о программе Microsoft Visual Studio)
    • x32 (или x64; в случае, если собирается x64 версия, необходимо будет также и OpenSSL скачивать в x64, и библиотеки thrift собирать в x64 и пример собирать в x64)
      (при желании можно собрать Boost по этой инструкции — если вкратце, то из Командной Строки Разработчика Visual Studio необходимо запустить два файла: bootstrap и b2, последовательное выполнение которых займёт ~15-20 минут и собранные библиотеки будут лежать нe в папке «{корневая папка boost}\lib32-msvc-12.0\», а в «{корневая папка boost}\stage\lib»; также при необходимости можно запускать процесс сборки с нужными параметрами, меняя настройки сборки и компиляторы).
  3. Скачать архив libevent здесь (остальные версии также можно найти на официальном сайте)
  4. Скачать OpenSSL для Windows здесь
      (В случае если нужна версия x64, её можно найти следующим образом:
    • переходим на официальный сайт в раздел Downloads
    • далее переходим по ссылке page, которая открывает список сайтов, где можно скачать бинарники OpenSSL
    • далее ищем ссылку на сайт с бинарниками OpenSSL для Window — «OpenSSL for Windows» и выбираем тот, в описании которого указано «Works with MSVC++» — здесь
    • в таблице находим полные(НЕ Light) версии для разработчиков ПО: Win32 OpenSSL v1.0.2h или Win64 OpenSSL v1.0.2h )
      Необходимо учесть, что эти бинарники поставляются т.н. третьими лицами и не были официально подтверждены командой OpenSSL, но, поскольку других нет, используем эти.
  5. Распаковываем архивы (.tar.gz; .tar; .exe) и получаем в итоге:
    1. папка с файлом компилятора thrift-0.9.2.exe
    2. корневая папка \thrift-0.9.2\
      • \lib\cpp\src\
      • \lib\cpp\src\thrift\windows\
      • \lib\cpp\Debug\ (появляется после сборки, выходная папка с бинарниками thrift)
      • \tutorial\ (здесь находится описание сервисов и структур примера Калькулятора tutorial.thrift и shared.thrift)
      • \tutorial\cpp\ (здесь лежат примеры клиента и сервера Калькулятора)
    3. корневая папка \boost_1_59_0\
      • \boost\
      • \lib32-msvc-12.0\ (если собирать самому, появится выходной каталог \stage\lib\)
    4. корневая папка \libevent-2.0.22-stable
      • \include\
      • \WIN32-Code\
    5. корневая папка \OpenSSL-Win32
      • \include\
      • \lib\

III. Непосредственная сборка библиотек Thrift

IIIa. Собираем libevent

  1. Открываем Командную Строку Разработчика для VS2013
  2. Переходим в {корневая папка libevent} (в ней лежат такие папки, как «compat», «include», «test»)
  3. Вызываем команду «nmake -f Makefile.nmake«

IIIb. Собираем thrift

  1. Открываем решение {корневая папка thrift}\lib\cpp\thrift.sln в Visual Studio 2013 и соглашаемся на преобразование проектов libthrift и libthriftnb (расшифровывается как libthriftNonBlocking, т.е. неблокирующий сервер)
  2. Выбираем конфигурацию Debug или Release.
  3. В свойствах проекта libthrift указываем следующие пути:
    • Свойства конфигурации — C\C++ — Общие — Дополнительные каталоги включаемых файлов:
      1. {корневая папка boost}
      2. {корневая папка boost}\boost
      3. {корневая папка OpenSSL}\include
    • Свойства конфигурации — Библиотекарь — Общие — Дополнительные каталоги библиотек:
      1. {корневая папка OpenSSL}\lib
  4. В свойствах проекта libthriftnb указываем следующие пути:
    • Свойства конфигурации — C\C++ — Общие — Дополнительные каталоги включаемых файлов:
      1. {корневая папка boost}
      2. {корневая папка libevent}
      3. {корневая папка libevent}\include
      4. {корневая папка libevent}\WIN32-Code
  5. В Обозревателе решений, в проекте libthrift\concurrency исключаем из решения файл BoostThreadFactory.cpp (вызываем проблемы при компиляции)
  6. Перестраиваем решение и получаем в Debug\Release бинарники libthrift.lib и libthriftnb.lib

IV. Создание сервера\клиента и подключение к нему библиотек Thrift

IVа. Генерируем C++ код сервиса и структур данных примера Калькулятора

  1. из {корневая папка thrift}\tutorial\ копируем tutorial.thrift и shared.thrift в папку с компилятором thrift-0.9.2.exe
  2. открываем Командную Строку Разработчика VS2013
  3. Переходим в папку с компилятором thrift-0.9.2.exe
  4. С помощью следующих команд генерируем C++ код сервиса и структур данных примера Калькулятора:
    • «thrift-0.9.2.exe -r --gen cpp tutorial.thrift«
    • «thrift-0.9.2.exe -r --gen cpp shared.thrift«

    В результате создаётся папка «gen-cpp» с набором исходных и заголовочных файлов C++.

IVb. Создаём проект

  1. Создаём новый пустой C++ проект в Visual Studio 2013
  2. Добавляем из папки «gen-cpp» файлы с расширением .h — в Заголовочные Файлы; файлы с расширением .cpp — в Файлы Исходного кода.
  3. Исключаем skeleton-файлы из проекта (*.skeleton.cpp, — они нужны для того, чтобы иметь представление, как писать сервер\клиент; но у нас уже имеется готовый пример, который идёт в архиве — см. далее).
  4. Добавляем из {корневая папка thrift}\tutorial\cpp\CppServer.cpp (или CppClient.cpp, если создаём клиент).
  5. Проверяем в добавленном на предыдущем шаге файле путь в #include Calculator.h (правильный путь находится в свойствах файла Calculator.h, в поле «Относительный путь»).

IVc. Подключаем к проекту библиотеки thrift

  1. В свойствах проекта сервера\клиента указываем следующие пути и строки:
    • Свойства конфигурации — C\C++ — Все параметры — Дополнительные каталоги включаемых файлов:
      1. {корневая папка boost}
      2. {корневая папка thrift}\lib\cpp\src\
      3. {корневая папка thrift}\lib\cpp\src\thrift\windows
    • Свойства конфигурации — Компоновщик — Все параметры — Дополнительные зависимости:
      1. «libboost_thread-vc120-mt-gd-1_59.lib;libboost_chrono-vc120-mt-gd-1_59.lib;libthrift.lib;%(AdditionalDependencies)»
        (Внимание!
        а) Необходимо убедиться в наличии соответствующих либ с версиями: в заранее собранном boost они лежат в «{корневая папка boost}\lib32-msvc-12.0\», в случае же собственноручной сборки Boost они находятся в «{корневая папка boost}\stage\lib\»
        б) В зависимости от версии Visual Studio и Boost числа могут меняться; так, для Visual Studio 2015 и Boost 1.61.0 это будет «libboost_thread-vc140-mt-gd-1_61.lib»)
    • Свойства конфигурации — Компоновщик — Все параметры — Дополнительные каталоги библиотек:
        1. {корневая папка boost}\lib32-msvs-12.0\
          (в случае собственноручной сборки Boost это будет «{корневая папка boost}\stage\lib\»
        2. {корневая папка thrift}\lib\cpp\Debug\
          (Release\Debug в зависимости от выбора конфигурации)

       

  2. Перестраиваем проект.

V. Запуск

  1. запускаем сервер
  2. запускаем клиент и видим результат операций (которые были выполнены на сервере)

VI. Дополнительно

VIа. Переносим проект из VS2013 на Qt

  1. Создаём консольный проект в Qt, который для отладки использует компилятор MSVC2013 32bit; Собираем в режиме Выпуска, т.е. Release (в Qt рекомендуется использовать именно этот режим сборки)
  2. Выполняем IVa и IVb(генерируем исходные файлы с помощью компилятора thrift; добавляем .h и .cpp файлы в проект, за исключением файлов с расширением .skeleton; в main.cpp добавляем код из CppServer.cpp\CppClient.cpp; проверяем путь к Calculator.h)
  3. Подключаем к проекту библиотеки thrift. Для этого открываем файл проекта .pro в Qt и редактируем его, добавляя необходимые пути(для проверки путей смотри пункт IVc):
    INCLUDEPATH += "{папка с компилятором thrift}/gen-cpp"
    INCLUDEPATH += "{корневая папка boost}"
    INCLUDEPATH += "{корневая папка boost}/lib32-msvc-12.0"
    INCLUDEPATH += "{корневая папка thrift}/lib/cpp/src"
    INCLUDEPATH += "{корневая папка thrift}/lib/cpp/src/thrift/windows"
    INCLUDEPATH += "{корневая папка thrift}/lib/cpp/Release"

    LIBS += -L{корневая папка boost}/lib32-msvc-12.0 -llibboost_thread-vc120-mt-gd-1_59
    LIBS += -L{корневая папка boost}/lib32-msvc-12.0 -llibboost_chrono-vc120-mt-gd-1_59
    LIBS += -L{корневая папка thrift}/lib/cpp/Release -llibthriftnb
    LIBS += -L{корневая папка thrift}/lib/cpp/Release -llibthrift

  4. Далее сохраняем изменения в файле .pro, собираем и запускаем проект

VIb. Собираем компилятор из исходников

  1. Скачиваем и распаковываем WinFlexBison и получаем {корневая папка winflexbison}, в которой нам интересны два файла: win_flex.exe и win_bison.exe (также там имеется инструкция по автоматизированию работы с ним)
  2. Открываем решение {корневая папка thrift}\compiler\cpp\compiler.sln в Visual Studio 2013 и соглашаемся на преобразование проекта.
  3. Открываем свойства проекта и в Свойства конфигурации-События сборки-События перед сборкой-Командная строка заменяем «flex» — на полный путь к файлу «{корневая папка winflexbison}/win_flex.exe» и «bison» — на полный путь к файлу «{корневая папка winflexbison}/win_bison.exe» и сохраняем
  4. Перестраиваем проект и получаем в выходной папке файл компилятора «thrift.exe»

Источники:

  1. Инстркуция, по работе с thrift c++ на Windows
  2. Инструкция по работе с Boost

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.