Commit 109a1e53 authored by Simon Marlow's avatar Simon Marlow

Tidy up cross-compiling

We have two cases:
 1. building a cross-compiler
 2. compiling GHC to run on a foreign platform

These two are done with almost the same setup: (1) is the stage 1
compiler, and (2) is the stage 2 compiler, when CrossCompiling=YES.

The only difference between (1) and (2) is that you if you set up the
build for (1), then it stops before stage 2 and you can 'make install'
to install stage 1.

Unfortunately, (2) didn't work, and the build system code needed some
tidying up.

Change to the way the build is set up:

Before
------

To build a cross-compiler:
  ./configure --target=<..>

To compile a foreign GHC:
  ./configure --host=<..> --target=<..>

Now
---

To build a cross-compiler:
  ./configure --target=<..>
  And set "Stage1Only=YES" in mk/build.mk

To compile a foreign GHC:
  ./configure --target=<..>
parent 900e7d25
......@@ -61,18 +61,25 @@ AC_DEFUN([FPTOOLS_SET_PLATFORM_VARS],
if test "$target_alias" = ""
then
if test "$bootstrap_target" != ""
if test "$host_alias" != ""
then
target=$bootstrap_target
echo "Target platform inferred as: $target"
GHC_CONVERT_CPU([$host_cpu], [TargetArch])
GHC_CONVERT_VENDOR([$host_vendor], [TargetVendor])
GHC_CONVERT_OS([$host_os], [TargetOS])
else
echo "Can't work out target platform"
exit 1
if test "$bootstrap_target" != ""
then
target=$bootstrap_target
echo "Target platform inferred as: $target"
else
echo "Can't work out target platform"
exit 1
fi
TargetArch=`echo "$target" | sed 's/-.*//'`
TargetVendor=`echo "$target" | sed -e 's/.*-\(.*\)-.*/\1/'`
TargetOS=`echo "$target" | sed 's/.*-//'`
fi
TargetArch=`echo "$target" | sed 's/-.*//'`
TargetVendor=`echo "$target" | sed -e 's/.*-\(.*\)-.*/\1/'`
TargetOS=`echo "$target" | sed 's/.*-//'`
else
GHC_CONVERT_CPU([$target_cpu], [TargetArch])
GHC_CONVERT_VENDOR([$target_vendor], [TargetVendor])
......@@ -377,6 +384,7 @@ AC_DEFUN([FP_SETTINGS],
then
mingw_bin_prefix=mingw/bin/
SettingsCCompilerCommand="\$topdir/../${mingw_bin_prefix}gcc.exe"
SettingsLdCommand="\$topdir/../${mingw_bin_prefix}ld.exe"
SettingsArCommand="\$topdir/../${mingw_bin_prefix}ar.exe"
SettingsPerlCommand='$topdir/../perl/perl.exe'
SettingsDllWrapCommand="\$topdir/../${mingw_bin_prefix}dllwrap.exe"
......@@ -384,6 +392,7 @@ AC_DEFUN([FP_SETTINGS],
SettingsTouchCommand='$topdir/touchy.exe'
else
SettingsCCompilerCommand="$WhatGccIsCalled"
SettingsLdCommand="$LdCmd"
SettingsArCommand="$ArCmd"
SettingsPerlCommand="$PerlCmd"
SettingsDllWrapCommand="/bin/false"
......@@ -406,6 +415,7 @@ AC_DEFUN([FP_SETTINGS],
SettingsLdFlags="$CONF_LD_LINKER_OPTS_STAGE2"
AC_SUBST(SettingsCCompilerCommand)
AC_SUBST(SettingsCCompilerFlags)
AC_SUBST(SettingsLdCommand)
AC_SUBST(SettingsLdFlags)
AC_SUBST(SettingsArCommand)
AC_SUBST(SettingsPerlCommand)
......
......@@ -130,53 +130,48 @@ endif
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 $@..."
@echo "#ifndef __PLATFORM_H__" >> $@
@echo "#define __PLATFORM_H__" >> $@
@echo >> $@
@echo "#define BuildPlatform_NAME \"$(BUILDPLATFORM)\"" >> $@
@echo "#define HostPlatform_NAME \"$(BUILDPLATFORM)\"" >> $@
@echo "#define TargetPlatform_NAME \"$(HOSTPLATFORM)\"" >> $@
@echo >> $@
@echo "#define $(BuildPlatform_CPP)_BUILD 1" >> $@
@echo "#define $(BuildPlatform_CPP)_HOST 1" >> $@
@echo "#define $(HostPlatform_CPP)_TARGET 1" >> $@
@echo >> $@
@echo "#define $(BuildArch_CPP)_BUILD_ARCH 1" >> $@
@echo "#define $(BuildArch_CPP)_HOST_ARCH 1" >> $@
@echo "#define $(HostArch_CPP)_TARGET_ARCH 1" >> $@
@echo "#define BUILD_ARCH \"$(BuildArch_CPP)\"" >> $@
@echo "#define HOST_ARCH \"$(BuildArch_CPP)\"" >> $@
@echo "#define TARGET_ARCH \"$(HostArch_CPP)\"" >> $@
@echo >> $@
@echo "#define $(BuildOS_CPP)_BUILD_OS 1" >> $@
@echo "#define $(BuildOS_CPP)_HOST_OS 1" >> $@
@echo "#define $(HostOS_CPP)_TARGET_OS 1" >> $@
@echo "#define BUILD_OS \"$(BuildOS_CPP)\"" >> $@
@echo "#define HOST_OS \"$(BuildOS_CPP)\"" >> $@
@echo "#define TARGET_OS \"$(HostOS_CPP)\"" >> $@
ifeq "$(HostOS_CPP)" "irix"
@echo "#ifndef $(IRIX_MAJOR)_TARGET_OS" >> $@
@echo "#define $(IRIX_MAJOR)_TARGET_OS 1" >> $@
@echo "#endif" >> $@
@echo "#define BuildPlatform_NAME \"$(BUILDPLATFORM)\"" >> $@
@echo "#define HostPlatform_NAME \"$(HOSTPLATFORM)\"" >> $@
@echo "#define TargetPlatform_NAME \"$(TARGETPLATFORM)\"" >> $@
@echo >> $@
@echo "#define $(BuildPlatform_CPP)_BUILD 1" >> $@
@echo "#define $(HostPlatform_CPP)_HOST 1" >> $@
@echo "#define $(TargetPlatform_CPP)_TARGET 1" >> $@
@echo >> $@
@echo "#define $(BuildArch_CPP)_BUILD_ARCH 1" >> $@
@echo "#define $(HostArch_CPP)_HOST_ARCH 1" >> $@
@echo "#define $(TargetArch_CPP)_TARGET_ARCH 1" >> $@
@echo "#define BUILD_ARCH \"$(BuildArch_CPP)\"" >> $@
@echo "#define HOST_ARCH \"$(HostArch_CPP)\"" >> $@
@echo "#define TARGET_ARCH \"$(TargetArch_CPP)\"" >> $@
@echo >> $@
@echo "#define $(BuildOS_CPP)_BUILD_OS 1" >> $@
@echo "#define $(HostOS_CPP)_HOST_OS 1" >> $@
@echo "#define $(TargetOS_CPP)_TARGET_OS 1" >> $@
@echo "#define BUILD_OS \"$(BuildOS_CPP)\"" >> $@
@echo "#define HOST_OS \"$(HostOS_CPP)\"" >> $@
@echo "#define TARGET_OS \"$(TargetOS_CPP)\"" >> $@
ifeq "$(TargetOS_CPP)" "irix"
@echo "#ifndef $(IRIX_MAJOR)_TARGET_OS" >> $@
@echo "#define $(IRIX_MAJOR)_TARGET_OS 1" >> $@
@echo "#endif" >> $@
endif
@echo >> $@
@echo "#define $(BuildVendor_CPP)_BUILD_VENDOR 1" >> $@
@echo "#define $(BuildVendor_CPP)_HOST_VENDOR 1" >> $@
@echo "#define $(HostVendor_CPP)_TARGET_VENDOR 1" >> $@
@echo "#define BUILD_VENDOR \"$(BuildVendor_CPP)\"" >> $@
@echo "#define HOST_VENDOR \"$(BuildVendor_CPP)\"" >> $@
@echo "#define TARGET_VENDOR \"$(HostVendor_CPP)\"" >> $@
@echo >> $@
@echo "#endif /* __PLATFORM_H__ */" >> $@
@echo >> $@
@echo "#define $(BuildVendor_CPP)_BUILD_VENDOR 1" >> $@
@echo "#define $(HostVendor_CPP)_HOST_VENDOR 1" >> $@
@echo "#define $(TargetVendor_CPP)_TARGET_VENDOR 1" >> $@
@echo "#define BUILD_VENDOR \"$(BuildVendor_CPP)\"" >> $@
@echo "#define HOST_VENDOR \"$(HostVendor_CPP)\"" >> $@
@echo "#define TARGET_VENDOR \"$(TargetVendor_CPP)\"" >> $@
@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
......@@ -187,26 +182,26 @@ compiler/stage2/$(PLATFORM_H) : mk/config.mk mk/project.mk | $$(dir $$@)/.
@echo "#ifndef __PLATFORM_H__" >> $@
@echo "#define __PLATFORM_H__" >> $@
@echo >> $@
@echo "#define BuildPlatform_NAME \"$(BUILDPLATFORM)\"" >> $@
@echo "#define HostPlatform_NAME \"$(HOSTPLATFORM)\"" >> $@
@echo "#define BuildPlatform_NAME \"$(HOSTPLATFORM)\"" >> $@
@echo "#define HostPlatform_NAME \"$(TARGETPLATFORM)\"" >> $@
@echo "#define TargetPlatform_NAME \"$(TARGETPLATFORM)\"" >> $@
@echo >> $@
@echo "#define $(BuildPlatform_CPP)_BUILD 1" >> $@
@echo "#define $(HostPlatform_CPP)_HOST 1" >> $@
@echo "#define $(HostPlatform_CPP)_BUILD 1" >> $@
@echo "#define $(TargetPlatform_CPP)_HOST 1" >> $@
@echo "#define $(TargetPlatform_CPP)_TARGET 1" >> $@
@echo >> $@
@echo "#define $(BuildArch_CPP)_BUILD_ARCH 1" >> $@
@echo "#define $(HostArch_CPP)_HOST_ARCH 1" >> $@
@echo "#define $(HostArch_CPP)_BUILD_ARCH 1" >> $@
@echo "#define $(TargetArch_CPP)_HOST_ARCH 1" >> $@
@echo "#define $(TargetArch_CPP)_TARGET_ARCH 1" >> $@
@echo "#define BUILD_ARCH \"$(HostArch_CPP)\"" >> $@
@echo "#define HOST_ARCH \"$(HostArch_CPP)\"" >> $@
@echo "#define HOST_ARCH \"$(TargetArch_CPP)\"" >> $@
@echo "#define TARGET_ARCH \"$(TargetArch_CPP)\"" >> $@
@echo >> $@
@echo "#define $(HostOS_CPP)_BUILD_OS 1" >> $@
@echo "#define $(HostOS_CPP)_HOST_OS 1" >> $@
@echo "#define $(TargetOS_CPP)_HOST_OS 1" >> $@
@echo "#define $(TargetOS_CPP)_TARGET_OS 1" >> $@
@echo "#define BUILD_OS \"$(HostOS_CPP)\"" >> $@
@echo "#define HOST_OS \"$(HostOS_CPP)\"" >> $@
@echo "#define HOST_OS \"$(TargetOS_CPP)\"" >> $@
@echo "#define TARGET_OS \"$(TargetOS_CPP)\"" >> $@
ifeq "$(TargetOS_CPP)" "irix"
@echo "#ifndef $(IRIX_MAJOR)_TARGET_OS" >> $@
......@@ -214,11 +209,11 @@ ifeq "$(TargetOS_CPP)" "irix"
@echo "#endif" >> $@
endif
@echo >> $@
@echo "#define $(BuildVendor_CPP)_BUILD_VENDOR 1" >> $@
@echo "#define $(HostVendor_CPP)_HOST_VENDOR 1" >> $@
@echo "#define $(HostVendor_CPP)_BUILD_VENDOR 1" >> $@
@echo "#define $(TargetVendor_CPP)_HOST_VENDOR 1" >> $@
@echo "#define $(TargetVendor_CPP)_TARGET_VENDOR 1" >> $@
@echo "#define BUILD_VENDOR \"$(BuildVendor_CPP)\"" >> $@
@echo "#define HOST_VENDOR \"$(HostVendor_CPP)\"" >> $@
@echo "#define BUILD_VENDOR \"$(HostVendor_CPP)\"" >> $@
@echo "#define HOST_VENDOR \"$(TargetVendor_CPP)\"" >> $@
@echo "#define TARGET_VENDOR \"$(TargetVendor_CPP)\"" >> $@
@echo >> $@
@echo "#endif /* __PLATFORM_H__ */" >> $@
......
......@@ -210,7 +210,6 @@ AC_CANONICAL_TARGET
# Testing ARM ABI
# required for code generation (LLVM options)
ARM_ABI=SOFT
echo HOST: $host
case $host in
arm*-*-linux-gnueabihf)
......@@ -451,12 +450,9 @@ 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
if test "$target" != "$host" ; then
CrossCompiling=YES
cross_compiling=yes # This tells configure that it can accept just 'target',
# otherwise you get
......@@ -464,25 +460,17 @@ if test "$host" != "$target" ; then
# 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:
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=<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
BUILD must equal HOST; that is, we do not support building GHC itself
with a cross-compiler. To cross-compile GHC itself, set TARGET: stage
1 will be a cross-compiler, and stage 2 will be the cross-compiled
GHC.
])
fi
if test "$CrossCompiling" = "YES"
......@@ -492,9 +480,7 @@ else
CrossCompilePrefix=""
fi
TargetPlatformFull="${target}"
AC_SUBST(BuildingCrossCompiler) # 'toolchain' case
AC_SUBST(PortingCompiler) # 'port' case
AC_SUBST(CrossCompiling) # BuildingCrossCompiler OR PortingCompiler
AC_SUBST(CrossCompiling)
AC_SUBST(CrossCompilePrefix)
AC_SUBST(TargetPlatformFull)
AC_ARG_WITH([alien],
......@@ -1019,8 +1005,7 @@ fi
echo ["\
Using GCC : $WhatGccIsCalled
which is version : $GccVersion
Building a cross compiler : $BuildingCrossCompiler
Porting to foreign arch : $PortingCompiler
Building a cross compiler : $CrossCompiling
Alien script : $AlienScript
ld : $LdCmd
......
......@@ -397,7 +397,7 @@ 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"
ifneq "$(Stage1Only)" "YES"
$(call addPackageGeneral,PACKAGES_STAGE2,$1,$2)
endif
else
......@@ -608,7 +608,7 @@ BUILD_DIRS += \
$(GHC_GENPRIMOP_DIR)
endif
ifeq "$(BuildingCrossCompiler)-$(phase)" "YES-final"
ifeq "$(Stage1Only)-$(phase)" "YES-final"
MAYBE_GHCI=
else
MAYBE_GHCI=driver/ghci
......@@ -640,7 +640,7 @@ else ifneq "$(findstring clean,$(MAKECMDGOALS))" ""
BUILD_DIRS += libraries/integer-gmp/gmp
endif
ifeq "$(BuildingCrossCompiler)-$(phase)" "YES-final"
ifeq "$(Stage1Only)-$(phase)" "YES-final"
MAYBE_COMPILER=
MAYBE_GHCTAGS=
MAYBE_HPC=
......@@ -668,7 +668,7 @@ BUILD_DIRS += \
ghc
ifneq "$(BINDIST)" "YES"
ifneq "$(BuildingCrossCompiler)-$(phase)" "YES-final"
ifneq "$(Stage1Only)-$(phase)" "YES-final"
BUILD_DIRS += \
utils/mkUserGuidePart
endif
......@@ -911,7 +911,7 @@ INSTALLED_GHC_PKG_REAL=$(DESTDIR)$(bindir)/ghc-pkg.exe
endif
INSTALLED_PKG_DIRS := $(addprefix libraries/,$(PACKAGES_STAGE1))
ifeq "$(BuildingCrossCompiler)" "NO"
ifeq "$(Stage1Only)" "NO"
INSTALLED_PKG_DIRS := $(INSTALLED_PKG_DIRS) compiler
endif
INSTALLED_PKG_DIRS := $(INSTALLED_PKG_DIRS) $(addprefix libraries/,$(PACKAGES_STAGE2))
......
......@@ -99,7 +99,7 @@ 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"
ifeq "$(Stage1Only)" "YES"
ghc_stage2_NOT_NEEDED = YES
endif
# stage 3 has to be requested explicitly with stage=3
......
primitive @ 75c3379b
Subproject commit 75c3379b6d76e914cc3c7ffd290b6b1cad7ea3e6
vector @ c4c5a740
Subproject commit c4c5a740ec977a4300449bc85f4707ec641be923
......@@ -582,32 +582,37 @@ endif
TargetPlatformFull = @TargetPlatformFull@
GccLT34 = @GccLT34@
GccLT46 = @GccLT46@
CC = $(WhatGccIsCalled)
CC_STAGE0 = @CC_STAGE0@
CC_STAGE1 = $(CC)
CC_STAGE2 = $(CC)
CC_STAGE3 = $(CC)
AS = $(WhatGccIsCalled)
AS_STAGE0 = @CC_STAGE0@
AS_STAGE1 = $(AS)
AS_STAGE2 = $(AS)
AS_STAGE3 = $(AS)
# We don't have an LD_STAGE0. CC_STAGE0 is determined by asking "ghc
# --info", and it doesn't report an LD.
LD_STAGE0 = error-no-ld-stage0
LD_STAGE1 = $(LD)
LD_STAGE2 = $(LD)
LD_STAGE3 = $(LD)
# 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
# Change this to YES if you're building a cross-compiler and don't
# want to build stage 2.
Stage1Only = NO
# Install stage 2 by default, or stage 1 in the cross compiler
# case. Can be changed to 3
INSTALL_GHC_STAGE= $(if $(filter YES,$(Stage1Only)),1,2)
# 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
......
......@@ -81,7 +81,12 @@ $1_$2_CONFIGURE_OPTS += $$(BOOT_PKG_CONSTRAINTS)
endif
$1_$2_CONFIGURE_OPTS += --with-gcc="$$(CC_STAGE$3)"
$1_$2_CONFIGURE_OPTS += --with-ld="$$(LD)"
ifneq "$3" "0"
# There is no LD_STAGE0, Cabal will figure it out
$1_$2_CONFIGURE_OPTS += --with-ld="$$(LD_STAGE$3)"
endif
$1_$2_CONFIGURE_OPTS += --configure-option=--with-cc="$$(CC_STAGE$3)"
$1_$2_CONFIGURE_OPTS += --with-ar="$$(AR_STAGE$3)"
$1_$2_CONFIGURE_OPTS += --with-ranlib="$$(RANLIB)"
......
[("GCC extra via C opts", "@GccExtraViaCOpts@"),
("C compiler command", "@SettingsCCompilerCommand@"),
("C compiler flags", "@SettingsCCompilerFlags@"),
("ld command", "@SettingsLdCommand@"),
("ld flags", "@SettingsLdFlags@"),
("ld supports compact unwind", "@LdHasNoCompactUnwind@"),
("ld supports build-id", "@LdHasBuildId@"),
......
......@@ -85,7 +85,7 @@ $(eval $(call clean-target,utils/ghc-pkg,dist,utils/ghc-pkg/dist))
# Cross-compile case: Install our dist version
# Normal case: Build ghc-pkg with stage 1
ifeq "$(BuildingCrossCompiler)" "YES"
ifeq "$(Stage1Only)" "YES"
GHC_PKG_DISTDIR=dist
else
GHC_PKG_DISTDIR=dist-install
......@@ -104,7 +104,7 @@ 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"
ifeq "$(Stage1Only)" "YES"
$(eval $(call shell-wrapper,utils/ghc-pkg,dist))
else
$(eval $(call build-prog,utils/ghc-pkg,dist-install,1))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment