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