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