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