如何交叉编译应用程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
如何交叉编译应用程序,技巧,注意事项。
最近大家都涉及交叉编译应用程序,感觉大家的路子有点偏,觉得有必要纠正一下。一般的应用程序编译的步骤无外呼./configur e&&mak e&&m ake install
但是对于交叉编译不能照搬,尤其要注意不能轻易mak e install(当然如果指定了--prefix就无所谓了,否则可能会覆盖标准路径的程序就惨了)
这里有两个思路:
1>对于刚开始交叉编译的人来说,往往很晕,总想借助./configure后面加一堆参数来解决,比如./ configure--tar get=ar m-9tdm i-linux-gnu--host=arm-9tdmi-linux-gnu来搞定,对于一般的小的程序来说,应该没有问题,而且也推荐大家这样用,但是要注意,这样作之前,先要./ configure--help|grep--host,看看有没有这样的选项,如果没有呢?想想也可能,如果程序的作者根本没有考虑到除了x86的平台呢?你只能自己改写Mak efile了。
所以,./configur e不是万能的,而且语法很混乱,不要指望./configure给你作一切。而且局限很大。
2>所以这个时候,就要求交叉编译的第二个层次,自己改写Mak efile,想怎么改就怎么改,灵活性最大需要你开始就./configure一下,跟平台有关的参数一律不加。./configur e过后就会生成Makefile了,里面的gcc相关的参数,包括lib的路径当然是x86下的了,比如/usr/local/lib/,/usr/lib/,/lib/什么的,改掉就是了。或者注释掉。gcc要换成ar m-linux-gcc一类的编译器,(如果不想每次都改,参考下面的include prer ules.m k的做法),
总之,这要求你的Makefile掌握的很熟练,思路就是边编译,发现问题,再改,即使一开始Mak efile 不熟练,到后来,也熟练了。是个练习Mak efile的好方式。
总之,我们最后要的就是Makefile,看你怎么能得到它。
一个最标准的Mak efile(去掉很多无用的东西)
通过./configure生成的Makefile,你会发现冗余的地方非常多,其实关键的地方,就那么20几条,可以试着精简一下,这样对程序的组织架构会熟悉的快一些,毕竟Makefile反应了程序(具体就是.c和. h)之间的依赖关系。
openssh的Mak efile我没有精简过(当然要精简也很容易),举个telnetd的例子,说明一下:
---------------------------telnetd
----------------------------------------
#-----------------------------------------------------
TOPDIR:=$(shell/bin/pwd)
TOPDIR:=$(TOPDIR)/..
#prerules.mk包含了这些变量的定义,比如$CC,$CPP,$CXX,$CFLAGS等等。
#尽量不要在这里出现,CC=arm-linux-gcc这样的定义,扩展性不好,尽量用全局变量,便于管理和拓展。include$(TOPDIR)/pr erules.mk
#-----------------------------------------------------
EXEC=telnetd
#好的Makefile都是这样写的,也就是具体生成一个可执行文件或者lib库,需要哪些.o,这些.o会依据后面的.c.o:规则来编译出来的。
OBJS=telnetd.o state.o term stat.o slc.o sys_term.o\
utility.o global.o authenc.o logwtm p.o logout.o
#$(CC)的编译选项,一般程序自己的带的,不要改它,而且一般都是+=,不要用=,
CFLAGS+=-DEMBED-DPARANOID_TT YS-DUSE_TERMIO-DKLUDGELINEMODE-D_GNU_SOURCE-Wall
ifdef CONFIG_DEFAULT S_LIBC_UCLIBC
LDLIBS:=-lutil$(LDLIBS)
endif
all:$(EXEC)#很显然all是最关键的了,也要发在最开始的地方。这样m ak e就相当于m ak e all,这是大家的潜规则。
.c.o:
$(CC)-c-o$@$<$(CFLAGS)-I../include/-I.-Ixxx在交叉编译的时候,要在这个后面添上自己的头文件的路径。
$(EXEC):$(OBJS)
$(CC)$(LDFLAGS)-o$@$(OBJS)$(LDLIBS$(LDLIBS_$@))#这里的LDFLAGS=-lcrypt-
lzlib-L../lib-L.总之根据自己的需要往里面增加。
$(STRIP)telnetd#如果不需要调试,一定要strip一下,比如15M的file,strip过后,可能变成3M,还不影响功能。
install:
cp$(EXEC)$(T_USBIN)#自己写install,不要用原来的,可以copy到自己的r am disk中去。
clean:
-r m-f$(EXEC)*.elf*.gdb*.[do]
$(OBJS):defs.h ext.h pathnames.h telnetd.h logwtm p.h logout.h
交叉编译成功后,就万事大吉了,这才万里长征的第一步。剩下的也许更麻烦呢。首先拿到一个opensour ce,我们首先要让它在pc上run起来才行至少我们要稍微了解了一下它,才可以开始我们的cr oss compile的工作。至少,我们要了解要r un这个程式,哪些东西是需要的,哪些是不需要的。一开始,谁也不会了解的那么多,只能一步步的拿到板子上跑跑看了。
准备工作:
1>如果是应用程序的可执行文件,我们可以用ldd命令来查看它需要哪些必要的库。具体的命令:
refer,http://infom ax/bbs/viewthr ead.php?tid=52&extra=page%3D1
2>看看需要哪些配置文件,也就是conf文件。
其实如果想知道上面的这些,还有个办法,就是先在pc上编译,安装,./configure--prefix=/work/bob(改成你自己的目录即可),m ake&&m ak e install,
看看/work/bob/下面到底生成了哪些file,你不就心里有数了吗。
先把你知道的应用程序可执行文件copy到板子上去,执行一下,如果缺少哪些库,屏幕上会打出来一些出错信息的。缺什么,就copy什么到板子上好了,多半缺的都是库(.so文件).
如果还是莫名其妙的出什么问题(ps结果就是没有该进程),有可能是缺少什么配置文件,可以用str ace 来查查看:
具体str ace的用法可以refer:http://infom ax/bbs/viewthread.php?tid=56&extr a=page%3D1
如果程序运行的结果和pc上不太一样。就要注意几个根本的问题了。
1>板子的endian是什么类型的呢?x86是little endian,arm的板子可能是little endian,也可能是big-endian的,如果是big-endian,就要注意了。要在程序里面改,添加什么le32_to_cpu()这样的函数来转换的。
2>对齐问题,x86和arm的对齐处理方式是不一样的。
3>中文的问题,有些程序需要支持中文,繁体,什么的,pc上可以,拿到板子上就不可以了。你要考虑一下glibc库上面是否支持locale,libiconv一类的库。
生成动态链接库的一个例子,也是标准的Makefile
#Star t of Makefile
#-----------------------------------------------------
TOPDIR:=$(shell/bin/pwd)
TOPDIR:=$(TOPDIR)/../../
include$(TOPDIR)/pr erules.mk
#-----------------------------------------------------
SRCS=download.c cur l_err.c DownloadStatusQuer y.c
OBJS=download.o curl_err.o DownloadStatusQuery.o
CFLAGS+=-I../../include-Wall#-g-ggdb
all:libdownload.so.1.0.0
#test_main: