构建OCaml交叉编译器 - 配置部分

3
我需要构建一个OCaml交叉编译器。遗憾的是,它似乎不支持开箱即用,需要一些工作,正如旧版OCaml编译器描述所示。 我的第一个问题是:生成config/m.hconfig/s.hconfig/Makefile文件的好方法是什么?
2个回答

7
我已经建立了几年的OCaml交叉编译器. (有关我的网站的链接, 请参阅我的资料页面.) 我所做的是构建编译器1 1/2次。 第一次是为主机(带有某些针对目标的设置)。第二个部分是为了构建目标的运行时。
我构建从OS X到ARM / iOS的交叉编译器脚本名为“ xarm-build”。如果您拥有Subversion,可以从我的公共存储库中获取副本:
$ svn cat svn://svn.psellos.com/trunk/ocamlxarm/3.1/xarm-build

免责声明:目前,此脚本仅构建编译器的字节码版本。也就是说,编译器本身是一个OCaml字节码可执行文件。但是它会为目标生成本地代码。
如果您尝试此操作并有任何问题,请告诉我。
回答您具体的问题,如果您的目标系统类似于Unix,您可以尝试在目标上运行“configure”脚本以生成“config / s.h”,“config / m.h”和“config / Makefile”,这些是关键文件,正如您所提到的。如果有您的目标的模拟器,您可以在模拟器中运行“configure” - 这就是我在iOS上所做的。否则,您必须自己找出合理的内容。(可能在与您的目标尽可能相似的类Unix系统上运行configure。)

谢谢你的回答。我使用ipkg提供的gcc在DiskStation上生成了文件,我认为这是最接近目标系统的方式。我也阅读了你的脚本,有一点让我有些困惑。首先是一个微不足道的观察:你可以通过在两个configure调用中输入-prefix $XARMTARGET/v7来节省4行代码。此外,我有些不知所措。build1中的ocamlopt是什么?它将OCaml编译成ARM,但没有正确的工具链环境吗?而这个问题在build2中得到解决了吗?你是否隐含地认为ARM环境与i386环境差别不大? - Percival Ulysses
你需要构建一个编译器,为你的目标生成代码。作为OCaml程序,这个编译器需要在主机上运行的运行时(特别是字节码解释器)。但是,你还需要一个针对编译器编译的程序的运行时,这个运行时在目标上工作。由于你需要两个运行时,所以你必须进行两次构建。(在旧版本的OCaml中,-prefix对我没有用。如果现在有效,那太好了。) - Jeffrey Scofield
我修改了configure脚本,使得文件可以通过两次运行生成(并已发布,请您看一下,好吗?)。我有几个问题:我注意到在您的脚本的第二阶段中,您没有在Makefile中后置修改“RANLIB*”,“ARCMD”和“MKLIB”行,因此这些仅在主机上使用(第一阶段)?对于utils/config.ml的修改,只需要提供正确的交叉编译器即可?在第二阶段中,如果提供了正确的环境,则不需要修改任何内容吗?(也许这次我应该问一个新的SO问题) - Percival Ulysses
我的原始脚本运行了两次,这正是关键所在。所以我不确定你的修改具体做了什么。如果它们对你有效,那太好了!(使用原始脚本,您可以说“xarm-build phase1”来运行第一阶段,“xarm-build phase2”来运行第二阶段。) - Jeffrey Scofield

1

通过修改“chain”配置,可以生成文件。 Ocamls配置脚本假设可以在同一运行中编译和执行结果,但在交叉编译环境中可能是不可能的。
因此,必须修改配置过程,以便编译结果(包括可执行文件)被存储并可在目标机器上的第二次运行中使用。这是显示修改的差异文件(约200行)。

diff -r -U 1 ocaml-4.00.0-orig/config/auto-aux/hasgot ocaml-4.00.0-cross/config/auto-aux/hasgot
--- ocaml-4.00.0-orig/config/auto-aux/hasgot
+++ ocaml-4.00.0-cross/config/auto-aux/hasgot
@@ -15,2 +15,4 @@

+. ./keyval.sh
+
 opts=""
@@ -36,7 +38,13 @@

+key="$cc $args"
+getValueExit "$key"
+
 if test "$verbose" = yes; then
   echo "hasgot $args: $cc $opts -o tst hasgot.c $libs" >&2
-  exec $cc $opts -o tst hasgot.c $libs > /dev/null
+  `exec $cc $opts -o tst hasgot.c $libs > /dev/null`
 else
-  exec $cc $opts -o tst hasgot.c $libs > /dev/null 2>/dev/null
+  `exec $cc $opts -o tst hasgot.c $libs > /dev/null 2>/dev/null`
 fi
+res=$?
+setValue "$key" "$res"
+exit "$res"
diff -r -U 1 ocaml-4.00.0-orig/config/auto-aux/hasgot2 ocaml-4.00.0-cross/config/auto-aux/hasgot2
--- ocaml-4.00.0-orig/config/auto-aux/hasgot2
+++ ocaml-4.00.0-cross/config/auto-aux/hasgot2
@@ -15,2 +15,4 @@

+. ./keyval.sh
+
 opts=""
@@ -36,7 +38,13 @@

+key="$cc $args"
+getValueExit "$key"
+
 if test "$verbose" = yes; then
   echo "hasgot2 $args: $cc $opts -o tst hasgot.c $libs" >&2
-  exec $cc $opts -o tst hasgot.c $libs > /dev/null
+  `exec $cc $opts -o tst hasgot.c $libs > /dev/null`
 else
-  exec $cc $opts -o tst hasgot.c $libs > /dev/null 2>/dev/null
+  `exec $cc $opts -o tst hasgot.c $libs > /dev/null 2>/dev/null`
 fi
+res=$?
+setValue "$key" "$res"
+exit "$res"
Only in ocaml-4.00.0-cross/config/auto-aux: keyval.sh
diff -r -U 1 ocaml-4.00.0-orig/config/auto-aux/runtest ocaml-4.00.0-cross/config/auto-aux/runtest
--- ocaml-4.00.0-orig/config/auto-aux/runtest
+++ ocaml-4.00.0-cross/config/auto-aux/runtest
@@ -17,6 +17,30 @@
 echo "runtest: $cc -o tst $* $cclibs" >&2
-$cc -o tst $* $cclibs || exit 100
+stream=/dev/stderr
 else
-$cc -o tst $* $cclibs 2> /dev/null || exit 100
+stream=/dev/null
+#$cc -o tst $* $cclibs 2> /dev/null || exit 100
 fi
+
+key="$* $cclibs"
+
+if test "$crossmode" = cross-cc; then
+   i=`cat ./counter`
+   $cc -o tst"$i" $* $cclibs 2> "$stream" || exit 100
+   echo "$key"'%%#%%'tst"$i" >> ./map_runtest
+   i=`expr $i + 1`
+   echo "$i" > ./counter
+   if test "$*" = sizes.c; then
+       echo "4 4 4 2"
+   fi
+   if test `expr "$*" : '.*tclversion.c'` -ne 0; then
+       echo "8.5"
+   fi
+   exit 0
+fi
+if test "$crossmode" = cross-run; then
+   tst=`awk -v ccargs="$key" 'BEGIN {FS="%%#%%"} $1 == ccargs {print $2}' ./map_runtest`
+   exec ./"$tst"
+fi
+
+$cc -o tst $* $cclibs 2> "$stream" || exit 100
 exec ./tst
diff -r -U 1 ocaml-4.00.0-orig/config/auto-aux/tryassemble ocaml-4.00.0-cross/config/auto-aux/tryassemble
--- ocaml-4.00.0-orig/config/auto-aux/tryassemble
+++ ocaml-4.00.0-cross/config/auto-aux/tryassemble
@@ -1,8 +1,16 @@
 #!/bin/sh
+
+. ./keyval.sh
+
+key="$aspp $*"
+getValueExit "$key"
+
 if test "$verbose" = yes; then
 echo "tryassemble: $aspp -o tst $*" >&2
-$aspp -o tst $* || exit 100
+`$aspp -o tst $* || exit 100`
 else
-$aspp -o tst $* 2> /dev/null || exit 100
+`$aspp -o tst $* 2> /dev/null || exit 100`
 fi
+res=$?
+setValue "$key" "$res"

@@ -11,7 +19,14 @@
 if test "$verbose" = yes; then
+key="$as $*"
+getValueExit "$key"
 echo "tryassemble: $as -o tst $*" >&2
-$as -o tst $* || exit 100
+`$as -o tst $* || exit 100`
 else
-$as -o tst $* 2> /dev/null || exit 100
+`$as -o tst $* 2> /dev/null || exit 100`
 fi
+res=$?
+setValue "$key" "$res"
+exit $res
+else
+exit $res
 fi
diff -r -U 1 ocaml-4.00.0-orig/config/auto-aux/trycompile ocaml-4.00.0-cross/config/auto-aux/trycompile
--- ocaml-4.00.0-orig/config/auto-aux/trycompile
+++ ocaml-4.00.0-cross/config/auto-aux/trycompile
@@ -15,7 +15,15 @@

+. ./keyval.sh
+
+key="$cc $* $cclibs"
+getValueExit "$key"
+
 if test "$verbose" = yes; then
 echo "trycompile: $cc -o tst $* $cclibs" >&2
-$cc -o tst $* $cclibs || exit 100
+`$cc -o tst $* $cclibs || exit 100`
 else
-$cc -o tst $* $cclibs 2> /dev/null || exit 100
+`$cc -o tst $* $cclibs 2> /dev/null || exit 100`
 fi
+res=$?
+setValue "$key" "$res"
+exit $res
diff -r -U 1 ocaml-4.00.0-orig/configure ocaml-4.00.0-cross/configure
--- ocaml-4.00.0-orig/configure
+++ ocaml-4.00.0-cross/configure
@@ -47,2 +47,3 @@
 withcamlp4=camlp4
+crossmode=''

@@ -119,2 +120,4 @@
         withcamlp4="";;
+    -cross|--cross)
+       crossmode="$2"; shift;;
     *) echo "Unknown option \"$1\"." 1>&2; exit 2;;
@@ -158,2 +161,21 @@

+case "$crossmode" in
+   cc)
+       crossmode=cross-cc
+       echo 0 > ./counter
+       rm -f ./map_runtest ./map_hasgot
+       touch ./map_runtest ./map_hasgot;;
+   run)
+       crossmode=cross-run
+       if test ! -e ./map_runtest -o ! -e ./map_hasgot; then
+           echo 'Run with -cross cc first'
+           exit 2
+       fi
+       rm -f ./counter;;
+   none) crossmode=none;;
+   "") crossmode=none ;;
+   *)
+       echo 'Unknown crossmode'>&2
+       exit 2;;
+esac
 # Write options to Makefile
@@ -350,3 +372,3 @@
 cc="$bytecc -O $bytecclinkopts"
-export cc cclibs verbose
+export cc cclibs verbose crossmode

@@ -1647,2 +1669,5 @@

+if test "$crossmode" = cross-run; then
+   rm -f tst* ./map_runtest ./map_hasgot
+fi
 # Print a summary 

配置脚本增加了一个新的-cross选项。当cc是它的参数时,它只编译;当它是run时,它只执行已编译的内容。中间结果存储在config/auto-aux/map_{hasgot,runtest}中,大多数使用setValue和getValueExit进行检索,两者都在config/auto-aux/keyval.sh中定义。如果提供交叉工具链数据,则应使用-cc、-as、-aspp、-partialld、-libs、-dllibs、-dldefs来使用Makefile。最后,文件keyval.sh的内容不在差异中。
getValueExit()
{
if test "$crossmode" = cross-run; then
    res=`awk -v ccargs="$1" 'BEGIN {FS="%%#%%"} $1 == ccargs {print $2; exit}' ./map_hasgot`
    exit "$res"
fi
}

setValue()
{
if test "$crossmode" = cross-cc; then
    echo "$1"'%%#%%'"$2" >> ./map_hasgot
fi
}

如果使用tk,则必须修改config/auto-aux/runtest并将0.0替换为其版本号。此外,如果solaris用作目标或主机机器,则可能需要修改文件config/auto-aux/solaris-ld

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