blob: 76f7e9ba48a3a2e3aa49966e52ff12a452bb3480 [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"
developer521bb952024-09-26 17:06:50 +0800131 if test x"${reserve_feeds_set}" != x"yes"; then
132 exec_log "rm -rf \"${openwrt_root}/feeds\""
133 exec_log "rm -rf \"${openwrt_root}/package/feeds\""
134 fi
developer782bc7f2024-08-23 15:39:22 +0800135 exec_log "rm -rf \"${openwrt_root}/.ab\""
136
137 exit 0
138fi
139
140# Check if we need prepare for build stage
141if list_find ab_stages build; then
142 if test \( ! -f "${ab_tmp}/branch_name" \) -o -f "${ab_tmp}/.stamp.menuconfig"; then
143 list_add_before_unique ab_stages build prepare
144 fi
145fi
146
147# Check for prepare stage
148if list_find ab_stages prepare; then
149 if test -f "${ab_tmp}/branch_name"; then
150 # If prepare stage has been done before, check whether clean is required
151
152 if test -z "${do_menuconfig}" -a -f "${ab_tmp}/.stamp.menuconfig"; then
153 log_warn "This OpenWrt source code has already been prepared for menuconfig."
154 log_warn "Please call \`${0} clean' first."
155 exit 1
156 fi
157
158 if test -n "${do_menuconfig}" -a ! -f "${ab_tmp}/.stamp.menuconfig"; then
159 log_warn "This OpenWrt source code has already been prepared, but not for menuconfig."
160 log_warn "Please call \`${0} clean' first."
161 exit 1
162 fi
163
164 last_ab_branch=$(cat "${ab_tmp}/branch_name")
165
166 if test -n "${ab_branch}"; then
167 if test x"${ab_branch}" != x"${last_ab_branch}"; then
168 log_warn "Autobuild branch name has changed."
169 log_warn "Please call \`${0} clean' first."
170 exit 1
171 fi
172
173 if test -z "${do_menuconfig}"; then
174 last_ab_cmdline=$(cat "${ab_tmp}/cmdline")
175
176 if test x"${ab_cmdline}" != x"${last_ab_cmdline}"; then
177 log_warn "Autobuild configuration has changed."
178 log_warn "Please call \`${0} clean' first."
179 exit 1
180 fi
181 fi
182
183 # Configuration unchanged
184 else
185 # Read previous configuration
186 canonicalize_autobuild_branch_name "${last_ab_branch}" ab_branch_names ab_branch
187 fi
188
189 # prepare stage is not needed
190 list_del ab_stages prepare
191 else
192 if test -z "${ab_branch}" -a x"${do_help}" != x"1"; then
193 log_err "Autobuild branch name is invalid or not specified."
194 print_text "Quick start:"
195 print_text "- To show detailed help:"
196 log_info_raw " ${0} help"
197 print_text "- To start full build for a branch (<branch-name> example: mtxxxx-mtxxxx-xxx):"
198 log_info_raw " ${0} <branch-name>"
199 print_text "- To continue current build:"
200 log_info_raw " ${0} build"
201 print_text "- To clean everything under OpenWrt source tree:"
202 log_info_raw " ${0} clean"
203 print_text "- To start menuconfig and update defconfig for specified branch:"
204 log_info_raw " ${0} <branch-name> menuconfig"
205 print_text "- To list all available branch names:"
206 log_info_raw " ${0} <branch-name> list"
207 exit 1
208 fi
209 fi
210else
211 if test -z "${ab_branch}" -a -f "${ab_tmp}/branch_name"; then
212 last_ab_branch=$(cat "${ab_tmp}/branch_name")
213
214 # Read previous configuration
215 canonicalize_autobuild_branch_name "${last_ab_branch}" ab_branch_names ab_branch
216 fi
217fi
218
219## Fill branch names
220ab_branch_level=${#ab_branch_names[@]}
221ab_branch_platform=${ab_branch_names[0]}
222ab_branch_wifi=${ab_branch_names[1]}
223ab_branch_sku=${ab_branch_names[2]}
224ab_branch_variant=${ab_branch_names[3]}
225
226## Set and print branch configuration
227[ -n "${ab_branch}" ] && log_info "Autobuild branch: ${ab_branch}"
228
229if test -n "${ab_branch_platform}"; then
230 ab_branch_level=1
231 ab_platform_dir=${ab_root}/${ab_branch_platform}
232 print_conf "Platform" "${ab_branch_platform}"
233fi
234
235if test -n "${ab_branch_wifi}"; then
236 ab_branch_level=2
237 ab_wifi_dir=${ab_platform_dir}/${ab_branch_wifi}
238 print_conf "WiFi" "${ab_branch_wifi}"
239fi
240
241if test -n "${ab_branch_sku}"; then
242 ab_branch_level=3
243 ab_sku_dir=${ab_wifi_dir}/${ab_branch_sku}
244 print_conf "SKU" "${ab_branch_sku}"
245fi
246
247if test -n "${ab_branch_variant}"; then
248 ab_branch_level=4
249 ab_variant_dir=${ab_sku_dir}/${ab_branch_variant}
250 print_conf "Variant" "${ab_branch_variant}"
251fi
252
253# Setup global settings
254
255## Set new binary release directory
256if test x"${release_dir_set}" = x"yes"; then
257 ab_bin_release="${openwrt_root}/${release_dir}"
258fi
259
260ab_bin_release="${ab_bin_release}/${ab_branch}"
261
262## Set global directories
263ab_global=${ab_root}/global
264
265# Setup help text
266help_add_line ""
267help_add_line "Autobuild script for OpenWrt"
268help_add_line ""
269help_add_line "Usage: autobuild.sh [branch] [stage] [options...]"
270help_add_line ""
271help_add_line "Branch: <platform>[-<wifi>[-<sku>[-<variant>]]]"
272help_add_line " Branch is only required for prepare. It can be omitted for build/release"
273help_add_line " after a successful prepare."
274help_add_line ""
275help_add_line "Stages:"
276help_add_line " (If stage is not specified, default will be \"prepare/build/release\")"
277help_add_line " prepare - Prepare the OpenWrt source code."
278help_add_line " Do patching, copying/deleting files."
279help_add_line " Once prepared, clean must be done before another prepare."
280help_add_line " build - Do actual build."
281help_add_line " release - Collect built binary files only."
282help_add_line " sdk_release - Do source code release. MediaTek internal use only."
283help_add_line " menuconfig - Do menuconfig for specified branch. defconfig of this branch"
284help_add_line " will be updated."
285help_add_line " clean - Clean all modified/untraced files/directories from OpenWrt"
286help_add_line " source code."
287help_add_line " list - List all available branch names."
288help_add_line " help - Show this help."
289help_add_line ""
290help_add_line "Options:"
291help_add_line " The options can be <key>=<value>, or just simple <key>."
292help_add_line " log_file=<file> - Enable log output to file."
293help_add_line " log_file_merge - Log stdout and stderr to one file."
294help_add_line " debug - Enable debug log output."
295help_add_line " release_dir=<dir> - Override default release directory."
296help_add_line " Default directory is 'autobuild_release' under OpenWrt's source directory."
developer561475a2024-09-27 11:07:06 +0800297help_add_line " sync_config - When used with menuconfig, .config will be updated with"
298help_add_line " current branch defconfigs before starting menuconfig"
developer782bc7f2024-08-23 15:39:22 +0800299
300# Include branch rules (the rule is child level overriding parent level)
301. "${ab_root}/rules"
302[ -f "${ab_global}/${openwrt_branch}/rules" ] && . "${ab_global}/${openwrt_branch}/rules"
303[ -n "${ab_platform_dir}" ] && . "${ab_platform_dir}/rules"
304[ -n "${ab_wifi_dir}" ] && . "${ab_wifi_dir}/rules"
305[ -n "${ab_sku_dir}" ] && . "${ab_sku_dir}/rules"
306[ -n "${ab_variant_dir}" ] && . "${ab_variant_dir}/rules"
307
308# Show help?
309if test x"${do_help}" = x"1"; then
310 help_print
311 exit 0
312fi
313
314# Run stages
315log_dbg "All stages: ${ab_stages}"
316
317for stage in ${ab_stages}; do
318 substages=$(get_substages "${stage}")
319
320 prompt_stage "Current stage: \"${stage}\""
321 log_dbg "Substages of ${stage}: ${substages}"
322
323 for substage in ${substages}; do
324 hooks=$(get_hooks "${substage}")
325
326 prompt_stage "Current substage: \"${substage}\""
327
328 [ -z "${hooks}" ] && hooks="${substage}"
329 clean_hooks hooks
330
331 if test -z "${hooks}"; then
332 log_info "Nothing to do with substage ${substage}"
333 continue
334 fi
335
336 log_dbg "Hooks of substage \"${substage}\": ${hooks}"
337
338 for hook in ${hooks}; do
339 prompt_stage "Executing hook \"${hook}\""
340
341 eval "${hook}"
342
343 ret=$?
344
345 if test ${ret} != 0; then
346 log_err "${stage}/${substage}/${hook} exited with error code ${ret}"
347 exit 1
348 fi
349 done
350 done
351done
352
353# All done
354if list_find ab_stages build; then
355 log_info "Autobuild finished"
356fi
357
358exit 0