“ thrift -gen cpp”生成的代码无法在macOS上编译:找不到“ boost / tr1 / functional.hpp”文件

时间:2018-09-14 23:19:14

标签: c++ macos boost homebrew thrift

我正在使用macOS High Sierra 10.13.6

我按如下方式安装了Thrift:

$ brew install thrift

它是以下版本:

$ thrift --version
Thrift version 0.11.0

我按如下所示安装了boost:

$ 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 :(得分:3)

您可以查看导致thrift/stdcxx.h中包含boost/tr1/functional的代码

#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宏(不太可能),或者{{1} }没有定义。

通过查看boost config documentation,我们发现BOOST_NO_CXX11_HDR_FUNCTIONAL是在何时定义的

  

标准库不提供的C ++ 11兼容版本。

由于我不知道Apples的LLVM版本如何映射到真实的LLVM版本,所以我无法确定您的clang版本默认情况下是否启用了C ++ 11,但是我的最佳猜测是您需要手动启用它。唯一的其他选择是存在一个boost config错误,该错误会导致clang被识别为没有C ++ 11 BOOST_NO_CXX11_HDR_FUNCTIONAL

要测试您的Clang版本是否默认启用了C ++ 11,您可以尝试编译具有以下内容的文件

<functional>

不设置任何编译器标志。

所以总结一下:

  • 检查您(或除节俭之外使用的第三方库)是否在定义int main() { return []() -> int { return 0; } }
  • 检查编译器默认情况下是否支持C ++ 11,如果不支持,请在编译器标志列表中添加FORCE_BOOST_FUNCTIONAL
  • 如果不是这样,请尝试升级您的Boost版本,也许较新的版本可以正确识别您的支持C ++ 11功能的编译器
  • 否则,请使用boost.config提交错误。

答案 1 :(得分:3)

这里有几个问题:

  • 在macOS上,您必须使用clang ++而不是g ++。另外,必须使用libc ++库而不是默认的libstdc ++。 libstdc ++包含的版本很旧,因此不包括C ++ 11库功能。参见How to compile C++ with C++11 support in Mac Terminal

  • 您不需要-I / usr / local / include或-L / usr / local / lib(但添加它们不会造成危害)

如果您希望程序不仅可以编译,还可以链接,则还有一些其他问题:

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:我将赏金授予Corristo;尽管他的回答并没有给出答案,但他建议的测试程序使我开始着手,最终找到了解决方案。

答案 2 :(得分:0)

节俭似乎正在生成不赞成使用的代码。

如果存在,也许您可​​以升级到新版本。

否则,您可以尝试降级增强版(请注意支持限制)。

TR1 bits长期以来一直被采纳为标准。

因此,通常存在相同的东西,但不再使用tr1命名空间。例如

#include <boost/function.hpp>

可以工作,或者

#include <functional>

用于标准库版本。