While porting the Unison File Synchronizer to openwrt I added the OCaml compiler to openwrt toolchain. Cross-compiling OCaml seems to be only tested for windows mingw targets. I had to add a patch to the OCaml configure scripts, to feed it with a few bits of the target. I hope i did it right for all targets. Cross-compiling OCaml needs a bootstrap OCaml installed on the host, so I actually added OCaml twice, one time in tools and one time in toolchain. I discovered a bug when trying to cross-compile on a 64 bit host for a 32 bit target, the resulting binaries won't work on the target. For this case I added a workaround in tools/ocaml to compile a 32 bit bootstrap OCaml on x86_64 hosts when building for 32 bit targets. This workaround is tested for a x86_64 host when compiling for ar71xx and x86_64 targets. This workaround is probably buggy when switching from x86_64 to ar71xx targets without make dirclean, as tools/ocaml is not rebuild in this case.
Tested with Unison File Synchronizer on ar71xx and x86_64. Beware: Stripping unison won't work! Better solutions and comments are appreciated! Signed-off-by: Stefan Hellermann <[email protected]> --- toolchain/Config.in | 6 +++ toolchain/Makefile | 3 +- toolchain/ocaml/Makefile | 55 +++++++++++++++++++++++++ toolchain/ocaml/patches/001-crosscompile.patch | 57 ++++++++++++++++++++++++++ tools/Makefile | 1 + tools/ocaml/Makefile | 35 ++++++++++++++++ 6 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 toolchain/ocaml/Makefile create mode 100644 toolchain/ocaml/patches/001-crosscompile.patch create mode 100644 tools/ocaml/Makefile diff --git a/toolchain/Config.in b/toolchain/Config.in index 474a14f..88bbe98 100644 --- a/toolchain/Config.in +++ b/toolchain/Config.in @@ -206,6 +206,12 @@ comment "Compiler" source "toolchain/gcc/Config.in" +config OCAML + bool + prompt "Build OCaml Compiler" if TOOLCHAINOPTS + help + Enable if you want to build the OCaml Compiler. + comment "C Library" depends on TOOLCHAINOPTS diff --git a/toolchain/Makefile b/toolchain/Makefile index cd5399e..92c6f82 100644 --- a/toolchain/Makefile +++ b/toolchain/Makefile @@ -28,7 +28,7 @@ curdir:=toolchain # subdirectories to descend into -$(curdir)/builddirs := $(if $(CONFIG_GDB),gdb) $(if $(CONFIG_INSIGHT),insight) $(if $(CONFIG_EXTERNAL_TOOLCHAIN),wrapper,kernel-headers binutils gcc/minimal gcc/initial gcc/final $(LIBC)/headers $(LIBC) fortify-headers) +$(curdir)/builddirs := $(if $(CONFIG_GDB),gdb) $(if $(CONFIG_INSIGHT),insight) $(if $(CONFIG_OCAML),ocaml) $(if $(CONFIG_EXTERNAL_TOOLCHAIN),wrapper,kernel-headers binutils gcc/minimal gcc/initial gcc/final $(LIBC)/headers $(LIBC) fortify-headers) ifdef CONFIG_USE_UCLIBC $(curdir)/builddirs += $(LIBC)/utils endif @@ -49,6 +49,7 @@ ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),) $(curdir)/$(LIBC)/utils/compile:=$(curdir)/gcc/final/install $(curdir)/$(LIBC)/prepare:=$(curdir)/$(LIBC)/headers/prepare $(curdir)/$(LIBC)/utils/prepare:=$(curdir)/$(LIBC)/headers/prepare + $(curdir)/ocaml/prepare:=$(curdir)/gcc/final/install endif ifndef DUMP_TARGET_DB diff --git a/toolchain/ocaml/Makefile b/toolchain/ocaml/Makefile new file mode 100644 index 0000000..dfb4135 --- /dev/null +++ b/toolchain/ocaml/Makefile @@ -0,0 +1,55 @@ +# +# Copyright (C) 2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=ocaml +PKG_VERSION:=4.02.3 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://caml.inria.fr/pub/distrib/$(PKG_NAME)-$(word 1,$(subst ., ,$(PKG_VERSION))).$(word 2,$(subst ., ,$(PKG_VERSION)))/ +PKG_MD5SUM:=ef1a324608c97031cbd92a442d685ab7 + +include $(INCLUDE_DIR)/toolchain-build.mk + +# custom configure script +HOST_CONFIGURE_VARS = +HOST_CONFIGURE_ARGS = \ + -prefix $(TOOLCHAIN_DIR) \ + -target-bindir $(TOOLCHAIN_DIR)/bin \ + -target $(REAL_GNU_TARGET_NAME) \ + -cc "$(TARGET_CC) $(TARGET_CFLAGS)" \ + -as "$(TARGET_AS) $(TARGET_ASFLAGS)" \ + -no-pthread -no-shared-libs \ + -no-debugger -no-ocamldoc -no-graph -no-cfi + +ifneq ($(CONFIG_BIG_ENDIAN),) +HOST_CONFIGURE_ARGS += -big-endian +endif + +# OCaml applications for 32 bit targets need to be cross-compiled on a 32 bit host OCaml. +# The following catches x86_64 hosts only. Tested on x86_64 for ar71xx and x86_64 targets. +ifeq ($(HOST_ARCH)$(CONFIG_ARCH_64BIT),x86_64) +HOST_CONFIGURE_ARGS += -host i386-linux +else +HOST_CONFIGURE_ARGS += -host $(GNU_HOST_NAME) +endif + +define Host/Compile + $(MAKE) -C $(HOST_BUILD_DIR) world +endef + +define Host/Install + $(call Host/Install/Default) + mv $(TOOLCHAIN_DIR)/bin/ocamlc $(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)ocamlc +endef + +define Host/Clean + $(call Host/Clean/Default) + rm -f $(STAGING_DIR_HOST)/bin/$(TARGET_CROSS)ocamlc +endef + +$(eval $(call HostBuild)) diff --git a/toolchain/ocaml/patches/001-crosscompile.patch b/toolchain/ocaml/patches/001-crosscompile.patch new file mode 100644 index 0000000..a5eedca --- /dev/null +++ b/toolchain/ocaml/patches/001-crosscompile.patch @@ -0,0 +1,57 @@ +--- ocaml-4.02.3/configure 2015-05-12 16:46:37.000000000 +0200 ++++ ocaml-4.02.3_new/configure 2015-09-17 16:20:07.104000000 +0200 +@@ -47,6 +47,7 @@ + no_naked_pointers=false + TOOLPREF="" + with_cfi=true ++big_endian=1 + + # Try to turn internationalization off, can cause config.guess to malfunction! + unset LANG +@@ -154,6 +155,8 @@ + no_naked_pointers=true;; + -no-cfi|--no-cfi) + with_cfi=false;; ++ -big-endian|--big-endian) ++ big_endian=0;; + *) if echo "$1" | grep -q -e '^--\?[a-zA-Z0-9-]\+='; then + err "configure expects arguments of the form '-prefix /foo/bar'," \ + "not '-prefix=/foo/bar' (note the '=')." +@@ -532,18 +535,14 @@ + else + # For cross-compilation, runtest always fails: add special handling. + case "$target" in +- i686-*-mingw*) inf "OK, this is a regular 32 bit architecture." +- echo "#undef ARCH_SIXTYFOUR" >> m.h +- set 4 4 4 2 8 +- arch64=false;; +- x86_64-*-mingw*) inf "Wow! A 64 bit architecture!" ++ *64-*) inf "Wow! A 64 bit architecture!" + echo "#define ARCH_SIXTYFOUR" >> m.h + set 4 4 8 2 8 + arch64=true;; +- *) err "Since datatype sizes cannot be guessed when cross-compiling,\n" \ +- "a hardcoded list is used but your architecture isn't known yet.\n" \ +- "You need to determine the sizes yourself.\n" \ +- "Please submit a bug report in order to expand the list." ;; ++ *) inf "OK, this is a regular 32 bit architecture." ++ echo "#undef ARCH_SIXTYFOUR" >> m.h ++ set 4 4 4 2 8 ++ arch64=false;; + esac + fi + +@@ -567,8 +566,11 @@ + + # Determine endianness + +-sh ./runtest endian.c +-case $? in ++if ! $cross_compiler; then ++ sh ./runtest endian.c ++ big_endian=$? ++fi ++case $big_endian in + 0) inf "This is a big-endian architecture." + echo "#define ARCH_BIG_ENDIAN" >> m.h;; + 1) inf "This is a little-endian architecture." diff --git a/tools/Makefile b/tools/Makefile index 60041dd..ac2acd4 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -24,6 +24,7 @@ ifneq ($(CONFIG_PACKAGE_kmod-b43)$(CONFIG_PACKAGE_kmod-b43legacy)$(CONFIG_BRCMSM endif tools-$(BUILD_TOOLCHAIN) += gmp mpfr mpc libelf expat +tools-$(CONFIG_OCAML) += ocaml tools-y += m4 libtool autoconf automake flex bison pkg-config sed mklibs tools-y += sstrip make-ext4fs e2fsprogs mtd-utils mkimage tools-y += firmware-utils patch-image patch quilt yaffs2 flock padjffs2 diff --git a/tools/ocaml/Makefile b/tools/ocaml/Makefile new file mode 100644 index 0000000..4e0a595 --- /dev/null +++ b/tools/ocaml/Makefile @@ -0,0 +1,35 @@ +# +# Copyright (C) 2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=ocaml +PKG_VERSION:=4.02.3 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://caml.inria.fr/pub/distrib/$(PKG_NAME)-$(word 1,$(subst ., ,$(PKG_VERSION))).$(word 2,$(subst ., ,$(PKG_VERSION)))/ +PKG_MD5SUM:=ef1a324608c97031cbd92a442d685ab7 + +include $(INCLUDE_DIR)/host-build.mk + +# custom configure script +HOST_CONFIGURE_VARS = +HOST_CONFIGURE_ARGS = -prefix $(STAGING_DIR_HOST) \ + -no-pthread -no-debugger -no-ocamldoc -no-graph -no-cfi + +# OCaml applications for 32 bit targets need to be cross-compiled on a 32 bit host OCaml. +# The following catches x86_64 hosts only. Tested on x86_64 for ar71xx and x86_64 targets. +ifeq ($(HOST_ARCH)$(CONFIG_ARCH_64BIT),x86_64) +HOST_CONFIGURE_ARGS += \ + -cc "gcc -m32" -as "as --32" -aspp "gcc -m32 -c" \ + -host i386-linux -partialld "ld -r -melf_i386" +endif + +define Host/Compile + $(MAKE) -C $(HOST_BUILD_DIR) world +endef + +$(eval $(call HostBuild)) -- 2.1.4 _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
