Ubuntu下用arm-linux-gcc编译boost库

来源:互联网 发布:电信屏蔽80端口 编辑:程序博客网 时间:2024/05/21 15:47

目的:

Boost库是为C++语言标准库提供扩展的一些C++程序库的总称。

Boost由Boost社区组织开发、维护。其目的是为C++程序员提供免费、同行审查的、可移植的程序库Boost可以与C++标准库完美共同工作,并且为其提供扩展功能。Boost使用Boost License来授权使用,根据该协议,商业的非商业的使用都是允许并鼓励的。

 

Boost社区建立的初衷之一就是为C++的标准化工作提供可供参考的实现,Boost社区的发起人Dawes本人就是C++标准委员会的成员之一。从某种意义上来讲,Boost成为具有实践意义的准标准库。

 

从工程角度看,在PC上的C++开发中,boost已经很普遍。但对于Android这样的移动平台呢?底层用到boost库的thread和mutex等,必须移植过去。官方的boost并没有提供Android支持,需要自己搞。

 

参考文献:

 

1.  Bjam 教程

http://wenku.baidu.com/view/9ea06241a8956bec0975e358.html

2 boost 1.51.0移植到ARM S3C6410成功运行

http://blog.chinaunix.net/uid-8048969-id-3374823.html

3 ubuntu下编译安装boost

 http://www.cnblogs.com/longcpp/archive/2012/06/06/2538251.html

4 安装boost(手记)

http://www.cnblogs.com/finallyliuyu/archive/2010/08/23/1806811.html

5 用roid NDK r6编译boost 1.47-asp.net学习网

http://www.docin.com/p-308631204.html

6

http://boost.2283326.n4.nabble.com/Shit-Looks-like-I-broke-something-td4442903.html

 

7 Android NDK r6编译boost 1.47

http://www.cnblogs.com/gongminmin/archive/2011/11/02/2233345.html

 

编译boost 1.52

http://blog.sina.com.cn/s/blog_5383588c0101fuhz.html

 

需要下载的:

boost库,版本1.51.0

http://www.boost.org/users/history/version_1_51_0.html

进去以后选unix下的

下载地址

http://www.arm9.net/download.asp  (这个里面很全)

http://download.csdn.net/download/xinhuameng/2642452(我用的后面这个,后面这个需要9CSDN分)

mpi库

apt-get install mpi-default-dev  #安装mpi

libicu-dev库

apt-get install libicu-dev  #支持正则表达式的UNICODE字符集

python

apt-get install python-dev

python的主页是http://www.python.org/,下载python2.5.2版本,安装即可。boost默认是会编译python,并且会自动寻找python的安装目录。版本要大于2.2.

libbz2

apt-get install libbz2-dev  #如果编译出现错误:bzlib.h: No such file or directory (这个错误很难搞)

 

bzip的主页是 http://www.bzip.org/,从http://www.bzip.org/downloads.html下面下载源代码包即可,boost直接使用源代码来进行编译。

 

1 boost 1.51.0,下载arm-linux-gcc  4.3.2,并解压缩。

2 安装各种依赖的包

3 boost目录,找到bootstrap.sh文件。

4 bjam文件。

执行 ./boostrap.sh

生成bjamproject-config.jam,上述命令可以带有各种选项,具体可参考帮助文档: ./bootstrap.sh --help。其中--prefix参数,可以指定安装路径,如果不带--prefix参数的话(推荐),默认路径是 /usr/local/include /usr/local/lib,分别存放头文件和各种库。执行完成后,会生成bjam,已经存在的脚本将会被自动备份。注意,boost 1.51会在当前目录下,生成两个文件bjamb2,这两个是一样的,所以接下来的步骤,可以用这两个中的任意一个来执行。

5 project-config.jam

 这一步很关键,jam语法很特殊,

 

if ! gcc in [ feature.values <toolset> ]

{

    using gcc : : /usr/local/arm/4.3.2/bin/arm-none-linux-gnueabi-gcc ;(注意冒号里有空格)

}

注意,:中间有一个空格,分号前面必须有空格,冒号两边都有空格。

6 user-config.jam 文件。

./tools/build/v2/user-config.jam

在最后一行添加using mpi ;

 

7

   拷贝bzlib.h ./libs/iostreams/src/目录下

8

./b2 -a -sHAVE_ICU=1  或

./b2 -a -sHAVE_ICU=1 > bb2.log &

#-a参数,代表重新编译,-sHAVE_ICU=1代表支持Unicode/ICU

注意,这里是全部编译。当然也可以选择只编译一部分,选项 --with-<library> 只编译指定的库,如输入--with-regex就只编译regex库了。

 

9

tail -100 bb2.log

 

common.copy stage/lib/libboost_wave.a

...updated 866 targets...

 

The Boost C++ Libraries were successfully built!

 

The following directory should be added to compiler include paths:

 

   /home/jh/work/boost/boost_1_51_0

 

The following directory should be added to linker library paths:

 

/home/jh/work/boost/boost_1_51_0/stage/lib

 

有个succesffuly built就说明过了^_^,jam如果没过,会提示有多少失败,多少update,多少跳过。

如果有错误,也可以 cat bb2.log |grep error > err.log来看看有编译错误。

10.    把头文件和生成的库,放到指定路径下 --prefix)下

生成的库拷贝出来

./b2 install

一些问题

1.       找不到ndk等。

安装ndksdk并添加环境变量ANDROID_NDK=/home/jh/work/android/android-ndk-r8

ANDROID_SDK=/home/jh/work/android/android-sdk-linux

2.      依赖pthread编译不过:

bjam --build-type=complete --toolset=%TOOLSET% --user-config=./android-config.jam cxxflags=%CXXFLAGS% --stagedir=./lib_android_arm --builddir=./ target-os=linux --with-system link=static runtime-link=static threading=multi stage。因为asio要用到system组件,所以我开始只build这个,后来要编译thread组件就需要在cmd文件中的bjam命令加入threadapi=pthread属性,否则无法通过编译。

3.     STL相关错误

--user-config=./android-config.jam选项指定刚才建立的jam文件,否则会用默认的\tools\build\v2\user-config.jam

如果CXXFLAGSinclude的是Stlport版标准库,那么以后编译程序也要使用Stlport,否则会有链接错误。

另外就是编译date_timefilesystem组件前还需要修改源代码才行:

首先是date_time,需要把\boost\detail\endian.hpp34行的条件预编译:

#if defined (__GLIBC__)

后加入 || definded(ANDROID)为:

#if defined (__GLIBC__) || definded(ANDROID)

就可以生成date_time

而编译filesystem组件前需要把\libs\filesystem\src\operations.cpp原来的include和宏定义

#     include

#     define BOOST_STATVFS statvfs

#     define BOOST_STATVFS_F_FRSIZE vfs.f_frsize

改为

#     ifdef __ANDROID__

#       include

#       define BOOST_STATVFS statfs

#       define BOOST_STATVFS_F_FRSIZE vfs.f_frsize

#     else

#       include

#       define BOOST_STATVFS statvfs

#       define BOOST_STATVFS_F_FRSIZE vfs.f_frsize

#     endif

即可。

4.      select_asm_context_sources相关问题,一般是说编译不过。Jam编译完,最后有4failed的文件。

这个需要加一个aliaslibs/context/build/Jamfile.v2文件,大概在342行左右,# X86_64标签下的,+号是我加的。

+   explicit asm_context_sources ;

 

+   alias asm_context_sources

+   : unsupported.cpp

 +   ;

alias select_asm_context_sources

: asm_context_sources

: [ architecture.architecture ]

 [ architecture.address-model ]

;

然后再添加一个新的文件cpp,到libs/context/src/unsupported.cpp下,

文件内容为:

#error "This platform is not currently support by Boost.Context"

这样在找不到contex的时候,也会忽略。

测试验证

写一个小程序,jni验证一下。

测试的mk文件

Application.mk 文件:

APP_OPTIM := release

APP_STL := gnustl_static

APP_CPPFLAGS += -frtti

APP_CPPFLAGS += -fexceptions

APP_CPPFLAGS += -DANDROID

APP_ABI := armeabi

APP_PLATFORM := android-5

Android.mk 文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE   := libboost_thread

LOCAL_SRC_FILES := libboost_thread.a

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE   := libboost_system

LOCAL_SRC_FILES := libboost_system.a

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_CPPFLAGS += -fexceptions

LOCAL_C_INCLUDES += $(LOCAL_PATH)/

LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../boost/boost_1_51_0-new/

LOCAL_LDLIBS +=  -llog

LOCAL_LDFLAGS += -L$(LOCAL_PATH)/ -lboost_system

LOCAL_LDFLAGS += -L$(LOCAL_PATH)/ -lboost_thread

LOCAL_LDLIBS += -lboost_system -lboost_thread -lgnustl_static

 

LOCAL_MODULE   := hello-jni

LOCAL_SRC_FILES := hello-jni.cpp \

    test_thread.cpp

LOCAL_STATIC_LIBRARIES := libboost_system.a libboost_thread.a

include $(BUILD_SHARED_LIBRARY)

测试源码:(java层用的是ndk-r8b下的simple/hello-jni

#include <string.h>

#include <assert.h>

#include <jni.h>

#define PLAYER_DEBUG 1;

#include "log.h"

#include "test_thread.h"

 

#ifndef NELEM

# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))

#endif

 

static const char* const kClassPathName = "com/example/hellojni/HelloJni";

static int register_native_methods(JNIEnv *env);

int jniRegisterNativeMethods(JNIEnv* env,

                            const char* className,

                            const JNINativeMethod* gMethods,

                            int numMethods)

{

    jclass clazz;

    DLOGI("Registering %s natives\n", className);

    clazz = env->FindClass(className);

    if (clazz == NULL) {

        DLOGE("Native registration unable to find class '%s'\n", className);

        return -1;

    }

    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {

        DLOGE("RegisterNatives failed for '%s'\n", className);

        return -1;

    }  

    return 0;

}

 

jint JNI_OnLoad(JavaVM* vm, void* reserved)

{

  JNIEnv* env = NULL;

  jint result = -1;

 

  if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {

     goto fail;

   }  

   assert(env != NULL);

   if (register_native_methods(env) < 0) {

        goto fail;

   }  

   result = JNI_VERSION_1_4;

fail:

    return result;

}

 

static jstring com_example_hellojni_HelloJni_stringFromJNI(JNIEnv *env, jobject thiz)

{

    DLOGI("niuli log \n");

    run_b_thread();

    return env->NewStringUTF("Hello from JNI !");

}

static JNINativeMethod gMethods[] = {

    {"stringFromJNI", "()Ljava/lang/String;",   (void *)com_example_hellojni_HelloJni_stringFromJNI},

};

static int register_native_methods(JNIEnv *env)

{

    return jniRegisterNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));

}

 

总结

常用的编译脚本,个人认为:

好用程度:   comake2 > comake > jam > ant > makefile

跨语言能力: jam  > ant  > makefile > comake2 > comake

 

如何在手机上抓包

手机抓包的前提是要刷了root才行。

 

tcpdump in android device:


 Download tcpdump from http://www.strazzere.com/android/tcpdump
 Documents: www.tcpdump.org
 adb push tcpdump /data/tool/tcpdump
 adb shell chmod 6755 /data/tool/tcpdump
 adb shell /data/tool/tcpdump -p -vv -s0 -w /sdcard/capture.pcap
 adb pull /sdcard/capture.pcap

 

然后用wired-shark或者peak之类的打开capture.pcap看就ok啦^_^

原创粉丝点击