Compiling Apache Thrift Service in Windows - c++

I'm trying to build a thrift service on my windows machine. Im using cygwin and Netbeans IDE. I've downloaded Thrift and built it trough cygwin and was able to successfully get Thrift to generate the server code for me, shown below.
#include "Feed.h"
#include <protocol/TBinaryProtocol.h>
#include <server/TSimpleServer.h>
#include <transport/TServerSocket.h>
#include <transport/TBufferTransports.h>
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using boost::shared_ptr;
using namespace feed;
class FeedHandler : virtual public FeedIf {
public:
FeedHandler() {
// Your initialization goes here
}
void ping() {
// Your implementation goes here
printf("ping\n");
}
void search_text(search_resultset& _return, const std::string& query, const int32_t offset, const int32_t per_page) {
// Your implementation goes here
printf("search_text\n");
}
void search_prox_web(search_resultset& _return, const double lat, const double lon, const int32_t offset, const int32_t distance) {
// Your implementation goes here
printf("search_prox_web\n");
}
void search_prox_mob(search_resultset& _return, const double lat, const double lon, const int32_t offset, const int32_t distance) {
// Your implementation goes here
printf("search_prox_mob\n");
}
int32_t add_event(const std::string& name) {
// Your implementation goes here
printf("add_event\n");
}
int32_t associate_venue_with_event(const int32_t event_id, const int32_t venue_id, const int32_t usr_loc_id) {
// Your implementation goes here
printf("associate_venue_with_event\n");
}
int32_t save_usr_loc(const std::string& address) {
// Your implementation goes here
printf("save_usr_loc\n");
}
};
int main(int argc, char **argv) {
int port = 9090;
shared_ptr<FeedHandler> handler(new FeedHandler());
shared_ptr<TProcessor> processor(new FeedProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();
return 0;
}
Then I built the libraries so I could compile and link my implementation. The libraries built successfully, however when I try to compile I get the following error:
build/Debug/Cygwin_4.x-Windows/main.o: In function `FeedProcessor':
/cygdrive/c/Feed Service/Feed.h:930: undefined reference to `vtable for feed::FeedProcessor'
/cygdrive/c/Feed Service/Feed.h:930: undefined reference to `vtable for feed::FeedProcessor'
/cygdrive/c/Feed Service/Feed.h:931: undefined reference to `feed::FeedProcessor::process_ping(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:932: undefined reference to `feed::FeedProcessor::process_search_text(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:933: undefined reference to `feed::FeedProcessor::process_search_prox_web(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:934: undefined reference to `feed::FeedProcessor::process_search_prox_mob(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:935: undefined reference to `feed::FeedProcessor::process_add_event(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:936: undefined reference to `feed::FeedProcessor::process_associate_venue_with_event(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:937: undefined reference to `feed::FeedProcessor::process_save_usr_loc(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/Cygwin_4.x-Windows/feed_service.exe] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 3s)
I thought these were all linker errors, so I did some googling and found a potential solution to add the following lines to the makefile:
THRIFT_O=C:/cygwin/home/thrift/lib/cpp
LTHRIFT=$(THRIFT_O)/Thrift.o $(THRIFT_O)/TSocket.o $(THRIFT_O)/TSimpleServer.o $(THRIFT_O)/TBufferTransports.o $(THRIFT_O)/TSimpleServer.o $(THRIFT_O)/TBinaryProtocol.o
and then link with $(LTHRIFT) rather than -lthrift. However the file TBinaryProtocol.o doesn't seem to exist on my system. I tried re-building the libraries from source twice, and the file still isn't made.
First of all, is adding these lines to my makefile the correct solution to my initial problem? Secondly, is the absence of TBinaryProtocol.o a major problem, or is it not created for a reason? If I do need it, is there a way I can make it individually or download it from somewhere?
Edit: All of the include files are auto-generated by the Thrift compiler. I tried to include Feed.h here, but it is too big and goes over the character limit, so I included the portion that is referenced in the errors.
class FeedProcessor : virtual public ::apache::thrift::TProcessor {
protected:
boost::shared_ptr<FeedIf> iface_;
virtual bool process_fn(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, std::string& fname, int32_t seqid, void* callContext);
private:
std::map<std::string, void (FeedProcessor::*)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*)> processMap_;
void process_ping(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_search_text(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_search_prox_web(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_search_prox_mob(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_add_event(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_associate_venue_with_event(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_save_usr_loc(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
public:
FeedProcessor(boost::shared_ptr<FeedIf> iface) :
iface_(iface) {
processMap_["ping"] = &FeedProcessor::process_ping;
processMap_["search_text"] = &FeedProcessor::process_search_text;
processMap_["search_prox_web"] = &FeedProcessor::process_search_prox_web;
processMap_["search_prox_mob"] = &FeedProcessor::process_search_prox_mob;
processMap_["add_event"] = &FeedProcessor::process_add_event;
processMap_["associate_venue_with_event"] = &FeedProcessor::process_associate_venue_with_event;
processMap_["save_usr_loc"] = &FeedProcessor::process_save_usr_loc;
}
virtual bool process(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot, void* callContext);
virtual ~FeedProcessor() {}
};
Any help would be appreciated, I am very stuck on this.

Just for the sake of completeness:
(1) On Windows, there is no need to build the Thrift Compiler EXE on your own, there is a (small) installer to be downloaded here.
(2) If you still want or need to build the Thrift Compiler Binaries, you still don't need to fire up Cygwin: More recent versions of Apache Thrift offer a nice Visual Studio solution which only require Win flex-bison as dependency. Works like a charm.

Related

C++ template construction for class member lists

So I have made a little bit of C++ templates before: some quite basic examples of the curiously recurring template pattern for classes of mathematical numbers. This time I tried using the same pattern to create a list or "network" for objects of a class which they could add themselves to and look around for other objects. I thought I could use a static std::list to do this. So my attempt goes like this:
template<class C> class HasNetwork{
public:
HasNetwork(){}
static list<C*> m;
};
template<class C> list<C*> HasNetwork<C>::m = list<C*>();
class IHaveNetwork: public HasNetwork<IHaveNetwork>{
public:
IHaveNetwork(){ m.push_back(this); }
};
int main(){
IHaveNetwork lHF, lHF2;
//for(list<IHaveNetwork*>::iterator it = lHF.m->begin(); ; it++);
return 0;
}
It seems to compile, but I get nasty link errors ( even with the for loop iterator commented out ). Maybe I need to do some cast or maybe "this" is not defined until after the constructor finishes?
Here is the link error:
/tmp/templatest-912860.o: In function `__clang_call_terminate':
templatest.cpp:
(.text.__clang_call_terminate[__clang_call_terminate]+0x9): undefined reference to `__cxa_begin_catch'
templatest.cpp:(.text.__clang_call_terminate[__clang_call_terminate]+0x12): undefined reference to `std::terminate()'
/tmp/templatest-912860.o: In function `__gnu_cxx::new_allocator<std::_List_node<IHaveNetwork*>
>::deallocate(std::_List_node<IHaveNetwork*>*, unsigned long)':
templatest.cpp:
(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE10deallocateEPS4_m[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE10deallocateEPS4_m]+0x1c): undefined reference to `operator delete(void*)'
/tmp/templatest-912860.o: In function `std::list<IHaveNetwork*, std::allocator<IHaveNetwork*>
>::_M_insert(std::_List_iterator<IHaveNetwork*>, IHaveNetwork* const&)':
templatest.cpp:
(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE9_M_insertESt14_List_iteratorIS1_ERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE9_M_insertESt14_List_iteratorIS1_ERKS1_]+0x31): undefined reference to
`std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'
/tmp/templatest-912860.o: In function `std::list >::_M_create_node(IHaveNetwork* const&)':
templatest.cpp:
(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_]+0xa0): undefined reference to `__cxa_begin_catch'
templatest.cpp:(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_]+0xbb): undefined reference to `__cxa_rethrow'
templatest.cpp:
(.text._ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_[_ZNSt4listIP12IHaveNetworkSaIS1_EE14_M_create_nodeERKS1_]+0xce): undefined reference to `__cxa_end_catch'
/tmp/templatest-912860.o: In function `__gnu_cxx::new_allocator<std::_List_node<IHaveNetwork*> >::allocate(unsigned long, void const*)':
templatest.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv]+0x33): undefined reference to `std::__throw_bad_alloc()'
templatest.cpp:(.text._ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv[_ZN9__gnu_cxx13new_allocatorISt10_List_nodeIP12IHaveNetworkEE8allocateEmPKv]+0x40): undefined reference to `operator new(unsigned long)'
/tmp/templatest-912860.o:(.eh_frame+0x13): undefined reference to `__gxx_personality_v0'
I cannot reproduce.
Here is a slightly modified version of you code that compiles links and runs without even a warning (I only had to fix some indirection level errors):
#include <iostream>
#include <list>
#include <string>
template<class C> class HasNetwork{
public:
HasNetwork(){}
static std::list<C*> m;
};
template<class C> std::list<C*> HasNetwork<C>::m = std::list<C*>();
class IHaveNetwork: public HasNetwork<IHaveNetwork>{
std::string name;
public:
IHaveNetwork(const std::string &name): name(name) { m.push_back(this); }
std::string getName() const {
return name;
}
};
int main(){
IHaveNetwork lHF("foo"), lHF2("bar");
for(std::list<IHaveNetwork*>::iterator it = lHF.m.begin(); it != lHF.m.end(); it++) {
std::cout << (*it)->getName() << std::endl;
}
return 0;
}

GTEST - ASSERT_EQ and EXPECT_EQ compile error

I have been trying to use the assertion of ASSERT_EQ and EXPECT_EQ,
ASSERT_EQ(queue_->size(),6);
even using this
ASSERT_EQ(6,6);
However, I encountered this compiler error and everywhere I searched no one seems to be facing
this problem.
/tmp/cczZfMaq.o: In function testing::AssertionResult testing::internal::EqHelper<false>::Compare<char, char>(char const*, char const*, char const&, char const&)':
/usr/include/gtest/gtest.h:1485: undefined reference totesting::AssertionResult testing::internal::CmpHelperEQ(char const*, char const*, char const&, char const&)'
collect2: error: ld returned 1 exit status
make: * [priority_queue_test.out] Error 1
Full Test File :
//Include the class which you would like to test
#include "priority_queue.h"
//Include the google c++ test framework
#include
#include
#include
//use the namespace for the testing class
using namespace algorithms;
using namespace containers;
namespace{
//Test Fixture Class
//multple tests in a test case shared common objects and subroutines
class PriorityQueueTest : public ::testing::Test{
protected:
PriorityQueueTest(){
}
virtual ~PriorityQueueTest(){
}
virtual void SetUp(){
queue_ = new PriorityQueue(1000);
}
virtual void TearDown(){
}
PriorityQueue *queue_=NULL;
};
TEST_F(PriorityQueueTest,CheckAllMemberInitSuccessfully){
//ASSERT is a critcal assertion which will fail the test program
ASSERT_TRUE(queue_!=NULL) capacity()==1000) capacity();
}
TEST_F(PriorityQueueTest,CheckIfItemsAreEnqueueCorrectly){
//test cases
queue_->Enqueue(0,0);
queue_->Enqueue(1,1);
queue_->Enqueue(6,6);
queue_->Enqueue(5,5);
queue_->Enqueue(3,3);
queue_->Enqueue(2,2);
ASSERT_EQ('a','a');
}
}//namespace
int main(int argc, char *argv[]){
::testing::InitGoogleTest(&argc,argv);
return RUN_ALL_TESTS();
}

C++ trouble with extern - undefined reference

main.cpp:
bool lgstatus;
User currentUser;
//...
int main(){ //... }
loginwindow.cpp:
void LoginWindow::on_cmdCreate_clicked()
{
extern bool lgstatus;
extern User currentUser;
//...
currentUser.setMail(ui->txtAccountMail->text().toStdString());
currentUser.setName(ui->txtAccountName->text().toStdString());
currentUser.setPassword(ui->txtAccountPassword->text().toStdString());
//...
lgstatus = true;
}
My class User has 3 functions. Each of them takes a string as argument. I don't know whats wrong. The compiler doesn't complain if I change lgstatus but my currenUser.
Class :
class User
{
public:
User();
User(const std::string &name, const std::string &password);
User(const std::string &name, const std::string &password, const std::string &mail);
void setName(const std::string &name);
void setMail(const std::string &mail);
void setPassword(const std::string &password);
private:
std::string user_name;
std::string user_password;
std::string user_mail;
};
The "set" functions simply pass their argument to the user_name etc. I don't think it would be necessary to show them as well.
Errors :
undefined reference to 'User::setMail(std::string const&)'
undefined reference to 'User::setName(std::string const&)'
undefined reference to `User::setPassword(std::string const&)'
What did I do wrong?
More than likely you are not doing the correct #include in your loginwindow.cpp. As a result, the compiler never finds the correct functions.

function invoking undefined reference

hi every one I have this class with those headers
class WuManber
{
public:
WuManber( void );
virtual ~WuManber( void );
void Initialize( const vector<const char *> &patterns,
bool bCaseSensitive = false, bool bIncludeSpecialCharacters = false, bool bIncludeExtendedAscii = false );
when I try try to create an instance of WuManber and invoke Initialize I get the following error:
/tmp/ccx19Os5.o: In function main': Test.cpp:(.text+0x8d): undefined
reference toWuManber::WuManber()' Test.cpp:(.text+0xbc): undefined
reference to WuManber::Initialize(std::vector<char const*,
std::allocator<char const*> > const&, bool, bool, bool)'
Test.cpp:(.text+0xc8): undefined reference toWuManber::~WuManber()'
Test.cpp:(.text+0x115): undefined reference to `WuManber::~WuManber()'
collect2: ld returned 1 exit status
int main(int argc, char* argv[])
{
Parser CustomParserEx;
CustomParserEx.open("/home/abdullah/Project IDS/rules");
WuManber WmAlgorithm;
WmAlgorithm.Initialize(CustomParserEx.patterns,true,true,true);
}
so any hints of what I am doing wrong
You didn't implement the three methods of WuManber, or you didn't include the implementations where the linker can find them.

Using gcc/g++ instrument functions with MinGW?

i try to use the gcc instrument functions with g++ compiler of MinGW, but i
always got linker issues. Is it possible to use the instrument functions with
MinGW/MSYS?
The linker failure output:
$ g++ instrumentFunctions.cpp -o iftest -finstrument-functions >> iflog.txt
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x4e): undefined reference to `__cyg_prof
ile_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x158): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x179): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x18c): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x1a7): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x1bf): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x1db): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x1f3): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x22f): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x27a): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x29b): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x2e4): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x2ff): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x326): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x341): undefined reference to `__cyg_pro
file_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text+0x368): undefined reference to `__cyg_pro
file_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text$printf[_printf]+0x16): undefined referenc
e to `__cyg_profile_func_enter'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text$printf[_printf]+0x43): undefined referenc
e to `__cyg_profile_func_exit'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text$_ZSt3minIjERKT_S2_S2_[unsigned int const&
std::min<unsigned int>(unsigned int const&, unsigned int const&)]+0x15): undefined reference to `__cyg_profile_func_ent
er'
C:/Users/HELLHO~1/AppData/Local/Temp/ccUwxrxt.o:instrumentFunctions.cpp:(.text$_ZSt3minIjERKT_S2_S2_[unsigned int const&
std::min<unsigned int>(unsigned int const&, unsigned int const&)]+0x42): undefined reference to `__cyg_profile_func_exi
t'
collect2: ld returned 1 exit status
g++ command i use:
g++ iftest.cpp -o iftest -finstruction-functions
Listing of my testsource:
#include <stdio.h>
void __cyg_profile_func_enter( void *, void * ) __attribute__ ((no_instrument_function));
void __cyg_profile_func_enter(void *func, void *callsite)
{
printf("%p\n", (int)func);
}
void func_c( void )
{
return;
}
void func_b( void )
{
func_c();
return;
}
void func_a( void )
{
func_b();
return;
}
int main()
{
func_a();
func_c();
}
You need to give the __cyg* functions "C" linkage. A function defined in C++ normally gets a mangled name which can't be used from libraries not written in C++. You can ask the compiler to give a function the name C would give it by using an `extern "C"{} block. The following should compile fine.
#include <stdio.h>
extern "C" {
void __cyg_profile_func_enter( void *, void * ) __attribute__ ((no_instrument_function));
void __cyg_profile_func_enter(void *func, void *callsite)
{
printf("enter %p\n", func);
}
void __cyg_profile_func_exit( void *, void * ) __attribute__ ((no_instrument_function));
void __cyg_profile_func_exit(void *func, void *callsite)
{
printf("exit %p\n", func);
}
}
void func_c( void )
{
return;
}
void func_b( void )
{
func_c();
return;
}
void func_a( void )
{
func_b();
return;
}
int main()
{
func_a();
func_c();
}