如何移植library到Android(二)

之前我也写了一篇文章来说明 如何移植library到Android来说明大概要怎么移植。其实,里面有一些错误,错误的原因我觉得就是:水平有限。好了,废话不多说。进入正题。
  一般来说,当你拿到一包library的source code,要按照如下的方式开始:
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 方式来编译。
       但不管怎么说,我推荐使用ndk build system方式。我曾经到 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. 修改逻辑,添加逻辑适应自己的需要 .

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值