xref: /haiku/configure (revision b08627f310bb2e80bca50176e7a758182384735a)
1#!/bin/sh
2#
3# configure [ <options> ]
4
5# usage
6#
7# Prints usage.
8#
9usage()
10{
11	cat << EOF
12
13Usage: $0 <options>
14options:
15  --help                      Prints out this help.
16  --update                    Re-runs last configure invocation [must be given
17                              as first option!]
18  --bootstrap <haikuporter> <HaikuPorts cross repo> <HaikuPorts repo>
19                              Prepare for a bootstrap build. No pre-built
20                              packages will be used, instead they will be built
21                              from the sources (in several phases).
22                              <haikuporter> is the path to the haikuporter tool
23                              suitable for the host platform.
24                              <HaikuPorts cross repo> is the path to a checked
25                              out HaikuPorts cross-compilation repository.
26                              <HaikuPorts repo> is the path to a checked out
27                              HaikuPorts repository.
28  --build-cross-tools <arch> [ <build tools dir> ]
29                              Assume cross compilation. <build tools dir>
30                              defines the location of the build tools sources.
31                              They will be compiled and placed in the output
32                              directory under "cross-tools". The HAIKU_* tools
33                              variables will be set accordingly.
34                              <arch> specifies the target architecture, either
35                              "x86_gcc2", "x86", "x86_64", "ppc", "m68k", "arm"
36                              This option and --cross-tools-prefix can be
37                              specified multiple times. The first cross tools
38                              specify the primary tools, the subsequent ones the
39                              secondary tools (for "hybrid" images).
40                              For the first --build-cross-tools the
41                              <build tools dir> argument must be specified and
42                              for the subsequent ones it must be omitted.
43  --cross-tools-prefix <prefix>
44                              Assume cross compilation. <prefix> should be a
45                              path to the directory where the cross
46                              compilation tools are located, plus the platform
47                              prefix, e.g. "/path/to/tools/i586-pc-haiku-".
48                              This overrides the HAIKU_* tool variables.
49  --distro-compatibility <level>
50                              The distribution's level of compatibility with
51                              the official Haiku distribution. The generated
52                              files will contain the respective trademarks
53                              accordingly.
54                              official -- the official Haiku distribution.
55                              compatible -- a Haiku Compatible (tm) distro.
56                              default -- any other distro (default value).
57  --host-only                 Configure for building tools for the build host
58                              only. Haiku cannot be built when configured like
59                              this.
60  --include-patented-code     Enable code that is known to implemented patented
61                              ideas and techniques. If this option is not
62                              specified, the resulting distribution may still
63                              implement patented ideas and techniques. This
64                              option only enables code that is currently known
65                              to be problematic.
66  --include-sources           Includes the source code of projects that require
67                              either an offer of source code or a copy of the
68                              patched sources. This is preferable when
69                              distributing on physical mediums.
70  --include-3rdparty          Include 3rdparty/ in the build system.
71  -j<n>                       Only relevant for --build-cross-tools. Is passed
72                              on to the make building the build tools.
73  --no-downloads              Do not download anything. Useful when trying to
74                              bootstrap and build Haiku from source only.
75  --target-arch <arch>        Haiku only: Specify the target architecture to
76                              build for. Must be one of the architectures of the
77                              host system. The installed build tools for that
78                              architecture will be used.
79                              This option can be specified multiple times. The
80                              first occurrence specifies the primary
81                              architecture of the Haiku to build, subsequent
82                              ones the secondary architectures.
83  --use-clang <arch>          Build with host Clang instead of GCC cross
84                              compiler, targeting <arch>
85  --use-gcc-pipe              Build with GCC option -pipe. Speeds up the build
86                              process, but uses more memory.
87  --use-gcc-graphite          Build with GCC Graphite engine for loop
88                              optimizations. (Only for GCC 4+.)
89  --use-32bit                 Use -m32 flag on 64bit host gcc compiler.
90  --no-full-xattr             Do not use Linux/*BSD/Darwin's native extended file
91                              attributes as Haiku attributes. If they are still
92                              available, they will be used to store hashes for
93                              the attribute emulation layer.
94  --no-xattr                  Do not use Linux/*BSD/Darwin's native extended file
95                              attributes for Haiku extended attributes at all,
96                              even if they are available.
97  --with-gdb <gdb sources dir>
98                              specify the path to a GDB source dir, to build
99                              GDB for each arch we build the cross-tools for.
100
101environment variables:
102  CC                          The host compiler. Defaults to "gcc".
103  HAIKU_AR_<arch>             The static library archiver for <arch>.
104                              Defaults to "ar".
105  HAIKU_CC_<arch>             The compiler for <arch>. Defaults to "gcc".
106  HAIKU_LD_<arch>             The <arch> linker. Defaults to "ld".
107  HAIKU_OBJCOPY_<arch>        The <arch> objcopy to be used. Defaults to
108                              "objcopy".
109  HAIKU_RANLIB_<arch>         The static library indexer for <arch>. Defaults
110                              to "ranlib".
111  HAIKU_STRIP_<arch>          The <arch> strip command. Defaults to "strip".
112  HAIKU_NASM                  The nasm assembler (x86 and x86_64 only).
113  HAIKU_CPPFLAGS_<arch>       The preprocessor flags for target architecture
114                              <arch>. Defaults to "".
115  HAIKU_CCFLAGS_<arch>        The C flags for target architecture <arch>.
116                              Defaults to "".
117  HAIKU_CXXFLAGS_<arch>       The C++ flags for target architecture <arch>.
118                              Defaults to "".
119  HAIKU_LDFLAGS_<arch>        The linker flags for target architecture <arch>.
120                              Defaults to "".
121  HAIKU_ARFLAGS_<arch>        The flags passed to HAIKU_AR for target
122                              architecture <arch> for archiving. Defaults to
123                              "cru".
124  HAIKU_UNARFLAGS_<arch>      The flags passed to HAIKU_AR for target
125                              architecture <arch> for unarchiving. Defaults to
126                              "x".
127
128Non-default output directories:
129  By default all objects, build configuration, and other related files are
130  stored in /path/to/haiku_source/generated.  To store objects in a non-default
131  location, run "../../relative/path/to/haiku_source/configure <options>" from
132  within your non-default location.  "jam [ options ] targets" can then be run
133  directly inside your non-default location.  Another option is to invoke "jam
134  [ options ] targets" from within haiku_source.  This can be accomplished by
135  either "export HAIKU_OUTPUT_DIR=your non-default location" before invoking
136  jam or by creating a symlink of haiku_source/generated pointing to your
137  non-default location and running jam.
138
139
140EOF
141}
142
143# assertparam
144#
145# Checks whether at least one parameter is left.
146#
147assertparam()
148{
149	if [ $2 -lt 2 ]; then
150		echo $0: \`$1\': Parameter expected.
151		exit 1
152	fi
153}
154
155# assertparams
156#
157# Checks whether at least a certain number of parameters is left.
158#
159assertparams()
160{
161	if [ $3 -le $2 ]; then
162		echo $0: \`$1\': Not enough parameters.
163		exit 1
164	fi
165}
166
167# absolute_path
168#
169# returns the absolute path of a given path.
170#
171absolute_path()
172{
173	if [ "x$1" != "x${1#/}" ]; then
174		echo "$1"
175	else
176		echo "`pwd`/$1"
177	fi
178}
179
180# check_dir_exists
181#
182# check if a directory exists or not
183#
184check_dir_exists()
185{
186	if [ -d "$1" ]; then
187		return 0
188	else
189		return 1
190	fi
191}
192
193# check_file_exists
194#
195# check if a file exists or not
196#
197check_file_exists()
198{
199	if [ -f "$1" ]; then
200		return 0
201	else
202		return 1
203	fi
204}
205
206# real_path
207#
208# returns the realpath of a symbolic link.
209#
210real_path()
211{
212	perl -MCwd=realpath -e'print realpath($ARGV[0]), "\n"' "$1"
213}
214
215# valid_toolchain
216#
217# check if toolchain is valid
218#
219valid_toolchain()
220{
221	TRIPLET="$1"
222	BASE="$2"
223	if [ ! -d "$BASE" ]; then
224		return 1;
225	fi
226	if [ -f "$BASE/bin/$TRIPLET-gcc" ]; then
227		return 0;
228	fi
229	# TODO: Check this!
230	if [ -f "$BASE/bin/$TRIPLET-clang" ]; then
231		return 0;
232	fi
233	return 1;
234}
235
236# standard_gcc_settings
237#
238# Sets the variables for a GCC platform.
239#
240standard_gcc_settings()
241{
242	local gcc="$1"
243
244	if which greadlink > /dev/null 2>&1; then
245		readlink="greadlink -e"
246	elif which realpath > /dev/null 2>&1; then
247		readlink=realpath
248	elif readlink -e / > /dev/null 2>&1; then
249		readlink="readlink -e"
250	else
251		readlink=real_path
252	fi
253
254	# PLATFORM_LINKLIBS
255	local gcclib=`$gcc -print-libgcc-file-name`
256	local gccdir=`dirname ${gcclib}`
257
258	local gccRawVersion=`$gcc -dumpversion`
259	local gccMachine=`$gcc -dumpmachine`
260
261	# determine architecture from machine triple
262	case $gccMachine in
263		arm-*)		targetCpu=arm;;
264		i?86-*)		targetCpu=x86;;
265		m68k-*)		targetCpu=m68k;;
266		powerpc-*)	targetCpu=ppc;;
267		x86_64-*)	targetCpu=x86_64;;
268		*)
269			echo "Unsupported gcc target machine: $gccMachine" >&2
270			exit 1
271			;;
272	esac
273
274	local targetArch=$targetCpu
275
276	case $gccRawVersion in
277		2.9*)
278			# check for correct (most up-to-date) legacy compiler and complain
279			# if an older one is installed
280			if [ $gccRawVersion != $haikuRequiredLegacyGCCVersion ]; then
281				echo "GCC version $haikuRequiredLegacyGCCVersion is required!";
282				echo "Please download it from www.haiku-os.org...";
283				exit 1;
284			fi
285
286			targetArch=x86_gcc2
287			;;
288	esac
289
290	local bootLibgcc
291	local bootLibSupCxx
292	local bootCxxHeaders
293	case $gccMachine in
294		x86_64-*)
295			# Boot loader is 32-bit, need the 32-bit libs and c++ config
296			bootLibgcc=`$gcc -m32 -print-file-name=libgcc.a`
297			bootLibSupCxx=`$gcc -m32 -print-file-name=libsupc++.a`
298
299			local headersBase=$gccdir/../../../..
300			local headers=$headersBase/$gccMachine/include/c++/$gccRawVersion
301			if [ ! -d $headers ]; then
302				headers=$headersBase/include/c++/$gccRawVersion
303			fi
304			bootCxxHeaders="$headers/$gccMachine/32"
305			;;
306	esac
307
308	# determine whether graphite loop optimization should/can be used
309	local useGraphite=`get_variable HAIKU_USE_GCC_GRAPHITE_$targetCpu`
310	if [ -z "$useGraphite" ]; then
311		useGraphite=$useGccGraphiteDefault
312	fi
313
314	if [ "$useGraphite" != 0 ]; then
315		UNUSED=`echo "int main() {}" | $gcc -xc -c -floop-block - 2>&1`
316		if [ $? != 0 ]; then
317			echo "GCC Graphite loop optimizations cannot be used on $targetArch"
318			useGraphite=0
319		fi
320	fi
321
322	set_variable HAIKU_CPU_$targetArch $targetCpu
323
324	get_build_tool_path CC_$targetArch "$gcc"
325	set_variable HAIKU_CC_IS_CLANG_$targetArch $useClang
326	set_variable HAIKU_GCC_RAW_VERSION_$targetArch $gccRawVersion
327	set_variable HAIKU_GCC_MACHINE_$targetArch $gccMachine
328	set_variable HAIKU_GCC_LIB_DIR_$targetArch $gccdir
329	set_variable HAIKU_BOOT_CXX_HEADERS_DIR_$targetArch "$bootCxxHeaders"
330	set_variable HAIKU_BOOT_LIBSUPCXX_$targetArch "$bootLibSupCxx"
331	set_variable HAIKU_BOOT_LIBGCC_$targetArch $bootLibgcc
332	set_variable HAIKU_USE_GCC_GRAPHITE_$targetArch $useGraphite
333
334	standard_gcc_settings_targetArch=$targetArch
335}
336
337# set_variable
338#
339# Set the value of a variable.
340#
341set_variable()
342{
343	eval "$1=\"$2\""
344}
345
346# get_variable
347#
348# Echo the value of a variable.
349#
350get_variable()
351{
352	eval "echo \${$1}"
353}
354
355# set_default_value
356#
357# Set the value for a variable, if no value is set yet.
358#
359set_default_value()
360{
361	eval "$1=\${$1-$2}"
362}
363
364# get_build_tool_path
365#
366# Gets a usable absolute path of a build tool.
367#
368get_build_tool_path()
369{
370	local var="HAIKU_$1"
371	local varval="`get_variable $var`"
372	local cmd="$2"
373
374	if [ ! -z "$varval" ]; then
375		# this variable is already set (probably by user) so grab its contents
376		cmd=$varval
377	fi
378
379	local path=${cmd%% *}
380
381	if [ -f "$path" ]; then
382		# get absolute path from relative path
383		local oldPwd="`pwd`"
384		cd "`dirname "$path"`"
385		path="`pwd`/`basename "$path"`"
386		cd $oldPwd
387	else
388		which "$path" > /dev/null 2>&1 || {
389			echo "Build tool \"$path\" not found (maybe specify it in $var?)" >&2
390			exit 1
391		}
392	fi
393
394	if test "${cmd#* }" != "$cmd"; then
395		# $cmd contains arguments, so preserve them (and only them)
396		cmd=${cmd#* }
397	else
398		# $cmd does not contain arguments, so unset it
399		cmd=
400	fi
401	eval "$var=\"$path $cmd\""
402}
403
404# check_native_xattrs
405#
406# Checks the host platform's support for extended attributes.
407# 0: no support, 1: only enough for xattr-ref, 2: full support
408#
409check_native_xattrs()
410{
411	local xattr_set=
412	local xattr_set_args=
413	local xattr_get=
414	local xattr_get_args=
415	case $HOST_PLATFORM in
416		haiku_host)
417			xattr_set="addattr"; xattr_set_args="\$NAME \"\$VALUE\""
418			xattr_get="catattr"; xattr_get_args="\$NAME"
419			;;
420		darwin)
421			xattr_set="xattr"; xattr_set_args="-w \$NAME \"\$VALUE\""
422			xattr_get="xattr"; xattr_get_args="-p \$NAME"
423			;;
424		freebsd)
425			xattr_set="setextattr"; xattr_set_args="user \$NAME \"\$VALUE\""
426			xattr_get="getextattr"; xattr_get_args="user \$NAME"
427			;;
428		linux)
429			xattr_set="setfattr"; xattr_set_args="-n user.\$NAME -v \"\$VALUE\""
430			xattr_get="getfattr"; xattr_get_args="-n user.\$NAME"
431			;;
432		*)
433			return 0
434			;;
435	esac
436	if ! type $xattr_set >/dev/null 2>&1; then
437		echo "$0: could not find $xattr_set, assuming host has no extended attributes"
438		return 0
439	elif ! type $xattr_get >/dev/null 2>&1; then
440		echo "$0: could not find $xattr_get, assuming host has no extended attributes"
441		return 0
442	fi
443
444	mkdir -p "$outputDir"
445	echo "xattr test file" >"$outputDir/xattrtest"
446	local i=0
447	# on round 0, we test if we can set 3 attrs of 1K each (enough for xattr-ref)
448	# on round 1, we test if we can set 3 attrs of 45K each (enough for full xattr)
449	while [ $i -lt 2 ]; do
450		local j=0
451		while [ $j -lt 3 ]; do
452			NAME=attr$j
453			VALUE=`printf '%*s' $((1024 + $i * 45056)) "" | tr ' ' x`
454			if [ `echo -n $VALUE | wc -c` -lt $((1024 + $i * 45056)) ]; then
455				echo "$0: warning: could not generate test data for extended attributes"
456				rm "$outputDir/xattrtest"
457				return $i
458			elif ! $xattr_set `eval echo \"$xattr_set_args\"` \
459					"$outputDir/xattrtest" >/dev/null 2>&1 ; then
460				rm "$outputDir/xattrtest"
461				return $i
462			fi
463			j=$((j+1))
464		done
465		i=$((i+1))
466	done
467	rm "$outputDir/xattrtest"
468	return 2
469}
470
471is_in_list()
472{
473	local element
474	for element in $2; do
475		if [ "$1" = "$element" ]; then
476			return 0
477		fi
478	done
479	return 1
480}
481
482# check for --help or -h and show usage immediately
483if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
484	usage; exit 0;
485fi
486
487# ensure umask is not too restrictive
488if [ $(umask) -gt 22 ]; then
489	echo "Your umask is too restrictive (should be: <= 0022; is actually:" $(umask)")"
490	exit 1
491fi
492
493# get cwd and the source directory
494currentDir=`pwd`
495cd `dirname "$0"`
496sourceDir=`pwd`
497cd "$currentDir"
498
499# backup the passed arguments
500configureArgs="$@"
501configurePath=$0
502
503# backup relevant environs
504configureEnvirons=
505for var in `env`; do
506	case "$var" in
507		CC\=*|HAIKU*\=*)
508			configureEnvirons="$configureEnvirons $var"
509			;;
510	esac
511done
512
513# internal default parameter values
514#
515platform=`uname`
516platformMachine=`uname  -m`
517targetArchs=
518buildCrossTools=
519buildCrossToolsScript="$sourceDir/build/scripts/build_cross_tools"
520buildCrossToolsJobs=
521useClang=0
522useGccGraphiteDefault=0
523unknownArchIndex=1
524haikuTargetArchs=
525gdbSources=
526
527if [ -z "$CC" ]; then
528	CC=gcc
529fi
530
531# exported (BuildSetup) default parameter values
532#
533HOST_GCC_RAW_VERSION=`$CC -dumpversion`
534HOST_GCC_MACHINE=`$CC -dumpmachine`
535HAIKU_INCLUDE_PATENTED_CODE=0
536HAIKU_INCLUDE_SOURCES=0
537HAIKU_INCLUDE_3RDPARTY=0
538HAIKU_DISTRO_COMPATIBILITY=default
539TARGET_PLATFORM=haiku
540HAIKU_USE_GCC_PIPE=0
541HAIKU_HOST_USE_32BIT=0
542HAIKU_HOST_USE_XATTR=
543HAIKU_HOST_USE_XATTR_REF=
544HAIKU_HOST_BUILD_ONLY=0
545HOST_EXTENDED_REGEX_SED="sed -r"
546HOST_GCC_LD=`$CC -print-prog-name=ld`
547HOST_GCC_OBJCOPY=`$CC -print-prog-name=objcopy`
548HOST_SHA256=
549HOST_HAIKU_PORTER=
550HAIKU_PORTS=
551HAIKU_PORTS_CROSS=
552HAIKU_IS_BOOTSTRAP=0
553HAIKU_BOOT_BOARD=
554HAIKU_NO_DOWNLOADS=0
555
556HAIKU_PACKAGING_ARCHS=
557
558set_default_value HAIKU_NASM		nasm
559
560if sha256sum < /dev/null > /dev/null 2>&1; then
561	HOST_SHA256=sha256sum
562elif sha256 < /dev/null > /dev/null 2>&1; then
563	HOST_SHA256="sha256 -q"
564elif shasum < /dev/null > /dev/null 2>&1; then
565	HOST_SHA256="shasum -a 256"
566else
567	echo "Error: Neither sha256sum nor sha256 seem to be available!" >&2
568	exit 1
569fi
570
571haikuRequiredLegacyGCCVersion="2.95.3-haiku-2017_07_20"
572export haikuRequiredLegacyGCCVersion
573	# version of legacy gcc required to build haiku
574supportedTargetArchs="
575	arm
576	m68k
577	ppc
578	x86
579	x86_64
580	x86_gcc2
581	"
582
583# determine output directory
584if [ "$currentDir" = "$sourceDir" ]; then
585	outputDir=$currentDir/generated
586else
587	outputDir=$currentDir
588fi
589buildOutputDir="$outputDir/build"
590HAIKU_BUILD_ATTRIBUTES_DIR="$outputDir/attributes"
591buildConfigFile="$buildOutputDir/BuildConfig"
592
593# check for update request
594if [ "$1" = "--update" ]; then
595	if ! [ -e "$buildConfigFile" ]; then
596		echo $0 --update: \'$buildConfigFile\' not found - updating not possible.
597		exit 1
598	fi
599	# get last configure invocation and flags from BuildConfig and call ourselves with it
600	lastPwd=`grep "#d " "$buildConfigFile" | cut -c 4-`
601	lastConfig=`grep "#c " "$buildConfigFile" | cut -c 4-`
602	lastEnv=`grep "#e " "$buildConfigFile" | cut -c 4-`
603	lastArgs=`grep "#a " "$buildConfigFile" | cut -c 4-`
604	if [ -z "$lastConfig" ]; then
605		echo "$0 --update: The previous configure invocation was not properly" \
606			"encoded into '$buildConfigFile' - updating not possible."
607		exit 1
608	fi
609	cd $lastPwd
610	if [ -n "$lastEnv" ]; then
611		export $lastEnv
612	fi
613	$lastConfig $lastArgs
614	exit $?
615fi
616
617# parse parameters
618#
619while [ $# -gt 0 ] ; do
620	case "$1" in
621		--bootstrap)
622			assertparams "$1" 3 $#
623			HOST_HAIKU_PORTER="`absolute_path $2`"
624			HAIKU_PORTS_CROSS="`absolute_path $3`"
625			HAIKU_PORTS="`absolute_path $4`"
626			HAIKU_IS_BOOTSTRAP=1
627			HAIKU_NO_DOWNLOADS=1
628			check_file_exists "$HOST_HAIKU_PORTER" || (
629				echo "Invalid path to haikuporter: $HOST_HAIKU_PORTER" >&2
630				exit 1
631			)
632			check_dir_exists "$HAIKU_PORTS" || (
633				echo "Non-existent directory $HAIKU_PORTS" >&2
634				exit 1
635			)
636			check_dir_exists "$HAIKU_PORTS_CROSS" || (
637				echo "Non-existent directory $HAIKU_PORTS_CROSS" >&2
638				exit 1
639			)
640			shift 4
641			;;
642		--build-cross-tools)
643			if [ -z "$buildCrossTools" ]; then
644				assertparams "$1" 2 $#
645				targetArch=$2
646				buildCrossTools=$3
647				shift 3
648			else
649				assertparam "$1" $#
650				targetArch=$2
651				shift 2
652			fi
653			case "$targetArch" in
654				x86_gcc2)	targetMachine=i586-pc-haiku;;
655				x86)		targetMachine=i586-pc-haiku;;
656				x86_64)		targetMachine=x86_64-unknown-haiku;;
657				ppc)		targetMachine=powerpc-apple-haiku;;
658				m68k)		targetMachine=m68k-unknown-haiku;;
659				arm)		targetMachine=arm-unknown-haiku;;
660				*)
661					echo "Unsupported target architecture: $2" >&2
662					exit 1
663					;;
664			esac
665			set_variable buildCrossToolsMachine_$targetArch $targetMachine
666			targetArchs="$targetArchs $targetArch"
667			HAIKU_PACKAGING_ARCHS=
668			;;
669		--cross-tools-prefix)
670			assertparam "$1" $#
671			targetArch=unknown${unknownArchIndex}
672			set_variable crossToolsPrefix_$targetArch "$2"
673			targetArchs="$targetArchs $targetArch"
674			HAIKU_PACKAGING_ARCHS=
675			unknownArchIndex=$(($unknownArchIndex + 1))
676			shift 2
677			;;
678		--distro-compatibility)
679			assertparam "$1" $#
680			HAIKU_DISTRO_COMPATIBILITY=$2
681			case "$HAIKU_DISTRO_COMPATIBILITY" in
682				official)	;;
683				compatible)	;;
684				default)	;;
685				*)			echo "Invalid distro compatibility" \
686								"level: $HAIKU_DISTRO_COMPATIBILITY"
687							exit 1;;
688			esac
689			shift 2
690			;;
691		--host-only)	HAIKU_HOST_BUILD_ONLY=1; shift 1;;
692		--include-patented-code)	HAIKU_INCLUDE_PATENTED_CODE=1; shift 1;;
693		--include-sources)	HAIKU_INCLUDE_SOURCES=1; shift 1;;
694		--include-3rdparty)	HAIKU_INCLUDE_3RDPARTY=1; shift 1;;
695        -j*)				buildCrossToolsJobs="$1"; shift 1;;
696		--no-downloads)	HAIKU_NO_DOWNLOADS=1; shift 1;;
697		--target-arch)
698			assertparam "$1" $#
699			targetArch=$2
700			shift 2
701			if [ ! "$platform" = Haiku ]; then
702				echo "--target-arch can only be specified on Haiku." >&2
703				exit 1
704			fi
705			is_in_list "$targetArch" "$supportedTargetArchs" || (
706				echo "Unsupported target architecture: \"$targetArch\"" >&2
707				exit 1
708			)
709			haikuTargetArchs="$haikuTargetArchs $targetArch"
710			;;
711		--use-clang)
712			assertparam "$1" $#
713			targetArch=$2
714			useClang=1
715			case "$targetArch" in
716				x86)		targetMachine=i586-pc-haiku;;
717				x86_64)		targetMachine=x86_64-unknown-haiku;;
718				*)
719					echo "Unsupported target architecture: $2" >&2
720					exit 1
721					;;
722			esac
723			get_build_tool_path clang clang
724			if [ -z `get_variable "crossToolsPrefix_$targetArch"` ] \
725					&& [ -z `get_variable buildCrossToolsMachine_$targetArch` ]; then
726				set_variable crossToolsPrefix_$targetArch llvm-
727			fi
728			if ! test "${targetArchs#*$targetArch}" != "$targetArchs"; then
729				# we have not already added this arch to targetArchs, so add it now
730				targetArchs="$targetArchs $targetArch"
731			fi
732			HAIKU_PACKAGING_ARCHS=
733			shift 2
734			;;
735		--use-gcc-pipe)	HAIKU_USE_GCC_PIPE=1; shift 1;;
736		--use-gcc-graphite)	useGccGraphiteDefault=1; shift 1;;
737		--use-32bit)	HAIKU_HOST_USE_32BIT=1; shift 1;;
738		--no-full-xattr)HAIKU_HOST_USE_XATTR=0; shift 1;;
739		--no-xattr)		HAIKU_HOST_USE_XATTR_REF=0; shift 1;;
740		--with-gdb)	gdbSources=$2; shift 2;;
741		*)				echo Invalid argument: \`$1\'; exit 1;;
742	esac
743done
744
745# detect the build platform
746case "${platform}" in
747	Darwin)	HOST_PLATFORM=darwin ;;
748	FreeBSD)	HOST_PLATFORM=freebsd
749				if [ "$HAIKU_HOST_USE_32BIT" = 1 ] ; then
750					echo Unsupported platform: FreeBSD ${platformMachine}
751					exit 1
752				fi	;;
753	Haiku)	HOST_PLATFORM=haiku_host ;;
754	Linux)	HOST_PLATFORM=linux ;;
755	OpenBSD) HOST_PLATFORM=openbsd ;;
756	SunOS)	HOST_PLATFORM=sunos ;;
757	CYGWIN_NT-*) HOST_PLATFORM=cygwin ;;
758	*)		echo Unsupported platform: ${platform}
759			exit 1 ;;
760esac
761
762# check for case-sensitive filesystem
763mkdir haikuCaseTest 2>/dev/null
764mkdir haikucasetest 2>/dev/null
765caseInsensitive=$?
766rmdir haikuCaseTest haikucasetest 2>/dev/null
767if [ $caseInsensitive != 0 ]; then
768	echo "You need a case-sensitive file-system to build Haiku."
769	if [ $HOST_PLATFORM = "darwin" ]; then
770		echo "You can create a case-sensitive disk image using Disk Utility."
771	fi
772	exit 1
773fi
774
775# check xattr support
776if [ -z $HAIKU_HOST_USE_XATTR_REF ]; then
777	check_native_xattrs
778	attrSupport=$?
779	if [ $attrSupport = 2 ] && [ -z $HAIKU_HOST_USE_XATTR ]; then
780		HAIKU_HOST_USE_XATTR=1
781	elif [ $attrSupport = 1 ]; then
782		HAIKU_HOST_USE_XATTR_REF=1
783	fi
784fi
785if [ -z $HAIKU_HOST_USE_XATTR ]; then HAIKU_HOST_USE_XATTR=0; fi
786if [ -z $HAIKU_HOST_USE_XATTR_REF ]; then HAIKU_HOST_USE_XATTR_REF=0; fi
787
788# determine how to invoke sed with extended regexp support for non-GNU sed
789if [ $HOST_PLATFORM = "darwin" ]; then
790	HOST_EXTENDED_REGEX_SED="sed -E"
791fi
792
793# check if nasm can actually output ELF files
794# (the stock version in OSX can't)
795# XXX: should probably only test for x86* arch
796if [ "$("$HAIKU_NASM" -hf | grep -c elf'[36][24] ')" -ne "2" ]; then
797	echo "$HAIKU_NASM cannot generate ELF files. Please install a working version."
798	if [ $HOST_PLATFORM = "darwin" ]; then
799		echo "You can install it from Mac Ports."
800		echo "Mac Ports is available at: http://www.macports.org/"
801	fi
802	exit 1
803fi
804
805# create output directory
806mkdir -p "$buildOutputDir" || exit 1
807
808if [ "$HAIKU_HOST_BUILD_ONLY" = 1 ]; then
809	invalidCommand=$sourceDir/build/scripts/host_build_only
810	HAIKU_AR=$invalidCommand
811	HAIKU_CC=$invalidCommand
812	HAIKU_LD=$invalidCommand
813	HAIKU_OBJCOPY=$invalidCommand
814	HAIKU_RANLIB=$invalidCommand
815	HAIKU_ELFEDIT=$invalidCommand
816	HAIKU_NASM=$invalidCommand
817	HAIKU_STRIP=$invalidCommand
818else
819	if [ -n "$HAIKU_PACKAGING_ARCHS" ]; then
820		targetArchs="$HAIKU_PACKAGING_ARCHS"
821	fi
822	HAIKU_PACKAGING_ARCHS=
823
824	# On Haiku determine target architectures and tools automatically.
825	if [ -z "$targetArchs" ]; then
826		if [ $HOST_PLATFORM != haiku_host ]; then
827			echo "Please specify the build tools to use or build (via" \
828				"--cross-tools-prefix or --build-cross-tools) or specify a" \
829				"host-only build (--host-only)." >&2
830			echo "For more info, invoke $0 --help"
831			exit 1
832		fi
833
834		# determine primary architecture
835		targetArch=`package list -i /system/packages/haiku-*.hpkg \
836			| sed '/^\s*architecture:/!d; s,^\s*architecture:\s*,,'`
837		is_in_list "$targetArch" "$supportedTargetArchs" || (
838			echo "Unsupported target architecture: \"$targetArch\"" >&2
839			exit 1
840		)
841		targetArchs=$targetArch
842
843		set_default_value HAIKU_AR_$targetArch			ar
844		set_default_value HAIKU_CC_$targetArch			gcc
845		set_default_value HAIKU_LD_$targetArch			ld
846		set_default_value HAIKU_OBJCOPY_$targetArch		objcopy
847		set_default_value HAIKU_RANLIB_$targetArch		ranlib
848		set_default_value HAIKU_ELFEDIT_$targetArch		elfedit
849		set_default_value HAIKU_STRIP_$targetArch		strip
850
851		# determine secondary architectures
852		for targetArch in $supportedTargetArchs; do
853			if [ -e /system/packages/haiku_$targetArch-*.hpkg ]; then
854				targetArchs="$targetArchs $targetArch"
855				set_default_value HAIKU_AR_$targetArch		ar-$targetArch
856				set_default_value HAIKU_CC_$targetArch		gcc-$targetArch
857				set_default_value HAIKU_LD_$targetArch		ld-$targetArch
858				set_default_value HAIKU_OBJCOPY_$targetArch	objcopy-$targetArch
859				set_default_value HAIKU_RANLIB_$targetArch	ranlib-$targetArch
860				set_default_value HAIKU_ELFEDIT_$targetArch	elfedit-$targetArch
861				set_default_value HAIKU_STRIP_$targetArch	strip-$targetArch
862			fi
863		done
864
865		# The target architectures might have been specified explicitly.
866		if [ -n "$haikuTargetArchs" ]; then
867			for targetArch in $haikuTargetArchs; do
868				is_in_list "$targetArch" "$targetArchs" || (
869					echo "Unsupported target architecture: \"$targetArch\"." \
870						"Only native architectures of the host platform can" \
871						"be specified." >&2
872					exit 1
873				)
874			done
875			targetArchs="$haikuTargetArchs"
876		fi
877	fi
878
879	isPrimaryArch=1
880	for targetArch in $targetArchs; do
881		# Note: targetArch is "unknown<n>" at this point, if a cross-tools
882		# prefix was specified. The standard_gcc_settings call below will get
883		# the actual architecture.
884
885		crossToolsPrefix=`get_variable crossToolsPrefix_$targetArch`
886
887		# build cross tools from sources
888		if [ -n "$buildCrossTools" -a -z "$crossToolsPrefix" ]; then
889			crossToolsDir="$outputDir/cross-tools-$targetArch"
890			targetMachine=`get_variable buildCrossToolsMachine_$targetArch`
891			script="$buildCrossToolsScript"
892			scriptArgs=
893			if [ $targetArch != x86_gcc2 ]; then
894				script="${script}_gcc4"
895				scriptArgs="$targetMachine"
896				set_default_value HAIKU_USE_GCC_GRAPHITE_$targetArch	\
897					$useGccGraphiteDefault
898			fi
899			secondaryArch=
900			if [ -z "$isPrimaryArch" ]; then
901				secondaryArch=$targetArch
902			fi
903
904			case $HOST_PLATFORM in
905				freebsd|openbsd)	MAKE=gmake;;
906				*)					MAKE=make;;
907			esac
908
909			if ! valid_toolchain "${targetMachine}" "${crossToolsDir}"; then
910				MAKE=$MAKE \
911				SECONDARY_ARCH=$secondaryArch \
912				HAIKU_USE_GCC_GRAPHITE=`get_variable \
913					HAIKU_USE_GCC_GRAPHITE_$targetArch` \
914				HAIKU_USE_GCC_PIPE=$HAIKU_USE_GCC_PIPE \
915				HAIKU_USE_GDB="$gdbSources" \
916				"$script" $scriptArgs "$sourceDir" "$buildCrossTools" \
917					"$crossToolsDir" $buildCrossToolsJobs || exit 1
918			else
919				echo "$targetArch crosstools already exist in $crossToolsDir; skipping build"
920			fi
921			crossToolsPrefix="$crossToolsDir/bin/${targetMachine}-"
922		fi
923
924		# prepare gcc settings and get the actual target architecture
925		if [ $useClang = 1 ]; then
926			gcc="$HAIKU_clang -target ${targetMachine} -no-integrated-as"
927
928			# Clang's compiler intrinsics are not compatible with GCC's or even
929			# across versions of Clang, so we must collect them for use in the build.
930			mkdir -p "$outputDir/clang_headers" || exit 1
931			clangHeadersDir=`$gcc -print-resource-dir`/include/
932			cp $clangHeadersDir/*intrin* $clangHeadersDir/mm3* "$outputDir/clang_headers" || exit 1
933		elif [ -z "${crossToolsPrefix}" ]; then
934			gcc=`get_variable HAIKU_CC_$targetArch`
935		else
936			gcc="${crossToolsPrefix}gcc"
937		fi
938		standard_gcc_settings "$gcc"
939		targetArch=$standard_gcc_settings_targetArch
940
941		# set default values for flags
942		set_default_value HAIKU_CPPFLAGS_$targetArch	""
943		set_default_value HAIKU_CCFLAGS_$targetArch		""
944		set_default_value HAIKU_CXXFLAGS_$targetArch	""
945		set_default_value HAIKU_LDFLAGS_$targetArch		""
946		set_default_value HAIKU_ARFLAGS_$targetArch		cru
947		set_default_value HAIKU_UNARFLAGS_$targetArch	x
948
949		# Override the cross tools variables, if the tools were built or a
950		# prefix was specified.
951		if [ -n "$crossToolsPrefix" ]; then
952			get_build_tool_path AR_$targetArch ${crossToolsPrefix}ar
953			get_build_tool_path LD_$targetArch ${crossToolsPrefix}ld
954			get_build_tool_path OBJCOPY_$targetArch ${crossToolsPrefix}objcopy
955			get_build_tool_path RANLIB_$targetArch ${crossToolsPrefix}ranlib
956			get_build_tool_path STRIP_$targetArch ${crossToolsPrefix}strip
957
958			case `get_variable HAIKU_GCC_RAW_VERSION_$targetArch` in
959				4.*|5.*|6.*|7.*|8.*)
960					get_build_tool_path ELFEDIT_$targetArch \
961						${crossToolsPrefix}elfedit
962				;;
963			esac
964		fi
965
966		# check whether the Haiku compiler really targets Haiku
967		targetMachine=`get_variable HAIKU_GCC_MACHINE_$targetArch`
968		case "$targetMachine" in
969			*-*-haiku)	;;
970			*)
971				echo The compiler specified as Haiku target compiler is not a \
972				valid Haiku cross-compiler. Please see ReadMe.cross-compile. >&2
973				echo compiler: $HAIKU_CC
974				echo compiler is configured for target: $targetMachine
975				exit 1 ;;
976		esac
977
978		HAIKU_PACKAGING_ARCHS="$HAIKU_PACKAGING_ARCHS $targetArch"
979		isPrimaryArch=
980	done
981fi
982
983# Generate BuildConfig
984cat << EOF > "$buildConfigFile"
985# -- WARNING --
986# This file was AUTOMATICALLY GENERATED by configure, and will be completely
987# overwritten the next time configure is run.
988#
989#d ${currentDir}
990#c ${configurePath}
991#e ${configureEnvirons}
992#a ${configureArgs}
993
994TARGET_PLATFORM 			?= "${TARGET_PLATFORM}" ;
995HOST_PLATFORM				?= "${HOST_PLATFORM}" ;
996
997HAIKU_INCLUDE_PATENTED_CODE			?= "${HAIKU_INCLUDE_PATENTED_CODE}" ;
998HAIKU_INCLUDE_SOURCES				?= "${HAIKU_INCLUDE_SOURCES}" ;
999HAIKU_INCLUDE_3RDPARTY				?= "${HAIKU_INCLUDE_3RDPARTY}" ;
1000HAIKU_DISTRO_COMPATIBILITY			?= "${HAIKU_DISTRO_COMPATIBILITY}" ;
1001HAIKU_USE_GCC_PIPE					?= "${HAIKU_USE_GCC_PIPE}" ;
1002HAIKU_HOST_USE_32BIT				?= "${HAIKU_HOST_USE_32BIT}" ;
1003HAIKU_HOST_USE_XATTR				?= "${HAIKU_HOST_USE_XATTR}" ;
1004HAIKU_HOST_USE_XATTR_REF			?= "${HAIKU_HOST_USE_XATTR_REF}" ;
1005HAIKU_HOST_BUILD_ONLY				?= "${HAIKU_HOST_BUILD_ONLY}" ;
1006
1007HAIKU_PACKAGING_ARCHS		?= ${HAIKU_PACKAGING_ARCHS} ;
1008
1009HAIKU_NO_DOWNLOADS			?= "${HAIKU_NO_DOWNLOADS}" ;
1010
1011HAIKU_BUILD_ATTRIBUTES_DIR	?= ${HAIKU_BUILD_ATTRIBUTES_DIR} ;
1012
1013HAIKU_NASM					?= ${HAIKU_NASM} ;
1014HAIKU_BOOT_BOARD			?= ${HAIKU_BOOT_BOARD} ;
1015
1016HOST_EXTENDED_REGEX_SED		?= ${HOST_EXTENDED_REGEX_SED} ;
1017HOST_GCC_RAW_VERSION		?= ${HOST_GCC_RAW_VERSION} ;
1018HOST_GCC_MACHINE			?= ${HOST_GCC_MACHINE} ;
1019HOST_LD						?= ${HOST_GCC_LD} ;
1020HOST_OBJCOPY				?= ${HOST_GCC_OBJCOPY} ;
1021HOST_SHA256					?= ${HOST_SHA256} ;
1022
1023HOST_HAIKU_PORTER			?= ${HOST_HAIKU_PORTER} ;
1024HAIKU_PORTS					?= ${HAIKU_PORTS} ;
1025HAIKU_PORTS_CROSS			?= ${HAIKU_PORTS_CROSS} ;
1026HAIKU_IS_BOOTSTRAP			?= ${HAIKU_IS_BOOTSTRAP} ;
1027
1028EOF
1029
1030for targetArch in $HAIKU_PACKAGING_ARCHS; do
1031	variables="
1032		HAIKU_GCC_RAW_VERSION		HAIKU_GCC_RAW_VERSION
1033		HAIKU_GCC_MACHINE			HAIKU_GCC_MACHINE
1034		HAIKU_GCC_LIB_DIR			HAIKU_GCC_LIB_DIR
1035		HAIKU_CPU					HAIKU_CPU
1036		HAIKU_BOOT_LIBGCC			HAIKU_BOOT_LIBGCC
1037		HAIKU_BOOT_LIBSUPC++		HAIKU_BOOT_LIBSUPCXX
1038		HAIKU_AR					HAIKU_AR
1039		HAIKU_CC					HAIKU_CC
1040		HAIKU_CC_IS_CLANG			HAIKU_CC_IS_CLANG
1041		HAIKU_LD					HAIKU_LD
1042		HAIKU_OBJCOPY				HAIKU_OBJCOPY
1043		HAIKU_RANLIB				HAIKU_RANLIB
1044		HAIKU_ELFEDIT				HAIKU_ELFEDIT
1045		HAIKU_STRIP					HAIKU_STRIP
1046		HAIKU_CPPFLAGS				HAIKU_CPPFLAGS
1047		HAIKU_CCFLAGS				HAIKU_CCFLAGS
1048		HAIKU_C++FLAGS				HAIKU_CXXFLAGS
1049		HAIKU_LDFLAGS				HAIKU_LDFLAGS
1050		HAIKU_ARFLAGS				HAIKU_ARFLAGS
1051		HAIKU_UNARFLAGS				HAIKU_UNARFLAGS
1052		HAIKU_USE_GCC_GRAPHITE		HAIKU_USE_GCC_GRAPHITE
1053		"
1054	set -- $variables
1055	while [ $# -ge 2 ]; do
1056		value=`get_variable ${2}_$targetArch`
1057		echo "${1}_${targetArch} ?= $value ;" >> "$buildConfigFile"
1058		shift 2
1059	done
1060
1061	# For variables that may have long values, distribute them over multiple
1062	# lines so that jam doesn't hit the maximum line length.
1063	variables="
1064		HAIKU_BOOT_C++_HEADERS_DIR	HAIKU_BOOT_CXX_HEADERS_DIR
1065		"
1066	set -- $variables
1067	while [ $# -ge 2 ]; do
1068		echo "${1}_${targetArch} ?= " >> "$buildConfigFile"
1069		get_variable ${2}_$targetArch | xargs -n 1 echo "   " \
1070			>> "$buildConfigFile"
1071		echo "    ;" >> "$buildConfigFile"
1072		shift 2
1073	done
1074done
1075
1076
1077# Generate a boot strap Jamfile in the output directory.
1078
1079cat << EOF > $outputDir/Jamfile
1080# automatically generated Jamfile
1081
1082HAIKU_TOP			= ${sourceDir} ;
1083HAIKU_OUTPUT_DIR	= ${outputDir} ;
1084
1085include [ FDirName \$(HAIKU_TOP) Jamfile ] ;
1086
1087EOF
1088
1089echo "Configured successfully!"
1090