From 845b56d25af40d90e3cd6ec4d60c6b3f091c7588 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Tue, 15 Nov 2016 16:59:09 -0500 Subject: [PATCH] Initial support for cross-compiling ghc --- pkgs/development/compilers/ghc/D2710.patch | 19 +++ pkgs/development/compilers/ghc/D2711.patch | 22 +++ pkgs/development/compilers/ghc/D2712.patch | 158 ++++++++++++++++++ pkgs/development/compilers/ghc/D2713.patch | 17 ++ ...pass-linker-flags-via-response-files.patch | 20 --- pkgs/development/compilers/ghc/head.nix | 60 ++++--- pkgs/top-level/all-packages.nix | 2 +- pkgs/top-level/haskell-packages.nix | 7 +- 8 files changed, 263 insertions(+), 42 deletions(-) create mode 100644 pkgs/development/compilers/ghc/D2710.patch create mode 100644 pkgs/development/compilers/ghc/D2711.patch create mode 100644 pkgs/development/compilers/ghc/D2712.patch create mode 100644 pkgs/development/compilers/ghc/D2713.patch delete mode 100644 pkgs/development/compilers/ghc/ghc-HEAD-dont-pass-linker-flags-via-response-files.patch diff --git a/pkgs/development/compilers/ghc/D2710.patch b/pkgs/development/compilers/ghc/D2710.patch new file mode 100644 index 000000000000..0ee1b06c7346 --- /dev/null +++ b/pkgs/development/compilers/ghc/D2710.patch @@ -0,0 +1,19 @@ +diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h +--- a/rts/LinkerInternals.h ++++ b/rts/LinkerInternals.h +@@ -303,4 +303,14 @@ + # define OBJFORMAT_MACHO + #endif + ++/* In order to simplify control flow a bit, some references to mmap-related ++ definitions are blocked off by a C-level if statement rather than a CPP-level ++ #if statement. Since those are dead branches when !RTS_LINKER_USE_MMAP, we ++ just stub out the relevant symbols here ++*/ ++#if !RTS_LINKER_USE_MMAP ++#define munmap(x,y) /* nothing */ ++#define MAP_ANONYMOUS 0 ++#endif ++ + #endif /* LINKERINTERNALS_H */ + diff --git a/pkgs/development/compilers/ghc/D2711.patch b/pkgs/development/compilers/ghc/D2711.patch new file mode 100644 index 000000000000..8d229f273999 --- /dev/null +++ b/pkgs/development/compilers/ghc/D2711.patch @@ -0,0 +1,22 @@ +diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c +--- a/rts/sm/Storage.c ++++ b/rts/sm/Storage.c +@@ -1314,7 +1314,7 @@ + ------------------------------------------------------------------------- */ + + #if (defined(arm_HOST_ARCH) || defined(aarch64_HOST_ARCH)) && defined(ios_HOST_OS) +-void sys_icache_invalidate(void *start, size_t len); ++#include + #endif + + /* On ARM and other platforms, we need to flush the cache after +@@ -1327,7 +1327,7 @@ + (void)exec_addr; + #elif (defined(arm_HOST_ARCH) || defined(aarch64_HOST_ARCH)) && defined(ios_HOST_OS) + /* On iOS we need to use the special 'sys_icache_invalidate' call. */ +- sys_icache_invalidate(exec_addr, ((unsigned char*)exec_addr)+len); ++ sys_icache_invalidate(exec_addr, len); + #elif defined(__GNUC__) + /* For all other platforms, fall back to a libgcc builtin. */ + unsigned char* begin = (unsigned char*)exec_addr; + diff --git a/pkgs/development/compilers/ghc/D2712.patch b/pkgs/development/compilers/ghc/D2712.patch new file mode 100644 index 000000000000..d938d70bbcfe --- /dev/null +++ b/pkgs/development/compilers/ghc/D2712.patch @@ -0,0 +1,158 @@ +diff --git a/includes/rts/OSThreads.h b/includes/rts/OSThreads.h +--- a/includes/rts/OSThreads.h ++++ b/includes/rts/OSThreads.h +@@ -15,7 +15,12 @@ + #ifndef RTS_OSTHREADS_H + #define RTS_OSTHREADS_H + +-#if defined(THREADED_RTS) /* to near the end */ ++#if defined(HAVE_PTHREAD_H) && !defined(mingw32_HOST_OS) ++#define BUILD_OSTHREAD_POSIX ++#endif ++ ++ ++#if defined(THREADED_RTS) || defined(BUILD_OSTHREAD_POSIX) /* to near end */ + + #if defined(HAVE_PTHREAD_H) && !defined(mingw32_HOST_OS) + +@@ -205,13 +210,25 @@ + void releaseThreadNode (void); + #endif // !CMINUSMINUS + +-#else ++#endif /* defined(THREADED_RTS) || defined(BUILD_OSTHREAD_POSIX) */ ++ ++#ifndef THREADED_RTS ++ ++#ifdef ACQUIRE_LOCK ++// If we have pthreads, we pull in the threading primitives even when the RTS ++// isn't threaded, but we expect these macros to be noops on non-threaded RTS. ++ ++#undef ACQUIRE_LOCK ++#undef RELEASE_LOCK ++#undef ASSERT_LOCK_HELD ++ ++#endif + + #define ACQUIRE_LOCK(l) + #define RELEASE_LOCK(l) + #define ASSERT_LOCK_HELD(l) + +-#endif /* defined(THREADED_RTS) */ ++#endif + + #ifndef CMINUSMINUS + // +diff --git a/rts/posix/OSThreads.c b/rts/posix/OSThreads.c +--- a/rts/posix/OSThreads.c ++++ b/rts/posix/OSThreads.c +@@ -35,7 +35,7 @@ + #endif + #endif + +-#if defined(THREADED_RTS) ++#if defined(THREADED_RTS) || defined(BUILD_OSTHREAD_POSIX) + #include "RtsUtils.h" + #include "Task.h" + +@@ -225,47 +225,6 @@ + return NULL; + } + +-int +-forkOS_createThread ( HsStablePtr entry ) +-{ +- pthread_t tid; +- int result = pthread_create(&tid, NULL, +- forkOS_createThreadWrapper, (void*)entry); +- if(!result) +- pthread_detach(tid); +- return result; +-} +- +-void freeThreadingResources (void) { /* nothing */ } +- +-uint32_t +-getNumberOfProcessors (void) +-{ +- static uint32_t nproc = 0; +- +- if (nproc == 0) { +-#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) +- nproc = sysconf(_SC_NPROCESSORS_ONLN); +-#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) +- nproc = sysconf(_SC_NPROCESSORS_CONF); +-#elif defined(darwin_HOST_OS) +- size_t size = sizeof(uint32_t); +- if(sysctlbyname("hw.logicalcpu",&nproc,&size,NULL,0) != 0) { +- if(sysctlbyname("hw.ncpu",&nproc,&size,NULL,0) != 0) +- nproc = 1; +- } +-#elif defined(freebsd_HOST_OS) +- size_t size = sizeof(uint32_t); +- if(sysctlbyname("hw.ncpu",&nproc,&size,NULL,0) != 0) +- nproc = 1; +-#else +- nproc = 1; +-#endif +- } +- +- return nproc; +-} +- + #if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY) + // Schedules the thread to run on CPU n of m. m may be less than the + // number of physical CPUs, in which case, the thread will be allowed +@@ -353,6 +312,51 @@ + pthread_kill(id, SIGPIPE); + } + ++#endif /* defined(THREADED_RTS) || defined(BUILD_OSTHREAD_POSIX) */ ++ ++#if defined(THREADED_RTS) ++ ++int ++forkOS_createThread ( HsStablePtr entry ) ++{ ++ pthread_t tid; ++ int result = pthread_create(&tid, NULL, ++ forkOS_createThreadWrapper, (void*)entry); ++ if(!result) ++ pthread_detach(tid); ++ return result; ++} ++ ++void freeThreadingResources (void) { /* nothing */ } ++ ++uint32_t ++getNumberOfProcessors (void) ++{ ++ static uint32_t nproc = 0; ++ ++ if (nproc == 0) { ++#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) ++ nproc = sysconf(_SC_NPROCESSORS_ONLN); ++#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) ++ nproc = sysconf(_SC_NPROCESSORS_CONF); ++#elif defined(darwin_HOST_OS) ++ size_t size = sizeof(uint32_t); ++ if(sysctlbyname("hw.logicalcpu",&nproc,&size,NULL,0) != 0) { ++ if(sysctlbyname("hw.ncpu",&nproc,&size,NULL,0) != 0) ++ nproc = 1; ++ } ++#elif defined(freebsd_HOST_OS) ++ size_t size = sizeof(uint32_t); ++ if(sysctlbyname("hw.ncpu",&nproc,&size,NULL,0) != 0) ++ nproc = 1; ++#else ++ nproc = 1; ++#endif ++ } ++ ++ return nproc; ++} ++ + #else /* !defined(THREADED_RTS) */ + + int + diff --git a/pkgs/development/compilers/ghc/D2713.patch b/pkgs/development/compilers/ghc/D2713.patch new file mode 100644 index 000000000000..80cf35a52974 --- /dev/null +++ b/pkgs/development/compilers/ghc/D2713.patch @@ -0,0 +1,17 @@ +diff --git a/configure.ac b/configure.ac +--- a/configure.ac ++++ b/configure.ac +@@ -437,7 +437,11 @@ + else + CrossCompilePrefix="" + fi +-TargetPlatformFull="${TargetPlatform}" ++# Despite its similarity in name to TargetPlatform, TargetPlatformFull is used ++# in calls to subproject configure scripts and thus must be set to the autoconf ++# triple, not the normalized GHC triple that TargetPlatform is set to. ++# It may be better to just do away with the GHC triples all together. ++TargetPlatformFull="${target}" + AC_SUBST(CrossCompiling) + AC_SUBST(CrossCompilePrefix) + AC_SUBST(TargetPlatformFull) + diff --git a/pkgs/development/compilers/ghc/ghc-HEAD-dont-pass-linker-flags-via-response-files.patch b/pkgs/development/compilers/ghc/ghc-HEAD-dont-pass-linker-flags-via-response-files.patch deleted file mode 100644 index ebbb9326a829..000000000000 --- a/pkgs/development/compilers/ghc/ghc-HEAD-dont-pass-linker-flags-via-response-files.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- ghc/compiler/main/SysTools.hs 2016-11-09 14:03:05.304528147 -0500 -+++ ghc2/compiler/main/SysTools.hs 2016-11-09 14:00:19.712934686 -0500 -@@ -421,7 +421,7 @@ - args1 = map Option (getOpts dflags opt_c) - args2 = args0 ++ args1 ++ args - mb_env <- getGccEnv args2 -- runSomethingResponseFile dflags cc_filter "C Compiler" p args2 mb_env -+ runSomethingFiltered dflags cc_filter "C Compiler" p args2 mb_env - where - -- discard some harmless warnings from gcc that we can't turn off - cc_filter = unlines . doFilter . lines -@@ -911,7 +911,7 @@ - args1 = map Option (getOpts dflags opt_l) - args2 = args0 ++ linkargs ++ args1 ++ args - mb_env <- getGccEnv args2 -- runSomethingResponseFile dflags ld_filter "Linker" p args2 mb_env -+ runSomethingFiltered dflags ld_filter "Linker" p args2 mb_env - where - ld_filter = case (platformOS (targetPlatform dflags)) of - OSSolaris2 -> sunos_ld_filter diff --git a/pkgs/development/compilers/ghc/head.nix b/pkgs/development/compilers/ghc/head.nix index d57b6e575da5..21f0eecc87f7 100644 --- a/pkgs/development/compilers/ghc/head.nix +++ b/pkgs/development/compilers/ghc/head.nix @@ -1,27 +1,35 @@ { stdenv, fetchgit, bootPkgs, perl, gmp, ncurses, libiconv, binutils, coreutils -, autoconf, automake, happy, alex +, autoconf, automake, happy, alex, cross ? null }: let inherit (bootPkgs) ghc; -in stdenv.mkDerivation rec { - version = "8.1.20161109"; + commonBuildInputs = [ ghc perl autoconf automake happy alex ]; + + version = "8.1.20161115"; + + commonPreConfigure = '' + sed -i -e 's|-isysroot /Developer/SDKs/MacOSX10.5.sdk||' configure + '' + stdenv.lib.optionalString (!stdenv.isDarwin) '' + export NIX_LDFLAGS="$NIX_LDFLAGS -rpath $out/lib/ghc-${version}" + '' + stdenv.lib.optionalString stdenv.isDarwin '' + export NIX_LDFLAGS+=" -no_dtrace_dof" + ''; +in stdenv.mkDerivation (rec { + inherit version; name = "ghc-${version}"; - rev = "2e8463b232054b788b73e6551947a9434aa76009"; + rev = "017d11e0a36866b05ace32ece1af11adf652a619"; src = fetchgit { url = "git://git.haskell.org/ghc.git"; inherit rev; - sha256 = "12nxai5qqnw42syhd0vzl2f9f8z28rc0fsa7g771dyzpqglak90l"; + sha256 = "091zpb9vqqy4jqh4q7sz04dh1yfdczaaikbxi5ppim01gzbxwn65"; }; - patches = [ - ./ghc-HEAD-dont-pass-linker-flags-via-response-files.patch # https://github.com/NixOS/nixpkgs/issues/10752 - ]; - postUnpack = '' - pushd ghc-${builtins.substring 0 7 rev} + chmod -R +w ghc + pushd ghc echo ${version} >VERSION echo ${rev} >GIT_COMMIT_ID patchShebangs . @@ -29,20 +37,14 @@ in stdenv.mkDerivation rec { popd ''; - buildInputs = [ ghc perl autoconf automake happy alex ]; + buildInputs = commonBuildInputs; enableParallelBuilding = true; - preConfigure = '' - sed -i -e 's|-isysroot /Developer/SDKs/MacOSX10.5.sdk||' configure - '' + stdenv.lib.optionalString (!stdenv.isDarwin) '' - export NIX_LDFLAGS="$NIX_LDFLAGS -rpath $out/lib/ghc-${version}" - '' + stdenv.lib.optionalString stdenv.isDarwin '' - export NIX_LDFLAGS+=" -no_dtrace_dof" - ''; + preConfigure = commonPreConfigure; configureFlags = [ - "--with-cc=${stdenv.cc}/bin/cc" + "CC=cc" "--with-gmp-includes=${gmp.dev}/include" "--with-gmp-libraries=${gmp.out}/lib" "--with-curses-includes=${ncurses.dev}/include" "--with-curses-libraries=${ncurses.out}/lib" ] ++ stdenv.lib.optional stdenv.isDarwin [ @@ -76,4 +78,22 @@ in stdenv.mkDerivation rec { inherit (ghc.meta) license platforms; }; -} +} // stdenv.lib.optionalAttrs (cross != null) { + name = "${cross.config}-ghc-${version}"; + + # Some fixes for cross-compilation to iOS. See https://phabricator.haskell.org/D2710 (D2711,D2712,D2713) + patches = [ ./D2710.patch ./D2711.patch ./D2712.patch ./D2713.patch ]; + + preConfigure = commonPreConfigure + '' + sed 's|#BuildFlavour = quick-cross|BuildFlavour = perf-cross|' mk/build.mk.sample > mk/build.mk + ''; + + configureFlags = [ + "CC=${cross.config}-cc" + "--target=${cross.config}" + ]; + + buildInputs = commonBuildInputs ++ [ stdenv.ccCross stdenv.binutilsCross ]; + + dontSetConfigureCross = true; +}) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index e376eb40d62c..3d74d74e18cb 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -4855,7 +4855,7 @@ in # Haskell and GHC - haskell = callPackage ./haskell-packages.nix { }; + haskell = callPackage ./haskell-packages.nix { inherit crossSystem; }; haskellPackages = haskell.packages.ghc801.override { overrides = config.haskellPackageOverrides or (self: super: {}); diff --git a/pkgs/top-level/haskell-packages.nix b/pkgs/top-level/haskell-packages.nix index f305c55dbfa5..a3867860799d 100644 --- a/pkgs/top-level/haskell-packages.nix +++ b/pkgs/top-level/haskell-packages.nix @@ -1,4 +1,4 @@ -{ pkgs, callPackage, stdenv }: +{ pkgs, callPackage, stdenv, crossSystem }: rec { @@ -50,6 +50,10 @@ rec { bootPkgs = packages.ghc7103; inherit (bootPkgs) alex happy; }; + # TODO: how should we support multiple versions of this? + ghcCross = compiler.ghcHEAD.override { + cross = crossSystem; + }; ghcNokinds = callPackage ../development/compilers/ghc/nokinds.nix rec { bootPkgs = packages.ghc784; inherit (bootPkgs) alex happy; @@ -121,6 +125,7 @@ rec { ghc = compiler.ghcHEAD; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-head.nix { }; }; + # TODO Support for ghcCross here ghcNokinds = callPackage ../development/haskell-modules { ghc = compiler.ghcNokinds; compilerConfig = callPackage ../development/haskell-modules/configuration-ghc-nokinds.nix { };