summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2012-01-30 11:19:03 +0000
committerSimon Marlow <marlowsd@gmail.com>2012-01-30 11:19:03 +0000
commit9fff25eaf08016c4c0e32a7087a1249d586550c0 (patch)
tree7a2f13260f24d610abea5cd8f8bf3a51d0787c54
parent4ff3a642fbb61cf329d468993e9f732940f9f680 (diff)
downloadhaskell-9fff25eaf08016c4c0e32a7087a1249d586550c0.tar.gz
Improve support for cross-compilation
Patchset from Stephen Blackheath <stephen.blackheath@ipwnstudios.com>
-rw-r--r--aclocal.m427
-rw-r--r--compiler/ghc.mk5
-rw-r--r--configure.ac93
-rw-r--r--ghc.mk43
-rw-r--r--ghc/ghc.mk8
-rw-r--r--includes/ghc.mk22
-rw-r--r--libffi/ghc.mk2
-rw-r--r--mk/config.mk.in49
-rw-r--r--rules/build-package-data.mk2
-rw-r--r--rules/build-package.mk2
-rw-r--r--rules/haddock.mk2
-rw-r--r--rules/shell-wrapper.mk2
-rw-r--r--utils/ghc-pkg/ghc.mk33
13 files changed, 224 insertions, 66 deletions
diff --git a/aclocal.m4 b/aclocal.m4
index 8318452913..14c9d4c4aa 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -526,7 +526,8 @@ AC_DEFUN([FP_EVAL_STDERR],
# XXX
#
# $1 = the variable to set
-# $2 = the command to look for
+# $2 = the with option name
+# $3 = the command to look for
#
AC_DEFUN([FP_ARG_WITH_PATH_GNU_PROG],
[
@@ -544,10 +545,14 @@ AC_ARG_WITH($2,
[
if test "$HostOS" != "mingw32"
then
- AC_PATH_PROG([$1], [$2])
+ if test "$target_alias" = "" ; then
+ AC_PATH_PROG([$1], [$3])
+ else
+ AC_PATH_PROG([$1], [$target_alias-$3])
+ fi
if test -z "$$1"
then
- AC_MSG_ERROR([cannot find $2 in your PATH, no idea how to link])
+ AC_MSG_ERROR([cannot find $3 in your PATH, no idea how to link])
fi
fi
]
@@ -635,7 +640,7 @@ AC_CHECK_TYPE([$1], [], [], [$3])[]dnl
m4_pushdef([fp_Cache], [AS_TR_SH([fp_cv_alignment_$1])])[]dnl
AC_CACHE_CHECK([alignment of $1], [fp_Cache],
[if test "$AS_TR_SH([ac_cv_type_$1])" = yes; then
- FP_COMPUTE_INT([(long) (&((struct { char c; $1 ty; } *)0)->ty)],
+ FP_COMPUTE_INT([offsetof(struct { char c; $1 ty; },ty)],
[fp_Cache],
[AC_INCLUDES_DEFAULT([$3])],
[AC_MSG_ERROR([cannot compute alignment ($1)
@@ -1575,6 +1580,7 @@ AC_SUBST([ProjectPatchLevel])
# timer_create() in certain versions of Linux (see bug #1933).
#
AC_DEFUN([FP_CHECK_TIMER_CREATE],
+if test "$cross_compiling" = "no" ; then
[AC_CACHE_CHECK([for a working timer_create(CLOCK_REALTIME)],
[fptools_cv_timer_create_works],
[AC_TRY_RUN([
@@ -1698,6 +1704,7 @@ case $fptools_cv_timer_create_works in
yes) AC_DEFINE([USE_TIMER_CREATE], 1,
[Define to 1 if we can use timer_create(CLOCK_PROCESS_CPUTIME_ID,...)]);;
esac
+fi
])
# FP_ICONV
@@ -1996,6 +2003,10 @@ AC_DEFUN([XCODE_VERSION],[
# FIND_GCC()
# --------------------------------
# Finds where gcc is
+#
+# $1 = the variable to set
+# $2 = the with option name
+# $3 = the command to look for
AC_DEFUN([FIND_GCC],[
if test "$TargetOS_CPP" = "darwin" &&
test "$XCodeVersion1" -eq 4 &&
@@ -2004,13 +2015,11 @@ AC_DEFUN([FIND_GCC],[
# In Xcode 4.1, 'gcc-4.2' is the gcc legacy backend (rather
# than the LLVM backend). We prefer the legacy gcc, but in
# Xcode 4.2 'gcc-4.2' was removed.
- FP_ARG_WITH_PATH_GNU_PROG([CC], [gcc-4.2])
+ FP_ARG_WITH_PATH_GNU_PROG([$1], [gcc-4.2], [gcc-4.2])
else
- FP_ARG_WITH_PATH_GNU_PROG([CC], [gcc])
+ FP_ARG_WITH_PATH_GNU_PROG([$1], [$2], [$3])
fi
- export CC
- WhatGccIsCalled="$CC"
- AC_SUBST(WhatGccIsCalled)
+ AC_SUBST($1)
])
# LocalWords: fi
diff --git a/compiler/ghc.mk b/compiler/ghc.mk
index 8790df361e..d5607ee60c 100644
--- a/compiler/ghc.mk
+++ b/compiler/ghc.mk
@@ -150,6 +150,10 @@ $(eval $(call clean-target,compiler,config_hs,compiler/main/Config.hs))
PLATFORM_H = ghc_boot_platform.h
+ifeq "$(BuildingCrossCompiler)" "YES"
+compiler/stage1/$(PLATFORM_H) : compiler/stage2/$(PLATFORM_H)
+ cp $< $@
+else
compiler/stage1/$(PLATFORM_H) : mk/config.mk mk/project.mk | $$(dir $$@)/.
$(call removeFiles,$@)
@echo "Creating $@..."
@@ -192,6 +196,7 @@ endif
@echo >> $@
@echo "#endif /* __PLATFORM_H__ */" >> $@
@echo "Done."
+endif
# For stage2 and above, the BUILD platform is the HOST of stage1, and
# the HOST platform is the TARGET of stage1. The TARGET remains the same
diff --git a/configure.ac b/configure.ac
index bf7e84895a..84f0849689 100644
--- a/configure.ac
+++ b/configure.ac
@@ -333,19 +333,75 @@ then
fi
AC_SUBST([SplitObjsBroken])
+dnl ** Building a cross compiler?
+dnl --------------------------------------------------------------
+BuildingCrossCompiler=NO
+PortingCompiler=NO
+CrossCompiling=NO
+# If 'host' and 'target' differ, then this means we are building a cross-compiler.
+if test "$host" != "$target" ; then
+ BuildingCrossCompiler=YES
+ CrossCompiling=YES
+ cross_compiling=yes # This tells configure that it can accept just 'target',
+ # otherwise you get
+ # configure: error: cannot run C compiled programs.
+ # If you meant to cross compile, use `--host'.
+fi
+if test "$build" != "$host" ; then
+ CrossCompiling=YES
+ PortingCompiler=YES
+fi
+# Note: cross_compiling is set to 'yes' in both 'port' and 'toolchain' cases
+if ! test "$host" == "$target" -o "$host" == "$build" ; then
+ AC_MSG_ERROR([
+You've selected:
+
+ build: $build (the architecture we're building on)
+ host: $host (the architecture the compiler we're building will execute on)
+ target: $target (the architecture the compiler we're building will produce code for)
+
+host must equal build or target. The two allowed cases are:
+
+ --host=<arch> --target=<arch> to _port_ GHC to run on a foreign architecture
+ and produce code for that architecture
+ --target=<arch> to build a cross compiler _toolchain_ that runs
+ locally but produces code for a foreign
+ architecture
+])
+fi
+if [[ "$CrossCompiling" == "YES" ]] ; then
+ CrossCompilePrefix="${target}-"
+else
+ CrossCompilePrefix=""
+fi
+TargetPlatformFull="${target}"
+AC_SUBST(BuildingCrossCompiler) # 'toolchain' case
+AC_SUBST(PortingCompiler) # 'port' case
+AC_SUBST(CrossCompiling) # BuildingCrossCompiler OR PortingCompiler
+AC_SUBST(CrossCompilePrefix)
+AC_SUBST(TargetPlatformFull)
+AC_ARG_WITH([alien],
+[AC_HELP_STRING([--with-alien=ARG],
+ [Supply script for running target binaries locally when cross-compiling])],
+ [AlienScript="$withval"],
+ [AlienScript=""])
+AC_SUBST(AlienScript)
+
dnl ** Which gcc to use?
dnl --------------------------------------------------------------
-FIND_GCC()
+FIND_GCC([WhatGccIsCalled], [gcc], [gcc])
+CC="$WhatGccIsCalled"
+export CC
dnl ** Which ld to use?
dnl --------------------------------------------------------------
-FP_ARG_WITH_PATH_GNU_PROG([LD], [ld])
+FP_ARG_WITH_PATH_GNU_PROG([LD], [ld], [ld])
LdCmd="$LD"
AC_SUBST([LdCmd])
dnl ** Which nm to use?
dnl --------------------------------------------------------------
-FP_ARG_WITH_PATH_GNU_PROG([NM], [nm])
+FP_ARG_WITH_PATH_GNU_PROG([NM], [nm], [nm])
NmCmd="$NM"
AC_SUBST([NmCmd])
@@ -642,17 +698,19 @@ dnl ** check for more functions
dnl ** The following have been verified to be used in ghc/, but might be used somewhere else, too.
AC_CHECK_FUNCS([getclock getrusage gettimeofday setitimer siginterrupt sysconf times ctime_r sched_setaffinity setlocale])
-AC_TRY_RUN([
-#include <sys/types.h>
-#include <sys/time.h>
-int main(void) {
- struct itimerval tval;
- tval.it_value.tv_sec = 1;
- tval.it_value.tv_usec = 0;
- tval.it_interval = tval.it_value;
- return setitimer(ITIMER_VIRTUAL, &tval, (void*)0) != 0;
-}
-],[AC_DEFINE([HAVE_SETITIMER_VIRTUAL], [1], [Define to 1 if setitimer accepts ITIMER_VIRTUAL, 0 else.])])
+if test "$cross_compiling" = "no" ; then
+ AC_TRY_RUN([
+ #include <sys/types.h>
+ #include <sys/time.h>
+ int main(void) {
+ struct itimerval tval;
+ tval.it_value.tv_sec = 1;
+ tval.it_value.tv_usec = 0;
+ tval.it_interval = tval.it_value;
+ return setitimer(ITIMER_VIRTUAL, &tval, (void*)0) != 0;
+ }
+ ],[AC_DEFINE([HAVE_SETITIMER_VIRTUAL], [1], [Define to 1 if setitimer accepts ITIMER_VIRTUAL, 0 else.])])
+fi
dnl ** On OS X 10.4 (at least), time.h doesn't declare ctime_r if
dnl ** _POSIX_C_SOURCE is defined
@@ -852,8 +910,11 @@ echo ["\
fi
echo ["\
- Using GCC : $WhatGccIsCalled
- which is version : $GccVersion
+ Using GCC : $WhatGccIsCalled
+ which is version : $GccVersion
+ Building a cross compiler : $BuildingCrossCompiler
+ Porting to foreign arch : $PortingCompiler
+ Alien script : $AlienScript
ld : $LdCmd
Happy : $HappyCmd ($HappyVersion)
diff --git a/ghc.mk b/ghc.mk
index 2ab85ec33a..fef5346838 100644
--- a/ghc.mk
+++ b/ghc.mk
@@ -380,7 +380,9 @@ endef
define addPackage # args: $1 = package, $2 = condition
ifneq "$(filter $1,$(PKGS_THAT_USE_TH)) $(GhcProfiled)" "$1 YES"
ifeq "$(filter $1,$(PKGS_THAT_BUILD_WITH_STAGE2))" "$1"
+ifneq "$(BuildingCrossCompiler)" "YES"
$(call addPackageGeneral,PACKAGES_STAGE2,$1,$2)
+endif
else
$(call addPackageGeneral,PACKAGES_STAGE1,$1,$2)
endif
@@ -574,9 +576,15 @@ BUILD_DIRS += \
$(GHC_GENPRIMOP_DIR)
endif
+ifeq "$(BuildingCrossCompiler)-$(phase)" "YES-final"
+MAYBE_GHCI=
+else
+MAYBE_GHCI=driver/ghci
+endif
+
BUILD_DIRS += \
driver \
- driver/ghci \
+ $(MAYBE_GHCI) \
driver/ghc \
driver/haddock \
libffi \
@@ -600,24 +608,38 @@ else ifneq "$(findstring clean,$(MAKECMDGOALS))" ""
BUILD_DIRS += libraries/integer-gmp/gmp
endif
+ifeq "$(BuildingCrossCompiler)-$(phase)" "YES-final"
+MAYBE_COMPILER=
+MAYBE_GHCTAGS=
+MAYBE_HPC=
+MAYBE_RUNGHC=
+else
+MAYBE_COMPILER=compiler
+MAYBE_GHCTAGS=utils/ghctags
+MAYBE_HPC=utils/hpc
+MAYBE_RUNGHC=utils/runghc
+endif
+
BUILD_DIRS += \
utils/haddock \
utils/haddock/doc \
- compiler \
+ $(MAYBE_COMPILER) \
$(GHC_HSC2HS_DIR) \
$(GHC_PKG_DIR) \
utils/testremove \
- utils/ghctags \
+ $(MAYBE_GHCTAGS) \
utils/ghc-pwd \
$(GHC_CABAL_DIR) \
- utils/hpc \
- utils/runghc \
+ $(MAYBE_HPC) \
+ $(MAYBE_RUNGHC) \
ghc
ifneq "$(BINDIST)" "YES"
+ifneq "$(BuildingCrossCompiler)-$(phase)" "YES-final"
BUILD_DIRS += \
utils/mkUserGuidePart
endif
+endif
BUILD_DIRS += utils/count_lines
BUILD_DIRS += utils/compare_sizes
@@ -810,7 +832,7 @@ else
done
# We rename ghc-stage2, so that the right program name is used in error
# messages etc.
- "$(MV)" "$(DESTDIR)$(ghclibexecdir)/ghc-stage2" "$(DESTDIR)$(ghclibexecdir)/ghc"
+ "$(MV)" "$(DESTDIR)$(ghclibexecdir)/ghc-stage$(INSTALL_GHC_STAGE)" "$(DESTDIR)$(ghclibexecdir)/ghc"
endif
install_topdirs: $(INSTALL_TOPDIRS)
@@ -855,9 +877,11 @@ INSTALLED_GHC_REAL=$(DESTDIR)$(bindir)/ghc.exe
INSTALLED_GHC_PKG_REAL=$(DESTDIR)$(bindir)/ghc-pkg.exe
endif
-INSTALLED_PKG_DIRS := $(addprefix libraries/,$(PACKAGES_STAGE1)) \
- compiler \
- $(addprefix libraries/,$(PACKAGES_STAGE2))
+INSTALLED_PKG_DIRS := $(addprefix libraries/,$(PACKAGES_STAGE1))
+ifeq "$(BuildingCrossCompiler)" "NO"
+INSTALLED_PKG_DIRS := $(INSTALLED_PKG_DIRS) compiler
+endif
+INSTALLED_PKG_DIRS := $(INSTALLED_PKG_DIRS) $(addprefix libraries/,$(PACKAGES_STAGE2))
ifeq "$(InstallExtraPackages)" "NO"
INSTALLED_PKG_DIRS := $(filter-out $(addprefix libraries/,$(EXTRA_PACKAGES)),\
$(INSTALLED_PKG_DIRS))
@@ -879,6 +903,7 @@ install_packages: rts/package.conf.install
"$(INSTALLED_GHC_PKG_REAL)" --force --global-conf "$(INSTALLED_PACKAGE_CONF)" update rts/package.conf.install
$(foreach p, $(INSTALLED_PKG_DIRS), \
$(call make-command, \
+ CROSS_COMPILE="$(CrossCompilePrefix)" \
"$(GHC_CABAL_INPLACE)" install \
"$(INSTALLED_GHC_REAL)" \
"$(INSTALLED_GHC_PKG_REAL)" \
diff --git a/ghc/ghc.mk b/ghc/ghc.mk
index 2af90bed28..022ee85a84 100644
--- a/ghc/ghc.mk
+++ b/ghc/ghc.mk
@@ -86,6 +86,10 @@ endif
ifneq "$(filter-out 2,$(stage))" ""
ghc_stage2_NOT_NEEDED = YES
endif
+# When cross-compiling, the stage 1 compiler is our release compiler, so omit stage 2
+ifeq "$(BuildingCrossCompiler)" "YES"
+ghc_stage2_NOT_NEEDED = YES
+endif
# stage 3 has to be requested explicitly with stage=3
ifneq "$(stage)" "3"
ghc_stage3_NOT_NEEDED = YES
@@ -147,7 +151,7 @@ install: install_ghc_link
.PNONY: install_ghc_link
install_ghc_link:
$(call removeFiles,"$(DESTDIR)$(bindir)/ghc")
- $(LN_S) ghc-$(ProjectVersion) "$(DESTDIR)$(bindir)/ghc"
+ $(LN_S) $(CrossCompilePrefix)ghc-$(ProjectVersion) "$(DESTDIR)$(bindir)/$(CrossCompilePrefix)ghc"
else
# On Windows we install the main binary as $(bindir)/ghc.exe
# To get ghc-<version>.exe we have a little C program in driver/ghc
@@ -155,6 +159,6 @@ install: install_ghc_post
.PHONY: install_ghc_post
install_ghc_post: install_bins
$(call removeFiles,$(DESTDIR)$(bindir)/ghc.exe)
- "$(MV)" -f $(DESTDIR)$(bindir)/ghc-stage$(INSTALL_GHC_STAGE).exe $(DESTDIR)$(bindir)/ghc.exe
+ "$(MV)" -f $(DESTDIR)$(bindir)/ghc-stage$(INSTALL_GHC_STAGE).exe $(DESTDIR)$(bindir)/$(CrossCompilePrefix)ghc.exe
endif
diff --git a/includes/ghc.mk b/includes/ghc.mk
index ef994f2329..74edf55b1c 100644
--- a/includes/ghc.mk
+++ b/includes/ghc.mk
@@ -129,7 +129,7 @@ endif
includes_DERIVEDCONSTANTS = includes/dist-derivedconstants/header/DerivedConstants.h
-ifeq "$(PORTING_HOST)" "YES"
+ifeq "$(PORTING_HOST)-$(AlienScript)" "YES-"
DerivedConstants.h :
@echo "*** Cross-compiling: please copy DerivedConstants.h from the target system"
@@ -145,9 +145,18 @@ $(eval $(call build-prog,includes,dist-derivedconstants,0))
$(includes_dist-derivedconstants_depfile_c_asm) : $(includes_H_CONFIG) $(includes_H_PLATFORM) $(includes_H_FILES) $$(rts_H_FILES)
includes/dist-derivedconstants/build/mkDerivedConstants.o : $(includes_H_CONFIG) $(includes_H_PLATFORM)
+ifneq "$(AlienScript)" ""
+$(INPLACE_BIN)/mkDerivedConstants$(exeext): includes/$(includes_dist-derivedconstants_C_SRCS) | $$(dir $$@)/.
+ $(WhatGccIsCalled) -o $@ $< $(CFLAGS) $(includes_CC_OPTS)
+endif
+
ifneq "$(BINDIST)" "YES"
$(includes_DERIVEDCONSTANTS) : $(INPLACE_BIN)/mkDerivedConstants$(exeext) | $$(dir $$@)/.
+ifeq "$(AlienScript)" ""
./$< >$@
+else
+ $(AlienScript) run ./$< >$@
+endif
endif
endif
@@ -157,7 +166,7 @@ endif
includes_GHCCONSTANTS = includes/dist-ghcconstants/header/GHCConstants.h
-ifeq "$(PORTING_HOST)" "YES"
+ifeq "$(PORTING_HOST)-$(AlienScript)" "YES-"
$(includes_GHCCONSTANTS) :
@echo "*** Cross-compiling: please copy DerivedConstants.h from the target system"
@@ -176,8 +185,17 @@ $(includes_dist-ghcconstants_depfile_c_asm) : $(includes_H_CONFIG) $(includes_H_
includes/dist-ghcconstants/build/mkDerivedConstants.o : $(includes_H_CONFIG) $(includes_H_PLATFORM)
+ifneq "$(AlienScript)" ""
+$(INPLACE_BIN)/mkGHCConstants$(exeext): includes/$(includes_dist-ghcconstants_C_SRCS) | $$(dir $$@)/.
+ $(WhatGccIsCalled) -o $@ $< $(CFLAGS) $(includes_CC_OPTS) $(includes_dist-ghcconstants_CC_OPTS)
+endif
+
$(includes_GHCCONSTANTS) : $(INPLACE_BIN)/mkGHCConstants$(exeext) | $$(dir $$@)/.
+ifeq "$(AlienScript)" ""
./$< >$@
+else
+ $(AlienScript) run ./$< >$@
+endif
endif
endif
diff --git a/libffi/ghc.mk b/libffi/ghc.mk
index d9224108b4..879d482da8 100644
--- a/libffi/ghc.mk
+++ b/libffi/ghc.mk
@@ -82,7 +82,7 @@ $(libffi_STAMP_CONFIGURE): $(TOUCH_DEP)
--prefix=$(TOP)/libffi/build/inst \
--enable-static=yes \
--enable-shared=$(libffi_EnableShared) \
- --host=$(HOSTPLATFORM) --build=$(BUILDPLATFORM)
+ --host=$(TargetPlatformFull)
# wc on OS X has spaces in its output, which libffi's Makefile
# doesn't expect, so we tweak it to sed them out
diff --git a/mk/config.mk.in b/mk/config.mk.in
index 58e22cb664..2b5bd46aba 100644
--- a/mk/config.mk.in
+++ b/mk/config.mk.in
@@ -139,7 +139,7 @@ PlatformSupportsSharedLibs = $(if $(filter $(TARGETPLATFORM),\
# the compiler you build with is generating registerised binaries), but
# the stage2 compiler will be an unregisterised binary.
#
-ifneq "$(findstring $(HostArch_CPP), i386 x86_64 powerpc arm)" ""
+ifneq "$(findstring $(TargetArch_CPP), i386 x86_64 powerpc arm)" ""
GhcUnregisterised=NO
else
GhcUnregisterised=YES
@@ -151,8 +151,8 @@ endif
# Target platforms supported:
# i386, powerpc
# AIX is not supported
-ArchSupportsNCG=$(strip $(patsubst $(HostArch_CPP), YES, $(findstring $(HostArch_CPP), i386 x86_64 powerpc sparc)))
-OsSupportsNCG=$(strip $(patsubst $(HostOS_CPP), YES, $(patsubst aix,,$(HostOS_CPP))))
+ArchSupportsNCG=$(strip $(patsubst $(TargetArch_CPP), YES, $(findstring $(TargetArch_CPP), i386 x86_64 powerpc sparc)))
+OsSupportsNCG=$(strip $(patsubst $(TargetOS_CPP), YES, $(patsubst aix,,$(TargetOS_CPP))))
# lazy test, because $(GhcUnregisterised) might be set in build.mk later.
GhcWithNativeCodeGen=$(strip\
@@ -163,7 +163,7 @@ HaveLibDL = @HaveLibDL@
# ArchSupportsSMP should be set iff there is support for that arch in
# includes/stg/SMP.h
-ArchSupportsSMP=$(strip $(patsubst $(HostArch_CPP), YES, $(findstring $(HostArch_CPP), i386 x86_64 sparc powerpc arm)))
+ArchSupportsSMP=$(strip $(patsubst $(TargetArch_CPP), YES, $(findstring $(TargetArch_CPP), i386 x86_64 sparc powerpc arm)))
# lazy test, because $(GhcUnregisterised) might be set in build.mk later.
GhcWithSMP=$(strip $(if $(filter YESNO, $(ArchSupportsSMP)$(GhcUnregisterised)),YES,NO))
@@ -171,8 +171,8 @@ GhcWithSMP=$(strip $(if $(filter YESNO, $(ArchSupportsSMP)$(GhcUnregisterised)),
# Whether to include GHCi in the compiler. Depends on whether the RTS linker
# has support for this OS/ARCH combination.
-OsSupportsGHCi=$(strip $(patsubst $(HostOS_CPP), YES, $(findstring $(HostOS_CPP), mingw32 cygwin32 linux solaris2 freebsd dragonfly netbsd openbsd darwin kfreebsdgnu)))
-ArchSupportsGHCi=$(strip $(patsubst $(HostArch_CPP), YES, $(findstring $(HostArch_CPP), i386 x86_64 powerpc sparc sparc64)))
+OsSupportsGHCi=$(strip $(patsubst $(TargetOS_CPP), YES, $(findstring $(TargetOS_CPP), mingw32 cygwin32 linux solaris2 freebsd dragonfly netbsd openbsd darwin kfreebsdgnu)))
+ArchSupportsGHCi=$(strip $(patsubst $(TargetArch_CPP), YES, $(findstring $(TargetArch_CPP), i386 x86_64 powerpc sparc sparc64)))
ifeq "$(OsSupportsGHCi)$(ArchSupportsGHCi)" "YESYES"
GhcWithInterpreter=YES
@@ -194,7 +194,7 @@ endif
# Whether to use libffi for adjustors (foreign import "wrapper") or
# not. If we have built-in support (rts/Adjustor.c) then we use that,
# otherwise we fall back on libffi, which is slightly slower.
-ArchHasAdjustorSupport = $(if $(findstring $(HostArch_CPP),i386 x86_64),YES,NO)
+ArchHasAdjustorSupport = $(if $(findstring $(TargetArch_CPP),i386 x86_64),YES,NO)
ifeq "$(ArchHasAdjustorSupport)" "YES"
UseLibFFIForAdjustors=NO
else
@@ -515,9 +515,6 @@ GHC_STAGE1 = $(INPLACE_BIN)/ghc-stage1$(exeext)
GHC_STAGE2 = $(INPLACE_BIN)/ghc-stage2$(exeext)
GHC_STAGE3 = $(INPLACE_BIN)/ghc-stage3$(exeext)
-# Install stage 2 by default, can be changed to 3
-INSTALL_GHC_STAGE=2
-
BOOTSTRAPPING_CONF = libraries/bootstrapping.conf
INPLACE_PACKAGE_CONF = $(INPLACE_LIB)/package.conf.d
@@ -553,8 +550,17 @@ endif
# the flag --with-gcc=<blah> instead. The reason is that the configure script
# needs to know which gcc you're using in order to perform its tests.
-WhatGccIsCalled = @WhatGccIsCalled@
-GccVersion = @GccVersion@
+WhatGccIsCalled = @WhatGccIsCalled@
+GccVersion = @GccVersion@
+AlienScript = @AlienScript@
+ifeq "$(phase)" "0"
+CrossCompilePrefix =
+else
+CrossCompilePrefix = @CrossCompilePrefix@
+endif
+# TargetPlatformFull retains the string passed to configure so we have it in
+# the necessary format to pass to libffi's configure.
+TargetPlatformFull = @TargetPlatformFull@
GccLT34 = @GccLT34@
GccLT46 = @GccLT46@
CC = $(WhatGccIsCalled)
@@ -568,6 +574,22 @@ AS_STAGE1 = $(AS)
AS_STAGE2 = $(AS)
AS_STAGE3 = $(AS)
+# Cross-compiling options
+#
+# The 'toolchain' case: Cross-compiler to run locally:
+BuildingCrossCompiler = @BuildingCrossCompiler@
+# The 'port' case: Porting to a foreign architecture:
+PortingCompiler = @PortingCompiler@
+# BuildingCrossCompiler OR PortingCompiler
+CrossCompiling = @CrossCompiling@
+
+# Install stage 2 by default, or stage 1 in the cross compiler case. Can be changed to 3
+ifeq "$(BuildingCrossCompiler)" "YES"
+INSTALL_GHC_STAGE=1
+else
+INSTALL_GHC_STAGE=2
+endif
+
# C compiler and linker flags from configure (e.g. -m<blah> to select
# correct C compiler backend). The stage number is the stage of GHC
# that is being used to compile with.
@@ -596,6 +618,9 @@ SRC_HSC2HS_OPTS += --cross-safe
endif
SRC_HSC2HS_OPTS += $(addprefix --cflag=,$(filter-out -O,$(SRC_CC_OPTS) $(CONF_CC_OPTS_STAGE0)))
SRC_HSC2HS_OPTS += $(foreach d,$(GMP_INCLUDE_DIRS),-I$(d))
+ifeq "$(CrossCompiling)" "YES"
+SRC_HSC2HS_OPTS += --cross-compile
+endif
#-----------------------------------------------------------------------------
# Mingwex Library
diff --git a/rules/build-package-data.mk b/rules/build-package-data.mk
index fd267b0347..d535e34cbe 100644
--- a/rules/build-package-data.mk
+++ b/rules/build-package-data.mk
@@ -79,7 +79,7 @@ $1/$2/build/autogen/cabal_macros.h : $1/$2/package-data.mk
# for our build system, and registers the package for use in-place in
# the build tree.
$1/$2/package-data.mk : $$(GHC_CABAL_INPLACE) $$($1_$2_GHC_PKG_DEP) $1/$$($1_PACKAGE).cabal $$(wildcard $1/configure) $$(LAX_DEPS_FOLLOW) $$($1_$2_HC_CONFIG_DEP)
- "$$(GHC_CABAL_INPLACE)" configure --with-ghc="$$($1_$2_HC_CONFIG)" --with-ghc-pkg="$$($1_$2_GHC_PKG)" $$($1_CONFIGURE_OPTS) $$($1_$2_CONFIGURE_OPTS) -- $2 $1
+ CROSS_COMPILE="$(CrossCompilePrefix)" "$$(GHC_CABAL_INPLACE)" configure --with-ghc="$$($1_$2_HC_CONFIG)" --with-ghc-pkg="$$($1_$2_GHC_PKG)" $$($1_CONFIGURE_OPTS) $$($1_$2_CONFIGURE_OPTS) -- $2 $1
ifeq "$$($1_$2_PROG)" ""
ifneq "$$($1_$2_REGISTER_PACKAGE)" "NO"
"$$($1_$2_GHC_PKG)" update --force $$($1_$2_GHC_PKG_OPTS) $1/$2/inplace-pkg-config
diff --git a/rules/build-package.mk b/rules/build-package.mk
index d83a79d89d..ccd1659c30 100644
--- a/rules/build-package.mk
+++ b/rules/build-package.mk
@@ -133,7 +133,7 @@ CHECKED_$1 = YES
check_packages: check_$1
.PHONY: check_$1
check_$1: $$(GHC_CABAL_INPLACE)
- $$(GHC_CABAL_INPLACE) check $1
+ CROSS_COMPILE="$(CrossCompilePrefix)" $$(GHC_CABAL_INPLACE) check $1
endif
ifneq "$3" "0"
diff --git a/rules/haddock.mk b/rules/haddock.mk
index ff922ae978..0fc2043d67 100644
--- a/rules/haddock.mk
+++ b/rules/haddock.mk
@@ -42,7 +42,7 @@ endif
ifneq "$$(BINDIST)" "YES"
$$($$($1_PACKAGE)-$$($1_$2_VERSION)_HADDOCK_FILE) : $$(INPLACE_BIN)/haddock$$(exeext) $$(GHC_CABAL_INPLACE) $$($1_$2_HS_SRCS) $$($$($1_PACKAGE)-$$($1_$2_VERSION)_HADDOCK_DEPS) | $$$$(dir $$$$@)/.
ifeq "$$(HSCOLOUR_SRCS)" "YES"
- "$$(GHC_CABAL_INPLACE)" hscolour $2 $1
+ CROSS_COMPILE="$(CrossCompilePrefix)" "$$(GHC_CABAL_INPLACE)" hscolour $2 $1
endif
"$$(TOP)/$$(INPLACE_BIN)/haddock" \
--odir="$1/$2/doc/html/$$($1_PACKAGE)" \
diff --git a/rules/shell-wrapper.mk b/rules/shell-wrapper.mk
index 2376db137f..a291d852fe 100644
--- a/rules/shell-wrapper.mk
+++ b/rules/shell-wrapper.mk
@@ -62,7 +62,7 @@ BINDIST_WRAPPERS += $$($1_$2_SHELL_WRAPPER_NAME)
install: install_$1_$2_wrapper
.PHONY: install_$1_$2_wrapper
-install_$1_$2_wrapper: WRAPPER=$$(DESTDIR)$$(bindir)/$$($1_$2_INSTALL_SHELL_WRAPPER_NAME)
+install_$1_$2_wrapper: WRAPPER=$$(DESTDIR)$$(bindir)/$(CrossCompilePrefix)$$($1_$2_INSTALL_SHELL_WRAPPER_NAME)
install_$1_$2_wrapper:
$$(call INSTALL_DIR,"$$(DESTDIR)$$(bindir)")
$$(call removeFiles, "$$(WRAPPER)")
diff --git a/utils/ghc-pkg/ghc.mk b/utils/ghc-pkg/ghc.mk
index b6e762530a..b4302cc8e0 100644
--- a/utils/ghc-pkg/ghc.mk
+++ b/utils/ghc-pkg/ghc.mk
@@ -30,7 +30,7 @@ endif
else
-$(GHC_PKG_INPLACE) : utils/ghc-pkg/dist/build/$(utils/ghc-pkg_dist_PROG)$(exeext) | $$(dir $$@)/. $(INPLACE_PACKAGE_CONF)/.
+$(GHC_PKG_INPLACE) : utils/ghc-pkg/dist/build/tmp/$(utils/ghc-pkg_dist_PROG)$(exeext) | $$(dir $$@)/. $(INPLACE_PACKAGE_CONF)/.
$(call removeFiles,$(wildcard $(INPLACE_PACKAGE_CONF)/*))
ifeq "$(Windows)" "YES"
cp $< $@
@@ -51,7 +51,7 @@ endif
#
# ToDo: we might want to do this using ghc-cabal instead.
#
-utils/ghc-pkg/dist/build/$(utils/ghc-pkg_dist_PROG)$(exeext): utils/ghc-pkg/Main.hs utils/ghc-pkg/Version.hs | bootstrapping/. $$(dir $$@)/. $(GHC_CABAL_INPLACE)
+utils/ghc-pkg/dist/build/tmp/$(utils/ghc-pkg_dist_PROG)$(exeext): utils/ghc-pkg/Main.hs utils/ghc-pkg/Version.hs | bootstrapping/. $$(dir $$@)/. $(GHC_CABAL_INPLACE)
"$(GHC)" $(SRC_HC_OPTS) --make utils/ghc-pkg/Main.hs -o $@ \
-no-user-package-conf \
-Wall -fno-warn-unused-imports -fno-warn-warnings-deprecations \
@@ -82,30 +82,41 @@ $(eval $(call clean-target,utils/ghc-pkg,dist,\
utils/ghc-pkg/Version.hs))
# -----------------------------------------------------------------------------
-# Building ghc-pkg with stage 1
+# Cross-compile case: Install our dist version
+# Normal case: Build ghc-pkg with stage 1
-utils/ghc-pkg_dist-install_USES_CABAL = YES
+ifeq "$(BuildingCrossCompiler)" "YES"
+GHC_PKG_DISTDIR=dist
+else
+GHC_PKG_DISTDIR=dist-install
+endif
+
+utils/ghc-pkg_$(GHC_PKG_DISTDIR)_USES_CABAL = YES
utils/ghc-pkg_PACKAGE = ghc-pkg
-utils/ghc-pkg_dist-install_PROG = ghc-pkg
-utils/ghc-pkg_dist-install_SHELL_WRAPPER = YES
-utils/ghc-pkg_dist-install_INSTALL_SHELL_WRAPPER = YES
-utils/ghc-pkg_dist-install_INSTALL_SHELL_WRAPPER_NAME = ghc-pkg-$(ProjectVersion)
-utils/ghc-pkg_dist-install_INSTALL_INPLACE = NO
+utils/ghc-pkg_$(GHC_PKG_DISTDIR)_PROG = ghc-pkg
+utils/ghc-pkg_$(GHC_PKG_DISTDIR)_SHELL_WRAPPER = YES
+utils/ghc-pkg_$(GHC_PKG_DISTDIR)_INSTALL_SHELL_WRAPPER = YES
+utils/ghc-pkg_$(GHC_PKG_DISTDIR)_INSTALL_SHELL_WRAPPER_NAME = ghc-pkg-$(ProjectVersion)
+utils/ghc-pkg_$(GHC_PKG_DISTDIR)_INSTALL_INPLACE = NO
ifeq "$(BootingFromHc)" "YES"
utils/ghc-pkg_dist-install_OTHER_OBJS += $(ALL_STAGE1_LIBS) $(ALL_STAGE1_LIBS) $(ALL_STAGE1_LIBS) $(ALL_RTS_LIBS) $(libffi_STATIC_LIB)
endif
+ifeq "$(BuildingCrossCompiler)" "YES"
+$(eval $(call shell-wrapper,utils/ghc-pkg,dist))
+else
$(eval $(call build-prog,utils/ghc-pkg,dist-install,1))
+endif
ifeq "$(Windows)" "NO"
install: install_utils/ghc-pkg_link
-.PNONY: install_utils/ghc-pkg_link
+.PHONY: install_utils/ghc-pkg_link
install_utils/ghc-pkg_link:
$(call INSTALL_DIR,"$(DESTDIR)$(bindir)")
$(call removeFiles,"$(DESTDIR)$(bindir)/ghc-pkg")
- $(LN_S) ghc-pkg-$(ProjectVersion) "$(DESTDIR)$(bindir)/ghc-pkg"
+ $(LN_S) $(CrossCompilePrefix)ghc-pkg-$(ProjectVersion) "$(DESTDIR)$(bindir)/$(CrossCompilePrefix)ghc-pkg"
endif