2016年4月29日 星期五

最簡單的 CMake 使用說明 – how to use cmake

http://mqjing.blogspot.hk/2009/09/cmake-how-to-use-cmake.html
最簡單的 CMake 使用說明 – how to use cmake


2009年9月15日 星期二


[程式設計] 最簡單的 CMake 使用說明 – how to use cmake

http://mqjing.blogspot.hk/2009/09/cmake-how-to-use-cmake.html
我們常常改別人已經寫好的 open source 專案, 讓我有一種感覺 … 似乎大的系統都會有一套 building system, 先解析平台上的 toolchain, 使得系統可以容易安裝到其他平台上.
在 Unix 世界裡面, 最常見的就是 GNU Building System. 也就是你常見的先下 .configure -參數 指令, 然後會產生一堆 Makefile. 使用 building system 有另外一個好處, 那就是我們的 source code 就不會被某個編譯環境鎖住了 (ex: Visual Studio .Net).

今天要介紹的是 CMake!
CMake 指令, 可以讓我們的使用者更容易把程式建構於不同的平台. 重要的是, 它可以讓我選擇要產生 Makefile 或 Visual Studio .Net 的專案檔 (sln 專案檔).
本文的主要結構為:
        1. 最簡單的 CMakeLists.txt 範例
        2. 如何在 Cygwin 下, 自動產生 Makefile
        3. 如何在 Windows 下, 自動產生 Visual Studio .Net 專案檔 (sln)
        4. FAQ
               -  設定/使用變數範例: set       
               -  建立/使用 macro 範例: MACRO
               -  存取環境變數的範例: $ENV{PATH}
               -  加入 Post Build 的範例: add_custom_command
               -  秀 Message 的範例: Message
               -  若你的執行檔是 Windows 程式, 請加入 Win32
               -  MFC 設定
               -  設定 source code 群組範例: set_group
               -  目前 binary 目錄 與 source 目錄:
                              CMAKE_CURRENT_SOURCE_DIR
                              CMAKE_CURRENT_BINARY_DIR
             
   -  建立 dll 範例
                - console 與 windows (/SUBSYSTEM:CONSOLE or /SUBSYSTEM:WINDOWS)
       5.  好用的變數 (more)

我想達成的目的, 如下所示:
cmake_structure

先把範例端上來

-------------------- fun.cpp --------------------
int add(int a,int b){
    return a+b;
}

// fun.h
int add(int a,int b);

-------------------- main.cpp --------------------
#include "fun.h"
#include <stdio.h>
int main(){
    int ans=add(1,2);
    printf("ans=%d",ans);
    return 0;
}

我想要做的事情是
1. 建立一個 library 檔稱為 MyLibrary, 裡面包含 fun.cpp
2. 自動建立 makefile, 把 main.cpp 與 MyLibrary 連接並且編譯.
用 cmake 該怎麼作?

Step 1: 寫一個 CMakeLists.txt, 描述該怎麼編譯你的 source
ex:
-------------------- CMakeLists.txt -----------------
project(MyProject)
add_library(MyLibrary fun.cpp)  # 建立程式庫 MyLibrary
add_executable(MyProgram main.cpp) # 建立執行檔 MyProgram

# 產生執行檔 MyProgram 與 程式庫 MyLibrary 連結指令
target_link_libraries(MyProgram MyLibrary)
-------------------- end of CMakeLists.txt -----------------

Step 2: 把它與你的 source files 放在一起
ex:
cmake_CMakeLists
Step 3: Enjoy

選擇你要產生的專案

自動產生 Makefile 的作法


Step 1: 在要放置 binary 的位置, 直接下指令 cmake [source code 目錄位置]
ex: 我在 ~/cmake_demo/bin 這個空目錄中, 下 cmake ../source 指令
cmake
 Step 2: 來看看結果如何? (cmake 會把 Makefile 放在 bin/ 中)
01_Makefile

 Step 3: 在 bin/ 下 make 指令, 看到底會不會動
02_in_process

嗯! 確實可以執行! ^_^
02_result

----------------------------------------------------------------------------------------

產生 Microsoft Visual Studio 專案的作法


Step 1: 選擇編譯結果目錄, 我們希望
    a.  指定 source code 的位置在: cmake_demo/source
    b. 編譯後的結果放在: cmake_demo/bin
    這樣作就不會把 source code 目錄弄髒了.
04_Windows_Configure

Step 2: 選擇產生 Visual Studio 8 2005 專案檔
05_win_Choose_Target_and_Specify_Native_compilers

Step 3: 設定編譯器所在位置
    ex: C:\Program Files\Microsoft Visual Studio 8\VC\bin
06_win_Choose_VisualStudio_cl

Step 4: 選擇 [Generate] 開始產生 Visual Studio 專案
07_win_reConfigure_and_runGenerate
07_win_run_testing

08_win_solution_result

FAQ
Unicode 設定的問題
如果你的字元處理是 Unicode, 那麼可以在 CMakeLists.txt 裡面加入
# 設定 Unicode
add_definitions(-DUNICODE -D_UNICODE)
如下圖所示
unicode

你會在產生出來的 project 設定中, 看見
unicode_prj 
# 設定變數範例           set(MYLIBPATH "C:\\Documents and
                  Settings\\Jing\\Desktop\\opencv_bin\\lib\\release\\")
# 使用變數範例           target_link_libraries(${name} ${MYLIBPATH}cv200.lib)

# 建立 macro 範例
           MACRO(MY_DEFINE_EXAMPLE name srcs)
                 add_executable(${name} ${srcs})
           ENDMACRO(MY_DEFINE_EXAMPLE)
# 使用 macro 範例            MY_DEFINE_EXAMPLE(demo     demo.cpp)

# 存取環境變數的範例
             MESSAGE("$ENV{PATH}")
# 加入 Post Build 的範例     add_custom_command(
            TARGET ${MyPluginTarget}
            POST_BUILD
            COMMAND copy
                           ${CMAKE_CFG_INTDIR}\\${MyPluginTarget}.dll
                           "C:\\Program Files\\Mozilla Firefox\\
                             plugins\\${MyPluginTarget}.dll"
        )

# 若你的執行檔是 Windows 程式, 請加入 Win32
# ex:
        add_executable(demo WIN32 ${SOURCE})

# MFC 設定
# ex:
        set(CMAKE_MFC_FLAG 2)
        set_target_properties(MyApp      PROPERTIES   
                   COMPILE_DEFINITIONS
                                                                  _AFXDLL, _UNICODE, UNICODE,
                                                                  _BIND_TO_CURRENT_CRT_VERSION,
                                                                  _BIND_TO_CURRENT_MFC_VERSION
                    LINK_FLAGS
                                                                  " /ENTRY:\"wWinMainCRTStartup\"    ")
         記得:
                         add_executable(demo WIN32 ${SOURCE})
# 設定 source code 群組範例
ex 1:
    file(GLOB_RECURSE myRESOURCE_FILE “*.def” “*.rc”)
    source_group(Resource FILES ${myRESOURCE_FILE })
ex 2:
    source_group(abc_group REGULAR_EXPRESSION "abc.*")
    source_group(123_group REGULAR_EXPRESSION "123.*")
   
    set(SOURCE abc.cpp abc.h 123.cpp 123.h abc.rc main.cpp main.h
                              resource.h stdafx.cpp  stdafx.h
                              ./res/123.ico ./res/123.rc2)
     add_executable(demo WIN32 ${SOURCE})

# 建立 dll 範例
ex:
     add_library( target SHARED a.c b.c);

#console 與 windows (/SUBSYSTEM:CONSOLE or /SUBSYSTEM:WINDOWS)
a. 如果你的程式是 Windows.
          => 則 add_executable(demo WIN32 ${SOURCE})
b. 如果是 console, 則
          => 則 add_executable(demo ${SOURCE})


5. 好用的變數 (more)
PROJECT_SOURCE_DIR:  包含 project 命令的 CMakeFile.txt 完整路徑. (ex: c:\abc)
usage:
       set(PROJECT_HOME ${PROJECT_SOURCE_DIR}\\..\\)

Enjoy.
by Jing

2016年4月28日 星期四

PXE Boot on CentOS 7

http://www.unixmen.com/install-pxe-server-and-configure-pxe-client-on-centos-7/


Essentially you follow the article "Install PXE Server And Configure PXE Client On CentOS 7" of the link about to setup a PXE network.


A few thing to note.
1.
You may see below
curl: (22) The requested URL returned error: 403 Forbidden
Warning: Download 'http://192.16.1.150/centos7_x64/LiveOS/squashfs.img' failed!

So, using this will be working
[root@pxe centos7_x64]# vi /etc/httpd/conf.d/pxeboot.conf
Alias /centos7_x64 /var/lib/tftpboot/centos7_x64/
<Directory /var/lib/tftpboot/centos7_x64>
    Options Indexes FollowSymLinks
    AllowOverride none
    Require all granted
</Directory>
<Directory />
    Options Indexes FollowSymLinks
    AllowOverride none
    Require all granted
</Directory>

2. DCHP ARGS

vi /etc/sysconfig/dhcpd
# WARNING: This file is NOT used anymore.

# If you are here to restrict what interfaces should dhcpd listen on,
# be aware that dhcpd listens *only* on interfaces for which it finds subnet
# declaration in dhcpd.conf. It means that explicitly enumerating interfaces
# also on command line should not be required in most cases.

# If you still insist on adding some command line options,
# copy dhcpd.service from /lib/systemd/system to /etc/systemd/system and modify
# it there.
# https://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F

DHCPDARGS=enp0s8

# example:
# $ cp /usr/lib/systemd/system/dhcpd.service /etc/systemd/system/
# $ vi /etc/systemd/system/dhcpd.service
# $ ExecStart=/usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid <your_interface_name(s)>
# $ systemctl --system daemon-reload
# $ systemctl restart dhcpd.service



3. When setting the dchp server, you may not be able to restarat the dhcpd service.
You need to add a subnet section accoridng to http://linux.vbird.org/linux_server/0340dhcp.php#theory

subnet 192.168.100.0 netmask 255.255.255.0 {
    range 192.168.100.101 192.168.100.200;  <==分配的 IP 範圍

    # 3. 關於固定的 IP 啊!
    host win7 {
        hardware ethernet    08:00:27:11:EB:C2; <==用戶端網卡 MAC
        fixed-address        192.168.100.30;    <==給予固定的 IP
    }
}

2016年4月22日 星期五

Thrift C++ on Linux with Makefile Tutorial


首先假设你已经安装好thrift,我用的是CentOS7.2

C++

[root@thrift gen-cpp]# thrift --version
Thrift version 1.0.0-dev

准备thrift档案内容如下
[root@thrift cal]# vi cal.thrift
struct nums {
    1: i32 i1;
    2: i32 i2;
}

service sumservice {
    void sum(1: nums n)
}

然后用thrift产生cpp的header及source档案
[root@thrift cal]# thrift --gen cpp cal.thrift

可以看见产生了gen-cpp文件夹,进入gen-cpp文件夹,看见以下几个产生出来的文件。
其中3组.h及.cpp文件:cal_constants.*,cal_types.*,sumservice.*,共6个文件thrift已经完全写好。
cal_constants.* 及 cal_types.* 的命名方式是基于cal.thrift档案名称的
sumservice.* 的命名方式cal.thrift档案里面所有的service的名称的
sumservice.*是server side交易资料的implementation
产生出来的3组.h及.cpp合共全部6个文件一般无需自行更改
[root@thrift sum]# ls && cd gen-cpp/ && ls
cal.thrift  gen-cpp
cal_constants.cpp  cal_types.cpp  sumservice.cpp  sumservice_server.skeleton.cpp
cal_constants.h    cal_types.h    sumservice.h

留意sumservice.*里面的几个class名字及顺序
If, IfFactory, IfSingletonFactory, Null:If
args__isset, args, pargs, result, presult
Client:If, Processor:TDispatchProcessor, ProcessorFactory:TPorcessorFactory
Multiface:If, ConcurrentClient : If, 

唯一需要自行更改的是sumservice_server.skeleton.cpp, 这是Handler:If的
原本这个sumservice的预设implementation是把function名字打印出来
[root@thrift gen-cpp]# vi sumservice_server.skeleton.cpp
class sumserviceHandler : virtual public sumserviceIf {
 public:
  sumserviceHandler() {
    // Your initialization goes here
  }
  void sum(const nums& n) {
    // Your implementation goes here
    printf("sum\n");
  }
};
其中的main function大意是这样的,主要有关联的是Handler>TProcessor>TSimpleServer,而ServerTransport, TransportFactory及ProtocolFactory是配角。
int main() {
  TSimpleServer server(TProcessor(sumserviceHandler()));
  server.server();
};

由于每次运行都会把这歌现有的skeleton覆盖掉,所以现在干脆直接改名以免后顾之忧,改名以后列出的档案也比较工整
[root@thrift gen-cpp]# mv sumservice_server.skeleton.cpp server.cpp && ls
cal_constants.cpp  cal_types.cpp  client.cpp  sumservice.cpp
cal_constants.h    cal_types.h    server.cpp  sumservice.h

我们把server.cpp其中的两个方法改成以下有意义的内容,值得注意的是这两个方法都是放在一个由sumserviceIf界面虚疑继承的
[root@thrift gen-cpp]# vi server.cpp
class sumserviceHandler : virtual public sumserviceIf {
sumserviceHandler() {
    printf("server created \n");
  }
void sum(const nums& n) {
    printf("sum: %d + %d = %d \n", n.i1, n.i2, n.i1 + n.i2);
  }
}

用g++编译server程序 其中server档案需要参考types, constants 及service档案,留意最后要加上-lthrift
[root@thrift gen-cpp]# g++ -o server server.cpp sumservice.cpp cal_types.cpp cal_constants.cpp -lthrift

可以试试把server程序跑起来,并且看见sumserviceHandler的建构子被呼叫了
[root@thrift gen-cpp]# ls
cal_constants.cpp  cal_types.cpp  server          sumservice.h
cal_constants.h    cal_types.h    sumservice.cpp  server.cpp
[root@thrift gen-cpp]# ./server
server created
^C


下一步要建立client代码去跟server程序沟通
首先要从sumservice.h找出你等下准备要继承的client class, grep Client一下会发现名有两个classes sumserviceClient  sumserviceConcurrentClient 
[root@thrift gen-cpp]# grep Client sumservice.h
#include <thrift/async/TConcurrentClientSyncInfo.h>
class sumserviceClient : virtual public sumserviceIf {
  sumserviceClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
  sumserviceClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
class sumserviceConcurrentClient : virtual public sumserviceIf {
  sumserviceConcurrentClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> prot) {
  sumserviceConcurrentClient(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> iprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> oprot) {
  ::apache::thrift::async::TConcurrentClientSyncInfo sync_;


client跟server的基本代码结构非常类似,所以直接考出来修改
[root@thrift gen-cpp]# cp server.cpp client.cpp && vi client.cpp

顶头加入TSocket.h并把main方法改成以下
#include <thrift/transport/TSocket.h>
int main(int argc, char **argv) {
  shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
  shared_ptr<TTransport> transport(new TBufferedTransport(socket));
  shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
  transport->open();
  // client code starts here
  nums n;
  n.i1 = 1;
  n.i2 = 2;
  sumserviceClient(protocol).sum(n);
  // client code ends here
  transport->close();
  return 0;
}

client.cpp以下几句只跟server有关却跟client无关,正在写client code的我们为求简洁把他们移除掉。不怕,万一忘记移除,client程序还是可以编译跑起来的。
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
using namespace ::apache::thrift::server;
class sumserviceHandler
shared_ptr<sumserviceHandler> handler(new sumserviceHandler());
shared_ptr<TProcessor> processor(new sumserviceProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));

client.cpp中你会看见原本server的TTransportFactory及TProtocolFactory,如果把它们的Factory去掉就会变成client的要员
  1. boost::shared_ptr<TSocket> socket(new TSocket("localhost", 9090));    
  2.     boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));    
  3.     boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); 

client.cpp整个就是这样
#include "sumservice.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TBufferTransports.h>
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using boost::shared_ptr;
#include <thrift/transport/TSocket.h>
int main(int argc, char **argv) {
  shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
  shared_ptr<TTransport> transport(new TBufferedTransport(socket));
  shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
  transport->open();
  // client code starts here
  nums n;
  n.i1 = 1;
  n.i2 = 2;
  sumserviceClient(protocol).sum(n);
  // client code ends here
  transport->close();
  return 0;
}


可以编译了
[root@thrift gen-cpp]# g++ -o client client.cpp sumservice.cpp cal_types.cpp cal_constants.cpp -lthrift

如果看见這个问题不要紧
[ricky@thrift1 gen-cpp]$ ./server
./server: error while loading shared libraries: libthrift-1.0.0-dev.so: cannot open shared object file: No such file or directory

再跑一次就可以
$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
$ export LD_LIBRARY_PATH
$ ./server


可以跑了!背景跑server,前景跑client
[root@thrift gen-cpp]# ./server &
[1] 22189
[root@thrift gen-cpp]# server created
./client
sum: 1 + 2 = 3
[root@thrift gen-cpp]# pkill server


做个最原始的makefile,可以看到server跟client档案的dependency
[root@thrift gen-cpp]# vi makefile

.PHONY: all
all: server client

server: cal_constants.cpp cal_types.cpp sumservice.cpp cal_constants.h cal_types.h server.cpp sumservice.h
        g++ -std=c++11 -o server cal_constants.cpp cal_types.cpp sumservice.cpp server.cpp -lthrift
client: cal_constants.cpp cal_types.cpp client.cpp sumservice.cpp cal_constants.h cal_types.h server.cpp sumservice.h
        g++ -std=c++11 -o client cal_constants.cpp cal_types.cpp sumservice.cpp client.cpp -lthrift


Python

假设你不用C++而要使用Python,用thrift产生cpp的header及source档案
[root@thrift sum]# thrift --gen py cal.thrift && ls && ls ./gen-py/ && ls ./gen-py/cal
cal.thrift  gen-cpp  gen-py
cal  __init__.py
constants.py  __init__.py  sumservice.py  sumservice-remote  ttypes.py


可以看到thrift并不会把server代码skeleton产生给你,于是你需要在thrift档案同一目录下,建立以下的server.py,值得注意的是里面的CalHandler这个类并没有使用继承,只要是任何一个有写好sum(self,n)的类就可以送给sumservice.Processor()去被呼叫。留意,sumservice.py已经由thrift写好里面传送的代码,不用自己修改的。
[root@thrift sum]# vi server.py
#!/usr/bin/env python
import socket
import sys
sys.path.append('./gen-py')
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
from cal import sumservice
from cal.ttypes import *
class CalHandler :
    def sum(self, n) :
        print(n.i1 + n.i2)
handler = CalHandler()
processor = sumservice.Processor(handler)
transport = TSocket.TServerSocket("127.0.0.1", 9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)

server.serve()

参考./gen-py/sum/ttypes.py,可以看见nums已经写好了建构子,与c++的POD struct不同
class nums(object):
    def __init__(self, i1=None, i2=None,):
        self.i1=i1
        self.i2=i2

[root@thrift sum]# vi client.py
#!/usr/bin/env python
import sys
sys.path.append('./gen-py')
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from cal import sumservice
from cal.ttypes import *
try:
    transport = TSocket.TSocket('127.0.0.1', 9090)
    transport = TTransport.TBufferedTransport(transport)
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = sumservice.Client(protocol)
    transport.open()
    client.sum(nums(1,2)) # call constructor of nums() class from ttypes.py
    transport.close()
except Thrift.TException as ex:

    print ("%s" % (ex.message))

Java

must use "127.0.0.1" instead of "localhost" in server.py and JavaClient.java

JavaClient.java
import org.apache.thrift.TException;
import org.apache.thrift.transport.TSSLTransportFactory;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TSSLTransportFactory.TSSLTransportParameters;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
public class JavaClient {
    public static void main(String[] args) {
        try {
            TTransport transport;
            transport = new TSocket("127.0.0.1", 9090);
            transport.open();
            TProtocol protocol = new  TBinaryProtocol(transport);
            sumservice.Client client = new sumservice.Client(protocol);
            client.sum(new nums(1, 6));
            System.out.println("done");
            transport.close();
        }
        catch (TException x) {
            x.printStackTrace();
        }
    }
}

[ricky@thrift2 cal]$ thrift --gen java cal.thrift && ls gen-java
nums.java  sumservice.java

[ricky@thrift1 gen-java]$ pwd
/home/ricky/dev/Thrift/cal/gen-java
cp /path/to/thrift/lib/java/build/lib/*.jar ./lib/
cp /path/to/thrift/lib/java/build/libthrift-1.0.0.jar ./lib/

[ricky@thrift2 gen-java]$ javac -cp ".:./lib/*" JavaClient.java && java -cp ".:./lib/*" JavaClient






asdfas

2016年4月20日 星期三

Installing Thrift 1.0.0 on CentOS 7.2 on 4/20/2016

Installing Thrift 0.9.3 on CentOS 7.2 on 4/20/2016

Main Reference https://thrift.apache.org/docs/install/centos

sudo yum install -y autoconf automake libtool flex bison pkgconfig

sudo yum -y groupinstall "Development Tools"

sudo yum install -y wget

Build and Install the Apache Thrift IDL Compiler

git clone https://git-wip-us.apache.org/repos/asf/thrift.git
cd thrift
./bootstrap.sh
./configure --with-lua=no

Python 2

Configure Thrift
./configure --with-lua=no
By default only Python available on Linux CentOS 7.2 after ./configure

thrift 1.0.0-dev
Building Plugin Support ...... : no
Building C++ Library ......... : no
Building C (GLib) Library .... : no
Building Java Library ........ : no
Building C# Library .......... : no
Building Python Library ...... : yes
Building Ruby Library ........ : no
Building Haxe Library ........ : no
Building Haskell Library ..... : no
Building Perl Library ........ : no
Building PHP Library ......... : no
Building Dart Library ........ : no
Building Erlang Library ...... : no
Building Go Library .......... : no
Building D Library ........... : no
Building NodeJS Library ...... : no
Building Lua Library ......... : no

Make and Install Thrift
echo "note: make takes 10 minutes to complete"
make
sudo make install
This will build the compiler (thrift/compiler/cpp/thrift --version) and any language libraries supported. The make install step installs the compiler on the path: /usr/local/bin/thrift You can use the ./configure --enable-libs=no switch to build the Apache Thrift IDL Compiler only without lib builds. To run tests use "make check".
[ricky@thrift2 thrift]$ thrift --version
Thrift version 1.0.0-dev

Using CentOS 7.2 default python 2.7.5 to run the Thrift server.py


[ricky@thrift2 cal]$ python --version
Python 2.7.5
[ricky@thrift2 cal]$ python server.py Traceback (most recent call last): File "server.py", line 6, in <module> from thrift.protocol import TBinaryProtocol File "/usr/lib/python2.7/site-packages/thrift/protocol/TBinaryProtocol.py", line 20, in <module> from .TProtocol import TType, TProtocolBase, TProtocolException File "/usr/lib/python2.7/site-packages/thrift/protocol/TProtocol.py", line 24, in <module> import six ImportError: No module named six
[ricky@thrift2 cal]$ sudo yum install -y python-six
[ricky@thrift2 cal]$ python server.py
running...


Python 3 (No Solution yet on 12/21/2016 found!)

Install Anaconda 3
wget https://repo.continuum.io/archive/Anaconda3-4.2.0-Linux-x86_64.sh
chomd +x Anaconda3-4.2.0-Linux-x86_64.sh
./Anaconda3-4.2.0-Linux-x86_64.sh
[ricky@thrift2 ~]$ python --version
Python 3.5.2 :: Anaconda 4.2.0 (64-bit)

Error 1: ImportError: No module named 'thrift'
[ricky@thrift2 cal]$ python server.py
Traceback (most recent call last):
  File "server.py", line 4, in <module>
    from thrift.transport import TSocket
ImportError: No module named 'thrift'

So, you must use pip to install thrift (only works for Windows but not Linux)
pip install --upgrade pip
pip install thrift

Error 2: ImportError: cannot import name 'TFrozenDict'
[ricky@thrift2 cal]$ python server.py
Traceback (most recent call last):
  File "server.py", line 8, in <module>
    from cal import sumservice
  File "./gen-py/cal/sumservice.py", line 9, in <module>
    from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException
ImportError: cannot import name 'TFrozenDict'

No Solution yet on 12/21/2016 found! Now for me I can only use Python 2 with Thrift, but not Python 3.

JAVA

Installing Java 8 by RPM and ant
wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u111-b14/jdk-8u111-linux-x64.rpm
sudo rpm -ivh jdk-8u111-linux-x64.rpm
sudo yum install -y ant

Check JDK Version
[ricky@thrift2 ~]$ java -version
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
[ricky@thrift2 thrift]$ javac -version
javac 1.8.0_111

Configure Thrift
./configure --with-lua=no
thrift 1.0.0-dev

Building Plugin Support ...... : no
Building C++ Library ......... : no
Building C (GLib) Library .... : no
Building Java Library ........ : yes
Building C# Library .......... : no
Building Python Library ...... : yes
Building Ruby Library ........ : no
Building Haxe Library ........ : no
Building Haskell Library ..... : no
Building Perl Library ........ : no
Building PHP Library ......... : no
Building Dart Library ........ : no
Building Erlang Library ...... : no
Building Go Library .......... : no
Building D Library ........... : no
Building NodeJS Library ...... : no
Building Lua Library ......... : no

Java Library:
   Using javac ............... : javac
   Using java ................ : java
   Using ant ................. : /usr/bin/ant

Make and Install Thrift
echo "note: make takes 10 minutes to complete"
make
sudo make install








C++

Add Optional C++ Language Library Dependencies

Install C++ Lib Dependencies


sudo yum -y install gcc-c++ libevent-devel zlib-devel openssl-devel

Upgrade Boost >= 1.53

wget http://sourceforge.net/projects/boost/files/boost/1.53.0/boost_1_53_0.tar.gz
tar xvf boost_1_53_0.tar.gz
cd boost_1_53_0
./bootstrap.sh
sudo ./b2 install


Thrift的安装和简单示例
http://blog.csdn.net/anonymalias/article/details/26154405

g++ -o server server_types.cpp server_constants.cpp serDemo.cpp serDemo_server.skeleton.cpp -lthrift
g++ -o client server_types.cpp server_constants.cpp serDemo.cpp  client.cpp -lthrift
// client has no no serDemo_server.skeleton.cpp

When running, if you see

error while loading shared libraries: libthrift-1.0.0-dev.so: cannot open shared object file: No such file or directory

Then add below to ~/.bash_profile
export LD_LIBRARY_PATH=/usr/local/lib/:${LD_LIBRARY_PATH}


thrift 0.9.3 on Centos 7.2


yum install boost-devel
cd /root/test/thrift/thrift-0.9.3
./configure

if configure: error: "Error: libcrypto required."

yum install openssl-devel


Download the thrift.tar
tar zxvf thrift.tar
./configure

Then you will see

Building C++ Library ......... : yes

Building C (GLib) Library .... : no

Building Java Library ........ : no

Building C# Library .......... : no

Building Python Library ...... : no

Building Ruby Library ........ : no

Building Haxe Library ........ : no

Building Haskell Library ..... : no

Building Perl Library ........ : no

Building PHP Library ......... : no

Building Erlang Library ...... : no

Building Go Library .......... : no

Building D Library ........... : no

Building NodeJS Library ...... : no

Building Lua Library ......... : no



C++ Library:

   Build TZlibTransport ...... : yes

   Build TNonblockingServer .. : no
   Build TQTcpServer (Qt4) .... : no
   Build TQTcpServer (Qt5) .... : no




2007 to 2023 HP and Dell Servers Comparison

  HP Gen5 to Gen11  using ChatGPT HP ProLiant Gen Active Years CPU Socket Popular HP CPUs Cores Base Clock Max RAM Capacity Comparable Dell ...