交叉编译针对ARM架构的OCaml应用程序

9
我正在进行触摸屏驱动的交叉编译,其中包含一个OCaml校准应用程序。
我试图将驱动程序和应用程序编译为ARM架构,特别是针对运行Angström的Beagleboard。
操作步骤如下:
^_^[raziel@Bebop zytouch-driver-20081121]$ source /usr/local/angstrom/arm/environment-setup 
^_^[raziel@Bebop zytouch-driver-20081121]$ make CC=arm-angstrom-linux-gnueabi-gcc 
arm-angstrom-linux-gnueabi-gcc -std=gnu99 -g -O2 -Wall -Wextra -Werror -Wstrict-prototypes -Wmissing-prototypes   -c -o daemon/config.o daemon/config.c
arm-angstrom-linux-gnueabi-gcc -std=gnu99 -g -O2 -Wall -Wextra -Werror -Wstrict-prototypes -Wmissing-prototypes   -c -o daemon/util.o daemon/util.c
arm-angstrom-linux-gnueabi-gcc -std=gnu99 -g -O2 -Wall -Wextra -Werror -Wstrict-prototypes -Wmissing-prototypes   -c -o daemon/debug.o daemon/debug.c
arm-angstrom-linux-gnueabi-gcc -std=gnu99 -g -O2 -Wall -Wextra -Werror -Wstrict-prototypes -Wmissing-prototypes   -c -o daemon/zytouch_usb.o daemon/zytouch_usb.c
arm-angstrom-linux-gnueabi-gcc -std=gnu99 -g -O2 -Wall -Wextra -Werror -Wstrict-prototypes -Wmissing-prototypes   -c -o daemon/zytouchd.o daemon/zytouchd.c
arm-angstrom-linux-gnueabi-gcc daemon/config.o daemon/util.o daemon/debug.o daemon/zytouch_usb.o daemon/zytouchd.o -lX11 -lXtst -lusb -lm -o zytouch-daemon
ocamlopt -cc arm-angstrom-linux-gnueabi-gcc -cclib -lcairo -cclib -lextlib -cclib -llablgtk2 -warn-error A -c -I +lablgtk2 -I +cairo -I +extlib -I calibrate calibrate/version.ml -o calibrate/version.cmx
ocamlopt -cc arm-angstrom-linux-gnueabi-gcc -cclib -lcairo -cclib -lextlib -cclib -llablgtk2 -warn-error A -c -I +lablgtk2 -I +cairo -I +extlib -I calibrate calibrate/util.ml -o calibrate/util.cmx
ocamlopt -cc arm-angstrom-linux-gnueabi-gcc -cclib -lcairo -cclib -lextlib -cclib -llablgtk2 -warn-error A -c -I +lablgtk2 -I +cairo -I +extlib -I calibrate calibrate/config.ml -o calibrate/config.cmx
ocamlopt -cc arm-angstrom-linux-gnueabi-gcc -cclib -lcairo -cclib -lextlib -cclib -llablgtk2 -warn-error A -c -I +lablgtk2 -I +cairo -I +extlib -I calibrate calibrate/orientation.ml -o calibrate/orientation.cmx
ocamlopt -cc arm-angstrom-linux-gnueabi-gcc -cclib -lcairo -cclib -lextlib -cclib -llablgtk2 -warn-error A -c -I +lablgtk2 -I +cairo -I +extlib -I calibrate calibrate/tscalibrate.ml -o calibrate/tscalibrate.cmx
ocamlopt -cc arm-angstrom-linux-gnueabi-gcc -cclib -lcairo -cclib -lextlib -cclib -llablgtk2 -warn-error A -cc arm-angstrom-linux-gnueabi-gcc -cclib -lcairo -cclib -lextlib -cclib -llablgtk2 -warn-error A -I +lablgtk2 -I +cairo -I +extlib -I calibrate extLib.cmxa str.cmxa unix.cmxa lablgtk.cmxa cairo_lablgtk.cmxa cairo.cmxa gtkInit.cmx calibrate/version.cmx calibrate/util.cmx calibrate/config.cmx calibrate/orientation.cmx calibrate/tscalibrate.cmx -o zytouch-calibrate
/usr/local/angstrom/arm/lib/gcc/arm-angstrom-linux-gnueabi/4.3.3/../../../../arm-angstrom-linux-gnueabi/bin/ld: /tmp/camlstartup71ef32.o: Relocations in generic ELF (EM: 3)
/usr/local/angstrom/arm/lib/gcc/arm-angstrom-linux-gnueabi/4.3.3/../../../../arm-angstrom-linux-gnueabi/bin/ld: /tmp/camlstartup71ef32.o: Relocations in generic ELF (EM: 3)
/tmp/camlstartup71ef32.o: could not read symbols: File in wrong format
collect2: ld returned 1 exit status
File "caml_startup", line 1, characters 0-1:
Error: Error during linking
make: *** [zytouch-calibrate] Error 2

我是一名有用的助手,可以翻译文本。

我被困在那个Relocations in generic ELF (EM: 3)错误中。

Makefile看起来像这样:

(...)
OFLAGS = -cc ${CC} -cclib -lcairo -cclib -lextlib -cclib -llablgtk2 -warn-error A
OCAMLOPT = ocamlopt $(OFLAGS)

OCAML_INC =  -I +lablgtk2 -I +cairo -I +extlib -I calibrate
OCAML_LIBS = $(OCAML_INC) extLib.cmxa str.cmxa unix.cmxa lablgtk.cmxa cairo_lablgtk.cmxa cairo.cmxa gtkInit.cmx

(...)    
config.cmx: util.cmx
orientation.cmx: config.cmx
tscalibrate.cmx: version.cmx util.cmx orientation.cmx config.cmx

%.cmx : %.ml
        $(OCAMLOPT) -c $(OCAML_INC) $< -o $@

%.mli : %.ml
        $(OCAMLC) -i $(OCAML_INC) $+

由于/usr/local/angstrom/arm/environment-setup/usr/local/angstrom/arm/bin作为我的PATH的第一个元素,因此我尝试用ARM版本替换一些程序。
sudo ln -s /usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-ar /usr/local/angstrom/arm/bin/ar
sudo ln -s /usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-as /usr/local/angstrom/arm/bin/as
sudo ln -s /usr/local/angstrom/arm/bin/arm-angstrom-linux-gnueabi-ld /usr/local/angstrom/arm/bin/ld

然而,替换as后,模块甚至无法编译。
ocamlopt -cc arm-angstrom-linux-gnueabi-gcc -cclib -lcairo -cclib -lextlib -cclib -llablgtk2 -warn-error A -c -I +lablgtk2 -I +cairo -I +extlib -I calibrate calibrate/version.ml -o calibrate/version.cmx
/tmp/camlasm41bb77.s: Assembler messages:
/tmp/camlasm41bb77.s:31: Error: alignment too large: 15 assumed
/tmp/camlasm41bb77.s:35: Error: bad instruction `movl $camlVersion__3,%eax'
/tmp/camlasm41bb77.s:36: Error: bad instruction `movl %eax,camlVersion'
/tmp/camlasm41bb77.s:37: Error: bad instruction `movl $camlVersion__2,%eax'
/tmp/camlasm41bb77.s:38: Error: bad instruction `movl %eax,camlVersion+4'
/tmp/camlasm41bb77.s:39: Error: bad instruction `movl $camlVersion__1,%eax'
/tmp/camlasm41bb77.s:40: Error: bad instruction `movl %eax,camlVersion+8'
/tmp/camlasm41bb77.s:41: Error: bad instruction `movl $1,%eax'
/tmp/camlasm41bb77.s:42: Error: bad instruction `ret'
/tmp/camlasm41bb77.s:43: Error: unrecognized symbol type ""
File "calibrate/version.ml", line 1, characters 0-1:
Error: Assembler error, input left in file /tmp/camlasm41bb77.s
make: *** [calibrate/version.cmx] Error 2

我相信这一定是一个非常愚蠢的错误,但我找不到如何正确执行此操作的文档。有人知道可能出了什么问题吗?
我正在尝试构建的驱动程序的源代码可以在这里找到。
2个回答

7

目前,OCaml不支持交叉编译,使用-cc选项也不能让它神奇地交叉编译到ARM。有一些补丁可以实现交叉编译,但都不是官方的。我记得使用过打了补丁的ocamlopt,对于简单的程序来说还可以。但在这种情况下,您还需要交叉编译所有依赖库,这可能会是一个相当大的任务。

我认为您最好的解决方案是:

  • 在ARM QEMU中本地构建(这很容易,有预构建的Debian映像可用

  • 构建校准应用程序的字节码二进制文件(字节码在不同架构之间是可移植的,但需要在目标上安装相同版本的OCaml),并在ARM上安装所需的存根库(包含与gtk、cairo等绑定的C代码的库,可以本地构建或从软件包中获取)


我正在尝试第一种选择,因为Angstrom发行版没有ocaml包。然而,在我使用的Debian Squeeze ARM机器上,我似乎找不到ocamlopt(它们可以在此处轻松找到:http://people.debian.org/~aurel32/qemu/armel/)。根据此处(http://old.nabble.com/Bug-377499%3A-ocaml-nox%3A--usr-bin-ocamlopt-missing-in-ocaml-nox_3.09.2-5_s390.deb-td5243672.html)的内容,ocamlopt在ARM上不可用,这让我的一天变得更加悲伤了。您是否知道解决此问题的方法? - RazZziel
2
在Squeeze(3.11.2)中,OCaml确实没有针对ARM的ocamlopt,但是3.12.1有,因此只需启用测试存储库或从源代码构建即可(非常容易)。还要注意,下一个OCaml版本将具有全新的ARM代码生成器 - 如果您感到勇敢,它已经在svn主干中可用。 - ygrek

2

看起来你没有用交叉编译工具链替换所有的工具链。 movl %eax,camlVersion 是典型的x86指令,不是在ARM代码中看到的。当我忘记在为不同架构构建代码之间进行清理时,通常会出现这些错误。


我删除了源目录,重新解压缩,并仔细检查了是否有任何杂散的二进制文件,但是仍然没有改变。 - RazZziel
是的,但问题可能不在源代码上。从您的日志中可以看出,ocamlopt命令生成的是x86代码而不是arm代码。ygrek的答案似乎也表明ocaml不支持交叉编译。 - Leo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接