原文 http://bloodysofiya.blog.163.com/blog/static/11656234320103231352327/ 一般来说,当你拿到一包library的source co de,要按照如下的方式开始: 1.请仔细仔细的阅读Readme,以及各种文档.这里面包含了绝大部分你想要的东西。 2. 尝试的编译一个可以运行的版本出来看看效果。
a . 这时候你应该了解你要移植的库 , 是怎么编译的了吧?没有 ? Goto 1 : 继续往下阅读
b . 一般来说, source code 的编译会分成两种:
< 1 >. 只有一个 Makefile , 或者是有 configure 文件的。
这种的,最好是你阅读 makefile 文件 , 把这个 makefile 转换为 Android . mk 文件 , 使用 ndk build system 去编译。
< 2 >. 另一种的是大型的源代码系统。这种的通常都会有自己的 build system . 比如 android .
碰到这种大型的,可能源代码太多了,一时半会根本不能写出一个 Android . mk 文件。可以酱紫,换成你要的目标平台的 cross toolchain .
举个通常的 android 例子:
CC = $( Compile_Path )/ arm - eabi - gcc
STRIP = $( Compile_Path )/ arm - eabi - strip
AR = $( Compile_Path )/ arm - eabi - ar
LINK =&( Compile_Path )/ arm - eabi - g ++
再配合上一些编译参数:比如 , Compile_Flags = - fPIC , march = armv5t mno - thumb - interwork 之类的。
c . 试试看能不能编译出来。
能是最好的,不能,又要分几种情况了
< 1 >. 一般来说, source code 的逻辑不太会错误 . 所以不要尝试大幅度修改源代码(除非你有能力推翻重写 , 都重写那干嘛还要移植?) .
< 2 >. Compile 时,报语法错误,比如 result = obj -> func ()-> func2() ,会说类似“ XXX can ' t find func2
你可以该成 : temp = obj -> func(); result = temp -> func2(); 这主要是编译器方面的差异。
< 3 >. Compile 时,报 "can't find xxx.h" or "can't find xxx.cpp xxx.c" 之类,请正确包含该文件;
比如你可以写上: INCLUDE_PATH += - I /../......./ include . 或者放到编译下的 include 路径。比如 ndk 目录下的 build / platforms / android - 3 / arch - arm / usr / include 下面 . 不过这不是好方法就是了 .
< 4 >. Link , "can't find reference XXX" ,基本是忘记添加库文件了。你可以写上 : Library_Path += - L /.../.../ lib 或者放到 ndk 下面的 build / platforms / android - 3 / arch - arm / usr / lib 下面。
< 5 >. 当你该加的 library 都加了,依然出现 "can't find reference XXX" , 那多半就是你用的库不是标准的,这里面没有 XXX 函数的实现 .
比如 android bionic libc 就没有 ftime 函数(应该没记错吧?!)那你只好自己去添上实现文件了。
< 6 >. 又报 link error 了?通常来说,使用 android build system 的人,不应该会遇到这类问题。只有直接使用 toolchain 才有可能会出现这类问题,这类 link error 比较棘手。
解决的方法有:
( I) 库之间有依赖 , 正确的链接库的顺序;比如 libz . a 依赖 liby . a , 那么链接顺序是: ld liby . a libz . a
( II) 库版本不对,请仔细读 documentation . 这里要注意 version 的区别 , debug & release 的区别 , 是不是同一个编译器编译的库( ABI 会不一致) , static & shared 的区别
( III) C C ++ 库之间的调用 . 要记得使用 extern "C" {}, 和# ifdef __PLUSPLUS
( IV) 我碰到这样一个问题,就是作者使用了 #define OWNFUNC(Function) NEWNAME##Function字符拼接宏,把所有的函数名都转换了,dumpobj时候当然找不到函数签名啦.
( V) 当你 link 成功了,运行的时候挂掉了 . 也可能是 link 的时候没有成功哦 . 举个列子来说明:
当你写了一个 android c 版本的 helloworld , 编译链接过了,但是运行的时候告诉你 : "can't find _start symbol" , 这就是说 android OS 把执行权交个 c runtime library 的时候 , 找不到入口 , 而这个入口就是 _start . 解决的办法是 : ld crtBegin_dynamic . o 以及 crtEnd_android . o
当然还有很多的问题不是上面说的这些,比如编译参数不对, - fPIC - fpic , 应该编译 32 bit arm 指令,却用了 16 bit thumb 指令 ... 等等。
< 7 > 大部分的问题,你都解决了。剩下各种平时都没见过的问题了?去论坛上问吧。我就挺喜欢到国外的论坛上去问的。
< 8 >. 考虑使用 ndk build system 方式来编译。
但不管怎么说,我推荐使用ndkbuildsystem方式。我曾经到 google ndk group 上去问过问题,得到过 David Turner 的回答:
You should not be trying to use the toolchain directly like this .... 省略 .... Really , you should use the NDK build system instead . 3. 修改逻辑,添加逻辑适应自己的需要 .

先看看androidndk的目录layout大概长的怎么样.
root
|------apps,所有你要编译的Cc++code都放到这个目录下。
|------build
||----platforms下面目前为止放了3subfold,里面分别放了android需要的include,library(提供的library有限)
||------android3代表android1.5
||------android4代表android1.6
||------android5代表android2.0
||----prebuilt该目录下存放toolchain的可执行档案,以及include&library.对于arm-eabi-4.4.0了解不多.
||------arm-eabi-4.2.1
||------------bin所有的toolchainexcutefile
||------------arm-eabi
||------include
||------lib
||----tools这个目录下存放了很多有用的工具,包括下载,buildtoolchain
|------docs必须仔细读的文档
|------out生成的所有临时文件

先从docs开始谈,这个也是非常重要的一步。
1.纠正Android-mk.txt中写的ndk只能编译出staticlibrarysharedlibrary,实际上他还提供了命令编译可执行程序.
a.include$(BUILD_SHARED_LIBRARY)
b.include$(BUILD_STATIC_LIBRARY)
c.include$(BUILD_EXECUTABLE)
理论上能编译出so文件,当然能编译出execute文件.只是ndk是否提供这个接口。
2.apps目录下,新建一个目录,再建立project目录,这一级目录下建立Application.mk,再建立一个subfoldjni,jni里面放的都是cc++源代码,还有Android.mk.Android.mk就必须仔细写了.
常用的有LOCAL_PATH:=$(callmy-dir)//访问当前path下的所有子目录,
<1>.LOCAL_DEBUG:=no|yes
<2>.LOCAL_OS:=linux//目标平台
<3>.LOCAL_ARCH:=arm//目标平台cpu
<4>.LOCAL_ARM_MODE:=arm//CPU指令集
<5>.COMMON_DEFINES+=ISP=isp_arm9-D_ARM_//这里通常会把要移植的library中的各种flag写在这里.(从待移植中的Configure或者Makefile中拷贝过来)
<6>.ifeq($(DEBUG),no)
COMMON_FLAGS+=-s-O2-fno-strict-aliasing-DNDEBUG-fno-rtti//好像都采用O2优化,fno-rtti 告诉C++不要runtime 中的一些support.
<7>.COMMON_COMPILE_FLAGS+=-fPIC+=-msoft-float+=march=armv5t

相对应的有了COMMON_XXX就有了LOCAL_XXX,
我们可以定义相关的
<1>.LOCAL_MODULE:=libxxx//定义要编译的moule
<2>.LOCAL_CFLAGS:=-I$(LOCAL_PATH)/xxx/include以及局部FLAG(Configure或者Makefile中拷贝过来)//定义search .h fold
<3>.LOCAL_CXXFILES:=//和上面是相同的,只是这个是C++的,上面的是C
<4>.LOCAL_SRC_FILES:=XXX.cXXX.cppXXX.hpp//定义源代码
<5>.include$(BUILD_STATIC_LIBRARY)定义该模块是静态的
要编译到android上运行的excutable,还会依赖
<1>.LOCAL_LDLIBS:=-Llibrary_path-lxx//定义库的路径,以及要的library, 这里其实用的都是动态库.
android,有一个参数是:-dynamic-linker,/system/bin/linker,采用的不是标准的linux下的ld.so.6(好像是这个数字,具体的不清楚了),而是/system/bin/linker来链接.这也是为什么我们用其他编译器(比如codesourcery)编译出来的东西不能在android上直接跑的原因,而一定要加上-static参数,也就是说用codesourcery编译出来的东西必须不依赖android的调度,而是靠编译时把所有的库全部加入.所以这时候写出来的helloworld都可能会有1~2Mb.提到了liner,就不得不提到androidbionic,这个Cruntimelibrary设计并不是功能特别强大,并且有些gnuglic中的函数没有实现,这是移植时会碰到的问题.而且,这个Cruntimelibrary也并没有采用crt0.o,crt1.o,crti.ocrtn.o,crtbegin.ocrtend.o,而是采用了android自己的crtBegin_dynamic.o,crtBegin_static.ocrtEnd_android.ocrt1.ocrt0.o的后续演进版本,crt1.o中会非常重要的.init段和.fini段以及_start函数的入口..init段和.fini段实际上是靠crti.o以及crtn.o来实现的.init段是main函数之前的初始化工作代码,比如全局变量的构造.fini段则负责main函数之后的清理工作.crti.ocrtn.o是负责C的初始化,C++则必须依赖crtbegin.ocrtend.o来帮助实现.
So,在标准的linux平台下,link的顺序是:ldcrt1.ocrti.o[user_objects][system_libraries]crtn.o
而在android,link的顺序是:arm-eabi-g++crtBegin_dynamic.o[user_objects][system_libraries]crtEnd_android.o
所以这就是从另一个方面说明为什么不适合codesourcery之类编译来开发android底层东西的原因了,这里我不包括BSP之类.
<2>.LOCAL_STATIC_LIBRARIES:=//excute file 依赖的库
<3>.include$(BUILD_EXCUTEABLE)
在谈谈platform目录下的东西,这里面要说的是可能includelibrary中包含的头文件和library文件不太够,我们可以使用busyboxforandroid把我们要的资料都给pull出来.或者编译android源代码,需要的都东西都会有.
prebuilt目录下,有我们编译器的可执行文件,但是很不幸androidtoolchain不支持STL.目前支持STL有两种方法:
1.使用STLPort(据说这种方式不是太好)
2.重新编译使androidtoolchain支持STL.

更多相关文章

  1. window 下 利用gradle编译volley源代码
  2. Android工程使用SVG图片
  3. E/ServiceManager( 54): add_service('led',0x35) uid=10028 - P
  4. android预览word(WPS预览)
  5. 【从源码看Android】01从Looper说起
  6. android 控件: xml 设置 Button 按下背景
  7. android编译分析之10—config.mk
  8. Android(安卓)Studio 生成的目录,对应应用Logo的尺寸___ AS 与 Ec
  9. Tools属性Tools Attributes

随机推荐

  1. 2018-6月Android试题整理
  2. MIPI-DSI转HDMI
  3. 漫谈Android网络编程
  4. Android(安卓)点击通知栏消息 跳转到指定
  5. Android:Android(安卓)6.0+权限适配--简单
  6. Android开发规范之编码规范
  7. Android(安卓)WebView使用
  8. [摘]Android移动开发
  9. Android中ExpandableListView的实现
  10. 导入开源库到基于Android(安卓)Studio构