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