From patchwork Thu Sep 17 17:31:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hellermann X-Patchwork-Id: 518982 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 33DAF1414EE for ; Fri, 18 Sep 2015 03:32:25 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=the2masters.de header.i=@the2masters.de header.b=PlpEZR68; dkim-atps=neutral Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 23629284249; Thu, 17 Sep 2015 19:31:07 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00,T_DKIM_INVALID autolearn=unavailable version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id DE3172802AF for ; Thu, 17 Sep 2015 19:30:57 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 CL_IP_EQ_HELO_IP=-2 (check from: .the2masters. - helo: .mail-wi0-f180.google. - helo-domain: .google.) FROM/MX_MATCHES_HELO(DOMAIN)=-2; rate: -8.5 Received: from mail-wi0-f180.google.com (mail-wi0-f180.google.com [209.85.212.180]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Thu, 17 Sep 2015 19:30:56 +0200 (CEST) Received: by wiclk2 with SMTP id lk2so33666678wic.0 for ; Thu, 17 Sep 2015 10:32:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=the2masters.de; s=mail; h=from:to:subject:date:message-id; bh=fAbSYTkguWYPi+5E4oFyrMwyRA2qAjx5z+UlzUOmRME=; b=PlpEZR68EyKD799vP8PxXZ1fU0NOEXi0lt4SKz3cFurg8bx1btTSOt0eY2aBjW+jEF ivZ4fT8eGnL/f8Uv176BKW070AljkN00eRDU9kRvncXD4fJ4YOxOOva4Xtxgm5GZFzLe pQmINR/WXitKsN2OAc4bI1JbZ8q5/RdvRY1Rk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=fAbSYTkguWYPi+5E4oFyrMwyRA2qAjx5z+UlzUOmRME=; b=aI5PAQ/9HarzFEIno0vDJvM7jIqzuk5tC+kkXD2LCxmZNJGd+Yef963V0Zuzg/lFKJ u//F5PGIpipNCnE1UkMznR4lV/sVLsVqWv+r++jOiBADAJTA6btV2W/UtwA1i/5/ELGr pBNDmkZihRwu9i8YmGzJ+fPLsRd/XrsYTSmxWnrWN486MkO0ft7FKrYtZ3IoXbT3VVxL TLGBss/iV/aSujSeTCfy19L3UcRUVt2pp4G74SfjLDt0VOy2iH19BXooAd+VxmaHZCXd 3fdtFIZhW7NBz7VWv26fbJWgjhGURmRz5ZBFEgk4QUXZfWmexjFD2Ud7InAL7d5t28LV ryXA== X-Gm-Message-State: ALoCoQkHaHkouV4w7Cx602hBWx0/GOiGsjjeSnTKmITYAtrQe7PCEd/e3LivsO66FoZrItHJuakP X-Received: by 10.194.185.236 with SMTP id ff12mr520540wjc.49.1442511127861; Thu, 17 Sep 2015 10:32:07 -0700 (PDT) Received: from devel.eslohe.lan (p579F552D.dip0.t-ipconnect.de. [87.159.85.45]) by smtp.googlemail.com with ESMTPSA id gt10sm11152266wib.20.2015.09.17.10.32.06 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 17 Sep 2015 10:32:07 -0700 (PDT) From: Stefan Hellermann To: openwrt-devel@lists.openwrt.org Date: Thu, 17 Sep 2015 19:31:56 +0200 Message-Id: <1442511116-24869-1-git-send-email-stefan@the2masters.de> X-Mailer: git-send-email 2.1.4 Subject: [OpenWrt-Devel] [PATCH] [RFC] toolchain: add OCaml compiler X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" 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 --- 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))