blob: ddfa76c54ffaef20298eb8be89f581fa1831b643 [file] [log] [blame]
developer782bc7f2024-08-23 15:39:22 +08001#!/usr/bin/env bash
2
3# Copyright (C) 2024 MediaTek Inc. All rights reserved.
4# Author: Weijie Gao <weijie.gao@mediatek.com>
5# Autobuild framework for OpenWrt
6
7# Autobuild script base directory
8ab_root="$(dirname "$(readlink -f "$0")")"
9
10. ${ab_root}/scripts/log.sh
11. ${ab_root}/scripts/list.sh
12. ${ab_root}/scripts/kconfig.sh
13. ${ab_root}/scripts/openwrt_helpers.sh
14. ${ab_root}/scripts/ab-common.sh
15
16# Command line processing
17
18## Parse autobuild branch name
19ab_branch=
20ab_branch_names=
21ab_branch_level=0
22
23if autobuild_branch_name_check "${1}"; then
24 canonicalize_autobuild_branch_name "${1}" ab_branch_names ab_branch
25 shift
26fi
27
28## Stages
29ab_stages="prepare build release"
30do_menuconfig=
31do_help=
32do_list=
33do_clean=
34
35if list_find ab_stages "${1}"; then
36 ab_stages="${1}"
37 shift
38elif test x"${1}" = x"sdk_release"; then
39 ab_stages="prepare sdk_release"
40 shift
41elif test x"${1}" = x"menuconfig"; then
42 ab_stages="prepare menuconfig"
43 do_menuconfig=1
44 shift
45elif test x"${1}" = x"help"; then
46 ab_stages="help"
47 do_help=1
48 shift
49elif test x"${1}" = x"list"; then
50 do_list=1
51 shift
52elif test x"${1}" = x"clean"; then
53 do_clean=1
54 shift
55fi
56
57## Options
58__logged_args=()
59for arg in "$@"; do
60 if expr index ${arg} '=' 2>&1 >/dev/null; then
61 name=${arg%%=*}
62 value=${arg#*=}
63
64 eval ${name}=\"\${value}\"
65 eval ${name}_set=yes
66
67 __logged_args[${#__logged_args[@]}]="${name}=\"${value}\""
68 else
69 eval ${arg}_set=yes
70
71 __logged_args[${#__logged_args[@]}]="${arg}"
72 fi
73done
74
75IFS=$'\n' __sorted_args=($(sort <<< "${__logged_args[*]}")); unset IFS
76IFS=' ' ab_cmdline="${__logged_args[@]}"; unset IFS
77
78# Enable debugging log?
79if test x"${debug_set}" = x"yes"; then
80 enable_log_debug
81fi
82
83# Enable logging to file?
84if test x"${log_file_set}" = x"yes"; then
85 log_file_merge=
86
87 [ x"${log_file_merge_set}" = x"yes" ] && log_file_merge=1
88
89 set_log_file_prefix "${log_file}" ${log_file_merge}
90fi
91
92# OK, do list here if required
93if test x"${do_list}" = x"1"; then
94 list_all_autobuild_branches
95 exit 0
96fi
97
98openwrt_root="$(pwd)"
99
100if ! is_openwrt_build_root "${openwrt_root}"; then
101 log_err "${openwrt_root} is not a OpenWrt root directory."
102 log_err "The autobuild script must be called from within the OpenWrt root directory."
103 exit 1
104fi
105
106# OpenWrt branch (master, 21.02, ...)
107openwrt_branch=$(openwrt_get_branch)
108
109if test -z "${openwrt_branch}"; then
110 log_err "Failed to get OpenWrt's branch"
111 exit 1
112else
113 log_info "OpenWrt's branch is ${openwrt_branch}"
114fi
115
116# Temporary directory for storing configs and intermediate files
117ab_tmp="${openwrt_root}/.ab"
118
119# Default release directory
120ab_bin_release="${openwrt_root}/autobuild_release"
121
122# OK, do clean here if required
123if test x"${do_clean}" = x"1"; then
124 if ! git status >/dev/null; then
125 log_warn "The clean stage can only be applied if the OpenWrt source is managed by Git."
126 exit 1
127 fi
128
129 exec_log "git -C \"${openwrt_root}\" checkout ."
130 exec_log "git -C \"${openwrt_root}\" clean -f -d -e autobuild"
131 exec_log "rm -rf \"${openwrt_root}/feeds\""
132 exec_log "rm -rf \"${openwrt_root}/package/feeds\""
133 exec_log "rm -rf \"${openwrt_root}/.ab\""
134
135 exit 0
136fi
137
138# Check if we need prepare for build stage
139if list_find ab_stages build; then
140 if test \( ! -f "${ab_tmp}/branch_name" \) -o -f "${ab_tmp}/.stamp.menuconfig"; then
141 list_add_before_unique ab_stages build prepare
142 fi
143fi
144
145# Check for prepare stage
146if list_find ab_stages prepare; then
147 if test -f "${ab_tmp}/branch_name"; then
148 # If prepare stage has been done before, check whether clean is required
149
150 if test -z "${do_menuconfig}" -a -f "${ab_tmp}/.stamp.menuconfig"; then
151 log_warn "This OpenWrt source code has already been prepared for menuconfig."
152 log_warn "Please call \`${0} clean' first."
153 exit 1
154 fi
155
156 if test -n "${do_menuconfig}" -a ! -f "${ab_tmp}/.stamp.menuconfig"; then
157 log_warn "This OpenWrt source code has already been prepared, but not for menuconfig."
158 log_warn "Please call \`${0} clean' first."
159 exit 1
160 fi
161
162 last_ab_branch=$(cat "${ab_tmp}/branch_name")
163
164 if test -n "${ab_branch}"; then
165 if test x"${ab_branch}" != x"${last_ab_branch}"; then
166 log_warn "Autobuild branch name has changed."
167 log_warn "Please call \`${0} clean' first."
168 exit 1
169 fi
170
171 if test -z "${do_menuconfig}"; then
172 last_ab_cmdline=$(cat "${ab_tmp}/cmdline")
173
174 if test x"${ab_cmdline}" != x"${last_ab_cmdline}"; then
175 log_warn "Autobuild configuration has changed."
176 log_warn "Please call \`${0} clean' first."
177 exit 1
178 fi
179 fi
180
181 # Configuration unchanged
182 else
183 # Read previous configuration
184 canonicalize_autobuild_branch_name "${last_ab_branch}" ab_branch_names ab_branch
185 fi
186
187 # prepare stage is not needed
188 list_del ab_stages prepare
189 else
190 if test -z "${ab_branch}" -a x"${do_help}" != x"1"; then
191 log_err "Autobuild branch name is invalid or not specified."
192 print_text "Quick start:"
193 print_text "- To show detailed help:"
194 log_info_raw " ${0} help"
195 print_text "- To start full build for a branch (<branch-name> example: mtxxxx-mtxxxx-xxx):"
196 log_info_raw " ${0} <branch-name>"
197 print_text "- To continue current build:"
198 log_info_raw " ${0} build"
199 print_text "- To clean everything under OpenWrt source tree:"
200 log_info_raw " ${0} clean"
201 print_text "- To start menuconfig and update defconfig for specified branch:"
202 log_info_raw " ${0} <branch-name> menuconfig"
203 print_text "- To list all available branch names:"
204 log_info_raw " ${0} <branch-name> list"
205 exit 1
206 fi
207 fi
208else
209 if test -z "${ab_branch}" -a -f "${ab_tmp}/branch_name"; then
210 last_ab_branch=$(cat "${ab_tmp}/branch_name")
211
212 # Read previous configuration
213 canonicalize_autobuild_branch_name "${last_ab_branch}" ab_branch_names ab_branch
214 fi
215fi
216
217## Fill branch names
218ab_branch_level=${#ab_branch_names[@]}
219ab_branch_platform=${ab_branch_names[0]}
220ab_branch_wifi=${ab_branch_names[1]}
221ab_branch_sku=${ab_branch_names[2]}
222ab_branch_variant=${ab_branch_names[3]}
223
224## Set and print branch configuration
225[ -n "${ab_branch}" ] && log_info "Autobuild branch: ${ab_branch}"
226
227if test -n "${ab_branch_platform}"; then
228 ab_branch_level=1
229 ab_platform_dir=${ab_root}/${ab_branch_platform}
230 print_conf "Platform" "${ab_branch_platform}"
231fi
232
233if test -n "${ab_branch_wifi}"; then
234 ab_branch_level=2
235 ab_wifi_dir=${ab_platform_dir}/${ab_branch_wifi}
236 print_conf "WiFi" "${ab_branch_wifi}"
237fi
238
239if test -n "${ab_branch_sku}"; then
240 ab_branch_level=3
241 ab_sku_dir=${ab_wifi_dir}/${ab_branch_sku}
242 print_conf "SKU" "${ab_branch_sku}"
243fi
244
245if test -n "${ab_branch_variant}"; then
246 ab_branch_level=4
247 ab_variant_dir=${ab_sku_dir}/${ab_branch_variant}
248 print_conf "Variant" "${ab_branch_variant}"
249fi
250
251# Setup global settings
252
253## Set new binary release directory
254if test x"${release_dir_set}" = x"yes"; then
255 ab_bin_release="${openwrt_root}/${release_dir}"
256fi
257
258ab_bin_release="${ab_bin_release}/${ab_branch}"
259
260## Set global directories
261ab_global=${ab_root}/global
262
263# Setup help text
264help_add_line ""
265help_add_line "Autobuild script for OpenWrt"
266help_add_line ""
267help_add_line "Usage: autobuild.sh [branch] [stage] [options...]"
268help_add_line ""
269help_add_line "Branch: <platform>[-<wifi>[-<sku>[-<variant>]]]"
270help_add_line " Branch is only required for prepare. It can be omitted for build/release"
271help_add_line " after a successful prepare."
272help_add_line ""
273help_add_line "Stages:"
274help_add_line " (If stage is not specified, default will be \"prepare/build/release\")"
275help_add_line " prepare - Prepare the OpenWrt source code."
276help_add_line " Do patching, copying/deleting files."
277help_add_line " Once prepared, clean must be done before another prepare."
278help_add_line " build - Do actual build."
279help_add_line " release - Collect built binary files only."
280help_add_line " sdk_release - Do source code release. MediaTek internal use only."
281help_add_line " menuconfig - Do menuconfig for specified branch. defconfig of this branch"
282help_add_line " will be updated."
283help_add_line " clean - Clean all modified/untraced files/directories from OpenWrt"
284help_add_line " source code."
285help_add_line " list - List all available branch names."
286help_add_line " help - Show this help."
287help_add_line ""
288help_add_line "Options:"
289help_add_line " The options can be <key>=<value>, or just simple <key>."
290help_add_line " log_file=<file> - Enable log output to file."
291help_add_line " log_file_merge - Log stdout and stderr to one file."
292help_add_line " debug - Enable debug log output."
293help_add_line " release_dir=<dir> - Override default release directory."
294help_add_line " Default directory is 'autobuild_release' under OpenWrt's source directory."
295
296# Include branch rules (the rule is child level overriding parent level)
297. "${ab_root}/rules"
298[ -f "${ab_global}/${openwrt_branch}/rules" ] && . "${ab_global}/${openwrt_branch}/rules"
299[ -n "${ab_platform_dir}" ] && . "${ab_platform_dir}/rules"
300[ -n "${ab_wifi_dir}" ] && . "${ab_wifi_dir}/rules"
301[ -n "${ab_sku_dir}" ] && . "${ab_sku_dir}/rules"
302[ -n "${ab_variant_dir}" ] && . "${ab_variant_dir}/rules"
303
304# Show help?
305if test x"${do_help}" = x"1"; then
306 help_print
307 exit 0
308fi
309
310# Run stages
311log_dbg "All stages: ${ab_stages}"
312
313for stage in ${ab_stages}; do
314 substages=$(get_substages "${stage}")
315
316 prompt_stage "Current stage: \"${stage}\""
317 log_dbg "Substages of ${stage}: ${substages}"
318
319 for substage in ${substages}; do
320 hooks=$(get_hooks "${substage}")
321
322 prompt_stage "Current substage: \"${substage}\""
323
324 [ -z "${hooks}" ] && hooks="${substage}"
325 clean_hooks hooks
326
327 if test -z "${hooks}"; then
328 log_info "Nothing to do with substage ${substage}"
329 continue
330 fi
331
332 log_dbg "Hooks of substage \"${substage}\": ${hooks}"
333
334 for hook in ${hooks}; do
335 prompt_stage "Executing hook \"${hook}\""
336
337 eval "${hook}"
338
339 ret=$?
340
341 if test ${ret} != 0; then
342 log_err "${stage}/${substage}/${hook} exited with error code ${ret}"
343 exit 1
344 fi
345 done
346 done
347done
348
349# All done
350if list_find ab_stages build; then
351 log_info "Autobuild finished"
352fi
353
354exit 0