1#!/bin/sh
2
3# Parameters <haiku sourcedir> <buildtools dir> <install dir>
4# Influential environmental variable:
5# * haikuRequiredLegacyGCCVersion: The required version of the gcc. Will be
6#   checked against the version in the buildtools directory.
7
8# get and check the parameters
9if [ $# -lt 3 ]; then
10	echo Usage: $0 '<haiku sourcedir> <buildtools dir> <install dir>' \
11		'[extra make flags]' >&2
12	exit 1
13fi
14
15set -e
16
17if [ -z "$MAKE" ]; then
18	echo "MAKE undefined. Assuming make."
19	export MAKE=make
20fi
21
22haikuSourceDir=$1
23buildToolsDir=$2/legacy
24installDir=$3
25shift 3
26additionalMakeArgs=$*
27	# Note: The gcc 2 build has trouble with -jN N > 1, hence we only use the
28	# additional flags for the binutils build. Should there ever be any other
29	# flags than -jN, we need to handle this differently.
30
31if [ `uname -s` = 'Haiku' ]; then
32	# force cross-build if building on Haiku:
33	buildhostMachine=i586-pc-haiku_buildhost
34	buildHostSpec="--build=$buildhostMachine --host=$buildhostMachine"
35fi
36
37if [ ! -d $haikuSourceDir ]; then
38	echo "ERROR: No such directory: \"$haikuSourceDir\"" >&2
39	exit 1
40fi
41
42if [ ! -d $buildToolsDir ]; then
43	echo "ERROR: No such directory: \"$buildToolsDir\"" >&2
44	exit 1
45fi
46
47# verify or extract the gcc version
48gccVersionDotC="$buildToolsDir/gcc/gcc/version.c"
49if [ -n "$haikuRequiredLegacyGCCVersion" ]; then
50	# haikuRequiredLegacyGCCVersion has been specified. Check whether the
51	# version of the gcc in the given build tools directory matches.
52	if ! grep "$haikuRequiredLegacyGCCVersion" \
53			"$gccVersionDotC" >/dev/null 2>&1 ; then
54		echo "*** Mismatching compiler versions between configure script and" \
55			>&2
56		echo "*** $gccVersionDotC" >&2
57		echo "*** Did you perhaps update only one of haiku & buildtools?" >&2
58		exit 1
59	fi
60else
61	# haikuRequiredLegacyGCCVersion wasn't specified. Extract the version string
62	# from the gcc's version.c.
63	haikuRequiredLegacyGCCVersion=`grep "2.95.3-haiku-" "$gccVersionDotC" \
64		| sed 's@.*\"\(.*\)\".*@\1@'`
65	if [ -z "$haikuRequiredLegacyGCCVersion" ]; then
66		echo "ERROR: Failed to extract version string from $gccVersionDotC" >&2
67		exit 1
68	fi
69fi
70
71
72# create the output dir
73mkdir -p $installDir || exit 1
74
75
76# get absolute paths
77currentDir=`pwd`
78
79cd $haikuSourceDir
80haikuSourceDir=`pwd`
81cd $currentDir
82
83cd $buildToolsDir
84buildToolsDir=`pwd`
85cd $currentDir
86
87cd $installDir
88installDir=`pwd`
89cd $currentDir
90
91
92# create the object and installation directories for the cross compilation tools
93objDir=${installDir}-build
94binutilsObjDir=$objDir/binutils
95gccObjDir=$objDir/gcc
96tmpIncludeDir=$objDir/sysincludes
97tmpLibDir=$objDir/syslibs
98
99rm -rf $installDir $objDir
100
101mkdir -p $installDir $objDir $binutilsObjDir $gccObjDir $tmpIncludeDir \
102	$tmpLibDir || exit 1
103mkdir -p $installDir/lib/gcc-lib/i586-pc-haiku/$haikuRequiredLegacyGCCVersion
104
105gccConfigureArgs=
106if [ -n "$SECONDARY_ARCH" ]; then
107	gccConfigureArgs="$gccConfigureArgs --with-hybrid-secondary=$SECONDARY_ARCH"
108fi
109
110# force the POSIX locale, as the build (makeinfo) might choke otherwise
111export LC_ALL=POSIX
112
113# drop an multiple job arguments from MAKEFLAGS
114if [ ! -z "$MAKEFLAGS" ]; then
115	export MAKEFLAGS=$(echo $MAKEFLAGS | sed -e 's/-j\s*[0-9][0-9]*//g')
116fi
117
118
119# build binutils
120cd $binutilsObjDir
121CFLAGS="-O2 -fcommon" CXXFLAGS="-O2 -fcommon" $buildToolsDir/binutils/configure \
122	--prefix=$installDir $buildHostSpec --target=i586-pc-haiku \
123	--disable-nls --enable-shared=yes --disable-werror || exit 1
124$MAKE $additionalMakeArgs || exit 1
125$MAKE $additionalMakeArgs install || exit 1
126
127PATH=$PATH:$installDir/bin
128export PATH
129
130
131# build gcc
132
133# prepare the include files
134copy_headers()
135{
136	sourceDir=$1
137	targetDir=$2
138
139	headers="`find $sourceDir -name \*\.h`"
140	headers="`echo $headers | sed -e s@$sourceDir/@@g`"
141	for f in $headers; do
142		headerTargetDir=$targetDir/`dirname $f`
143		mkdir -p $headerTargetDir
144		cp $sourceDir/$f $headerTargetDir
145	done
146}
147
148copy_headers $haikuSourceDir/headers/config $tmpIncludeDir/config
149copy_headers $haikuSourceDir/headers/os $tmpIncludeDir/os
150copy_headers $haikuSourceDir/headers/posix $tmpIncludeDir/posix
151
152# Touch some files generated by bison, so that bison won't run to update them.
153# Fixes issues with newer bison versions.
154# And while at it, touch gperf target, too (as gperf may not be installed)
155(cd $buildToolsDir/gcc/gcc; touch c-parse.c c-parse.h cexp.c cp/parse.c \
156	cp/parse.h c-gperf.h)
157
158# configure gcc
159cd $gccObjDir
160# GCC 2 compiled for x86_64 on most systems is broken, compile for 32-bit.
161export CC="gcc -m32"
162CFLAGS="-O2 -U_FORTIFY_SOURCE -fcommon" CXXFLAGS="-O2 -fcommon" $buildToolsDir/gcc/configure \
163	--prefix=$installDir $buildHostSpec --target=i586-pc-haiku \
164	--disable-nls --enable-shared=yes --enable-languages=c,c++ \
165	--with-headers=$tmpIncludeDir --with-libs=$tmpLibDir $gccConfigureArgs \
166	|| exit 1
167unset CC
168
169# hack the Makefile to avoid trouble with stuff we don't need anyway
170sedExpr=
171for toRemove in libiberty libio libjava libobjc libstdc++; do
172	sedExpr="$sedExpr -e 's@^\(TARGET_CONFIGDIRS =.*\)$toRemove\(.*\)@\1\2@'"
173done
174echo sedExpr: $sedExpr
175mv Makefile Makefile.bak || exit 1
176eval "sed $sedExpr Makefile.bak > Makefile" || exit 1
177rm Makefile.bak
178
179# make gcc
180$MAKE cross || {
181	echo "ERROR: Building gcc failed." >&2
182	exit 1
183}
184
185# install gcc
186$MAKE install-gcc-cross || {
187	echo "ERROR: Installing the cross compiler failed." >&2
188	exit 1
189}
190
191# Remove the math.h gcc header. It has been generated by fixincludes
192# (unconditional hack: math_huge_val_ifndef) from ours and it is semantically
193# equivalent.
194rm -f $installDir/lib/gcc-lib/i586-pc-haiku/$haikuRequiredLegacyGCCVersion/include/math.h
195
196# Symlink the built-in C++ headers path to the sys-include directory. This is
197# not actually needed for cross compiling Haiku itself, but simplifies using the
198# cross compiler for building the bootstrap packages.
199(cd $installDir/include; ln -s ../i586-pc-haiku/sys-include/c++/2.95.3 g++)
200
201
202# cleanup
203
204# remove the system headers from the installation dir
205# Only the ones from the source tree should be used.
206rm -rf $installDir/i586-pc-haiku/sys-include
207
208# remove the objects dir
209rm -rf $objDir
210
211
212echo "binutils and gcc for cross compilation have been built successfully!"
213