1#!/bin/bash
2
3#
4# Board Configuration Section
5# ===========================
6#
7# Board configuration moved to parse-platforms.py and platforms.config.
8#
9# No need to edit below unless you are changing script functionality.
10#
11
12unset WORKSPACE EDK_TOOLS_DIR MAKEFLAGS
13
14TOOLS_DIR="`dirname $0`"
15. "$TOOLS_DIR"/common-functions
16PLATFORM_CONFIG=""
17VERBOSE=0
18ATF_DIR=
19TOS_DIR=
20TOOLCHAIN=
21OPENSSL_CONFIGURED=FALSE
22
23# Number of threads to use for build
24export NUM_THREADS=$((`getconf _NPROCESSORS_ONLN` + 1))
25
26function build_platform
27{
28	PLATFORM_NAME="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o longname`"
29	PLATFORM_PREBUILD_CMDS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o prebuild_cmds`"
30	PLATFORM_BUILDFLAGS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o buildflags`"
31	PLATFORM_BUILDFLAGS="$PLATFORM_BUILDFLAGS ${EXTRA_OPTIONS[@]}"
32	PLATFORM_BUILDCMD="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o buildcmd`"
33	PLATFORM_DSC="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o dsc`"
34	PLATFORM_ARCH="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o arch`"
35	PLATFORM_PACKAGES_PATH="$PWD"
36
37	TEMP_PACKAGES_PATH="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o packages_path`"
38	if [ -n "$TEMP_PACKAGES_PATH" ]; then
39		IFS=:
40		for path in "$TEMP_PACKAGES_PATH"; do
41			case "$path" in
42				/*)
43					PLATFORM_PACKAGES_PATH="$PLATFORM_PACKAGES_PATH:$path"
44				;;
45				*)
46					PLATFORM_PACKAGES_PATH="$PLATFORM_PACKAGES_PATH:$PWD/$path"
47				;;
48		        esac
49		done
50		unset IFS
51	fi
52	if [ $VERBOSE -eq 1 ]; then
53		echo "Setting build parallellism to $NUM_THREADS processes\n"
54		echo "PLATFORM_NAME=$PLATFORM_NAME"
55		echo "PLATFORM_PREBUILD_CMDS=$PLATFORM_PREBUILD_CMDS"
56		echo "PLATFORM_BUILDFLAGS=$PLATFORM_BUILDFLAGS"
57		echo "PLATFORM_BUILDCMD=$PLATFORM_BUILDCMD"
58		echo "PLATFORM_DSC=$PLATFORM_DSC"
59		echo "PLATFORM_ARCH=$PLATFORM_ARCH"
60		echo "PLATFORM_PACKAGES_PATH=$PLATFORM_PACKAGES_PATH"
61	fi
62
63	set_cross_compile
64	CROSS_COMPILE="$TEMP_CROSS_COMPILE"
65
66	echo "Building $PLATFORM_NAME - $PLATFORM_ARCH"
67	echo "CROSS_COMPILE=\"$TEMP_CROSS_COMPILE\""
68	echo "$board"_BUILDFLAGS="'$PLATFORM_BUILDFLAGS'"
69
70	if [ "$TARGETS" == "" ]; then
71		TARGETS=( RELEASE )
72	fi
73
74	case $TOOLCHAIN in
75		"gcc")
76			export TOOLCHAIN=`get_gcc_version "$CROSS_COMPILE"gcc`
77			;;
78		"clang")
79			export TOOLCHAIN=`get_clang_version clang`
80			;;
81	esac
82	echo "TOOLCHAIN is ${TOOLCHAIN}"
83
84	export ${TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE
85	echo "Toolchain prefix: ${TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE"
86
87	export PACKAGES_PATH="$PLATFORM_PACKAGES_PATH"
88	for target in "${TARGETS[@]}" ; do
89		if [ X"$PLATFORM_PREBUILD_CMDS" != X"" ]; then
90			echo "Run pre build commands"
91			eval ${PLATFORM_PREBUILD_CMDS}
92		fi
93		if [ X"$PLATFORM_BUILDCMD" == X"" ]; then
94			echo  ${TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${TOOLCHAIN} -p "$PLATFORM_DSC" -b "$target" \
95				${PLATFORM_BUILDFLAGS}
96			build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${TOOLCHAIN} -p "$PLATFORM_DSC" -b "$target" \
97				${PLATFORM_BUILDFLAGS}
98		else
99			${PLATFORM_BUILDCMD} -b "$target" ${PLATFORM_BUILDFLAGS}
100		fi
101		RESULT=$?
102		if [ $RESULT -eq 0 ]; then
103			if [ X"$TOS_DIR" != X"" ]; then
104				pushd $TOS_DIR >/dev/null
105				if [ $VERBOSE -eq 1 ]; then
106					echo "$TOOLS_DIR/tos-build.sh -e "$EDK2_DIR" -t "$target"_${TOOLCHAIN} $board"
107				fi
108				$TOOLS_DIR/tos-build.sh -e "$EDK2_DIR" -t "$target"_${TOOLCHAIN} $board
109				RESULT=$?
110				popd >/dev/null
111			fi
112		fi
113		if [ $RESULT -eq 0 ]; then
114			if [ X"$ATF_DIR" != X"" ]; then
115				pushd $ATF_DIR >/dev/null
116				if [ $VERBOSE -eq 1 ]; then
117					echo "$TOOLS_DIR/atf-build.sh -e "$EDK2_DIR" -t "$target"_${TOOLCHAIN} $board"
118				fi
119				$TOOLS_DIR/atf-build.sh -e "$EDK2_DIR" -t "$target"_${TOOLCHAIN} $board
120				RESULT=$?
121				popd >/dev/null
122			fi
123		fi
124		result_log $RESULT "$PLATFORM_NAME $target"
125	done
126	unset PACKAGES_PATH
127}
128
129
130function uefishell
131{
132	BUILD_ARCH=`uname -m`
133	case $BUILD_ARCH in
134		arm*)
135			ARCH=ARM
136			;;
137		aarch64)
138			ARCH=AARCH64
139			;;
140		*)
141			unset ARCH
142			;;
143	esac
144	export ARCH
145	if [ $VERBOSE -eq 1 ]; then
146		echo "Building BaseTools"
147	fi
148	export EDK_TOOLS_PATH=`pwd`/BaseTools
149	. edksetup.sh BaseTools
150	make -C $EDK_TOOLS_PATH
151	if [ $? -ne 0 ]; then
152		echo " !!! UEFI BaseTools failed to build !!! " >&2
153		exit 1
154	fi
155}
156
157
158function usage
159{
160	echo "usage:"
161	echo -n "uefi-build.sh [-b DEBUG | RELEASE] [ all "
162	for board in "${boards[@]}" ; do
163	    echo -n "| $board "
164	done
165	echo "]"
166	printf "%8s\tbuild %s\n" "all" "all supported platforms"
167	for board in "${boards[@]}" ; do
168		PLATFORM_NAME="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o longname`"
169		printf "%8s\tbuild %s\n" "$board" "${PLATFORM_NAME}"
170	done
171}
172
173#
174# Since we do a command line validation on whether specified platforms exist or
175# not, do a first pass of command line to see if there is an explicit config
176# file there to read valid platforms from.
177#
178commandline=( "$@" )
179i=0
180for arg;
181do
182	if [ $arg == "-c" ]; then
183		FILE_ARG=${commandline[i + 1]}
184		if [ ! -f "$FILE_ARG" ]; then
185			echo "ERROR: configuration file '$FILE_ARG' not found" >&2
186			exit 1
187		fi
188		case "$FILE_ARG" in
189			/*)
190				PLATFORM_CONFIG="-c \"$FILE_ARG\""
191			;;
192			*)
193				PLATFORM_CONFIG="-c `readlink -f \"$FILE_ARG\"`"
194			;;
195		esac
196		echo "Platform config file: '$FILE_ARG'"
197		export PLATFORM_CONFIG
198	fi
199	i=$(($i + 1))
200done
201
202builds=()
203boards=()
204boardlist="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG shortlist`"
205for board in $boardlist; do
206    boards=(${boards[@]} $board)
207done
208
209NUM_TARGETS=0
210
211while [ "$1" != "" ]; do
212	case $1 in
213		all )
214			builds=(${boards[@]})
215			NUM_TARGETS=$(($NUM_TARGETS + 1))
216			;;
217		"/h" | "/?" | "-?" | "-h" | "--help" )
218			usage
219			exit
220			;;
221		"-v" )
222			VERBOSE=1
223			;;
224		"-a" )
225			shift
226			ATF_DIR="$1"
227			;;
228		"-c" )
229			# Already parsed above - skip this + option
230			shift
231			;;
232		"-s" )
233			shift
234			export TOS_DIR="$1"
235			;;
236		"-b" | "--build" )
237			shift
238			echo "Adding Build profile: $1"
239			TARGETS=( ${TARGETS[@]} $1 )
240			;;
241		"-D" )
242			shift
243			echo "Adding option: -D $1"
244			EXTRA_OPTIONS=( ${EXTRA_OPTIONS[@]} "-D" $1 )
245			;;
246		"-T" )
247			shift
248			echo "Setting toolchain to '$1'"
249			TOOLCHAIN="$1"
250			;;
251		"-1" )
252			NUM_THREADS=1
253			;;
254		* )
255			MATCH=0
256			for board in "${boards[@]}" ; do
257				if [ "$1" == $board ]; then
258					MATCH=1
259					builds=(${builds[@]} "$board")
260					break
261				fi
262			done
263
264			if [ $MATCH -eq 0 ]; then
265				echo "unknown arg $1"
266				usage
267				exit 1
268			fi
269			NUM_TARGETS=$(($NUM_TARGETS + 1))
270			;;
271	esac
272	shift
273done
274
275# If there were no args, use a menu to select a single board / all boards to build
276if [ $NUM_TARGETS -eq 0 ]
277then
278	read -p "$(
279			f=0
280			for board in "${boards[@]}" ; do
281					echo "$((++f)): $board"
282			done
283			echo $((++f)): all
284
285			echo -ne '> '
286	)" selection
287
288	if [ "$selection" -eq $((${#boards[@]} + 1)) ]; then
289		builds=(${boards[@]})
290	else
291		builds="${boards[$((selection-1))]}"
292	fi
293fi
294
295# Check to see if we are in a UEFI repository
296# refuse to continue if we aren't
297if [ ! -e BaseTools ]
298then
299	echo "ERROR: we aren't in the UEFI directory."
300	echo "       I can tell because I can't see the BaseTools directory"
301	exit 1
302fi
303
304EDK2_DIR="$PWD"
305export VERBOSE
306
307if [[ "${EXTRA_OPTIONS[@]}" != *"FIRMWARE_VER"* ]]; then
308	if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
309		FIRMWARE_VER=`git rev-parse --short HEAD`
310		if ! git diff-index --quiet HEAD --; then
311			FIRMWARE_VER="${FIRMWARE_VER}-dirty"
312		fi
313		EXTRA_OPTIONS=( ${EXTRA_OPTIONS[@]} "-D" FIRMWARE_VER=$FIRMWARE_VER )
314		if [ $VERBOSE -eq 1 ]; then
315			echo "FIRMWARE_VER=$FIRMWARE_VER"
316			echo "EXTRA_OPTIONS=$EXTRA_OPTIONS"
317		fi
318	fi
319fi
320
321uefishell
322
323if [ X"$TOOLCHAIN" = X"" ]; then
324	TOOLCHAIN=gcc
325fi
326
327for board in "${builds[@]}" ; do
328	build_platform
329done
330
331result_print
332