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