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