blob: 3e218b3c752614d5c728b930e59ebdf96f5e3b7b [file] [log] [blame]
John Stultzaccad872017-07-06 13:56:07 -07001#!/bin/bash
2
3#
4# edk2-build.sh: evolution of uefi-build.sh for edk2-platforms
5#
6
7unset MAKEFLAGS # BaseTools not safe to build parallel, prevent env overrides
8
9TOOLS_DIR="`dirname $0`"
10TOOLS_DIR="`readlink -f \"$TOOLS_DIR\"`"
11export TOOLS_DIR
12. "$TOOLS_DIR"/common-functions
13PLATFORM_CONFIG="-c $TOOLS_DIR/edk2-platforms.config"
14ARCH=
15VERBOSE=0 # Override with -v
16ATF_DIR=
17TOS_DIR=
18TOOLCHAIN="gcc" # Override with -T
19WORKSPACE=
20EDK2_DIR=
21PLATFORMS_DIR=
22NON_OSI_DIR=
23IMPORT_OPENSSL=TRUE
24OPENSSL_CONFIGURED=FALSE
25
26# Number of threads to use for build
27export NUM_THREADS=$((`getconf _NPROCESSORS_ONLN` + `getconf _NPROCESSORS_ONLN`))
28
29function do_build
30{
31 PLATFORM_ARCH=`echo $board | cut -s -d: -f2`
32 if [ -n "$PLATFORM_ARCH" ]; then
33 board=`echo $board | cut -d: -f1`
34 else
35 PLATFORM_ARCH="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o arch`"
36 fi
37 PLATFORM_NAME="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o longname` ($PLATFORM_ARCH)"
38 if [ -z "$PLATFORM_ARCH" ]; then
39 echo "Unknown target architecture - aborting!" >&2
40 return 1
41 fi
42 PLATFORM_PREBUILD_CMDS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o prebuild_cmds`"
43 PLATFORM_BUILDFLAGS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o buildflags`"
44 PLATFORM_BUILDFLAGS="$PLATFORM_BUILDFLAGS ${EXTRA_OPTIONS[@]}"
45 PLATFORM_BUILDCMD="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o buildcmd`"
46 PLATFORM_DSC="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o dsc`"
47 PLATFORM_PACKAGES_PATH=""
48 COMPONENT_INF="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o inf`"
49
50 TEMP_PACKAGES_PATH="$GLOBAL_PACKAGES_PATH:`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o packages_path`"
51 IFS=:
52 for path in "$TEMP_PACKAGES_PATH"; do
53 case "$path" in
54 /*)
55 PLATFORM_PACKAGES_PATH="$PLATFORM_PACKAGES_PATH:$path"
56 ;;
57 *)
58 PLATFORM_PACKAGES_PATH="$PLATFORM_PACKAGES_PATH:$PWD/$path"
59 ;;
60 esac
61 done
62 unset IFS
63
64 if [ $VERBOSE -eq 1 ]; then
65 echo "Setting build parallellism to $NUM_THREADS processes"
66 echo "PLATFORM_NAME=$PLATFORM_NAME"
67 echo "PLATFORM_PREBUILD_CMDS=$PLATFORM_PREBUILD_CMDS"
68 echo "PLATFORM_BUILDFLAGS=$PLATFORM_BUILDFLAGS"
69 echo "PLATFORM_BUILDCMD=$PLATFORM_BUILDCMD"
70 echo "PLATFORM_DSC=$PLATFORM_DSC"
71 echo "PLATFORM_ARCH=$PLATFORM_ARCH"
72 echo "PLATFORM_PACKAGES_PATH=$PLATFORM_PACKAGES_PATH"
73 fi
74
75 set_cross_compile
76 CROSS_COMPILE="$TEMP_CROSS_COMPILE"
77
78 echo "Building $PLATFORM_NAME - $PLATFORM_ARCH"
79 echo "CROSS_COMPILE=\"$TEMP_CROSS_COMPILE\""
80 echo "$board"_BUILDFLAGS="'$PLATFORM_BUILDFLAGS'"
81
82 if [ "$TARGETS" == "" ]; then
83 TARGETS=( RELEASE )
84 fi
85
86 case $TOOLCHAIN in
87 "gcc")
88 PLATFORM_TOOLCHAIN=`get_gcc_version "$CROSS_COMPILE"gcc`
89 ;;
90 "clang")
91 PLATFORM_TOOLCHAIN=`get_clang_version clang`
92 ;;
93 *)
94 # Use command-line specified profile directly
95 PLATFORM_TOOLCHAIN=$TOOLCHAIN
96 ;;
97 esac
98 echo "PLATFORM_TOOLCHAIN is ${PLATFORM_TOOLCHAIN}"
99
100 export ${PLATFORM_TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE
101 echo "Toolchain prefix: ${PLATFORM_TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE"
102
103 export PACKAGES_PATH="$PLATFORM_PACKAGES_PATH"
104 for target in "${TARGETS[@]}" ; do
105 if [ X"$PLATFORM_PREBUILD_CMDS" != X"" ]; then
106 echo "Run pre-build commands:"
107 if [ $VERBOSE -eq 1 ]; then
108 echo " ${PLATFORM_PREBUILD_CMDS}"
109 fi
110 eval ${PLATFORM_PREBUILD_CMDS}
111 fi
112
113 if [ -n "$COMPONENT_INF" ]; then
114 # Build a standalone component
115 if [ $VERBOSE -eq 1 ]; then
116 echo "build -n $NUM_THREADS -a \"$PLATFORM_ARCH\" -t ${PLATFORM_TOOLCHAIN} -p \"$PLATFORM_DSC\"" \
117 "-m \"$COMPONENT_INF\" -b "$target" ${PLATFORM_BUILDFLAGS}"
118 fi
119 build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${PLATFORM_TOOLCHAIN} -p "$PLATFORM_DSC" \
120 -m "$COMPONENT_INF" -b "$target" ${PLATFORM_BUILDFLAGS}
121 else
122 # Build a platform
123 if [ $VERBOSE -eq 1 ]; then
124 echo "build -n $NUM_THREADS -a \"$PLATFORM_ARCH\" -t ${PLATFORM_TOOLCHAIN} -p \"$PLATFORM_DSC\"" \
125 "-b "$target" ${PLATFORM_BUILDFLAGS}"
126 fi
127 build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${PLATFORM_TOOLCHAIN} -p "$PLATFORM_DSC" \
128 -b "$target" ${PLATFORM_BUILDFLAGS}
129 fi
130
131 RESULT=$?
132 if [ $RESULT -eq 0 ]; then
133 if [ X"$TOS_DIR" != X"" ]; then
134 pushd $TOS_DIR >/dev/null
135 if [ $VERBOSE -eq 1 ]; then
136 echo "$TOOLS_DIR/tos-build.sh -e "$EDK2_DIR" -t "$target"_${PLATFORM_TOOLCHAIN} $board"
137 fi
138 $TOOLS_DIR/tos-build.sh -e "$EDK2_DIR" -t "$target"_${PLATFORM_TOOLCHAIN} $board
139 RESULT=$?
140 popd >/dev/null
141 fi
142 fi
143 if [ $RESULT -eq 0 ]; then
144 if [ X"$ATF_DIR" != X"" ]; then
145 pushd $ATF_DIR >/dev/null
146 if [ $VERBOSE -eq 1 ]; then
147 echo "$TOOLS_DIR/atf-build.sh -e "$EDK2_DIR" -t "$target"_${PLATFORM_TOOLCHAIN} $board"
148 fi
149 $TOOLS_DIR/atf-build.sh -e "$EDK2_DIR" -t "$target"_${PLATFORM_TOOLCHAIN} $board
150 RESULT=$?
151 popd >/dev/null
152 fi
153 fi
154 result_log $RESULT "$PLATFORM_NAME $target"
155 done
156 unset PACKAGES_PATH
157}
158
159
160function configure_paths
161{
162 WORKSPACE="$PWD"
163
164 # Check to see if we are in a UEFI repository
165 # refuse to continue if we aren't
166 if [ ! -d "$EDK2_DIR"/BaseTools ]
167 then
168 if [ -d "$PWD"/edk2/BaseTools ]; then
169 EDK2_DIR="$PWD"/edk2
170 else
171 echo "ERROR: can't locate the edk2 directory" >&2
172 echo " please specify -e/--edk2-dir" >&2
173 exit 1
174 fi
175 fi
176
177 GLOBAL_PACKAGES_PATH="$EDK2_DIR"
178
179 # locate edk2-platforms
180 if [ -z "$PLATFORMS_DIR" -a -d "$PWD"/edk2-platforms ]; then
181 PLATFORMS_DIR="$PWD"/edk2-platforms
182 fi
183 if [ -n "$PLATFORMS_DIR" ]; then
184 GLOBAL_PACKAGES_PATH="$GLOBAL_PACKAGES_PATH:$PLATFORMS_DIR"
185 fi
186
187 # locate edk2-non-osi
188 if [ -z "$NON_OSI_DIR" -a -d "$PWD"/edk2-non-osi ]; then
189 NON_OSI_DIR="$PWD"/edk2-non-osi
190 fi
191 if [ -n "$NON_OSI_DIR" ]; then
192 GLOBAL_PACKAGES_PATH="$GLOBAL_PACKAGES_PATH:$NON_OSI_DIR"
193 fi
194
195 # locate arm-trusted-firmware
196 if [ -z "$ATF_DIR" -a -d "$PWD"/arm-trusted-firmware ]; then
197 ATF_DIR="$PWD"/arm-trusted-firmware
198 fi
199
200 export WORKSPACE
201}
202
203
204function prepare_build
205{
206 get_build_arch
207 export ARCH=$BUILD_ARCH
208
209 export ARCH
210 cd $EDK2_DIR
211 PACKAGES_PATH=$GLOBAL_PACKAGES_PATH . edksetup.sh --reconfig
212 if [ $? -ne 0 ]; then
213 echo "Sourcing edksetup.sh failed!" >&2
214 exit 1
215 fi
216 if [ $VERBOSE -eq 1 ]; then
217 echo "Building BaseTools"
218 fi
219 make -C BaseTools
220 RET=$?
221 cd -
222 if [ $RET -ne 0 ]; then
223 echo " !!! BaseTools failed to build !!! " >&2
224 exit 1
225 fi
226
227 if [ "$IMPORT_OPENSSL" = "TRUE" ]; then
228 cd $EDK2_DIR
229 import_openssl
230 if [ $? -ne 0 ]; then
231 echo "Importing OpenSSL failed - aborting!" >&2
232 echo " specify --no-openssl to attempt build anyway." >&2
233 exit 1
234 fi
235 cd $WORKSPACE
236 fi
237}
238
239
240function usage
241{
242 echo "usage:"
243 echo -n "uefi-build.sh [-b DEBUG | RELEASE] [ all "
244 for board in "${boards[@]}" ; do
245 echo -n "| $board "
246 done
247 echo "]"
248 printf "%8s\tbuild %s\n" "all" "all supported platforms"
249 for board in "${boards[@]}" ; do
250 PLATFORM_NAME="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o longname`"
251 printf "%8s\tbuild %s\n" "$board" "${PLATFORM_NAME}"
252 done
253}
254
255#
256# Since we do a command line validation on whether specified platforms exist or
257# not, do a first pass of command line to see if there is an explicit config
258# file there to read valid platforms from.
259#
260commandline=( "$@" )
261i=0
262for arg;
263do
264 if [ $arg == "-c" ]; then
265 FILE_ARG=${commandline[i + 1]}
266 if [ ! -f "$FILE_ARG" ]; then
267 echo "ERROR: configuration file '$FILE_ARG' not found" >&2
268 exit 1
269 fi
270 case "$FILE_ARG" in
271 /*)
272 PLATFORM_CONFIG="-c $FILE_ARG"
273 ;;
274 *)
275 PLATFORM_CONFIG="-c `readlink -f \"$FILE_ARG\"`"
276 ;;
277 esac
278 echo "Platform config file: '$FILE_ARG'"
279 fi
280 i=$(($i + 1))
281done
282
283export PLATFORM_CONFIG
284
285builds=()
286boards=()
287boardlist="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG shortlist`"
288for board in $boardlist; do
289 boards=(${boards[@]} $board)
290done
291
292NUM_TARGETS=0
293
294while [ "$1" != "" ]; do
295 case $1 in
296 -1) # Disable build parallellism
297 NUM_THREADS=1
298 ;;
299 -a | --arm-tf-dir)
300 shift
301 ATF_DIR="`readlink -f $1`"
302 ;;
303 -c) # Already parsed above - skip this + option
304 shift
305 ;;
306 -b | --build-target)
307 shift
308 echo "Adding Build target: $1"
309 TARGETS=(${TARGETS[@]} $1)
310 ;;
311 -D) # Pass through as -D option to 'build'
312 shift
313 echo "Adding Macro: -D $1"
314 EXTRA_OPTIONS=(${EXTRA_OPTIONS[@]} "-D" $1)
315 ;;
316 -e | --edk2-dir)
317 shift
318 export EDK2_DIR="`readlink -f $1`"
319 ;;
320 -h | --help)
321 usage
322 exit
323 ;;
324 --no-openssl)
325 IMPORT_OPENSSL=FALSE
326 ;;
327 -n | --non-osi-dir)
328 shift
329 NON_OSI_DIR="`readlink -f $1`"
330 ;;
331 -p | --platforms-dir)
332 shift
333 PLATFORMS_DIR="`readlink -f $1`"
334 ;;
335 -s | --tos-dir)
336 shift
337 export TOS_DIR="`readlink -f $1`"
338 ;;
339 -T) # Set specific toolchain tag, or clang/gcc for autoselection
340 shift
341 echo "Setting toolchain tag to '$1'"
342 TOOLCHAIN="$1"
343 ;;
344 -v)
345 VERBOSE=1
346 ;;
347 all) # Add all targets in configuration file to list
348 builds=(${boards[@]})
349 NUM_TARGETS=$(($NUM_TARGETS + 1))
350 ;;
351 *) # Try to match target in configuration file, add to list
352 MATCH=0
353 for board in "${boards[@]}" ; do
354 if [ "`echo $1 | cut -d: -f1`" == $board ]; then
355 MATCH=1
356 builds=(${builds[@]} "$1")
357 break
358 fi
359 done
360
361 if [ $MATCH -eq 0 ]; then
362 echo "unknown arg $1"
363 usage
364 exit 1
365 fi
366 NUM_TARGETS=$(($NUM_TARGETS + 1))
367 ;;
368 esac
369 shift
370done
371
372if [ $NUM_TARGETS -le 0 ]; then
373 echo "No targets specified - exiting!" >&2
374 exit 0
375fi
376
377export VERBOSE
378
379configure_paths
380
381prepare_build
382
383if [[ "${EXTRA_OPTIONS[@]}" != *"FIRMWARE_VER"* ]]; then
384 if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`; then
385 FIRMWARE_VER=`git rev-parse --short HEAD`
386 if ! git diff-index --quiet HEAD --; then
387 FIRMWARE_VER="${FIRMWARE_VER}-dirty"
388 fi
389 EXTRA_OPTIONS=( ${EXTRA_OPTIONS[@]} "-D" FIRMWARE_VER=$FIRMWARE_VER )
390 if [ $VERBOSE -eq 1 ]; then
391 echo "FIRMWARE_VER=$FIRMWARE_VER"
392 echo "EXTRA_OPTIONS=$EXTRA_OPTIONS"
393 fi
394 fi
395fi
396
397for board in "${builds[@]}" ; do
398 do_build
399done
400
401result_print