Reputation: 3797
I am on macOS High Sierra 10.13.6
I installed thrift as follows:
$ brew install thrift
It is the following version:
$ thrift --version
Thrift version 0.11.0
I installed boost as follows:
$ brew install boost
I have the following model.thrift file:
struct Person {
1: required i32 age;
}
I run the Thrift compiler to generate the cpp code as follows:
$ thrift -gen cpp model.thrift
I have to following cpp_encode.cpp file that includes the generate code:
#include "gen-cpp/model_types.h"
int main(int argc, char const *argv[])
{
return 0;
}
I attempt to compile the file as follows:
$ g++ -Wall -I /usr/local/include -L /usr/local/lib -o cpp_encode cpp_encode.cpp
The compiler version is as follows:
$ 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
I get the following compile error:
$ 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>
The directory /usr/local/boost directory exists:
$ ls -1 /usr/local/include/boost
accumulators
algorithm
align
align.hpp
aligned_storage.hpp
any.hpp
archive
[...]
But the directory /usr/local/include/boost/tr1 does not exist:
$ ls -1 /usr/local/include/boost/tr1
ls: /usr/local/include/boost/tr1: No such file or directory
Should I install /usr/local/include/boost/tr1? If so, how?
Should I use Thrift differently?
Upvotes: 1
Views: 1628
Reputation: 3797
There are a couple of issues here:
On macOS you must use clang++ instead of g++. Also, you must use the libc++ library instead of the default libstdc++; the included version of libstdc++ is quite old and therefore does not include C++11 library features. See How to compile C++ with C++11 support in Mac Terminal
You don't need -I /usr/local/include or -L /usr/local/lib (but adding them doesn't cause harm)
If you want the program to not just compile but also link, there are some additional issues:
You also need to compile and link with the generated code gen-cpp/model_types.cpp
You need add the implementation of Coordinate::operator to the program. Thrift does generate the declaration for the Coordinate::operator< but does not generate the implementation of Coordinate::operator<. The reason for this is that Thrift does not understand the semantics of the struct and hence cannot guess the correct implementation of the comparison operator. This is discussed at http://mail-archives.apache.org/mod_mbox/thrift-user/201007.mbox/%[email protected]%3E
.
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;
}
}
Given all of the above, the following works:
clang++ -std=c++11 -stdlib=libc++ -Wall -o cpp_encode cpp_encode.cpp gen-cpp/model_types.cpp
Note 1: This simple program does not require it, but once you write more complete Thrift code, you will need to link with the thrift library (-lthrift) and with the boost library (-lboost).
Note 2: I am granting the bounty to Corristo; even though his reply did not quite give the answer, his suggested test program got me started on the path that eventually led to the solution.
Upvotes: 3
Reputation: 5510
You can look at the code that causes the inclusion of boost/tr1/functional
in 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
Since we can safely assume that your MacOS g++ doesn't define _MSC_VER
there is only one of two options remaining: Either you yourself defined the FORCE_BOOST_FUNCTIONAL
macro (unlikely), or BOOST_NO_CXX11_HDR_FUNCTIONAL
is not defined.
By looking at the boost config documentation we find that BOOST_NO_CXX11_HDR_FUNCTIONAL
is defined when
The standard library does not provide a C++11 compatible version of < functional >.
Since I don't know how Apples LLVM version maps to the real LLVM version I can't tell whether your version of clang has C++11 enabled by default, but my best guess is that you need to enable it manually. The only other alternative is that there is a boost config bug which causes clang to be identified as not having C++11 <functional>
.
To test whether your version of clang has C++11 enabled by default you can try to compile a file with the following content
int main()
{
return []() -> int { return 0; }
}
without setting any compiler flags.
So to summarize:
FORCE_BOOST_FUNCTIONAL
macro-std=c++11
to the list of compiler flagsUpvotes: 3
Reputation: 393134
It appears that thrift is generating deprecated code.
Maybe you can upgrade to a newer version if it exists.
Otherwise, you could try to downgrade the boost version (beware of support limitations).
The TR1 bits have long (loooong) been adopted into the standard.
So in general the same things exist, but no longer using the tr1 namespace. E.g.
#include <boost/function.hpp>
could work, or
#include <functional>
for the standard library version.
Upvotes: 0