cygwin上編譯RPC框架thrift

cygwin的配置就很少說了,缺什麼就經過安裝器安裝好了。mysql

在thrift的官網下載 thrift-0.11.0源碼,經過cmake編譯,生成Makefile以後,make出現編譯錯誤c++

/cygdrive/d/work/thrift-0.11.0/mybuild $ make

[ 1%] Building CXX object compiler/cpp/CMakeFiles/parse.dir/thrift/thrifty.cc.o
/cygdrive/d/work/thrift-0.11.0/compiler/cpp/src/thrift/thrifty.yy: 在函數‘int yyparse()’中:
/cygdrive/d/work/thrift-0.11.0/compiler/cpp/src/thrift/thrifty.yy:1197:20: 錯誤:‘strdup’在此做用域中還沒有聲明
$$ = strdup("1");
^~~~
/cygdrive/d/work/thrift-0.11.0/compiler/cpp/src/thrift/thrifty.yy:1197:20: 附註:suggested alternative: ‘strcmp’
$$ = strdup("1");
^~~~
strcmp
make[2]: *** [compiler/cpp/CMakeFiles/parse.dir/build.make:74:compiler/cpp/CMakeFiles/parse.dir/thrift/thrifty.cc.o] 錯誤 1
make[1]: *** [CMakeFiles/Makefile2:1055:compiler/cpp/CMakeFiles/parse.dir/all] 錯誤 2
make: *** [Makefile:161:all] 錯誤 2

查看cmake生成Makefile的日誌,在某個cmake文件裏設置了-std=c++11,找到:sql

D:\work\thrift-0.11.0\build\cmake\DefineCMakeDefaults.cmake (2 hits)
Line 79: message(STATUS "Setting C++98 as the default language level (for an older MSVC compiler).")
Line 82: message(STATUS "Setting C++11 as the default language level.")apache

以下修改:函數

if (NOT DEFINED CMAKE_CXX_STANDARD)
  if (MSVC AND MSVC_VERSION LESS 1800)
    # MSVC 2012 and earlier don't support template aliases so you have to use C++98
    set(CMAKE_CXX_STANDARD 98) 
    message(STATUS "Setting C++98 as the default language level (for an older MSVC compiler).")
  else()
    #set(CMAKE_CXX_STANDARD 11) # C++11
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
    message(STATUS "Setting C++11 as the default language level.")
  endif()
  message(STATUS "To specify a different C++ language level, set CMAKE_CXX_STANDARD")
endif()

 繼續編譯,隨即遇到編譯錯誤:單元測試

[ 11%] Building CXX object lib/cpp/CMakeFiles/thrift_static.dir/src/thrift/transport/THttpServer.cpp.o
/cygdrive/d/work/thrift-0.11.0/lib/cpp/src/thrift/transport/THttpServer.cpp: 在成員函數‘virtual void apache::thrift::transport::THttpServer::parseHeader(char*)’中:
/cygdrive/d/work/thrift-0.11.0/lib/cpp/src/thrift/transport/THttpServer.cpp:52:47: 錯誤:‘strcasestr’在此做用域中還沒有聲明
   #define THRIFT_strcasestr(haystack, needle) strcasestr(haystack, needle)
                                               ^
/cygdrive/d/work/thrift-0.11.0/lib/cpp/src/thrift/transport/THttpServer.cpp:64:9: 附註:in expansion of macro ‘THRIFT_strcasestr’
     if (THRIFT_strcasestr(value, "chunked") != NULL) {
         ^~~~~~~~~~~~~~~~~
/cygdrive/d/work/thrift-0.11.0/lib/cpp/src/thrift/transport/THttpServer.cpp:52:47: 附註:suggested alternative: ‘strcasecmp’
   #define THRIFT_strcasestr(haystack, needle) strcasestr(haystack, needle)
                                               ^
/cygdrive/d/work/thrift-0.11.0/lib/cpp/src/thrift/transport/THttpServer.cpp:64:9: 附註:in expansion of macro ‘THRIFT_strcasestr’
     if (THRIFT_strcasestr(value, "chunked") != NULL) {
         ^~~~~~~~~~~~~~~~~
make[2]: *** [lib/cpp/CMakeFiles/thrift_static.dir/build.make:495:lib/cpp/CMakeFiles/thrift_static.dir/src/thrift/transport/THttpServer.cpp.o] 錯誤 1
make[1]: *** [CMakeFiles/Makefile2:1140:lib/cpp/CMakeFiles/thrift_static.dir/all] 錯誤 2
make: *** [Makefile:161:all] 錯誤 2

這裏我就直接修改源代碼了:測試

#define _GNU_SOURCE
#include <string.h>

將這兩行放在thrift-0.11.0/lib/cpp/src/thrift/transport/THttpServer.cpp的其餘include頭文件的前面,否則 #define _GNU_SOURCE 會被編譯器忽略ui

 隨即又遇到編譯錯誤:this

/cygdrive/d/work/thrift-0.11.0/lib/cpp/src/thrift/concurrency/Mutex.cpp: 在靜態成員函數‘static void apache::thrift::concurrency::Mutex::RECURSIVE_INITIALIZER(void*)’中:
/cygdrive/d/work/thrift-0.11.0/lib/cpp/src/thrift/concurrency/Mutex.cpp:271:41: 錯誤:‘PTHREAD_MUTEX_RECURSIVE_NP’在此做用域中還沒有聲明
   init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE_NP);
                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~
/cygdrive/d/work/thrift-0.11.0/lib/cpp/src/thrift/concurrency/Mutex.cpp:271:41: 附註:suggested alternative: ‘PTHREAD_MUTEX_RECURSIVE’
   init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE_NP);
                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~
                                         PTHREAD_MUTEX_RECURSIVE
make[2]: *** [lib/cpp/CMakeFiles/thrift_static.dir/build.make:951:lib/cpp/CMakeFiles/thrift_static.dir/src/thrift/concurrency/Mutex.cpp.o] 錯誤 1
make[1]: *** [CMakeFiles/Makefile2:11
這裏又是cygwin的庫問題了,不支持PTHREAD_MUTEX_RECURSIVE_NP,改爲 PTHREAD_MUTEX_RECURSIVE
#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
void Mutex::RECURSIVE_INITIALIZER(void* arg) {
  //init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE_NP);
  init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE);
}
#endif

 連接單元測試時又出現庫不兼容的問題。。。spa

CMakeFiles/UnitTests.dir/concurrency/MutexTest.cpp.o:MutexTest.cpp:(.rdata$.refptr._ZN6apache6thrift11concurrency5Mutex20ADAPTIVE_INITIALIZEREPv[.refptr._ZN6apache6thrift11concurrency5Mutex20ADAPTIVE_INITIALIZEREPv]+0x0):對‘apache::thrift::concurrency::Mutex::ADAPTIVE_INITIALIZER(void*)’未定義的引用
collect2: 錯誤:ld 返回 1
make[2]: *** [lib/cpp/test/CMakeFiles/UnitTests.dir/build.make:339:bin/UnitTests.exe] 錯誤 1
make[1]: *** [CMakeFiles/Makefile2:1736:lib/cpp/test/CMakeFiles/UnitTests.dir/all] 錯誤 2
make: *** [Makefile:161:all] 錯誤 2

自適應鎖在cygwin的最新版是沒有的,就給它弄個默認的,該咋死咋死吧:

#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
void Mutex::ADAPTIVE_INITIALIZER(void* arg) {
  // From mysql source: mysys/my_thr_init.c
  // Set mutex type to "fast" a.k.a "adaptive"
  //
  // In this case the thread may steal the mutex from some other thread
  // that is waiting for the same mutex. This will save us some
  // context switches but may cause a thread to 'starve forever' while
  // waiting for the mutex (not likely if the code within the mutex is
  // short).
  init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_ADAPTIVE_NP);
}
#else
void Mutex::ADAPTIVE_INITIALIZER(void* arg) {
  // From mysql source: mysys/my_thr_init.c
  // Set mutex type to "fast" a.k.a "adaptive"
  //
  // In this case the thread may steal the mutex from some other thread
  // that is waiting for the same mutex. This will save us some
  // context switches but may cause a thread to 'starve forever' while
  // waiting for the mutex (not likely if the code within the mutex is
  // short).
  init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_NORMAL);
}    
#endif

 OK,至此,完美編譯成功!

相關文章
相關標籤/搜索