xref: /haiku/configure (revision 5d0fd0e4220b461e2021d5768ebaa936c13417f8)
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", "arm64"
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		arm64-*)	targetCpu=arm64;;
258		i?86-*)		targetCpu=x86;;
259		m68k-*)		targetCpu=m68k;;
260		powerpc-*)	targetCpu=ppc;;
261		x86_64-*)	targetCpu=x86_64;;
262		*)
263			echo "Unsupported gcc target machine: $gccMachine" >&2
264			exit 1
265			;;
266	esac
267
268	local targetArch=$targetCpu
269
270	case $gccRawVersion in
271		2.9*)
272			# check for correct (most up-to-date) legacy compiler and complain
273			# if an older one is installed
274			if [ $gccRawVersion != $haikuRequiredLegacyGCCVersion ]; then
275				echo "GCC version $haikuRequiredLegacyGCCVersion is required!";
276				echo "Please download it from www.haiku-os.org...";
277				exit 1;
278			fi
279
280			targetArch=x86_gcc2
281			;;
282	esac
283
284	local bootLibgcc
285	local bootLibSupCxx
286	local bootCxxHeaders
287	case $gccMachine in
288		x86_64-*)
289			# Boot loader is 32-bit, need the 32-bit libs and c++ config
290			bootLibgcc=`$gcc -m32 -print-file-name=libgcc.a`
291			bootLibSupCxx=`$gcc -m32 -print-file-name=libsupc++.a`
292
293			local headersBase=$gccdir/../../../..
294			local headers=$headersBase/$gccMachine/include/c++/$gccRawVersion
295			if [ ! -d $headers ]; then
296				headers=$headersBase/include/c++/$gccRawVersion
297			fi
298			bootCxxHeaders="$headers/$gccMachine/32"
299			;;
300	esac
301
302	# determine whether graphite loop optimization should/can be used
303	local useGraphite=`get_variable HAIKU_USE_GCC_GRAPHITE_$targetCpu`
304	if [ -z "$useGraphite" ]; then
305		useGraphite=$useGccGraphiteDefault
306	fi
307
308	if [ "$useGraphite" != 0 ]; then
309		UNUSED=`echo "int main() {}" | $gcc -xc -c -floop-block - 2>&1`
310		if [ $? != 0 ]; then
311			echo "GCC Graphite loop optimizations cannot be used on $targetArch"
312			useGraphite=0
313		fi
314	fi
315
316	set_variable HAIKU_CPU_$targetArch $targetCpu
317
318	get_build_tool_path CC_$targetArch "$gcc"
319	set_variable HAIKU_CC_IS_CLANG_$targetArch $useClang
320	set_variable HAIKU_GCC_RAW_VERSION_$targetArch $gccRawVersion
321	set_variable HAIKU_GCC_MACHINE_$targetArch $gccMachine
322	set_variable HAIKU_GCC_LIB_DIR_$targetArch $gccdir
323	set_variable HAIKU_BOOT_CXX_HEADERS_DIR_$targetArch "$bootCxxHeaders"
324	set_variable HAIKU_BOOT_LIBSUPCXX_$targetArch "$bootLibSupCxx"
325	set_variable HAIKU_BOOT_LIBGCC_$targetArch $bootLibgcc
326	set_variable HAIKU_USE_GCC_GRAPHITE_$targetArch $useGraphite
327
328	standard_gcc_settings_targetArch=$targetArch
329}
330
331# set_variable
332#
333# Set the value of a variable.
334#
335set_variable()
336{
337	eval "$1=\"$2\""
338}
339
340# get_variable
341#
342# Echo the value of a variable.
343#
344get_variable()
345{
346	eval "echo \${$1}"
347}
348
349# set_default_value
350#
351# Set the value for a variable, if no value is set yet.
352#
353set_default_value()
354{
355	eval "$1=\${$1-$2}"
356}
357
358# get_build_tool_path
359#
360# Gets a usable absolute path of a build tool.
361#
362get_build_tool_path()
363{
364	local var="HAIKU_$1"
365	local varval="`get_variable $var`"
366	local cmd="$2"
367
368	if [ ! -z "$varval" ]; then
369		# this variable is already set (probably by user) so grab its contents
370		cmd=$varval
371	fi
372
373	local path=${cmd%% *}
374
375	if [ -f "$path" ]; then
376		# get absolute path from relative path
377		local oldPwd="`pwd`"
378		cd "`dirname "$path"`"
379		path="`pwd`/`basename "$path"`"
380		cd $oldPwd
381	else
382		which "$path" > /dev/null 2>&1 || {
383			echo "Build tool \"$path\" not found (maybe specify it in $var?)" >&2
384			exit 1
385		}
386	fi
387
388	if test "${cmd#* }" != "$cmd"; then
389		# $cmd contains arguments, so preserve them (and only them)
390		cmd=${cmd#* }
391	else
392		# $cmd does not contain arguments, so unset it
393		cmd=
394	fi
395	eval "$var=\"$path $cmd\""
396}
397
398# check_native_xattrs
399#
400# Checks the host platform's support for extended attributes.
401# 0: no support, 1: only enough for xattr-ref, 2: full support
402#
403check_native_xattrs()
404{
405	local xattr_set=
406	local xattr_set_args=
407	local xattr_get=
408	local xattr_get_args=
409	case $HOST_PLATFORM in
410		haiku_host)
411			xattr_set="addattr"; xattr_set_args="\$NAME \"\$VALUE\""
412			xattr_get="catattr"; xattr_get_args="\$NAME"
413			;;
414		darwin)
415			xattr_set="xattr"; xattr_set_args="-w \$NAME \"\$VALUE\""
416			xattr_get="xattr"; xattr_get_args="-p \$NAME"
417			;;
418		freebsd)
419			xattr_set="setextattr"; xattr_set_args="user \$NAME \"\$VALUE\""
420			xattr_get="getextattr"; xattr_get_args="user \$NAME"
421			;;
422		linux)
423			xattr_set="setfattr"; xattr_set_args="-n user.\$NAME -v \"\$VALUE\""
424			xattr_get="getfattr"; xattr_get_args="-n user.\$NAME"
425			;;
426		*)
427			return 0
428			;;
429	esac
430	if ! type $xattr_set >/dev/null 2>&1; then
431		echo "$0: could not find $xattr_set, assuming host has no extended attributes"
432		return 0
433	elif ! type $xattr_get >/dev/null 2>&1; then
434		echo "$0: could not find $xattr_get, assuming host has no extended attributes"
435		return 0
436	fi
437
438	mkdir -p "$outputDir"
439	echo "xattr test file" >"$outputDir/xattrtest"
440	local i=0
441	# on round 0, we test if we can set 3 attrs of 1K each (enough for xattr-ref)
442	# on round 1, we test if we can set 3 attrs of 45K each (enough for full xattr)
443	while [ $i -lt 2 ]; do
444		local j=0
445		while [ $j -lt 3 ]; do
446			NAME=attr$j
447			VALUE=`printf '%*s' $((1024 + $i * 45056)) "" | tr ' ' x`
448			if [ `echo -n $VALUE | wc -c` -lt $((1024 + $i * 45056)) ]; then
449				echo "$0: warning: could not generate test data for extended attributes"
450				rm "$outputDir/xattrtest"
451				return $i
452			elif ! $xattr_set `eval echo \"$xattr_set_args\"` \
453					"$outputDir/xattrtest" >/dev/null 2>&1 ; then
454				rm "$outputDir/xattrtest"
455				return $i
456			fi
457			j=$((j+1))
458		done
459		i=$((i+1))
460	done
461	rm "$outputDir/xattrtest"
462	return 2
463}
464
465is_in_list()
466{
467	local element
468	for element in $2; do
469		if [ "$1" = "$element" ]; then
470			return 0
471		fi
472	done
473	return 1
474}
475
476# check for --help or -h and show usage immediately
477if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
478	usage; exit 0;
479fi
480
481# get cwd and the source directory
482currentDir=`pwd`
483cd `dirname "$0"`
484sourceDir=`pwd`
485cd "$currentDir"
486
487# determine output directory
488if [ "$currentDir" = "$sourceDir" ]; then
489	outputDir=$currentDir/generated
490else
491	outputDir=$currentDir
492fi
493buildOutputDir="$outputDir/build"
494HAIKU_BUILD_ATTRIBUTES_DIR="$outputDir/attributes"
495buildConfigFile="$buildOutputDir/BuildConfig"
496
497# check for update request
498if [ "$1" = "--update" ]; then
499	if ! [ -e "$buildConfigFile" ]; then
500		echo $0 --update: \'$buildConfigFile\' not found - updating not possible.
501		exit 1
502	fi
503	# get last configure invocation and flags from BuildConfig and call ourselves with it
504	lastPwd=`grep "#d " "$buildConfigFile" | cut -c 4-`
505	lastConfig=`grep "#c " "$buildConfigFile" | cut -c 4-`
506	lastEnv=`grep "#e " "$buildConfigFile" | cut -c 4-`
507	lastArgs=`grep "#a " "$buildConfigFile" | cut -c 4-`
508	if [ -z "$lastConfig" ]; then
509		echo "$0 --update: The previous configure invocation was not properly" \
510			"encoded into '$buildConfigFile' - updating not possible."
511		exit 1
512	fi
513	cd $lastPwd
514	if [ -n "$lastEnv" ]; then
515		export $lastEnv
516	fi
517	$lastConfig $lastArgs
518	exit $?
519fi
520
521# backup the passed arguments
522configureArgs="$@"
523configurePath=$0
524
525# backup relevant environs
526configureEnvirons=
527for var in `env`; do
528	case "$var" in
529		CC\=*|HAIKU*\=*)
530			configureEnvirons="$configureEnvirons $var"
531			;;
532	esac
533done
534
535# ensure umask is not too restrictive
536if [ $(umask) -gt 22 ]; then
537	echo "Your umask is too restrictive (should be: <= 0022; is actually:" $(umask)")"
538	exit 1
539fi
540
541# internal default parameter values
542#
543platform=`uname`
544platformMachine=`uname  -m`
545targetArchs=
546buildCrossTools=
547buildCrossToolsScript="$sourceDir/build/scripts/build_cross_tools"
548buildCrossToolsJobs=
549useClang=0
550useGccGraphiteDefault=0
551unknownArchIndex=1
552haikuTargetArchs=
553gdbSources=
554
555if [ -z "$CC" ]; then
556	CC=gcc
557fi
558
559# exported (BuildSetup) default parameter values
560#
561HOST_GCC_RAW_VERSION=`$CC -dumpversion`
562HOST_GCC_MACHINE=`$CC -dumpmachine`
563HAIKU_INCLUDE_SOURCES=0
564HAIKU_INCLUDE_3RDPARTY=0
565HAIKU_DISTRO_COMPATIBILITY=default
566TARGET_PLATFORM=haiku
567HAIKU_USE_GCC_PIPE=0
568HAIKU_HOST_USE_32BIT=0
569HAIKU_HOST_USE_XATTR=
570HAIKU_HOST_USE_XATTR_REF=
571HAIKU_HOST_BUILD_ONLY=0
572HOST_EXTENDED_REGEX_SED="sed -r"
573HOST_GCC_LD=`$CC -print-prog-name=ld`
574HOST_GCC_OBJCOPY=`$CC -print-prog-name=objcopy`
575HOST_SHA256=
576HOST_HAIKU_PORTER=
577HAIKU_PORTS=
578HAIKU_PORTS_CROSS=
579HAIKU_IS_BOOTSTRAP=0
580HAIKU_BOOT_BOARD=
581HAIKU_NO_DOWNLOADS=0
582
583HAIKU_PACKAGING_ARCHS=
584
585set_default_value HAIKU_NASM		nasm
586
587if sha256sum < /dev/null > /dev/null 2>&1; then
588	HOST_SHA256=sha256sum
589elif sha256 < /dev/null > /dev/null 2>&1; then
590	HOST_SHA256="sha256 -q"
591elif shasum < /dev/null > /dev/null 2>&1; then
592	HOST_SHA256="shasum -a 256"
593else
594	echo "Error: Neither sha256sum nor sha256 seem to be available!" >&2
595	exit 1
596fi
597
598haikuRequiredLegacyGCCVersion="2.95.3-haiku-2017_07_20"
599export haikuRequiredLegacyGCCVersion
600	# version of legacy gcc required to build haiku
601supportedTargetArchs="
602	arm
603	arm64
604	m68k
605	ppc
606	x86
607	x86_64
608	x86_gcc2
609	"
610
611# parse parameters
612#
613while [ $# -gt 0 ] ; do
614	case "$1" in
615		--bootstrap)
616			assertparams "$1" 3 $#
617			HOST_HAIKU_PORTER="`absolute_path $2`"
618			HAIKU_PORTS_CROSS="`absolute_path $3`"
619			HAIKU_PORTS="`absolute_path $4`"
620			HAIKU_IS_BOOTSTRAP=1
621			HAIKU_NO_DOWNLOADS=1
622			check_file_exists "$HOST_HAIKU_PORTER" || (
623				echo "Invalid path to haikuporter: $HOST_HAIKU_PORTER" >&2
624				exit 1
625			)
626			check_dir_exists "$HAIKU_PORTS" || (
627				echo "Non-existent directory $HAIKU_PORTS" >&2
628				exit 1
629			)
630			check_dir_exists "$HAIKU_PORTS_CROSS" || (
631				echo "Non-existent directory $HAIKU_PORTS_CROSS" >&2
632				exit 1
633			)
634			shift 4
635			;;
636		--build-cross-tools)
637			if [ -z "$buildCrossTools" ]; then
638				assertparams "$1" 2 $#
639				targetArch=$2
640				buildCrossTools=$3
641				shift 3
642			else
643				assertparam "$1" $#
644				targetArch=$2
645				shift 2
646			fi
647			case "$targetArch" in
648				x86_gcc2)	targetMachine=i586-pc-haiku;;
649				x86)		targetMachine=i586-pc-haiku;;
650				x86_64)		targetMachine=x86_64-unknown-haiku;;
651				ppc)		targetMachine=powerpc-apple-haiku;;
652				m68k)		targetMachine=m68k-unknown-haiku;;
653				arm)		targetMachine=arm-unknown-haiku;;
654				*)
655					echo "Unsupported target architecture: $targetArch" >&2
656					exit 1
657					;;
658			esac
659			set_variable buildCrossToolsMachine_$targetArch $targetMachine
660			targetArchs="$targetArchs $targetArch"
661			;;
662		--cross-tools-prefix)
663			assertparam "$1" $#
664			targetArch=unknown${unknownArchIndex}
665			set_variable crossToolsPrefix_$targetArch "$2"
666			targetArchs="$targetArchs $targetArch"
667			unknownArchIndex=$(($unknownArchIndex + 1))
668			shift 2
669			;;
670		--distro-compatibility)
671			assertparam "$1" $#
672			HAIKU_DISTRO_COMPATIBILITY=$2
673			case "$HAIKU_DISTRO_COMPATIBILITY" in
674				official)	;;
675				compatible)	;;
676				default)	;;
677				*)			echo "Invalid distro compatibility" \
678								"level: $HAIKU_DISTRO_COMPATIBILITY"
679							exit 1;;
680			esac
681			shift 2
682			;;
683		--host-only)	HAIKU_HOST_BUILD_ONLY=1; shift 1;;
684		--include-sources)	HAIKU_INCLUDE_SOURCES=1; shift 1;;
685		--include-3rdparty)	HAIKU_INCLUDE_3RDPARTY=1; shift 1;;
686        -j*)				buildCrossToolsJobs="$1"; shift 1;;
687		--no-downloads)	HAIKU_NO_DOWNLOADS=1; shift 1;;
688		--target-arch)
689			assertparam "$1" $#
690			targetArch=$2
691			shift 2
692			if [ ! "$platform" = Haiku ]; then
693				echo "--target-arch can only be specified on Haiku." >&2
694				exit 1
695			fi
696			is_in_list "$targetArch" "$supportedTargetArchs" || (
697				echo "Unsupported target architecture: \"$targetArch\"" >&2
698				exit 1
699			)
700			haikuTargetArchs="$haikuTargetArchs $targetArch"
701			;;
702		--use-clang)
703			assertparam "$1" $#
704			targetArch=$2
705			useClang=1
706			case "$targetArch" in
707				x86)		targetMachine=i586-pc-haiku;;
708				x86_64)		targetMachine=x86_64-unknown-haiku;;
709				ppc)		targetMachine=powerpc-apple-haiku;;
710				arm)		targetMachine=arm-unknown-haiku;;
711				arm64)		targetMachine=arm64-unknown-haiku;;
712				*)
713					echo "Unsupported target architecture: $2" >&2
714					exit 1
715					;;
716			esac
717			get_build_tool_path clang clang
718			if [ -z `get_variable "crossToolsPrefix_$targetArch"` ] \
719					&& [ -z `get_variable buildCrossToolsMachine_$targetArch` ]; then
720				set_variable crossToolsPrefix_$targetArch llvm-
721			fi
722			targetArchs="$targetArchs $targetArch"
723			shift 2
724			;;
725		--use-gcc-pipe)	HAIKU_USE_GCC_PIPE=1; shift 1;;
726		--use-gcc-graphite)	useGccGraphiteDefault=1; shift 1;;
727		--use-32bit)	HAIKU_HOST_USE_32BIT=1; shift 1;;
728		--no-full-xattr)HAIKU_HOST_USE_XATTR=0; shift 1;;
729		--no-xattr)		HAIKU_HOST_USE_XATTR_REF=0; shift 1;;
730		--with-gdb)	gdbSources=$2; shift 2;;
731		*)				echo Invalid argument: \`$1\'; exit 1;;
732	esac
733done
734
735# detect the build platform
736case "${platform}" in
737	Darwin)	HOST_PLATFORM=darwin ;;
738	FreeBSD)	HOST_PLATFORM=freebsd
739				if [ "$HAIKU_HOST_USE_32BIT" = 1 ] ; then
740					echo Unsupported platform: FreeBSD ${platformMachine}
741					exit 1
742				fi	;;
743	Haiku)	HOST_PLATFORM=haiku_host ;;
744	Linux)	HOST_PLATFORM=linux ;;
745	OpenBSD) HOST_PLATFORM=openbsd ;;
746	SunOS)	HOST_PLATFORM=sunos ;;
747	CYGWIN_NT-*) HOST_PLATFORM=cygwin ;;
748	*)		echo Unsupported platform: ${platform}
749			exit 1 ;;
750esac
751
752# check for case-sensitive filesystem
753mkdir haikuCaseTest 2>/dev/null
754mkdir haikucasetest 2>/dev/null
755caseInsensitive=$?
756rmdir haikuCaseTest haikucasetest 2>/dev/null
757if [ $caseInsensitive != 0 ]; then
758	echo "You need a case-sensitive file-system to build Haiku."
759	if [ $HOST_PLATFORM = "darwin" ]; then
760		echo "You can create a case-sensitive disk image using Disk Utility."
761	fi
762	exit 1
763fi
764
765# check xattr support
766if [ -z $HAIKU_HOST_USE_XATTR_REF ]; then
767	check_native_xattrs
768	attrSupport=$?
769	if [ $attrSupport = 2 ] && [ -z $HAIKU_HOST_USE_XATTR ]; then
770		HAIKU_HOST_USE_XATTR=1
771	elif [ $attrSupport = 1 ]; then
772		HAIKU_HOST_USE_XATTR_REF=1
773	fi
774fi
775if [ -z $HAIKU_HOST_USE_XATTR ]; then HAIKU_HOST_USE_XATTR=0; fi
776if [ -z $HAIKU_HOST_USE_XATTR_REF ]; then HAIKU_HOST_USE_XATTR_REF=0; fi
777
778# determine how to invoke sed with extended regexp support for non-GNU sed
779if [ $HOST_PLATFORM = "darwin" ]; then
780	HOST_EXTENDED_REGEX_SED="sed -E"
781fi
782
783# check if nasm can actually output ELF files
784# (the stock version in OSX can't)
785# XXX: should probably only test for x86* arch
786if [ "$("$HAIKU_NASM" -hf | grep -c elf'[36][24] ')" -ne "2" ]; then
787	echo "$HAIKU_NASM cannot generate ELF files. Please install a working version."
788	if [ $HOST_PLATFORM = "darwin" ]; then
789		echo "You can install it from Mac Ports."
790		echo "Mac Ports is available at: http://www.macports.org/"
791	fi
792	exit 1
793fi
794
795# create output directory
796mkdir -p "$buildOutputDir" || exit 1
797
798if [ "$HAIKU_HOST_BUILD_ONLY" = 1 ]; then
799	invalidCommand=$sourceDir/build/scripts/host_build_only
800	HAIKU_AR=$invalidCommand
801	HAIKU_CC=$invalidCommand
802	HAIKU_LD=$invalidCommand
803	HAIKU_OBJCOPY=$invalidCommand
804	HAIKU_RANLIB=$invalidCommand
805	HAIKU_ELFEDIT=$invalidCommand
806	HAIKU_NASM=$invalidCommand
807	HAIKU_STRIP=$invalidCommand
808else
809	# On Haiku determine target architectures and tools automatically.
810	if [ -z "$targetArchs" ]; then
811		if [ $HOST_PLATFORM != haiku_host ]; then
812			echo "Please specify the build tools to use or build (via" \
813				"--cross-tools-prefix or --build-cross-tools) or specify a" \
814				"host-only build (--host-only)." >&2
815			echo "For more info, invoke $0 --help"
816			exit 1
817		fi
818
819		# determine primary architecture
820		targetArch=`package list -i /system/packages/haiku-*.hpkg \
821			| sed '/^\s*architecture:/!d; s,^\s*architecture:\s*,,'`
822		is_in_list "$targetArch" "$supportedTargetArchs" || (
823			echo "Unsupported target architecture: \"$targetArch\"" >&2
824			exit 1
825		)
826		targetArchs=$targetArch
827
828		set_default_value HAIKU_AR_$targetArch			ar
829		set_default_value HAIKU_CC_$targetArch			gcc
830		set_default_value HAIKU_LD_$targetArch			ld
831		set_default_value HAIKU_OBJCOPY_$targetArch		objcopy
832		set_default_value HAIKU_RANLIB_$targetArch		ranlib
833		set_default_value HAIKU_ELFEDIT_$targetArch		elfedit
834		set_default_value HAIKU_STRIP_$targetArch		strip
835
836		# determine secondary architectures
837		for targetArch in $supportedTargetArchs; do
838			if [ -e /system/packages/haiku_$targetArch-*.hpkg ]; then
839				targetArchs="$targetArchs $targetArch"
840				set_default_value HAIKU_AR_$targetArch		ar-$targetArch
841				set_default_value HAIKU_CC_$targetArch		gcc-$targetArch
842				set_default_value HAIKU_LD_$targetArch		ld-$targetArch
843				set_default_value HAIKU_OBJCOPY_$targetArch	objcopy-$targetArch
844				set_default_value HAIKU_RANLIB_$targetArch	ranlib-$targetArch
845				set_default_value HAIKU_ELFEDIT_$targetArch	elfedit-$targetArch
846				set_default_value HAIKU_STRIP_$targetArch	strip-$targetArch
847			fi
848		done
849
850		# The target architectures might have been specified explicitly.
851		if [ -n "$haikuTargetArchs" ]; then
852			for targetArch in $haikuTargetArchs; do
853				is_in_list "$targetArch" "$targetArchs" || (
854					echo "Unsupported target architecture: \"$targetArch\"." \
855						"Only native architectures of the host platform can" \
856						"be specified." >&2
857					exit 1
858				)
859			done
860			targetArchs="$haikuTargetArchs"
861		fi
862	fi
863
864	isPrimaryArch=1
865	for targetArch in $targetArchs; do
866		# Note: targetArch is "unknown<n>" at this point if a cross-tools
867		# prefix was specified. The standard_gcc_settings call below will get
868		# the actual architecture.
869
870		if test "${HAIKU_PACKAGING_ARCHS#*$targetArch\b}" != "$HAIKU_PACKAGING_ARCHS"; then
871			# somehow we wound up with a duplicate arch; skip this one
872			continue
873		fi
874
875		crossToolsPrefix=`get_variable crossToolsPrefix_$targetArch`
876
877		# build cross tools from sources
878		if [ -n "$buildCrossTools" -a -z "$crossToolsPrefix" ]; then
879			crossToolsDir="$outputDir/cross-tools-$targetArch"
880			targetMachine=`get_variable buildCrossToolsMachine_$targetArch`
881			script="$buildCrossToolsScript"
882			scriptArgs=
883			if [ $targetArch != x86_gcc2 ]; then
884				script="${script}_gcc4"
885				scriptArgs="$targetMachine"
886				set_default_value HAIKU_USE_GCC_GRAPHITE_$targetArch	\
887					$useGccGraphiteDefault
888			fi
889			secondaryArch=
890			if [ -z "$isPrimaryArch" ]; then
891				secondaryArch=$targetArch
892			fi
893
894			case $HOST_PLATFORM in
895				freebsd|openbsd)	MAKE=gmake;;
896				*)					MAKE=make;;
897			esac
898
899			if ! valid_toolchain "${targetMachine}" "${crossToolsDir}" "${buildCrossTools}"; then
900				MAKE=$MAKE \
901				SECONDARY_ARCH=$secondaryArch \
902				HAIKU_USE_GCC_GRAPHITE=`get_variable \
903					HAIKU_USE_GCC_GRAPHITE_$targetArch` \
904				HAIKU_USE_GCC_PIPE=$HAIKU_USE_GCC_PIPE \
905				HAIKU_USE_GDB="$gdbSources" \
906				"$script" $scriptArgs "$sourceDir" "$buildCrossTools" \
907					"$crossToolsDir" $buildCrossToolsJobs || exit 1
908			else
909				echo "$targetArch crosstools already exist in $crossToolsDir; skipping build"
910			fi
911			crossToolsPrefix="$crossToolsDir/bin/${targetMachine}-"
912		fi
913
914		# prepare gcc settings and get the actual target architecture
915		if [ $useClang = 1 ]; then
916			gcc="$HAIKU_clang -target ${targetMachine}"
917			if [ ! -z "${crossToolsPrefix}" ]; then
918				gcc="$gcc -B ${crossToolsPrefix}"
919			fi
920
921			# Clang's compiler intrinsics are not compatible with GCC's or even
922			# across versions of Clang, so we must collect them for use in the build.
923			mkdir -p "$outputDir/clang_headers" || exit 1
924			clangHeadersDir=`$gcc -print-resource-dir`/include/
925			case $targetArch in
926				x86*) cp $clangHeadersDir/*intrin* $clangHeadersDir/mm3* "$outputDir/clang_headers" || exit 1 ;;
927				ppc*) cp $clangHeadersDir/*altivec* "$outputDir/clang_headers" || exit 1 ;;
928				arm*) cp $clangHeadersDir/*arm* "$outputDir/clang_headers" || exit 1 ;;
929			esac
930		elif [ -z "${crossToolsPrefix}" ]; then
931			gcc=`get_variable HAIKU_CC_$targetArch`
932		else
933			gcc="${crossToolsPrefix}gcc"
934		fi
935		standard_gcc_settings "$gcc"
936		targetArch=$standard_gcc_settings_targetArch
937
938		# set default values for flags
939		set_default_value HAIKU_CPPFLAGS_$targetArch	""
940		set_default_value HAIKU_CCFLAGS_$targetArch		""
941		set_default_value HAIKU_CXXFLAGS_$targetArch	""
942		set_default_value HAIKU_LDFLAGS_$targetArch		""
943		set_default_value HAIKU_ARFLAGS_$targetArch		cru
944		set_default_value HAIKU_UNARFLAGS_$targetArch	x
945
946		# Override the cross tools variables, if the tools were built or a
947		# prefix was specified.
948		if [ $useClang = 1 ]; then
949			get_build_tool_path LD_$targetArch ld.lld
950			get_build_tool_path ELFEDIT_$targetArch elfedit
951		elif [ -n "$crossToolsPrefix" ]; then
952			get_build_tool_path LD_$targetArch ${crossToolsPrefix}ld
953			case `get_variable HAIKU_GCC_RAW_VERSION_$targetArch` in
954				4.*|5.*|6.*|7.*|8.*)
955					get_build_tool_path ELFEDIT_$targetArch \
956						${crossToolsPrefix}elfedit
957				;;
958			esac
959		fi
960		if [ -n "$crossToolsPrefix" ]; then
961			get_build_tool_path AR_$targetArch ${crossToolsPrefix}ar
962			get_build_tool_path OBJCOPY_$targetArch ${crossToolsPrefix}objcopy
963			get_build_tool_path RANLIB_$targetArch ${crossToolsPrefix}ranlib
964			get_build_tool_path STRIP_$targetArch ${crossToolsPrefix}strip
965		fi
966
967		# check whether the Haiku compiler really targets Haiku
968		targetMachine=`get_variable HAIKU_GCC_MACHINE_$targetArch`
969		case "$targetMachine" in
970			*-*-haiku)	;;
971			*)
972				echo The compiler specified as Haiku target compiler is not a \
973				valid Haiku cross-compiler. Please see ReadMe.cross-compile. >&2
974				echo compiler: $HAIKU_CC
975				echo compiler is configured for target: $targetMachine
976				exit 1 ;;
977		esac
978
979		HAIKU_PACKAGING_ARCHS="$HAIKU_PACKAGING_ARCHS $targetArch"
980		isPrimaryArch=
981	done
982fi
983
984# Generate BuildConfig
985cat << EOF > "$buildConfigFile"
986# -- WARNING --
987# This file was AUTOMATICALLY GENERATED by configure, and will be completely
988# overwritten the next time configure is run.
989#
990#d ${currentDir}
991#c ${configurePath}
992#e ${configureEnvirons}
993#a ${configureArgs}
994
995TARGET_PLATFORM 			?= "${TARGET_PLATFORM}" ;
996HOST_PLATFORM				?= "${HOST_PLATFORM}" ;
997
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_CC					HAIKU_CC
1033		HAIKU_CC_IS_CLANG			HAIKU_CC_IS_CLANG
1034		HAIKU_USE_GCC_GRAPHITE		HAIKU_USE_GCC_GRAPHITE
1035		HAIKU_CPU					HAIKU_CPU
1036		HAIKU_GCC_MACHINE			HAIKU_GCC_MACHINE
1037		HAIKU_GCC_RAW_VERSION		HAIKU_GCC_RAW_VERSION
1038		HAIKU_GCC_LIB_DIR			HAIKU_GCC_LIB_DIR
1039		HAIKU_BOOT_LIBGCC			HAIKU_BOOT_LIBGCC
1040		HAIKU_BOOT_LIBSUPC++		HAIKU_BOOT_LIBSUPCXX
1041		HAIKU_AR					HAIKU_AR
1042		HAIKU_LD					HAIKU_LD
1043		HAIKU_OBJCOPY				HAIKU_OBJCOPY
1044		HAIKU_RANLIB				HAIKU_RANLIB
1045		HAIKU_ELFEDIT				HAIKU_ELFEDIT
1046		HAIKU_STRIP					HAIKU_STRIP
1047		HAIKU_CPPFLAGS				HAIKU_CPPFLAGS
1048		HAIKU_CCFLAGS				HAIKU_CCFLAGS
1049		HAIKU_C++FLAGS				HAIKU_CXXFLAGS
1050		HAIKU_LDFLAGS				HAIKU_LDFLAGS
1051		HAIKU_ARFLAGS				HAIKU_ARFLAGS
1052		HAIKU_UNARFLAGS				HAIKU_UNARFLAGS
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