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




2023 Promox on Morefine N6000 16GB 512GB

2023 Promox on Morefine N6000 16GB 512GB Software Etcher 100MB (not but can be rufus-4.3.exe 1.4MB) Proxmox VE 7.4 ISO Installer (1st ISO re...