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