xref: /haiku/configure (revision c085f3863924bb32c6b250e1b9697a39688effef)
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
824# locate python
825if python3 --version < /dev/null > /dev/null 2>&1; then
826	HOST_PYTHON="python3"
827elif python --version < /dev/null > /dev/null 2>&1; then
828	HOST_PYTHON="python"
829else
830	echo "a python interpreter is required"
831	exit 1
832fi
833
834# check if nasm can actually output ELF files
835# (the stock version in OSX can't)
836# XXX: should probably only test for x86* arch
837if [ "$("$HAIKU_NASM" -hf | grep -c elf'[36][24] ')" -ne "2" ]; then
838	echo "$HAIKU_NASM cannot generate ELF files. Please install a working version."
839	if [ $HOST_PLATFORM = "darwin" ]; then
840		echo "You can install it from Mac Ports."
841		echo "Mac Ports is available at: http://www.macports.org/"
842	fi
843	exit 1
844fi
845
846# create output directory
847mkdir -p "$buildOutputDir" || exit 1
848
849if [ "$HAIKU_HOST_BUILD_ONLY" = 1 ]; then
850	invalidCommand=$sourceDir/build/scripts/host_build_only
851	HAIKU_AR=$invalidCommand
852	HAIKU_CC=$invalidCommand
853	HAIKU_LD=$invalidCommand
854	HAIKU_OBJCOPY=$invalidCommand
855	HAIKU_RANLIB=$invalidCommand
856	HAIKU_ELFEDIT=$invalidCommand
857	HAIKU_NASM=$invalidCommand
858	HAIKU_STRIP=$invalidCommand
859else
860	# On Haiku determine target architectures and tools automatically.
861	if [ -z "$targetArchs" ]; then
862		if [ $HOST_PLATFORM != haiku_host ]; then
863			echo "Please specify the build tools to use or build (via" \
864				"--cross-tools-prefix or --build-cross-tools) or specify a" \
865				"host-only build (--host-only)." >&2
866			echo "For more info, invoke $0 --help"
867			exit 1
868		fi
869
870		# determine primary architecture
871		targetArch=`package list -i /system/packages/haiku-*.hpkg \
872			| sed '/^\s*architecture:/!d; s,^\s*architecture:\s*,,'`
873		is_in_list "$targetArch" "$supportedTargetArchs" || (
874			echo "Unsupported target architecture: \"$targetArch\"" >&2
875			exit 1
876		)
877		targetArchs=$targetArch
878
879		set_default_value HAIKU_AR_$targetArch			ar
880		set_default_value HAIKU_CC_$targetArch			gcc
881		set_default_value HAIKU_LD_$targetArch			ld
882		set_default_value HAIKU_OBJCOPY_$targetArch		objcopy
883		set_default_value HAIKU_RANLIB_$targetArch		ranlib
884		set_default_value HAIKU_ELFEDIT_$targetArch		elfedit
885		set_default_value HAIKU_STRIP_$targetArch		strip
886
887		# determine secondary architectures
888		for targetArch in $supportedTargetArchs; do
889			if [ -e /system/packages/haiku_$targetArch-*.hpkg ]; then
890				targetArchs="$targetArchs $targetArch"
891				set_default_value HAIKU_AR_$targetArch		ar-$targetArch
892				set_default_value HAIKU_CC_$targetArch		gcc-$targetArch
893				set_default_value HAIKU_LD_$targetArch		ld-$targetArch
894				set_default_value HAIKU_OBJCOPY_$targetArch	objcopy-$targetArch
895				set_default_value HAIKU_RANLIB_$targetArch	ranlib-$targetArch
896				set_default_value HAIKU_ELFEDIT_$targetArch	elfedit-$targetArch
897				set_default_value HAIKU_STRIP_$targetArch	strip-$targetArch
898			fi
899		done
900
901		# The target architectures might have been specified explicitly.
902		if [ -n "$haikuTargetArchs" ]; then
903			for targetArch in $haikuTargetArchs; do
904				is_in_list "$targetArch" "$targetArchs" || (
905					echo "Unsupported target architecture: \"$targetArch\"." \
906						"Only native architectures of the host platform can" \
907						"be specified." >&2
908					exit 1
909				)
910			done
911			targetArchs="$haikuTargetArchs"
912		fi
913	fi
914
915	isPrimaryArch=1
916	for targetArch in $targetArchs; do
917		# Note: targetArch is "unknown<n>" at this point if a cross-tools
918		# prefix was specified. The standard_gcc_settings call below will get
919		# the actual architecture.
920
921		if test "${HAIKU_PACKAGING_ARCHS#*$targetArch\b}" != "$HAIKU_PACKAGING_ARCHS"; then
922			# somehow we wound up with a duplicate arch; skip this one
923			continue
924		fi
925
926		crossToolsPrefix=`get_variable crossToolsPrefix_$targetArch`
927
928		# build cross tools from sources
929		if [ -n "$buildCrossTools" -a -z "$crossToolsPrefix" ]; then
930			crossToolsDir="$outputDir/cross-tools-$targetArch"
931			targetMachine=`get_variable buildCrossToolsMachine_$targetArch`
932			script="$buildCrossToolsScript"
933			scriptArgs=
934			if [ $targetArch != x86_gcc2 ]; then
935				script="${script}_gcc4"
936				scriptArgs="$targetMachine"
937				set_default_value HAIKU_USE_GCC_GRAPHITE_$targetArch	\
938					$useGccGraphiteDefault
939			fi
940			secondaryArch=
941			if [ -z "$isPrimaryArch" ]; then
942				secondaryArch=$targetArch
943			fi
944
945			case $HOST_PLATFORM in
946				freebsd|openbsd)	MAKE=gmake;;
947				*)					MAKE=make;;
948			esac
949
950			if ! valid_toolchain "${targetMachine}" "${crossToolsDir}" "${buildCrossTools}"; then
951				MAKE=$MAKE \
952				SECONDARY_ARCH=$secondaryArch \
953				HAIKU_USE_GCC_GRAPHITE=`get_variable \
954					HAIKU_USE_GCC_GRAPHITE_$targetArch` \
955				HAIKU_USE_GCC_PIPE=$HAIKU_USE_GCC_PIPE \
956				HAIKU_USE_GDB="$gdbSources" \
957				"$script" $scriptArgs "$sourceDir" "$buildCrossTools" \
958					"$crossToolsDir" $buildCrossToolsJobs || exit 1
959			else
960				echo "$targetArch crosstools already exist in $crossToolsDir; skipping build"
961			fi
962			crossToolsPrefix="$crossToolsDir/bin/${targetMachine}-"
963		fi
964
965		# prepare gcc settings and get the actual target architecture
966		if [ $useClang = 1 ]; then
967			gcc="$HAIKU_clang -target ${targetMachine}"
968			if [ ! -z "${crossToolsPrefix}" ]; then
969				gcc="$gcc -B ${crossToolsPrefix}"
970			fi
971
972			# Clang's compiler intrinsics are not compatible with GCC's or even
973			# across versions of Clang, so we must collect them for use in the build.
974			mkdir -p "$outputDir/clang_headers" || exit 1
975			clangHeadersDir=`$gcc -print-resource-dir`/include/
976			case $targetArch in
977				x86*) cp $clangHeadersDir/*intrin* $clangHeadersDir/mm3* "$outputDir/clang_headers" || exit 1 ;;
978				ppc*) cp $clangHeadersDir/*altivec* "$outputDir/clang_headers" || exit 1 ;;
979				arm*) cp $clangHeadersDir/*arm* "$outputDir/clang_headers" || exit 1 ;;
980			esac
981		elif [ -z "${crossToolsPrefix}" ]; then
982			gcc=`get_variable HAIKU_CC_$targetArch`
983		else
984			gcc="${crossToolsPrefix}gcc"
985		fi
986		standard_gcc_settings "$gcc"
987		targetArch=$standard_gcc_settings_targetArch
988
989		# set default values for flags
990		set_default_value HAIKU_CPPFLAGS_$targetArch	""
991		set_default_value HAIKU_CCFLAGS_$targetArch		""
992		set_default_value HAIKU_CXXFLAGS_$targetArch	""
993		set_default_value HAIKU_LINKFLAGS_$targetArch	""
994		set_default_value HAIKU_LDFLAGS_$targetArch		""
995		set_default_value HAIKU_ARFLAGS_$targetArch		cru
996		set_default_value HAIKU_UNARFLAGS_$targetArch	x
997
998		# Override the cross tools variables, if the tools were built or a
999		# prefix was specified.
1000		if [ $useClang = 1 ]; then
1001			get_build_tool_path LD_$targetArch ld.lld
1002			get_build_tool_path ELFEDIT_$targetArch elfedit
1003		elif [ -n "$crossToolsPrefix" ]; then
1004			get_build_tool_path LD_$targetArch ${crossToolsPrefix}ld
1005			case `get_variable HAIKU_GCC_RAW_VERSION_$targetArch` in
1006				4.*|5.*|6.*|7.*|8.*)
1007					get_build_tool_path ELFEDIT_$targetArch \
1008						${crossToolsPrefix}elfedit
1009				;;
1010			esac
1011		fi
1012		if [ -n "$crossToolsPrefix" ]; then
1013			get_build_tool_path AR_$targetArch ${crossToolsPrefix}ar
1014			get_build_tool_path OBJCOPY_$targetArch ${crossToolsPrefix}objcopy
1015			get_build_tool_path RANLIB_$targetArch ${crossToolsPrefix}ranlib
1016			get_build_tool_path STRIP_$targetArch ${crossToolsPrefix}strip
1017		fi
1018
1019		# check whether the Haiku compiler really targets Haiku
1020		targetMachine=`get_variable HAIKU_GCC_MACHINE_$targetArch`
1021		case "$targetMachine" in
1022			*-*-haiku)	;;
1023			*)
1024				echo The compiler specified as Haiku target compiler is not a \
1025				valid Haiku cross-compiler. Please see ReadMe.cross-compile. >&2
1026				echo compiler: $HAIKU_CC
1027				echo compiler is configured for target: $targetMachine
1028				exit 1 ;;
1029		esac
1030
1031		HAIKU_PACKAGING_ARCHS="$HAIKU_PACKAGING_ARCHS $targetArch"
1032		isPrimaryArch=
1033	done
1034fi
1035
1036# Generate BuildConfig
1037cat << EOF > "$buildConfigFile"
1038# -- WARNING --
1039# This file was AUTOMATICALLY GENERATED by configure, and will be completely
1040# overwritten the next time configure is run.
1041#
1042#d ${currentDir}
1043#c ${configurePath}
1044#e ${configureEnvirons}
1045#a ${configureArgs}
1046
1047HOST_PLATFORM				?= "${HOST_PLATFORM}" ;
1048TARGET_PLATFORM 			?= "${TARGET_PLATFORM}" ;
1049HAIKU_PACKAGING_ARCHS		?= ${HAIKU_PACKAGING_ARCHS} ;
1050
1051HAIKU_NO_DOWNLOADS			?= "${HAIKU_NO_DOWNLOADS}" ;
1052HAIKU_INCLUDE_SOURCES		?= "${HAIKU_INCLUDE_SOURCES}" ;
1053HAIKU_INCLUDE_3RDPARTY		?= "${HAIKU_INCLUDE_3RDPARTY}" ;
1054HAIKU_DISTRO_COMPATIBILITY	?= "${HAIKU_DISTRO_COMPATIBILITY}" ;
1055
1056HAIKU_USE_GCC_PIPE			?= "${HAIKU_USE_GCC_PIPE}" ;
1057HAIKU_HOST_USE_32BIT		?= "${HAIKU_HOST_USE_32BIT}" ;
1058HAIKU_HOST_USE_XATTR		?= "${HAIKU_HOST_USE_XATTR}" ;
1059HAIKU_HOST_USE_XATTR_REF	?= "${HAIKU_HOST_USE_XATTR_REF}" ;
1060HAIKU_HOST_BUILD_ONLY		?= "${HAIKU_HOST_BUILD_ONLY}" ;
1061
1062HOST_CC						?= ${CC} ;
1063HOST_GCC_RAW_VERSION		?= ${HOST_GCC_RAW_VERSION} ;
1064HOST_GCC_MACHINE			?= ${HOST_GCC_MACHINE} ;
1065HOST_LD						?= ${HOST_GCC_LD} ;
1066HOST_OBJCOPY				?= ${HOST_GCC_OBJCOPY} ;
1067HOST_EXTENDED_REGEX_SED		?= ${HOST_EXTENDED_REGEX_SED} ;
1068HOST_SHA256					?= ${HOST_SHA256} ;
1069HOST_PYTHON					?= ${HOST_PYTHON} ;
1070HAIKU_NASM					?= ${HAIKU_NASM} ;
1071
1072HAIKU_BUILD_ATTRIBUTES_DIR	?= "${HAIKU_BUILD_ATTRIBUTES_DIR}" ;
1073
1074HOST_HAIKU_PORTER			?= ${HOST_HAIKU_PORTER} ;
1075HAIKU_PORTS					?= ${HAIKU_PORTS} ;
1076HAIKU_PORTS_CROSS			?= ${HAIKU_PORTS_CROSS} ;
1077HAIKU_IS_BOOTSTRAP			?= ${HAIKU_IS_BOOTSTRAP} ;
1078
1079EOF
1080
1081for targetArch in $HAIKU_PACKAGING_ARCHS; do
1082	variables="
1083		HAIKU_CC					HAIKU_CC
1084		HAIKU_CC_IS_CLANG			HAIKU_CC_IS_CLANG
1085		HAIKU_USE_GCC_GRAPHITE		HAIKU_USE_GCC_GRAPHITE
1086		HAIKU_CPU					HAIKU_CPU
1087		HAIKU_GCC_MACHINE			HAIKU_GCC_MACHINE
1088		HAIKU_GCC_RAW_VERSION		HAIKU_GCC_RAW_VERSION
1089		HAIKU_GCC_LIB_DIR			HAIKU_GCC_LIB_DIR
1090		HAIKU_BOOT_LIBGCC			HAIKU_BOOT_LIBGCC
1091		HAIKU_BOOT_LIBSUPC++		HAIKU_BOOT_LIBSUPCXX
1092		HAIKU_AR					HAIKU_AR
1093		HAIKU_LD					HAIKU_LD
1094		HAIKU_OBJCOPY				HAIKU_OBJCOPY
1095		HAIKU_RANLIB				HAIKU_RANLIB
1096		HAIKU_ELFEDIT				HAIKU_ELFEDIT
1097		HAIKU_STRIP					HAIKU_STRIP
1098		HAIKU_CPPFLAGS				HAIKU_CPPFLAGS
1099		HAIKU_CCFLAGS				HAIKU_CCFLAGS
1100		HAIKU_C++FLAGS				HAIKU_CXXFLAGS
1101		HAIKU_LINKFLAGS				HAIKU_LINKFLAGS
1102		HAIKU_LDFLAGS				HAIKU_LDFLAGS
1103		HAIKU_ARFLAGS				HAIKU_ARFLAGS
1104		HAIKU_UNARFLAGS				HAIKU_UNARFLAGS
1105		"
1106	set -- $variables
1107	while [ $# -ge 2 ]; do
1108		value=`get_variable ${2}_$targetArch`
1109		echo "${1}_${targetArch} ?= $value ;" >> "$buildConfigFile"
1110		shift 2
1111	done
1112
1113	# For variables that may have long values, distribute them over multiple
1114	# lines so that jam doesn't hit the maximum line length.
1115	variables="
1116		HAIKU_BOOT_C++_HEADERS_DIR	HAIKU_BOOT_CXX_HEADERS_DIR
1117		"
1118	set -- $variables
1119	while [ $# -ge 2 ]; do
1120		echo "${1}_${targetArch} ?= " >> "$buildConfigFile"
1121		get_variable ${2}_$targetArch | xargs -n 1 echo "   " \
1122			>> "$buildConfigFile"
1123		echo "    ;" >> "$buildConfigFile"
1124		shift 2
1125	done
1126done
1127
1128
1129# Generate a Jamfile in the output directory.
1130
1131cat << EOF > $outputDir/Jamfile
1132# -- WARNING --
1133# This file was AUTOMATICALLY GENERATED by configure, and will be completely
1134# overwritten the next time configure is run.
1135
1136HAIKU_TOP			= $(relative_to "${sourceDir}" "${outputDir}") ;
1137HAIKU_OUTPUT_DIR	= . ;
1138
1139include [ FDirName \$(HAIKU_TOP) Jamfile ] ;
1140
1141EOF
1142
1143echo "Configured successfully!"
1144