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