【问题标题】:Building an OCaml cross-compiler - configure part构建 OCaml 交叉编译器 - 配置部分
【发布时间】:2012-10-15 00:55:42
【问题描述】:

我需要构建一个 OCaml 交叉编译器。可悲的是,这似乎不支持开箱即用,需要一些工作,as described 用于旧版本的OCaml compiler
我的第一个问题是:生成文件 config/m.hconfig/s.hconfig/Makefile 的好方法是什么?

【问题讨论】:

    标签: makefile ocaml configure cross-compiling


    【解决方案1】:

    几年来,我一直在构建 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.hconfig/m.hconfig/Makefile,正如您提到的那样关键文件。如果你的目标有一个模拟器,你可以在模拟器中运行configure——这就是我为iOS所做的。否则你必须自己找出合理的内容。 (也许在与您的目标尽可能相似的类 Unix 系统上运行 configure。)

    【讨论】:

    • 感谢您的回答。我使用 ipkg 提供的 gcc 在 DiskStation 上生成文件,我认为它与目标系统尽可能接近。我也看了你的剧本,有点困扰。首先是一个琐碎的观察:您可以通过在两个配置调用中键入 -prefix $XARMTARGET/v7 来节省 4 行代码。此外,我有点不知所措。 build1 内置的 ocamlopt 是什么?将 ocaml 编译为 ARM,但没有正确的工具链环境?这是用build2 修复的?您是否隐含地认为 ARM 环境与 i386 环境没有太大区别?
    • 您需要构建一个为您的目标生成代码的编译器。作为一个 OCaml 程序,这个编译器需要一个可以在主机上运行的运行时(特别是字节码解释器)。但是您还需要一个运行时来用于编译器编译的程序。此运行时适用于目标。由于您需要两个运行时,因此您必须构建两次。 (在 OCaml 的旧版本中,-prefix 对我不起作用。如果它现在起作用,那就太好了。)
    • 我修改了配置脚本,以便可以通过两次运行生成文件(并发布它,请您简单看一下好吗?)。我有几个问题:我注意到在你的脚本的第二阶段,你没有对 Makefile 中的RANLIB*ARCMDMKLIB 行进行后期修改,所以这些只在主机上使用(第一阶段)? utils/config.ml的修改,只需要提供正确的交叉编译器?在第二阶段,如果提供了正确的环境,就不能修改任何东西? (也许这次我应该问一个新的 SO 问题)
    • 我的原始脚本运行了两次,这正是重点。所以我不确定你的修改具体在做什么。如果他们为您工作,那就太好了! (使用原始脚本,您可以说xarm-build phase1 运行第一阶段,xarm-build phase2 运行第二阶段。)
    【解决方案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 时,它只执行编译的东西。中间结果存储在config/auto-aux/map_{hasgot,runtest}中,主要使用setValuegetValueExit进行检索,均在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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-08
      • 2017-11-09
      • 1970-01-01
      相关资源
      最近更新 更多