如何构建OCaml交叉编译器

50
在找到一种方法为目标机器生成适当的配置文件后,交叉编译器本身仍然必须构建。使用1 1/2构建方法(在此处描述)(并且更详细地在此处),如果主机和目标系统差异太大,则似乎无法正常工作。以下是构建脚本的更改部分(可以使用$ svn cat svn://svn.psellos.com/trunk/ocamlxarm/3.1/xarm-build获得)。
# Small steps
config1 () {
    # Configure for building bytecode interpreter to run on Intel OS X.
    # But specify * architecture for assembly and partial link.
    echo 'xarm-build: ----- configure phase 1 -----'
    ./configure \
            -prefix "" \
            -no-curses \
            -no-tk \
            -no-graph \
            -as "" \
            -aspp ""\
            -partialld ""
    # Post-modify config/Makefile to select the * back end for
    # ocamlopt (to generate * assembly code).
    $SED -i'.bak'\
        -e '1i\# modified by xarm-build for OCamlXARM' \
        -e 's/^ARCH[    ]*=.*/ARCH=/' \
        -e 's/^MODEL[    ]*=.*/MODEL=/' \
        config/Makefile
        #-e 's/^SYSTEM[      ]*=.*/SYSTEM=/' \
    $SED -i'.bak'\
        -e '1i\/* modified by xarm-build for OCamlXARM*/' \
        -e 's/^#define[     ][  ]*HAS_STACK_OVERFLOW_DETECTION.*$//' \
        config/s.h

    # Post-modify utils/config.ml to tell ocamlopt to create *
    # binaries for itself.  Also tell ocamlc and ocamlopt to use *
    # architecture when compiling C files.
    make utils/config.ml 
    $SED -i'.bak'\
        -e 's#let[  ][  ]*mkexe[    ]*=.*#let mkexe ="'"$CC"'"#' \
        -e 's#let[  ][  ]*bytecomp_c_compiler[  ]*=.*#let bytecomp_c_compiler ="'"$CC"'"#' \
        -e 's#let[  ][  ]*native_c_compiler[    ]*=.*#let native_c_compiler ="'"$CC"'"#' \
        utils/config.ml
}

build1 () {
    # Don't assemble asmrun/*.S for Phase 1 build.  Modify Makefile
    # temporarily to disable.  Be really sure to put back for Phase 2.
    echo 'xarm-build: ----- build phase 1 -----'
    trap 'mv -f asmrun/Makefile.aside asmrun/Makefile' EXIT
    mv -f asmrun/Makefile asmrun/Makefile.aside
    $SED -e '/^[    ]*ASMOBJS[  ]*=/s/^/#/' \
        -e 's#^include[     ][  ]*../config/Makefile#include ../config/Target/Makefile#' \
        asmrun/Makefile.aside > asmrun/Makefile
    make world && make opt
    mv -f asmrun/Makefile.aside asmrun/Makefile
    trap - EXIT
}

编译卡在 stdlib 子文件夹中,调用约定的断言失败。
let loc_external_arguments =
  match Config.system with
  | "rhapsody" -> poweropen_external_conventions 0 7 100 112
  | "elf" | "bsd" -> calling_conventions 0 7 100 107 outgoing 8
  | _ -> assert false 

为了达到这个目的,必须修改amsrun/Makefile以使用交叉编译工具链,并从config/s.h中删除HAS_STACK_OVERFLOW_DETECTION,因为否则无法编译amsrun/signals_asm.c
那么有没有办法让它工作,或者这种方法更适合(并且可以与OCaml 4.00.0版本一起使用)?

7
我认为在OCaml的列表或论坛http://caml.inria.fr/resources/forums.en.html上提问会更好。 - Basile Starynkevitch
我不知道你的目标是什么样子的,但我怀疑xarm-build脚本实际上非常接近。它适用于从OS X on Intel交叉编译到ARM上的iOS(类似的系统,但CPU非常不同)。 (免责声明:我写了xarm-build。)但是Basile是正确的,你可能会在OCaml邮件列表中得到更好的答案。有许多必须完全正确的小细节。 - Jeffrey Scofield
@JeffreyScofield 它是 (Linux, i386) -> (Linux, PPC)。这些平台应该不会有太大的差异,但目标文件/可执行文件格式似乎略有不同。无论如何,我会向 OCAML 的开发人员询问。谢谢。 - Percival Ulysses
似乎你的情况与 OSX -> iOS 非常相似。就 FWIW 而言,xarm-build 应该非常接近。你不需要修改 Makefile,xarm-build 会处理这些细节(在阶段之间切换工具链)。希望你能让它以某种方式工作。 - Jeffrey Scofield
1个回答

5
这个问题已经以一种相当奇怪的方式得到了回答。实际上,它在2012年时真正想要的是一个针对iOS(未指定版本)的交叉编译器,用于Ocaml 4.x版本。该问题中的代码转储试图使用Jeffrey Scofield的交叉编译指令和脚本(ocamlxarm/3.1)来进行Ocaml 3.1.x,但并不适用于Ocaml 4.0。但是,该问题链接到的Scofield网页已在此期间进行了更新(最后一次更新于2014年12月),以提供Ocaml 4.0的解决方案(目前为ocaml-4.01.0+xarm-4.0.2-v7),因此使得这里所问的问题(“是否有办法让它工作”)变得无关紧要或相当琐碎。
  • 下载网页上提供的预编译的ocaml-4.01.0+xarm-4.0.2-v7.dmg软件包。确保也阅读使用说明,并使用他的交叉编译包装脚本使生活更轻松,该脚本可让您在iOS 7和8目标之间切换。或者,如果您仍然需要从源代码构建Ocaml交叉编译器...
  • 按照页面上“附录:从源代码构建”的说明操作(很抱歉,似乎没有HTML锚点)。这些说明不幸地有大约12段落(9KB的文本),因此我不会在此处复制它们。它们包括一个链接到交叉编译OCaml 4.0.1到iOS所需的补丁。希望在该网页上写的正是用于构建前述ocaml-4.01.0+xarm-4.0.2-v7.dmg的步骤。但是,由于那个dmg软件包没有像RedHat风格的SRPM那样的苹果等效技术(苹果公司甚至有这样的技术吗?),无法完全确定生成前述dmg所使用的步骤是否在该网页上完全重现。我自己没有尝试过按照这些步骤进行操作以查看它们是否有效。
但我认为,从基本上讲,“有没有办法使这个工作”这个问题,在 Scofield 的网页上下载预构建的 4.0.1 二进制文件就可以解决了……链接就在问题中。Scofield 的 ocamlxarm 构建系统版本 3.1 无法交叉编译 Ocaml 4.0 的问题,应该是此时无人关心的问题。如果 Scofield 的说明或补丁存在问题,不起作用,那么应该单独提出这些问题,因为这里的琐碎错误似乎与该场景无关。
尽管OP可能并不关心我在这一段中要说什么,考虑到他的问题标题有多么普通,我想指出还存在一个相当新的项目,维护一个针对Android的OCaml交叉编译器,称为opam-android。这个项目的所有构建部分都是git存储库中的脚本,因此从中窃取如何完成可能会更容易。比较这两个交叉编译器的补丁,除了:您需要针对特定目标平台进行修改之外,通常无法说出如何使OCaml作为交叉编译器工作的方法。有一件事我会说的是,Scofield的iOS补丁比Android补丁更具侵入性(也更长)。 Scofield的大量补丁与寄存器级代码生成有关。我不了解iOS内部足以说明为什么iOS需要这些更改而Android不需要,即使它们基本上使用相同的ARM CPU系列。也许应该将这个问题作为实际上有趣/非平凡的问题提出,Jeffrey Scofield自己可能会很乐意回答。

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