构建OCaml的交叉编译器 - 配置部分(Building an OCaml cross-compi

2019-09-23 13:22发布

我需要建立一个OCaml的交叉编译器。 可悲的是,看来这是不支持开箱即用,需要一点点的工作, 描述了旧版本的的OCaml的编译器 。
我的第一个问题是:什么是生成的文件配置/ MH, 配置/ sh配置/ Makefile文件的好方法?

Answer 1:

我一直在建设OCaml的交叉编译器了几年。 (见我的个人资料的链接,我的网站。)我做的是建立编译器1.5倍。 第一次是主机(与目标的一些设置)。 下半场构建是建立目标运行。

我从OS X构建一个交叉编译器对ARM脚本/ iOS版被命名为xarm-build 。 如果你有颠覆,你可以从我的公共仓库中取得副本:

$ svn cat svn://svn.psellos.com/trunk/ocamlxarm/3.1/xarm-build

免责声明:现在,这个脚本只是构建编译器的字节码版本。 即,编译器本身是一个ocaml的字节代码可执行文件。 但是它产生的本地代码为目标。

如果你试试这个,有任何问题,让我知道。

为了回答您的具体问题,如果你的目标系统是类Unix,你可以尝试运行configure上的目标脚本生成config/shconfig/mhconfig/Makefile ,正如你提到的都是重要的文件。 如果有你的目标模拟器,可以运行configure模拟器内-这是我为iOS做。 否则,你必须自己找出合理的内容。 (也许运行配置类Unix系统,就是尽可能相似,你的目标上。)



Answer 2:

与修改配置“链”,它可能产生的文件。 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 ,它只是执行编译的东西。 中间结果被存储在配置/自动AUX / map_ {hasgot,的runTest},大都采用setValuegetValueExit检索,无论是在配置/自动AUX / keyval.sh定义。 如果一个提供与交叉工具链数据

-cc-as-aspp-partialld-libs-dllibs-dldefs

生成文件应该是可用的。 最后,文件keyval.sh ,其内容是不是在DIFF:

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时,一个必须修改配置/自动AUX / runTest方法和替换0.0与它的版本号。 此外,它可能是必要的,如果在solaris被用作靶或主机修改文件配置/自动AUX / Solaris的LD。



文章来源: Building an OCaml cross-compiler - configure part