xref: /OK3568_Linux_fs/device/rockchip/common/scripts/build.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/bash
2*4882a593Smuzhiyun
3*4882a593Smuzhiyunif [ -z "$BASH_SOURCE" ]; then
4*4882a593Smuzhiyun	echo "Not in bash, switching to it..."
5*4882a593Smuzhiyun	case "${@:-shell}" in
6*4882a593Smuzhiyun		shell) ./build.sh shell ;;
7*4882a593Smuzhiyun		*)
8*4882a593Smuzhiyun			./build.sh $@
9*4882a593Smuzhiyun			bash
10*4882a593Smuzhiyun			;;
11*4882a593Smuzhiyun	esac
12*4882a593Smuzhiyunfi
13*4882a593Smuzhiyun
14*4882a593Smuzhiyunusage()
15*4882a593Smuzhiyun{
16*4882a593Smuzhiyun	echo "Usage: $(basename $BASH_SOURCE) [OPTIONS]"
17*4882a593Smuzhiyun	echo "Available options:"
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun	run_build_hooks usage
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun	# Global options
22*4882a593Smuzhiyun	echo -e "cleanall                          \tcleanup"
23*4882a593Smuzhiyun	echo -e "post-rootfs <rootfs dir>          \ttrigger post-rootfs hook scripts"
24*4882a593Smuzhiyun	echo -e "shell                             \tsetup a shell for developing"
25*4882a593Smuzhiyun	echo -e "help                              \tusage"
26*4882a593Smuzhiyun	echo ""
27*4882a593Smuzhiyun	echo "Default option is 'allsave'."
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun	rm -f "$INITIAL_ENV"
30*4882a593Smuzhiyun	exit 0
31*4882a593Smuzhiyun}
32*4882a593Smuzhiyun
33*4882a593Smuzhiyunerr_handler()
34*4882a593Smuzhiyun{
35*4882a593Smuzhiyun	ret=${1:-$?}
36*4882a593Smuzhiyun	[ "$ret" -eq 0 ] && return
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun	echo "ERROR: Running $BASH_SOURCE - ${2:-${FUNCNAME[1]}} failed!"
39*4882a593Smuzhiyun	echo "ERROR: exit code $ret from line ${BASH_LINENO[0]}:"
40*4882a593Smuzhiyun	echo "    ${3:-$BASH_COMMAND}"
41*4882a593Smuzhiyun	echo "ERROR: call stack:"
42*4882a593Smuzhiyun	for i in $(seq 1 $((${#FUNCNAME[@]} - 1))); do
43*4882a593Smuzhiyun		SOURCE="${BASH_SOURCE[$i]}"
44*4882a593Smuzhiyun		LINE=${BASH_LINENO[$(( $i - 1 ))]}
45*4882a593Smuzhiyun		echo "    $(basename "$SOURCE"): ${FUNCNAME[$i]}($LINE)"
46*4882a593Smuzhiyun	done
47*4882a593Smuzhiyun	exit $ret
48*4882a593Smuzhiyun}
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun# Export global functions
51*4882a593Smuzhiyunset -a
52*4882a593Smuzhiyun
53*4882a593Smuzhiyunfinish_build()
54*4882a593Smuzhiyun{
55*4882a593Smuzhiyun	echo -e "\e[35mRunning $(basename "${BASH_SOURCE[1]}") - ${@:-${FUNCNAME[1]}} succeeded.\e[0m"
56*4882a593Smuzhiyun	cd "$SDK_DIR"
57*4882a593Smuzhiyun}
58*4882a593Smuzhiyun
59*4882a593Smuzhiyunload_config()
60*4882a593Smuzhiyun{
61*4882a593Smuzhiyun	[ -r "$RK_CONFIG" ] || return 0
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun	for var in $@; do
64*4882a593Smuzhiyun		export $(grep "^$var=" "$RK_CONFIG" | \
65*4882a593Smuzhiyun			tr -d '"' || true) &>/dev/null
66*4882a593Smuzhiyun	done
67*4882a593Smuzhiyun}
68*4882a593Smuzhiyun
69*4882a593Smuzhiyuncheck_config()
70*4882a593Smuzhiyun{
71*4882a593Smuzhiyun	unset missing
72*4882a593Smuzhiyun	for var in $@; do
73*4882a593Smuzhiyun		eval [ \$$var ] && continue
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun		missing="$missing $var"
76*4882a593Smuzhiyun	done
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun	[ -z "$missing" ] && return 0
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun	echo "Skipping $(basename "${BASH_SOURCE[1]}") - ${FUNCNAME[1]} for missing configs: $missing."
81*4882a593Smuzhiyun	return 1
82*4882a593Smuzhiyun}
83*4882a593Smuzhiyun
84*4882a593Smuzhiyunkernel_version_real()
85*4882a593Smuzhiyun{
86*4882a593Smuzhiyun	[ -d kernel ] || return 0
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun	VERSION_KEYS="VERSION PATCHLEVEL"
89*4882a593Smuzhiyun	VERSION=""
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun	for k in $VERSION_KEYS; do
92*4882a593Smuzhiyun		v=$(grep "^$k = " kernel/Makefile | cut -d' ' -f3)
93*4882a593Smuzhiyun		VERSION=${VERSION:+${VERSION}.}$v
94*4882a593Smuzhiyun	done
95*4882a593Smuzhiyun	echo $VERSION
96*4882a593Smuzhiyun}
97*4882a593Smuzhiyun
98*4882a593Smuzhiyunkernel_version()
99*4882a593Smuzhiyun{
100*4882a593Smuzhiyun	[ -d kernel ] || return 0
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun	KERNEL_DIR="$(basename "$(realpath kernel)")"
103*4882a593Smuzhiyun	case "$KERNEL_DIR" in
104*4882a593Smuzhiyun		kernel-*)
105*4882a593Smuzhiyun			echo ${KERNEL_DIR#kernel-}
106*4882a593Smuzhiyun			return 0
107*4882a593Smuzhiyun			;;
108*4882a593Smuzhiyun	esac
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun	kernel_version_real
111*4882a593Smuzhiyun}
112*4882a593Smuzhiyun
113*4882a593Smuzhiyunstart_log()
114*4882a593Smuzhiyun{
115*4882a593Smuzhiyun	LOG_FILE="$RK_LOG_DIR/${2:-$1_$(date +%F_%H-%M-%S)}.log"
116*4882a593Smuzhiyun	ln -rsf "$LOG_FILE" "$RK_LOG_DIR/$1.log"
117*4882a593Smuzhiyun	echo "# $(date +"%F %T")" >> "$LOG_FILE"
118*4882a593Smuzhiyun	echo "$LOG_FILE"
119*4882a593Smuzhiyun}
120*4882a593Smuzhiyun
121*4882a593Smuzhiyunget_toolchain()
122*4882a593Smuzhiyun{
123*4882a593Smuzhiyun	TOOLCHAIN_ARCH="${1/arm64/aarch64}"
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun	MACHINE=$(uname -m)
126*4882a593Smuzhiyun	if [ "$MACHINE" = x86_64 ]; then
127*4882a593Smuzhiyun		TOOLCHAIN_VENDOR="${2:-none}"
128*4882a593Smuzhiyun		TOOLCHAIN_OS="${3:-linux}"
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun		# RV1126 uses custom toolchain
131*4882a593Smuzhiyun		if [ "$RK_CHIP_FAMILY" = "rv1126_rv1109" ]; then
132*4882a593Smuzhiyun			TOOLCHAIN_VENDOR=rockchip
133*4882a593Smuzhiyun		fi
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun		TOOLCHAIN_DIR="$(realpath prebuilts/gcc/*/$TOOLCHAIN_ARCH)"
136*4882a593Smuzhiyun		GCC="$(find "$TOOLCHAIN_DIR" \
137*4882a593Smuzhiyun			-name "*$TOOLCHAIN_VENDOR-$TOOLCHAIN_OS-*-gcc" | \
138*4882a593Smuzhiyun			head -n 1)"
139*4882a593Smuzhiyun		if [ ! -x "$GCC" ]; then
140*4882a593Smuzhiyun			echo "No prebuilt GCC toolchain!"
141*4882a593Smuzhiyun			exit 1
142*4882a593Smuzhiyun		fi
143*4882a593Smuzhiyun	elif [ "$TOLLCHAIN_ARCH" = aarch64 -a "$MACHINE" != aarch64 ]; then
144*4882a593Smuzhiyun		GCC=aarch64-linux-gnu-gcc
145*4882a593Smuzhiyun	elif [ "$TOLLCHAIN_ARCH" = arm -a "$MACHINE" != armv7l ]; then
146*4882a593Smuzhiyun		GCC=arm-linux-gnueabihf-gcc
147*4882a593Smuzhiyun	else
148*4882a593Smuzhiyun		GCC=gcc
149*4882a593Smuzhiyun	fi
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun	echo "${GCC%gcc}"
152*4882a593Smuzhiyun}
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun# For developing shell only
155*4882a593Smuzhiyun
156*4882a593Smuzhiyunrroot()
157*4882a593Smuzhiyun{
158*4882a593Smuzhiyun	cd "$SDK_DIR"
159*4882a593Smuzhiyun}
160*4882a593Smuzhiyun
161*4882a593Smuzhiyunrout()
162*4882a593Smuzhiyun{
163*4882a593Smuzhiyun	cd "$RK_OUTDIR"
164*4882a593Smuzhiyun}
165*4882a593Smuzhiyun
166*4882a593Smuzhiyunrcommon()
167*4882a593Smuzhiyun{
168*4882a593Smuzhiyun	cd "$COMMON_DIR"
169*4882a593Smuzhiyun}
170*4882a593Smuzhiyun
171*4882a593Smuzhiyunrscript()
172*4882a593Smuzhiyun{
173*4882a593Smuzhiyun	cd "$SCRIPTS_DIR"
174*4882a593Smuzhiyun}
175*4882a593Smuzhiyun
176*4882a593Smuzhiyunrchip()
177*4882a593Smuzhiyun{
178*4882a593Smuzhiyun	cd "$(realpath "$CHIP_DIR")"
179*4882a593Smuzhiyun}
180*4882a593Smuzhiyun
181*4882a593Smuzhiyunset +a
182*4882a593Smuzhiyun# End of global functions
183*4882a593Smuzhiyun
184*4882a593Smuzhiyunrun_hooks()
185*4882a593Smuzhiyun{
186*4882a593Smuzhiyun	DIR="$1"
187*4882a593Smuzhiyun	shift
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun	for dir in "$CHIP_DIR/$(basename "$DIR")/" "$DIR"; do
190*4882a593Smuzhiyun		[ -d "$dir" ] || continue
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun		for hook in $(find "$dir" -maxdepth 1 -name "*.sh" | sort); do
193*4882a593Smuzhiyun			"$hook" $@ && continue
194*4882a593Smuzhiyun			HOOK_RET=$?
195*4882a593Smuzhiyun			err_handler $HOOK_RET "${FUNCNAME[0]} $*" "$hook $*"
196*4882a593Smuzhiyun			exit $HOOK_RET
197*4882a593Smuzhiyun		done
198*4882a593Smuzhiyun	done
199*4882a593Smuzhiyun}
200*4882a593Smuzhiyun
201*4882a593Smuzhiyunrun_build_hooks()
202*4882a593Smuzhiyun{
203*4882a593Smuzhiyun	# Don't log these hooks
204*4882a593Smuzhiyun	case "$1" in
205*4882a593Smuzhiyun		init | pre-build | make-* | usage | support-cmds)
206*4882a593Smuzhiyun			run_hooks "$RK_BUILD_HOOK_DIR" $@ || true
207*4882a593Smuzhiyun			return 0
208*4882a593Smuzhiyun			;;
209*4882a593Smuzhiyun	esac
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun	LOG_FILE="$(start_log "$1")"
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun	echo -e "# run hook: $@\n" >> "$LOG_FILE"
214*4882a593Smuzhiyun	run_hooks "$RK_BUILD_HOOK_DIR" $@ 2>&1 | tee -a "$LOG_FILE"
215*4882a593Smuzhiyun	HOOK_RET=${PIPESTATUS[0]}
216*4882a593Smuzhiyun	if [ $HOOK_RET -ne 0 ]; then
217*4882a593Smuzhiyun		err_handler $HOOK_RET "${FUNCNAME[0]} $*" "$@"
218*4882a593Smuzhiyun		exit $HOOK_RET
219*4882a593Smuzhiyun	fi
220*4882a593Smuzhiyun}
221*4882a593Smuzhiyun
222*4882a593Smuzhiyunrun_post_hooks()
223*4882a593Smuzhiyun{
224*4882a593Smuzhiyun	LOG_FILE="$(start_log post-rootfs)"
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun	echo -e "# run hook: $@\n" >> "$LOG_FILE"
227*4882a593Smuzhiyun	run_hooks "$RK_POST_HOOK_DIR" $@ 2>&1 | tee -a "$LOG_FILE"
228*4882a593Smuzhiyun	HOOK_RET=${PIPESTATUS[0]}
229*4882a593Smuzhiyun	if [ $HOOK_RET -ne 0 ]; then
230*4882a593Smuzhiyun		err_handler $HOOK_RET "${FUNCNAME[0]} $*" "$@"
231*4882a593Smuzhiyun		exit $HOOK_RET
232*4882a593Smuzhiyun	fi
233*4882a593Smuzhiyun}
234*4882a593Smuzhiyun
235*4882a593Smuzhiyunoption_check()
236*4882a593Smuzhiyun{
237*4882a593Smuzhiyun	CMDS="$1"
238*4882a593Smuzhiyun	shift
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun	for opt in $@; do
241*4882a593Smuzhiyun		for cmd in $CMDS; do
242*4882a593Smuzhiyun			# NOTE: There might be patterns in commands
243*4882a593Smuzhiyun			echo "${opt%%:*}" | grep -q "^$cmd$" || continue
244*4882a593Smuzhiyun			return 0
245*4882a593Smuzhiyun		done
246*4882a593Smuzhiyun	done
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun	return 1
249*4882a593Smuzhiyun}
250*4882a593Smuzhiyun
251*4882a593Smuzhiyunmain()
252*4882a593Smuzhiyun{
253*4882a593Smuzhiyun	[ -z "$DEBUG" ] || set -x
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun	trap 'err_handler' ERR
256*4882a593Smuzhiyun	set -eE
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun	# Save intial envionments
259*4882a593Smuzhiyun	unset INITIAL_SESSION
260*4882a593Smuzhiyun	INITIAL_ENV=$(mktemp -u)
261*4882a593Smuzhiyun	if [ -z "$RK_SESSION" ]; then
262*4882a593Smuzhiyun		INITIAL_SESSION=1
263*4882a593Smuzhiyun		env > "$INITIAL_ENV"
264*4882a593Smuzhiyun	fi
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun	export LC_ALL=C
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun	export SCRIPTS_DIR="$(dirname "$(realpath "$BASH_SOURCE")")"
269*4882a593Smuzhiyun	export COMMON_DIR="$(realpath "$SCRIPTS_DIR/..")"
270*4882a593Smuzhiyun	export SDK_DIR="$(realpath "$COMMON_DIR/../../..")"
271*4882a593Smuzhiyun	export DEVICE_DIR="$SDK_DIR/device/rockchip"
272*4882a593Smuzhiyun	export CHIPS_DIR="$DEVICE_DIR/.chips"
273*4882a593Smuzhiyun	export CHIP_DIR="$DEVICE_DIR/.chip"
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun	export RK_DATA_DIR="$COMMON_DIR/data"
276*4882a593Smuzhiyun	export RK_TOOL_DIR="$COMMON_DIR/tools"
277*4882a593Smuzhiyun	export RK_IMAGE_DIR="$COMMON_DIR/images"
278*4882a593Smuzhiyun	export RK_KBUILD_DIR="$COMMON_DIR/linux-kbuild"
279*4882a593Smuzhiyun	export RK_CONFIG_IN="$COMMON_DIR/configs/Config.in"
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun	export RK_BUILD_HOOK_DIR="$COMMON_DIR/build-hooks"
282*4882a593Smuzhiyun	export BUILD_HELPER="$RK_BUILD_HOOK_DIR/build-helper"
283*4882a593Smuzhiyun	export RK_POST_HOOK_DIR="$COMMON_DIR/post-hooks"
284*4882a593Smuzhiyun	export POST_HELPER="$RK_POST_HOOK_DIR/post-helper"
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun	export PARTITION_HELPER="$SCRIPTS_DIR/partition-helper"
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun	export RK_SESSION="${RK_SESSION:-$(date +%F_%H-%M-%S)}"
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun	export RK_OUTDIR="$SDK_DIR/output"
291*4882a593Smuzhiyun	export RK_SESSION_DIR="$RK_OUTDIR/sessions"
292*4882a593Smuzhiyun	export RK_LOG_BASE_DIR="$RK_OUTDIR/log"
293*4882a593Smuzhiyun	export RK_LOG_DIR="$RK_SESSION_DIR/$RK_SESSION"
294*4882a593Smuzhiyun	export RK_INITIAL_ENV="$RK_LOG_DIR/initial.env"
295*4882a593Smuzhiyun	export RK_CUSTOM_ENV="$RK_LOG_DIR/custom.env"
296*4882a593Smuzhiyun	export RK_FINAL_ENV="$RK_LOG_DIR/final.env"
297*4882a593Smuzhiyun	export RK_ROCKDEV_DIR="$SDK_DIR/rockdev"
298*4882a593Smuzhiyun	export RK_FIRMWARE_DIR="$RK_OUTDIR/firmware"
299*4882a593Smuzhiyun	export RK_SECURITY_FIRMWARE_DIR="$RK_OUTDIR/security-firmware"
300*4882a593Smuzhiyun	export RK_CONFIG="$RK_OUTDIR/.config"
301*4882a593Smuzhiyun	export RK_DEFCONFIG_LINK="$RK_OUTDIR/defconfig"
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun	# For Makefile
304*4882a593Smuzhiyun	case "$@" in
305*4882a593Smuzhiyun		make-targets | make-usage)
306*4882a593Smuzhiyun			run_build_hooks "$@"
307*4882a593Smuzhiyun			rm -f "$INITIAL_ENV"
308*4882a593Smuzhiyun			exit 0 ;;
309*4882a593Smuzhiyun	esac
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun	# Prepare firmware dirs
312*4882a593Smuzhiyun	mkdir -p "$RK_FIRMWARE_DIR" "$RK_SECURITY_FIRMWARE_DIR"
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun	cd "$SDK_DIR"
315*4882a593Smuzhiyun	[ -f README.md ] || ln -rsf "$COMMON_DIR/README.md" .
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun	# TODO: Remove it in the repo manifest.xml
318*4882a593Smuzhiyun	rm -f envsetup.sh
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun	OPTIONS="${@:-allsave}"
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun	# Options checking
323*4882a593Smuzhiyun	CMDS="$(run_build_hooks support-cmds all | xargs)"
324*4882a593Smuzhiyun	for opt in $OPTIONS; do
325*4882a593Smuzhiyun		case "$opt" in
326*4882a593Smuzhiyun			help | h | -h | --help | usage | \?) usage ;;
327*4882a593Smuzhiyun			shell | cleanall)
328*4882a593Smuzhiyun				# Check single options
329*4882a593Smuzhiyun				if [ "$opt" = "$OPTIONS" ]; then
330*4882a593Smuzhiyun					break
331*4882a593Smuzhiyun				fi
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun				echo "ERROR: $opt cannot combine with other options!"
334*4882a593Smuzhiyun				;;
335*4882a593Smuzhiyun			post-rootfs)
336*4882a593Smuzhiyun				if [ "$opt" = "$1" -a -d "$2" ]; then
337*4882a593Smuzhiyun					# Hide other args from build stages
338*4882a593Smuzhiyun					OPTIONS=$opt
339*4882a593Smuzhiyun					break
340*4882a593Smuzhiyun				fi
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun				echo "ERROR: $opt should be the first option followed by rootfs dir!"
343*4882a593Smuzhiyun				;;
344*4882a593Smuzhiyun			*)
345*4882a593Smuzhiyun				# Make sure that all options are handled
346*4882a593Smuzhiyun				if option_check "$CMDS" $opt; then
347*4882a593Smuzhiyun					continue
348*4882a593Smuzhiyun				fi
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun				echo "ERROR: Unhandled option: $opt"
351*4882a593Smuzhiyun				;;
352*4882a593Smuzhiyun		esac
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun		usage
355*4882a593Smuzhiyun	done
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun	# Prepare log dirs
358*4882a593Smuzhiyun	if [ ! -d "$RK_LOG_DIR" ]; then
359*4882a593Smuzhiyun		rm -rf "$RK_LOG_BASE_DIR" "$RK_LOG_DIR" "$RK_SESSION_DIR/latest"
360*4882a593Smuzhiyun		mkdir -p "$RK_LOG_DIR"
361*4882a593Smuzhiyun		ln -rsf "$RK_SESSION_DIR" "$RK_LOG_BASE_DIR"
362*4882a593Smuzhiyun		ln -rsf "$RK_LOG_DIR" "$RK_SESSION_DIR/latest"
363*4882a593Smuzhiyun		echo -e "\e[33mLog saved at $RK_LOG_DIR\e[0m"
364*4882a593Smuzhiyun		echo
365*4882a593Smuzhiyun	fi
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun	# Drop old logs
368*4882a593Smuzhiyun	cd "$RK_LOG_BASE_DIR"
369*4882a593Smuzhiyun	rm -rf $(ls -t | sed '1,10d')
370*4882a593Smuzhiyun	cd "$SDK_DIR"
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun	# Save initial envionments
373*4882a593Smuzhiyun	if [ "$INITIAL_SESSION" ]; then
374*4882a593Smuzhiyun		rm -f "$RK_INITIAL_ENV"
375*4882a593Smuzhiyun		mv "$INITIAL_ENV" "$RK_INITIAL_ENV"
376*4882a593Smuzhiyun		ln -rsf "$RK_INITIAL_ENV" "$RK_OUTDIR/"
377*4882a593Smuzhiyun	fi
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun	# Init stage (preparing SDK configs, etc.)
380*4882a593Smuzhiyun	run_build_hooks init $OPTIONS
381*4882a593Smuzhiyun	rm -f "$RK_OUTDIR/.tmpconfig*"
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun	# No need to go further
384*4882a593Smuzhiyun	CMDS="$(run_build_hooks support-cmds pre-build build \
385*4882a593Smuzhiyun		post-build | xargs) shell cleanall post-rootfs"
386*4882a593Smuzhiyun	option_check "$CMDS" $OPTIONS || return 0
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun	# Force exporting config environments
389*4882a593Smuzhiyun	set -a
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun	# Load config environments
392*4882a593Smuzhiyun	source "$RK_CONFIG"
393*4882a593Smuzhiyun	cp "$RK_CONFIG" "$RK_LOG_DIR"
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun	if [ -z "$INITIAL_SESSION" ]; then
396*4882a593Smuzhiyun		# Inherit session environments
397*4882a593Smuzhiyun		sed -n 's/^\(RK_.*=\)\(.*\)/\1"\2"/p' "$RK_FINAL_ENV" > \
398*4882a593Smuzhiyun			"$INITIAL_ENV"
399*4882a593Smuzhiyun		source "$INITIAL_ENV"
400*4882a593Smuzhiyun		rm -f "$INITIAL_ENV"
401*4882a593Smuzhiyun	else
402*4882a593Smuzhiyun		# Detect and save custom environments
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun		# Find custom environments
405*4882a593Smuzhiyun		rm -f "$RK_CUSTOM_ENV"
406*4882a593Smuzhiyun		for cfg in $(grep "^RK_" "$RK_INITIAL_ENV" || true); do
407*4882a593Smuzhiyun			env | grep -q "^${cfg//\"/}$" || \
408*4882a593Smuzhiyun				echo "$cfg" >> "$RK_CUSTOM_ENV"
409*4882a593Smuzhiyun		done
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun		# Allow custom environments overriding
412*4882a593Smuzhiyun		if [ -e "$RK_CUSTOM_ENV" ]; then
413*4882a593Smuzhiyun			ln -rsf "$RK_CUSTOM_ENV" "$RK_OUTDIR/"
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun			echo -e "\e[31mWARN: Found custom environments: \e[0m"
416*4882a593Smuzhiyun			cat "$RK_CUSTOM_ENV"
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun			echo -e "\e[31mAssuming that is expected, please clear them if otherwise.\e[0m"
419*4882a593Smuzhiyun			read -t 10 -p "Press enter to continue."
420*4882a593Smuzhiyun			source "$RK_CUSTOM_ENV"
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun			if grep -q "^RK_KERNEL_VERSION=" "$RK_CUSTOM_ENV"; then
423*4882a593Smuzhiyun				echo -e "\e[31mCustom RK_KERNEL_VERSION ignored!\e[0m"
424*4882a593Smuzhiyun				load_config RK_KERNEL_VERSION
425*4882a593Smuzhiyun			fi
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun			if grep -q "^RK_ROOTFS_SYSTEM=" "$RK_CUSTOM_ENV"; then
428*4882a593Smuzhiyun				echo -e "\e[31mCustom RK_ROOTFS_SYSTEM ignored!\e[0m"
429*4882a593Smuzhiyun				load_config RK_ROOTFS_SYSTEM
430*4882a593Smuzhiyun			fi
431*4882a593Smuzhiyun		fi
432*4882a593Smuzhiyun	fi
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun	source "$PARTITION_HELPER"
435*4882a593Smuzhiyun	rk_partition_init
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun	set +a
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun	export PYTHON3=/usr/bin/python3
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun	if [ "$RK_KERNEL_CFG" ]; then
442*4882a593Smuzhiyun		export RK_KERNEL_TOOLCHAIN="$(get_toolchain "$RK_KERNEL_ARCH")"
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun		CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1)
445*4882a593Smuzhiyun		export KMAKE="make -C "$SDK_DIR/kernel/" -j$(( $CPUS + 1 )) \
446*4882a593Smuzhiyun			CROSS_COMPILE=$RK_KERNEL_TOOLCHAIN ARCH=$RK_KERNEL_ARCH"
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun		export RK_KERNEL_VERSION_REAL=$(kernel_version_real)
449*4882a593Smuzhiyun	fi
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun	# Handle special commands
452*4882a593Smuzhiyun	case "$OPTIONS" in
453*4882a593Smuzhiyun		shell)
454*4882a593Smuzhiyun			echo -e "\e[35mDoing this is dangerous and for developing only.\e[0m"
455*4882a593Smuzhiyun			# No error handling in develop shell.
456*4882a593Smuzhiyun			set +e; trap ERR
457*4882a593Smuzhiyun			/bin/bash
458*4882a593Smuzhiyun			echo -e "\e[35mExit from $BASH_SOURCE shell.\e[0m"
459*4882a593Smuzhiyun			exit 0 ;;
460*4882a593Smuzhiyun		cleanall)
461*4882a593Smuzhiyun			run_build_hooks clean
462*4882a593Smuzhiyun			rm -rf "$RK_OUTDIR" "$SDK_DIR/rockdev"
463*4882a593Smuzhiyun			finish_build cleanall
464*4882a593Smuzhiyun			exit 0 ;;
465*4882a593Smuzhiyun		post-rootfs)
466*4882a593Smuzhiyun			shift
467*4882a593Smuzhiyun			run_post_hooks $@
468*4882a593Smuzhiyun			finish_build post-rootfs
469*4882a593Smuzhiyun			exit 0 ;;
470*4882a593Smuzhiyun	esac
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun	# Save final environments
473*4882a593Smuzhiyun	rm -f "$RK_FINAL_ENV"
474*4882a593Smuzhiyun	env > "$RK_FINAL_ENV"
475*4882a593Smuzhiyun	ln -rsf "$RK_FINAL_ENV" "$RK_OUTDIR/"
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun	# Log configs
478*4882a593Smuzhiyun	echo
479*4882a593Smuzhiyun	echo "=========================================="
480*4882a593Smuzhiyun	echo "          Final configs"
481*4882a593Smuzhiyun	echo "=========================================="
482*4882a593Smuzhiyun	env | grep -E "^RK_.*=.+" | grep -vE "PARTITION_[0-9]" | \
483*4882a593Smuzhiyun		grep -vE "=\"\"$|_DEFAULT=y" | \
484*4882a593Smuzhiyun		grep -vE "^RK_CONFIG|_BASE_CFG=|_LINK=|DIR=|_ENV=|_NAME=" | sort
485*4882a593Smuzhiyun	echo
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun	# Pre-build stage (submodule configuring, etc.)
488*4882a593Smuzhiyun	run_build_hooks pre-build $OPTIONS
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun	# No need to go further
491*4882a593Smuzhiyun	CMDS="$(run_build_hooks support-cmds build post-build | xargs)"
492*4882a593Smuzhiyun	option_check "$CMDS" $OPTIONS || return 0
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun	# Build stage (building, etc.)
495*4882a593Smuzhiyun	run_build_hooks build $OPTIONS
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun	# No need to go further
498*4882a593Smuzhiyun	CMDS="$(run_build_hooks support-cmds post-build | xargs)"
499*4882a593Smuzhiyun	option_check "$CMDS" $OPTIONS || return 0
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun	# Post-build stage (firmware packing, etc.)
502*4882a593Smuzhiyun	run_build_hooks post-build $OPTIONS
503*4882a593Smuzhiyun}
504*4882a593Smuzhiyun
505*4882a593Smuzhiyunif [ "$0" != "$BASH_SOURCE" ]; then
506*4882a593Smuzhiyun	# Sourced, executing it directly
507*4882a593Smuzhiyun	"$BASH_SOURCE" ${@:-shell}
508*4882a593Smuzhiyunelif [ "$0" == "$BASH_SOURCE" ]; then
509*4882a593Smuzhiyun	# Executed directly
510*4882a593Smuzhiyun	main $@
511*4882a593Smuzhiyunfi
512