Код, сгенерированный "thrift -gen cpp", не компилируется в macOS: файл 'boost / tr1 / functions.hpp' не найден - PullRequest
0 голосов
/ 15 сентября 2018

Я на MacOS High Sierra 10.13.6

Я установил комиссионные следующим образом:

$ brew install thrift

Это следующая версия:

$ thrift --version
Thrift version 0.11.0

Я установил надстройку следующим образом:

$ brew install boost

У меня есть следующий файл model.thrift:

struct Person {
    1: required i32 age;
}

Я запускаю компилятор Thrift для генерации кода cpp следующим образом:

$ thrift -gen cpp model.thrift

Мне нужен следующий файл cpp_encode.cpp, который включает генерируемый код:

#include "gen-cpp/model_types.h"

int main(int argc, char const *argv[])
{
    return 0;
}

Я пытаюсь скомпилировать файл следующим образом:

$ g++ -Wall -I /usr/local/include -L /usr/local/lib -o cpp_encode cpp_encode.cpp

Версия компилятора выглядит следующим образом:

 $ g++ --version
 Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
 Apple LLVM version 9.1.0 (clang-902.0.39.2)
 Target: x86_64-apple-darwin17.7.0
 Thread model: posix
 InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Я получаю следующую ошибку компиляции:

 $ g++ -Wall -I /usr/local/include -L /usr/local/lib -o cpp_encode cpp_encode.cpp
 In file included from cpp_encode.cpp:1:
 In file included from ./gen-cpp/model_types.h:14:
 In file included from /usr/local/include/thrift/TBase.h:24:
 In file included from /usr/local/include/thrift/protocol/TProtocol.h:28:
 In file included from /usr/local/include/thrift/transport/TTransport.h:24:
 /usr/local/include/thrift/stdcxx.h:32:10: fatal error: 'boost/tr1/functional.hpp' file not found
 #include <boost/tr1/functional.hpp>

Каталог / usr / local / boost существует:

$ ls -1 /usr/local/include/boost
accumulators
algorithm
align
align.hpp
aligned_storage.hpp
any.hpp
archive
[...]

Но каталог / usr / local / include / boost / tr1 не существует:

$ ls -1 /usr/local/include/boost/tr1
ls: /usr/local/include/boost/tr1: No such file or directory

Должен ли я установить / usr / local / include / boost / tr1? Если да, то как?

Должен ли я использовать Thrift по-другому?

Ответы [ 3 ]

0 голосов
/ 18 сентября 2018

Вы можете посмотреть код, который вызывает включение boost/tr1/functional в thrift/stdcxx.h

#if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) || (defined(_MSC_VER) \
    && _MSC_VER < 1800) || defined(FORCE_BOOST_FUNCTIONAL)
#include <boost/tr1/functional.hpp>
#define _THRIFT_FUNCTIONAL_TR1_ 1
#endif

Поскольку мы можем с уверенностью предположить, что ваш MacOS g ++ не определяет _MSC_VER, остается только один из двух вариантов: либо вы сами определили макрос FORCE_BOOST_FUNCTIONAL (маловероятно), либо BOOST_NO_CXX11_HDR_FUNCTIONAL не определен.

Изучив документацию по boost config , мы обнаружим, что BOOST_NO_CXX11_HDR_FUNCTIONAL определяется, когда

Стандартная библиотека не предоставляет C ++ 11-совместимую версию <функционала>.

Так как я не знаю, как версия Apples LLVM отображается на настоящую версию LLVM, я не могу сказать, имеет ли по умолчанию в вашей версии clang C ++ 11, но я думаю, вам нужно включить ее вручную , Единственная другая альтернатива заключается в том, что существует ошибка конфигурации буста, из-за которой clang определяется как не имеющий C ++ 11 <functional>.

Чтобы проверить, поддерживает ли по умолчанию C ++ 11 C ++ 11, вы можете попробовать скомпилировать файл со следующим содержимым

int main() 
{
  return []() -> int { return 0; }
}

без установки флагов компилятора.

Итак, подведем итог:

  • Проверьте, определяете ли вы (или стороннюю библиотеку, которую вы используете в дополнение к Thrift) макросом FORCE_BOOST_FUNCTIONAL
  • Проверьте, поддерживает ли ваш компилятор C ++ 11 по умолчанию, если нет, то добавьте -std=c++11 в список флагов компилятора
  • Если это не так, попробуйте обновить версию Boost, возможно, более новая версия будет правильно идентифицировать ваш компилятор, поддерживающий функционал C ++ 11
  • В противном случае, сообщите об ошибке в boost.config.
0 голосов
/ 19 сентября 2018

Здесь есть несколько проблем:

  • В macOS вы должны использовать clang ++ вместо g ++. Кроме того, вы должны использовать библиотеку libc ++ вместо библиотеки по умолчанию libstdc ++; включенная версия libstdc ++ довольно старая и поэтому не включает в себя функции библиотеки C ++ 11. См. Как скомпилировать C ++ с поддержкой C ++ 11 в Mac Terminal

  • Вам не нужно -I / usr / local / include или -L / usr / local / lib (но их добавление не приносит вреда)

Если вы хотите, чтобы программа не только компилировалась, но и ссылалась, есть некоторые дополнительные проблемы:

  • Вам также необходимо скомпилировать и связать сгенерированный код gen-cpp / model_types.cpp

  • Вам необходимо добавить в программу реализацию оператора Coordinate ::. Thrift генерирует объявление для Coordinate :: operator

.

bool Coordinate::operator<(const Coordinate& other) const
{
    if (x < other.x) {
        return true;
    } else if (x > other.x) {
        return false;
    } else if (y < other.y) {
        return true;
    } else {
        return false;
    }
}

Учитывая все вышеперечисленное, работают следующие:

clang++ -std=c++11 -stdlib=libc++ -Wall -o cpp_encode cpp_encode.cpp gen-cpp/model_types.cpp

Примечание 1. Эта простая программа не требует этого, но как только вы напишите более полный код Thrift, вам нужно будет установить связь с библиотекой Thrift (-lthrift) и с библиотекой Boost (-lboost).

Примечание 2: Я даю награду Корристо; даже несмотря на то, что его ответ не совсем дал ответ, предложенная им программа испытаний позволила мне начать путь, который в итоге привел к решению.

0 голосов
/ 15 сентября 2018

Похоже, что Thrift генерирует устаревший код.

Возможно, вы сможете перейти на более новую версию, если она существует.

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

Биты TR1 уже давно (loooong) приняты в стандарте.

Таким образом, в общем то же самое существует, но больше не использует пространство имен tr1,Например,

#include <boost/function.hpp>

может работать или

#include <functional>

для стандартной версии библиотеки.

...