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