用Lazarus编译Android工程

注意的事项有:

  1. lazarus0.9.3.1版本以后的LCL才支持Android,所以lazarus必须使用大于此版本号的作为开发环境。
  2. fpc在2.6及2.7后继的版本中去掉了Android的编译支持,需要使用2.5.1的版本来作为ppcrossarm的编译器。否则会出现找不到ld.so.3等错误,虽然有一些使用-FLlibdl.so 或 -FLlinker -sh 生成脚本(配置使用ppas.sh并修改资源文件)的办法来回避此问题,但经过测试,似乎并不能在apk上应用。
  3. fpc2.5.1在fpc2.4上编译能顺利完成。但是在高版本的编译器似乎不顺利,如果要编译2.5.1版本,需要预装2.4.1的FPC,编译成功后,再删除。
  4. NDK使用r7或r7b版本在目前的Lazarus1.0.2中并没有问题,早期根据网上的资料,有BUG存在

编译环境的过程

  参考http://wiki.freepascal.org/Setup_Cross_Compile_For_ARM,并在下面有一个副本http://www.cnblogs.com/littlestone08/articles  /2752782.html,需要注意的问题有以下几点

  1. 关于Bintuils,Android的汇编器as是EABI5的形式,而默认的LINUX一般都是0,需要在调用as的时候加上 -meabi= 5 $@ 的参数来调用,尤其是使用预编译器2.5.1的时候,bintuils目录应该处于/usr/local/bin中,好像当时编译的时候路径就是这样的,所以使用的时候要还原当时的编译环境
  2. 如果要使用预编译的ppcrossarm,需要在/usr/bin建立一个ppcarm软件链接,因为fpc是使用ppcarm来进行调用的。
  3. 关于.fpc.cfg的配置:要包含原默认的fpc.cfg,并要正确设置参数,比如,我的预编译工作放在我的工作目录中,目录结构为

  

mei@mei-ubuntu:~/FPC4Android$ ls
arm-linux-as  arm-linux-as_org  ppcrossarm  units
mei@mei-ubuntu:~/FPC4Android$ pwd
/home/mei/FPC4Android

 则配置文件如下

  

#INCLUDE /etc/fpc.cfg
#DEFINE DEMOTEST
#DEFINE DEMOTEST1
#DEFINE LAZARUS

-Fu/home/mei/FPC4Android/units/$fpctarget/*
-Fl/home/mei/FPC4Android/units/$fpctarget/rtl/


-a
-Sd
-Xd
-Xs

-O-

#IFDEF CPUARM
-XParm-linux-
-Xr/home/mei/FPC4Android/units/arm-linux/rtl/
-darm
-Tlinux
#ENDIF

 

 

  上面设置则可以工作。如果用源码编译,参考下面的模板

#INCLUDE /etc/fpc.cfg
#DEFINE DEMOTEST
#DEFINE DEMOTEST1
#DEFINE LAZARUS

-Fu/usr/lib/fpc/2.5.1/units/$fpctarget/*
-Fl/usr/lib/fpc/2.5.1/units/$fpctarget/rtl/

-a
-Sd
-Xd
-Xs

-O-

#IFDEF CPUARM
-XP/home/user/lazarus/fpc/binutils/
-Xr/usr/lib/fpc/2.5.1/units/arm-linux/rtl/
-Xr/home/user/lazarus/fpc/libcross
-XR/home/user/lazarus/fpc/
-darm
-Tlinux
#ENDIF

 如果编译的时候无法在lazarus的 -Fl参数中设置Android NDK的lib,则可以使用-k 界面功能使用传递-l<库>的方式尝试,我有一次就出现这种上情况,暂不知道原因。

(现在找到原因了,罪魁祸首就是上面的-XR参数,去掉后,可以找到lib了。粗粗的找了一下资料,fpc或是fpc.cfg中并没有这个选项,即使在-XR后面加上你的lib的路径,也是无事无补。)

(网上找到下面的段话:You probably have to use the -XR command line parameter to tell the compiler to instruct the linker to only search for libraries in the Android SDK。笔误?是SDK,还是NDK?)

关于Codetyphon

同样用上面的方法,在Codetyphon2.8的Lazarus版本中,console的arm可正常编译,但是AndroidLCL例程无法正常进行,在编译lcl的时候会出现语法错误,察看代码后因为是编译器的版本的原因,新版本的Lazarus用的是新版本的编译器,代码中对版本进行了条件编译,致使在旧版本中编译不能通过,,如果把Codetyphon中的lazarusl的lcl用可以编译通过的lazarus版本进行把lcl目录替换,则可以正常为编译过去,并且正常生成so库,成功的在手机上运行。这个办法不是好办法,另一个办法是使用新版本的可以支持的Android的编译器,网上可以找到2.6版本的支持Android的ppcrossarm的预编译器,安装上以后,可以正常编译AndroidLCL例子。

但是如果不使用lcl库的话,则可以不用理会也可能正常的编译。

LINUX上暂时没有测试,应该差不多的,因为曾经在测试的时候也遇到过相同的问题,只是当时没有想到用标准版本的lcl替换。

关于Codetyphon安装脚本的发布速度,Linux版本都落后于Windows版本的发布,如果使用windows版本的话,as工具直接是与Android NDK的lib的EABI值相同的,可以直接使用其编译出的Binutils.

由于平时在Linux下面折腾CodeTyphon, 相比之下,WINDOWS版本的Codetypho编译之慢,资源占用之多,简直可以不可以接受,我差点以为编译lazarus big IDE时死掉了,但由于WIN平台上没有gcc,所以使用起来简单得多,缺点是比较慢。LINUX下面的版本就快多了,但需要更深入的了解一下LINUX相关的东西,要求更多的动手能力。

关于无法找到libxxxx.so的情况

这种情况归根结底是由于fpc不准备再支持Android平台上的编译造成的,由于Android的gcc及库与标准的gcc的不兼容(使用了优化过的libc也就罢了,结果连动态库加载都不使用ld而使用linker了,造成如果你只能使用静态库的方式来进行编写,否则接标准的办法是无法移值到Android的),虽然2.5.1版本的ppcossarm for Android解决了最基本的ld.so.x的链接问题,但是要是你使用了线程,就只有哭的份了。

根据以上情况我个人认为,如果想用这个已经不被官方支持的ppcrossarm for Android,最好不要写太复杂的东西,不要有依赖的功能函数,这就大大限制了发挥的空间。

一个小插曲,当我在长时间忍受了LAZARUS BIG IDE的编译后,悲剧的发现,IDE没有messages   windows,编译的提示,出错提示,什么也看不到。结果搜索网上资料说是因为docking插件引起的,它把messages box 停靠在Edit source 窗口上了,而且不可见。解决的办法就是移除docking控件包,并且删除lazarus的用户配置目录,当然再次编译是避免不了的。

 

 

附:

FPC4Android预编译下载地址 http://sourceforge.net/projects/p-tools

posted @ 2012-10-27 14:15  littlestone08  阅读(1796)  评论(0编辑  收藏  举报