Source: ghc Version: 8.0.1-17 Severity: normal Tags: patch User: helm...@debian.org Usertags: rebootstrap
Hi! Since building GHC natively on slower machines like m68k or sh4 can be quite painful, I have started working on making the GHC package cross-buildable. Naturally, being able to cross-build the GHC package also makes it much easier to bootstrap the compiler for new architecture once basic support has been added like here [1]. Quick summary what my current patch does: - use-stage1-binaries-for-install.patch: This patches the main ghc.mk to use the stage1 binaries of ghc and ghc-pkg to perform some installation jobs during 'make install'. This change was suggested by upstream [2] - build-unlit-and-hp2ps-twice.patch: Build the unlit and hp2ps binaries twice. Without the patch, the binaries created are for the build architecture, e.g. stage1 and not for the host architecture (stage2). See [3]. This change was suggested by upstream, I extended it for hp2ps. Unfortunately, it was never merged. See also this upstream ticket [4]. - debian/control: Replace "ghc (>= 7.8)" with "ghc:native (>= 7.8)" to tell debhelper to use the GHC compiler of the build system. This is what the gcc package does as well. Move haskell-devscripts-minimal and python-sphinx to Build-Depends-Indep. Please note, this is a hack. The proper fix would be to make both python-sphinx and haskell-devscripts-minimal (and probably haskell-devscripts, too) both arch:any. See this bug report [5]. - debian/rules: When DEB_BUILD_GNU_TYPE doesn't match DEB_HOST_GNU_TYPE, set: confflags += --target $(DEB_HOST_GNU_TYPE) --enable-unregisterised BUILD_HADDOCK_DOCS=NO Setting "--target" allows enabling cross-compiling, adding --enable-unregisterised is important for architectures not having native code generation support. Disabling the documentation is required by GHC itself. Trying to build the documentation when cross-compiling causes an error message. Throughout the rest of the debian/rules changes, I basically just made the necessary changes to cope with the fact that the documentation is not being built. This includes skipping the installation of all documentation and manpages. Additionally, I'm also guarding out the section which tries to run the compiler for cross-builds, e.g. ("# Do some very simple tests that the compiler actually works"). But Helmut Grohne already pointed out that the proper way would be to guard this by checking for "nocheck" in DEB_BUILD_OPTIONS as both sbuild and pbuilder set "nocheck" by default when cross-compiling. However, in some cases, like cross-compiling from amd64 to i386, running the tests is still desired. With the patch applied, I can successfully cross-build GHC provided that I have pre-installed "haskell-devscripts-minimal" in the chroot by simply running "sbuild --host=$HOST --no-arch-all -d sid" provided that the package cross-build-essential-$HOST exists which is unfortunately not the case for all architectures in Debian [6]. Adding additional architectures to cross-build-essential was very easy though. I just edited debian/cross-targets, uncommented the architectures I needed, ran ./debian/rules debian/control, rebuilt the package and pre-installed it in the build chroot. So, we should probably file a bug report against src:build-essential to add more architectures as needed. I don't see why most of the architectures are currently missing. Anyway, without the haskell-devscripts-minimal package pre-installed in the chroot, the cross-build will fail with: dh_haskell_provides make[1]: dh_haskell_provides: Command not found debian/rules:268: recipe for target 'override_dh_installdeb' failed make[1]: *** [override_dh_installdeb] Error 127 make[1]: Leaving directory '/<<PKGBUILDDIR>>' debian/rules:46: recipe for target 'binary-arch' failed make: *** [binary-arch] Error 2 dpkg-buildpackage: error: fakeroot debian/rules binary-arch gave error exit status 2 Additionally, the generated GHC package does not have the proper symlinks set: glaubitz@ikarus:/srv/chroots/sid-m68k-sbuild$ dpkg-deb -c ghc_8.0.1-17_m68k.deb |grep "/usr/bin" drwxr-xr-x root/root 0 2016-12-17 03:44 ./usr/bin/ -rwxr-xr-x root/root 55 2016-12-17 03:44 ./usr/bin/ghci-8.0.1 -rwxr-xr-x root/root 226 2016-12-17 03:44 ./usr/bin/m68k-unknown-linux-gnu-ghc-8.0.1 -rwxr-xr-x root/root 258 2016-12-17 03:44 ./usr/bin/m68k-unknown-linux-gnu-ghc-pkg-8.0.1 -rwxr-xr-x root/root 188 2016-12-17 03:44 ./usr/bin/m68k-unknown-linux-gnu-hpc -rwxr-xr-x root/root 967 2016-12-17 03:44 ./usr/bin/m68k-unknown-linux-gnu-hsc2hs -rwxr-xr-x root/root 234 2016-12-17 03:44 ./usr/bin/m68k-unknown-linux-gnu-runghc-8.0.1 lrwxrwxrwx root/root 0 2016-12-17 03:44 ./usr/bin/ghci -> ghci-8.0.1 lrwxrwxrwx root/root 0 2016-12-17 03:44 ./usr/bin/m68k-unknown-linux-gnu-ghc -> m68k-unknown-linux-gnu-ghc-8.0.1 lrwxrwxrwx root/root 0 2016-12-17 03:44 ./usr/bin/m68k-unknown-linux-gnu-ghc-pkg -> m68k-unknown-linux-gnu-ghc-pkg-8.0.1 lrwxrwxrwx root/root 0 2016-12-17 03:44 ./usr/bin/runghc -> runghc-8.0.1 lrwxrwxrwx root/root 0 2016-12-17 03:44 ./usr/bin/runhaskell -> runghc glaubitz@ikarus:/srv/chroots/sid-m68k-sbuild$ As you can see, /usr/bin/ghc is missing. For my tests, I added the symlinks manually in my m68k chroot, but I still ran into the following problem when trying to build haskell-text: Configuring text-1.2.2.1... Warning: cannot determine version of /usr/bin/ghc-pkg : "" hlibrary.setup: The program 'ghc-pkg' is required but the version of /usr/bin/ghc-pkg could not be determined. /usr/share/cdbs/1/class/hlibrary.mk:142: recipe for target 'configure-ghc-stamp' failed make: *** [configure-ghc-stamp] Error 1 dpkg-buildpackage: error: debian/rules build-arch gave error exit status 2 But I'm not sure if it's related because running 'ghc-pkg --version' works: (sid-m68k-sbuild)root@ikarus:/# ghc-pkg --version GHC package manager version 8.0.1 (sid-m68k-sbuild)root@ikarus:/# So, I'd really appreciate any advise on what could be wrong here. Either way, I think my patch is a good starting point to actually make the GHC package cross-buildable. > [1] > https://git.haskell.org/ghc.git/commitdiff/f48015bcac59960f6d266506a5f378c9bcf8f005 > [2] > https://github.com/rwbarton/ghc-android/blob/rwbarton-ghci/patches/ghc-install.patch > [3] > https://github.com/thomie/ghc/commit/eba93774c3ce2f151e7c72f6d068b753f24dbcfa > [4] https://ghc.haskell.org/trac/ghc/ticket/12193 > [5] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=818115 > [6] https://packages.qa.debian.org/b/build-essential.html -- .''`. John Paul Adrian Glaubitz : :' : Debian Developer - glaub...@debian.org `. `' Freie Universitaet Berlin - glaub...@physik.fu-berlin.de `- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
diff -Nru ghc-8.0.1/debian/control ghc-8.0.1/debian/control --- ghc-8.0.1/debian/control 2016-10-28 07:42:05.000000000 +0200 +++ ghc-8.0.1/debian/control 2017-01-27 15:26:59.000000000 +0100 @@ -6,23 +6,23 @@ Standards-Version: 3.9.8 Build-Depends: debhelper (>= 9), - haskell-devscripts-minimal, devscripts, dh-autoreconf, autotools-dev, grep-dctrl, pkg-config, - ghc (>= 7.8), + ghc:native (>= 7.8), libgmp-dev, llvm-3.7 [arm64 armel armhf], libffi-dev, binutils [arm64 armel armhf], libncurses5-dev, - python-sphinx, dpkg-dev (>= 1.16.1.1) Build-Depends-Indep: hscolour, - fop + fop, + python-sphinx, + haskell-devscripts-minimal Build-Conflicts: ccache, ghc (= 8.0.0.20160111-3), diff -Nru ghc-8.0.1/debian/patches/build-unlit-and-hp2ps-twice.patch ghc-8.0.1/debian/patches/build-unlit-and-hp2ps-twice.patch --- ghc-8.0.1/debian/patches/build-unlit-and-hp2ps-twice.patch 1970-01-01 01:00:00.000000000 +0100 +++ ghc-8.0.1/debian/patches/build-unlit-and-hp2ps-twice.patch 2017-01-30 17:11:34.000000000 +0100 @@ -0,0 +1,80 @@ +Description: Build unlit and hp2ps twice +Author: Thomas Miedema <thomasmied...@gmail.com> + John Paul Adrian Glaubitz <glaub...@physik.fu-berlin.de> + +Index: ghc-8.0.1/utils/ghc-pkg/ghc.mk +=================================================================== +--- ghc-8.0.1.orig/utils/ghc-pkg/ghc.mk ++++ ghc-8.0.1/utils/ghc-pkg/ghc.mk +@@ -27,7 +27,7 @@ utils/ghc-pkg_PACKAGE = ghc-pkg + # Note [Why build certain utils twice?] + # + # We build certain utils twice: once with stage0, and once with stage1. +-# Examples are ghc-pkg and hsc2hs. ++# Examples are ghc-pkg, hsc2hs, hp2ps and unlit. + # + # These tools are needed during the bootstrapping process, so we have to use + # stage0 to build them at first (stage1 doesn't exist yet). (side note: they're +@@ -38,6 +38,11 @@ utils/ghc-pkg_PACKAGE = ghc-pkg + # dynamically linked. But the stage0 copies are either statically linked, or + # linked against libraries on the build machine. + # ++# Another reason why we can't install the stage0 copies is that they are ++# built to run on the build(=host) platform, but when installing a ++# "cross-compiled stage2 compiler" we need copies that run on the target ++# platform. ++# + # Therefore we build fresh copies, using the stage1 compiler, and install them + # when you run 'make install'. They are not used for any other purpose. + +Index: ghc-8.0.1/utils/hp2ps/ghc.mk +=================================================================== +--- ghc-8.0.1.orig/utils/hp2ps/ghc.mk ++++ ghc-8.0.1/utils/hp2ps/ghc.mk +@@ -17,10 +17,23 @@ utils/hp2ps_dist_C_SRCS = AreaB + Utilities.c + utils/hp2ps_dist_EXTRA_LIBRARIES = m + utils/hp2ps_dist_PROGNAME = $(CrossCompilePrefix)hp2ps +-utils/hp2ps_dist_INSTALL = YES ++utils/hp2ps_dist_INSTALL = NO + utils/hp2ps_dist_INSTALL_INPLACE = YES + + utils/hp2ps_CC_OPTS += $(addprefix -I,$(GHC_INCLUDE_DIRS)) + + $(eval $(call build-prog,utils/hp2ps,dist,0)) + ++utils/hp2ps_dist-install_C_SRCS = AreaBelow.c Curves.c Error.c Main.c \ ++ Reorder.c TopTwenty.c AuxFile.c Deviation.c \ ++ HpFile.c Marks.c Scale.c TraceElement.c \ ++ Axes.c Dimensions.c Key.c PsFile.c Shade.c \ ++ Utilities.c ++utils/hp2ps_dist-install_EXTRA_LIBRARIES = m ++utils/hp2ps_dist-install_PROGNAME = hp2ps ++utils/hp2ps_dist-install_TOPDIR = YES ++utils/hp2ps_dist-install_INSTALL = YES ++utils/hp2ps_dist-install_INSTALL_INPLACE = NO ++ ++# See Note [Why build certain utils twice?]. ++$(eval $(call build-prog,utils/hp2ps,dist-install,1)) +Index: ghc-8.0.1/utils/unlit/ghc.mk +=================================================================== +--- ghc-8.0.1.orig/utils/unlit/ghc.mk ++++ ghc-8.0.1/utils/unlit/ghc.mk +@@ -13,8 +13,16 @@ + utils/unlit_dist_C_SRCS = unlit.c + utils/unlit_dist_PROGNAME = unlit + utils/unlit_dist_TOPDIR = YES +-utils/unlit_dist_INSTALL = YES ++utils/unlit_dist_INSTALL = NO + utils/unlit_dist_INSTALL_INPLACE = YES + + $(eval $(call build-prog,utils/unlit,dist,0)) + ++utils/unlit_dist-install_C_SRCS = unlit.c ++utils/unlit_dist-install_PROGNAME = unlit ++utils/unlit_dist-install_TOPDIR = YES ++utils/unlit_dist-install_INSTALL = YES ++utils/unlit_dist-install_INSTALL_INPLACE = NO ++ ++# See Note [Why build certain utils twice?]. ++$(eval $(call build-prog,utils/unlit,dist-install,1)) diff -Nru ghc-8.0.1/debian/patches/series ghc-8.0.1/debian/patches/series --- ghc-8.0.1/debian/patches/series 2016-12-17 03:43:34.000000000 +0100 +++ ghc-8.0.1/debian/patches/series 2017-01-30 16:16:17.000000000 +0100 @@ -15,3 +15,5 @@ osdecommitmemory-compat.patch smp-arm-fix.patch R_X86_64_REX_GOTPCRELX +use-stage1-binaries-for-install.patch +build-unlit-and-hp2ps-twice.patch diff -Nru ghc-8.0.1/debian/patches/use-stage1-binaries-for-install.patch ghc-8.0.1/debian/patches/use-stage1-binaries-for-install.patch --- ghc-8.0.1/debian/patches/use-stage1-binaries-for-install.patch 1970-01-01 01:00:00.000000000 +0100 +++ ghc-8.0.1/debian/patches/use-stage1-binaries-for-install.patch 2017-01-29 11:32:45.000000000 +0100 @@ -0,0 +1,26 @@ +Description: Use the stage1 binaries for install + In order to be able to perform a cross-build, we need to use + the stage1 binaries during installation. Both ghc and ghc-pkg + are run during the install target and therefore must be able + to run on the build machine. + . +Author: John Paul Adrian Glaubitz <glaub...@physik.fu-berlin.de> +Last-Update: 2017-01-29 + +--- ghc-8.0.1.orig/ghc.mk ++++ ghc-8.0.1/ghc.mk +@@ -958,8 +958,12 @@ INSTALLED_PACKAGE_CONF=$(DESTDIR)$(topdi + # Install packages in the right order, so that ghc-pkg doesn't complain. + # Also, install ghc-pkg first. + ifeq "$(Windows_Host)" "NO" +-INSTALLED_GHC_REAL=$(DESTDIR)$(ghclibexecdir)/bin/ghc +-INSTALLED_GHC_PKG_REAL=$(DESTDIR)$(ghclibexecdir)/bin/ghc-pkg ++# Use the inplace/stage1 versions for installation, ++# since the installed versions are built for the target ++#INSTALLED_GHC_REAL=$(DESTDIR)$(ghclibexecdir)/bin/ghc ++#INSTALLED_GHC_PKG_REAL=$(DESTDIR)$(ghclibexecdir)/bin/ghc-pkg ++INSTALLED_GHC_REAL=$(CURDIR)/inplace/bin/ghc-stage1 ++INSTALLED_GHC_PKG_REAL=$(CURDIR)/utils/ghc-pkg/dist/build/tmp/ghc-pkg + else + INSTALLED_GHC_REAL=$(DESTDIR)$(bindir)/ghc.exe + INSTALLED_GHC_PKG_REAL=$(DESTDIR)$(bindir)/ghc-pkg.exe diff -Nru ghc-8.0.1/debian/rules ghc-8.0.1/debian/rules --- ghc-8.0.1/debian/rules 2016-11-14 17:07:27.000000000 +0100 +++ ghc-8.0.1/debian/rules 2017-01-30 15:35:39.000000000 +0100 @@ -22,20 +22,20 @@ export DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) export DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) export DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) -# Commented out for now. The build scripts don't recognise i486 as an -# architecture and cross compiling isn't supported anyway. -#ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE)) -# confflags += --build $(DEB_HOST_GNU_TYPE) -#else -# confflags += --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE) -#endif + +# We're cross-building if DEB_BUILD_GNU_TYPE != DEB_HOST_GNU_TYPE +ifneq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE)) + confflags += --target $(DEB_HOST_GNU_TYPE) --enable-unregisterised + BUILD_HADDOCK_DOCS=NO +else + BUILD_HADDOCK_DOCS=YES +endif ProjectVersion=$(shell cat VERSION) GHC=$(firstword $(shell bash -c "type -p ghc")) EXTRA_CONFIGURE_FLAGS=--with-ghc="$(GHC)" -BUILD_HADDOCK_DOCS=YES DEB_HOOGLE_TXT_DIR = /usr/lib/ghc-doc/hoogle/ ifeq (x32,$(DEB_HOST_ARCH)) @@ -48,9 +48,13 @@ override_dh_auto_configure: dh_autoreconf perl -- boot echo "SRC_HC_OPTS += -lffi -optl-pthread" >> mk/build.mk +ifeq (YES,$(BUILD_HADDOCK_DOCS)) echo "HADDOCK_DOCS := YES" >> mk/build.mk echo "EXTRA_HADDOCK_OPTS += --mathjax=file:///usr/share/javascript/mathjax/MathJax.js" >> mk/build.mk echo "XSLTPROC_OPTS += --nonet" >> mk/build.mk +else + echo "HADDOCK_DOCS := NO" >> mk/build.mk +endif ifneq (,$(findstring $(DEB_HOST_ARCH), arm64 armel armhf)) echo "SRC_HC_OPTS += -optl-B/usr/bin/ld.gold" >> mk/build.mk endif @@ -98,6 +102,8 @@ echo 'dvidir := $$(docdir)' >> mk/build.mk echo 'pdfdir := $$(docdir)' >> mk/build.mk echo 'psdir := $$(docdir)' >> mk/build.mk + echo 'STRIP_CMD = $(DEB_HOST_GNU_TYPE)-strip' >> mk/build.mk + echo 'RANLIB_CMD = $(DEB_HOST_GNU_TYPE)-ranlib'>> mk/build.mk # We want verbose builds echo 'V=1' >> mk/build.mk ./configure $(confflags) --prefix=/usr \ @@ -108,6 +114,7 @@ override_dh_auto_build: dh_auto_build +ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE)) # Do some very simple tests that the compiler actually works rm -rf debian/testghc mkdir debian/testghc @@ -122,7 +129,7 @@ @printf "====BEGIN GHC INFO OUTPUT====\n" @inplace/bin/ghc-stage2 --info @printf "====END GHC INFO OUTPUT====\n" - +endif FILES = \( -type f -o -type l \) PROF_FILE = \( -name "*.p_*" -o -name "lib*_p.a" \) @@ -175,9 +182,8 @@ mkdir debian/tmp/usr/lib/ghc-doc/haddock/ghc/`basename $$f` ; \ mv $$f/*.haddock debian/tmp/usr/lib/ghc-doc/haddock/ghc/`basename $$f` ; done cd debian/tmp/usr/share/doc/ghc-doc/html/libraries/; ln -s ghc-$(ProjectVersion) ghc - install -Dm 644 debian/index.html debian/tmp/usr/share/doc/ghc-doc/index.html -endif + install -Dm 644 debian/index.html debian/tmp/usr/share/doc/ghc-doc/index.html # manpages rm -f debian/*.1 echo ".so man1/ghc.1" > debian/ghc-$(ProjectVersion).1 @@ -193,14 +199,13 @@ echo debian/*.1 > debian/ghc.manpages cp debian/haddock.man debian/haddock.1 echo debian/haddock.1 >> debian/ghc.manpages - +endif # #################### # Now all the files are sorted, create the package filelists # ghc find debian/tmp/usr/bin $(FILES) > debian/ghc.install # find debian/tmp/usr/share/ghc* $(FILES) >> debian/ghc.install - find debian/tmp/usr/share/man $(FILES) >> debian/ghc.install find debian/tmp/usr/lib/ghc $(FILES) ! $(PROF_FILE) >> debian/ghc.install find debian/tmp/var >> debian/ghc.install echo debian/tmp/usr/share/lintian/overrides/ghc >> debian/ghc.install @@ -209,14 +214,15 @@ echo debian/tmp/usr/share/lintian/overrides/ghc-prof >> debian/ghc-prof.install # ghc-doc ifeq (YES,$(BUILD_HADDOCK_DOCS)) + find debian/tmp/usr/share/man $(FILES) >> debian/ghc.install mkdir -p debian/tmp/$(DEB_HOOGLE_TXT_DIR) cat debian/ghc-doc.links.in > debian/ghc-doc.links find debian/tmp/usr/share/doc/ghc-doc/html/libraries/*/ -name "*.txt" \ -printf "%p $(DEB_HOOGLE_TXT_DIR)/%f\n" >> debian/ghc-doc.links find debian/tmp/usr/share/doc/ghc-doc $(FILES) > debian/ghc-doc.install find debian/tmp/usr/lib/ghc-doc $(FILES) >> debian/ghc-doc.install -endif sed -i s,^debian/tmp,, debian/*.install debian/*.links +endif rm -f debian/ghc.links echo "/var/lib/ghc/package.conf.d /usr/lib/ghc/package.conf.d" >> debian/ghc.links