注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Allen小笔记

有时会忘记努力...

 
 
 

日志

 
 

如何移植library到Android(二)  

2010-04-23 13:35:02|  分类: Android |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
                                                                                             keywords:   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函数的实现.
         比如androidbionic 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) CC++库之间的调用.要记得使用extern "C" {},和#ifdef __PLUSPLUS
          (IV) 我碰到这样一个问题,就是作者使用了#define OWNFUNC(Function) NEWNAME##Function字符拼接宏,把所有的函数名都转换了,dumpobj时候当然找不到函数签名啦.
          (V) 当你link成功了,运行的时候挂掉了.也可能是link的时候没有成功哦.举个列子来说明:
                当你写了一个android c 版本的helloworld,编译链接过了,但是运行的时候告诉你:"can't find _start symbol",这就是说android OS把执行权交个cruntime library的时候,找不到入口,而这个入口就是 _start.解决的办法是:ld crtBegin_dynamic.o以及 crtEnd_android.o  
              当然还有很多的问题不是上面说的这些,比如编译参数不对,-fPIC-fpic, 应该编译32bitarm指令,却用了16bit 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.修改逻辑,添加逻辑适应自己的需要.
  评论这张
 
阅读(2872)| 评论(8)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017