xref: /OK3568_Linux_fs/buildroot/support/scripts/br2-external (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/usr/bin/env bash
2*4882a593Smuzhiyunset -e
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun# This script must be able to run with bash-3.1, so it can't use
5*4882a593Smuzhiyun# associative arrays. Instead, it emulates them using 'eval'. It
6*4882a593Smuzhiyun# can however use indexed arrays, supported since at least bash-3.0.
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun# The names of the br2-external trees, once validated.
9*4882a593Smuzhiyundeclare -a BR2_EXT_NAMES
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun# URL to manual for help in converting old br2-external trees.
12*4882a593Smuzhiyun# Escape '#' so that make does not consider it a comment.
13*4882a593SmuzhiyunMANUAL_URL='https://buildroot.org/manual.html\#br2-external-converting'
14*4882a593Smuzhiyun
15*4882a593Smuzhiyunmain() {
16*4882a593Smuzhiyun    local OPT OPTARG
17*4882a593Smuzhiyun    local br2_ext outputdir
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun    while getopts :d: OPT; do
20*4882a593Smuzhiyun        case "${OPT}" in
21*4882a593Smuzhiyun        d)  outputdir="${OPTARG}";;
22*4882a593Smuzhiyun        :)  error "option '%s' expects a mandatory argument\n" "${OPTARG}";;
23*4882a593Smuzhiyun        \?) error "unknown option '%s'\n" "${OPTARG}";;
24*4882a593Smuzhiyun        esac
25*4882a593Smuzhiyun    done
26*4882a593Smuzhiyun    # Forget options; keep only positional args
27*4882a593Smuzhiyun    shift $((OPTIND-1))
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun    if [ -z "${outputdir}" ]; then
30*4882a593Smuzhiyun        error "no output directory specified (-d)\n"
31*4882a593Smuzhiyun    fi
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun    # Trap any unexpected error to generate a meaningful error message
34*4882a593Smuzhiyun    trap "error 'unexpected error while generating ${ofile}\n'" ERR
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun    mkdir -p "${outputdir}"
37*4882a593Smuzhiyun    do_validate "${outputdir}" ${@//:/ }
38*4882a593Smuzhiyun    do_mk "${outputdir}"
39*4882a593Smuzhiyun    do_kconfig "${outputdir}"
40*4882a593Smuzhiyun}
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun# Validates the br2-external trees passed as arguments. Makes each of
43*4882a593Smuzhiyun# them canonical and store them in the global arrays BR2_EXT_NAMES
44*4882a593Smuzhiyun# and BR2_EXT_PATHS.
45*4882a593Smuzhiyun#
46*4882a593Smuzhiyun# Note: since this script is always first called from Makefile context
47*4882a593Smuzhiyun# to generate the Makefile fragment before it is called to generate the
48*4882a593Smuzhiyun# Kconfig snippet, we're sure that any error in do_validate will be
49*4882a593Smuzhiyun# interpreted in Makefile context. Going up to generating the Kconfig
50*4882a593Smuzhiyun# snippet means that there were no error.
51*4882a593Smuzhiyun#
52*4882a593Smuzhiyundo_validate() {
53*4882a593Smuzhiyun    local outputdir="${1}"
54*4882a593Smuzhiyun    local br2_ext
55*4882a593Smuzhiyun    shift
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun    if [ ${#} -eq 0 ]; then
58*4882a593Smuzhiyun        # No br2-external tree is valid
59*4882a593Smuzhiyun        return
60*4882a593Smuzhiyun    fi
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun    for br2_ext in "${@}"; do
63*4882a593Smuzhiyun        do_validate_one "${br2_ext}"
64*4882a593Smuzhiyun    done >"${outputdir}/.br2-external.mk"
65*4882a593Smuzhiyun}
66*4882a593Smuzhiyun
67*4882a593Smuzhiyundo_validate_one() {
68*4882a593Smuzhiyun    local br2_ext="${1}"
69*4882a593Smuzhiyun    local br2_name br2_desc n d
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun    if [ ! -d "${br2_ext}" ]; then
72*4882a593Smuzhiyun        error "'%s': no such file or directory\n" "${br2_ext}"
73*4882a593Smuzhiyun    fi
74*4882a593Smuzhiyun    if [ ! -r "${br2_ext}" -o ! -x "${br2_ext}" ]; then
75*4882a593Smuzhiyun        error "'%s': permission denied\n" "${br2_ext}"
76*4882a593Smuzhiyun    fi
77*4882a593Smuzhiyun    if [ ! -f "${br2_ext}/external.desc" ]; then
78*4882a593Smuzhiyun        error "'%s': does not have an 'external.desc'. See %s\n" \
79*4882a593Smuzhiyun            "${br2_ext}" "${MANUAL_URL}"
80*4882a593Smuzhiyun    fi
81*4882a593Smuzhiyun    br2_name="$(sed -r -e '/^name: +(.*)$/!d; s//\1/' "${br2_ext}/external.desc")"
82*4882a593Smuzhiyun    if [ -z "${br2_name}" ]; then
83*4882a593Smuzhiyun        error "'%s/external.desc': does not define the name\n" "${br2_ext}"
84*4882a593Smuzhiyun    fi
85*4882a593Smuzhiyun    # Only ASCII chars in [A-Za-z0-9_] are permitted
86*4882a593Smuzhiyun    n="$(sed -r -e 's/[A-Za-z0-9_]//g' <<<"${br2_name}" )"
87*4882a593Smuzhiyun    if [ -n "${n}" ]; then
88*4882a593Smuzhiyun        # Escape '$' so that it gets printed
89*4882a593Smuzhiyun        error "'%s': name '%s' contains invalid chars: '%s'\n" \
90*4882a593Smuzhiyun            "${br2_ext}" "${br2_name//\$/\$\$}" "${n//\$/\$\$}"
91*4882a593Smuzhiyun    fi
92*4882a593Smuzhiyun    eval d="\"\${BR2_EXT_PATHS_${br2_name}}\""
93*4882a593Smuzhiyun    if [ -n "${d}" ]; then
94*4882a593Smuzhiyun        error "'%s': name '%s' is already used in '%s'\n" \
95*4882a593Smuzhiyun            "${br2_ext}" "${br2_name}" "${d}"
96*4882a593Smuzhiyun    fi
97*4882a593Smuzhiyun    br2_desc="$(sed -r -e '/^desc: +(.*)$/!d; s//\1/' "${br2_ext}/external.desc")"
98*4882a593Smuzhiyun    if [ ! -f "${br2_ext}/external.mk" ]; then
99*4882a593Smuzhiyun        error "'%s/external.mk': no such file or directory\n" "${br2_ext}"
100*4882a593Smuzhiyun    fi
101*4882a593Smuzhiyun    if [ ! -f "${br2_ext}/Config.in" ]; then
102*4882a593Smuzhiyun        error "'%s/Config.in': no such file or directory\n" "${br2_ext}"
103*4882a593Smuzhiyun    fi
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun    # Register this br2-external tree, use an absolute canonical path
106*4882a593Smuzhiyun    br2_ext="$( cd "${br2_ext}"; pwd )"
107*4882a593Smuzhiyun    BR2_EXT_NAMES+=( "${br2_name}" )
108*4882a593Smuzhiyun    eval BR2_EXT_PATHS_${br2_name}="\"\${br2_ext}\""
109*4882a593Smuzhiyun    eval BR2_EXT_DESCS_${br2_name}="\"\${br2_desc:-\${br2_name}}\""
110*4882a593Smuzhiyun}
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun# Generate the .mk snippet that defines makefile variables
113*4882a593Smuzhiyun# for the br2-external tree
114*4882a593Smuzhiyundo_mk() {
115*4882a593Smuzhiyun    local outputdir="${1}"
116*4882a593Smuzhiyun    local br2_name br2_desc br2_ext
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun    {
119*4882a593Smuzhiyun        printf '#\n# Automatically generated file; DO NOT EDIT.\n#\n'
120*4882a593Smuzhiyun        printf '\n'
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun        printf 'BR2_EXTERNAL ?='
123*4882a593Smuzhiyun        for br2_name in "${BR2_EXT_NAMES[@]}"; do
124*4882a593Smuzhiyun            eval br2_ext="\"\${BR2_EXT_PATHS_${br2_name}}\""
125*4882a593Smuzhiyun            printf ' %s' "${br2_ext}"
126*4882a593Smuzhiyun        done
127*4882a593Smuzhiyun        printf '\n'
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun        printf 'BR2_EXTERNAL_NAMES = \n'
130*4882a593Smuzhiyun        printf 'BR2_EXTERNAL_DIRS = \n'
131*4882a593Smuzhiyun        printf 'BR2_EXTERNAL_MKS = \n'
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun        if [ ${#BR2_EXT_NAMES[@]} -eq 0 ]; then
134*4882a593Smuzhiyun            printf '\n'
135*4882a593Smuzhiyun            printf '# No br2-external tree defined.\n'
136*4882a593Smuzhiyun            return
137*4882a593Smuzhiyun        fi
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun        for br2_name in "${BR2_EXT_NAMES[@]}"; do
140*4882a593Smuzhiyun            eval br2_desc="\"\${BR2_EXT_DESCS_${br2_name}}\""
141*4882a593Smuzhiyun            eval br2_ext="\"\${BR2_EXT_PATHS_${br2_name}}\""
142*4882a593Smuzhiyun            printf '\n'
143*4882a593Smuzhiyun            printf 'BR2_EXTERNAL_NAMES += %s\n' "${br2_name}"
144*4882a593Smuzhiyun            printf 'BR2_EXTERNAL_DIRS += %s\n' "${br2_ext}"
145*4882a593Smuzhiyun            printf 'BR2_EXTERNAL_MKS += %s/external.mk\n' "${br2_ext}"
146*4882a593Smuzhiyun            printf 'export BR2_EXTERNAL_%s_PATH = %s\n' "${br2_name}" "${br2_ext}"
147*4882a593Smuzhiyun            printf 'export BR2_EXTERNAL_%s_DESC = %s\n' "${br2_name}" "${br2_desc}"
148*4882a593Smuzhiyun        done
149*4882a593Smuzhiyun    } >"${outputdir}/.br2-external.mk"
150*4882a593Smuzhiyun}
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun# Generate the kconfig snippets for the br2-external tree.
153*4882a593Smuzhiyundo_kconfig() {
154*4882a593Smuzhiyun    local outputdir="${1}"
155*4882a593Smuzhiyun    local br2_name br2_desc br2_ext br2
156*4882a593Smuzhiyun    local -a items
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun    items=(
159*4882a593Smuzhiyun        paths
160*4882a593Smuzhiyun        menus
161*4882a593Smuzhiyun        toolchains
162*4882a593Smuzhiyun        jpeg
163*4882a593Smuzhiyun        openssl
164*4882a593Smuzhiyun        skeleton
165*4882a593Smuzhiyun        init
166*4882a593Smuzhiyun        linux
167*4882a593Smuzhiyun    )
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun    for br2 in "${items[@]}"; do
170*4882a593Smuzhiyun        {
171*4882a593Smuzhiyun            printf '#\n# Automatically generated file; DO NOT EDIT.\n#\n'
172*4882a593Smuzhiyun            printf '\n'
173*4882a593Smuzhiyun            if [ ${#BR2_EXT_NAMES[@]} -eq 0 ]; then
174*4882a593Smuzhiyun                printf '# No br2-external tree defined.\n'
175*4882a593Smuzhiyun            fi
176*4882a593Smuzhiyun        } >"${outputdir}/.br2-external.in.${br2}"
177*4882a593Smuzhiyun    done
178*4882a593Smuzhiyun    if [ ${#BR2_EXT_NAMES[@]} -eq 0 ]; then
179*4882a593Smuzhiyun        return
180*4882a593Smuzhiyun    fi
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun    printf 'menu "External options"\n\n' >>"${outputdir}/.br2-external.in.menus"
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun    for br2_name in "${BR2_EXT_NAMES[@]}"; do
185*4882a593Smuzhiyun        eval br2_desc="\"\${BR2_EXT_DESCS_${br2_name}}\""
186*4882a593Smuzhiyun        eval br2_ext="\"\${BR2_EXT_PATHS_${br2_name}}\""
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun        {
189*4882a593Smuzhiyun            printf 'config BR2_EXTERNAL_%s_PATH\n' "${br2_name}"
190*4882a593Smuzhiyun            printf '\tstring\n'
191*4882a593Smuzhiyun            printf '\tdefault "%s"\n' "${br2_ext}"
192*4882a593Smuzhiyun            printf '\n'
193*4882a593Smuzhiyun        } >>"${outputdir}/.br2-external.in.paths"
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun        {
196*4882a593Smuzhiyun            if [ ${#BR2_EXT_NAMES[@]} -gt 1 ]; then
197*4882a593Smuzhiyun                printf 'menu "%s"\n' "${br2_desc}"
198*4882a593Smuzhiyun            fi
199*4882a593Smuzhiyun            printf 'comment "%s (in %s)"\n' "${br2_desc}" "${br2_ext}"
200*4882a593Smuzhiyun            printf 'source "%s/Config.in"\n' "${br2_ext}"
201*4882a593Smuzhiyun            if [ ${#BR2_EXT_NAMES[@]} -gt 1 ]; then
202*4882a593Smuzhiyun                printf 'endmenu # %s\n' "${br2_name}"
203*4882a593Smuzhiyun            fi
204*4882a593Smuzhiyun            printf '\n'
205*4882a593Smuzhiyun        } >>"${outputdir}/.br2-external.in.menus"
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun        if [ -f "${br2_ext}/provides/toolchains.in" ]; then
208*4882a593Smuzhiyun            printf 'comment "Toolchains from: %s"\n' "${br2_desc}"
209*4882a593Smuzhiyun            printf 'source "%s/provides/toolchains.in"\n' "${br2_ext}"
210*4882a593Smuzhiyun            printf '\n'
211*4882a593Smuzhiyun        else
212*4882a593Smuzhiyun            printf '# No toolchain from: %s\n\n' "${br2_desc}"
213*4882a593Smuzhiyun        fi >>"${outputdir}/.br2-external.in.toolchains"
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun        if [ -f "${br2_ext}/provides/jpeg.in" ]; then
216*4882a593Smuzhiyun            printf 'comment "jpeg from: %s"\n' "${br2_desc}"
217*4882a593Smuzhiyun            printf 'source "%s/provides/jpeg.in"\n' "${br2_ext}"
218*4882a593Smuzhiyun            printf '\n'
219*4882a593Smuzhiyun        else
220*4882a593Smuzhiyun            printf '# No jpeg from: %s\n\n' "${br2_desc}"
221*4882a593Smuzhiyun        fi >>"${outputdir}/.br2-external.in.jpeg"
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun        if [ -f "${br2_ext}/provides/openssl.in" ]; then
224*4882a593Smuzhiyun            printf 'comment "openssl from: %s"\n' "${br2_desc}"
225*4882a593Smuzhiyun            printf 'source "%s/provides/openssl.in"\n' "${br2_ext}"
226*4882a593Smuzhiyun            printf '\n'
227*4882a593Smuzhiyun        else
228*4882a593Smuzhiyun            printf '# No openssl from: %s\n\n' "${br2_desc}"
229*4882a593Smuzhiyun        fi >>"${outputdir}/.br2-external.in.openssl"
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun        if [ -f "${br2_ext}/provides/skeleton.in" ]; then
232*4882a593Smuzhiyun            printf 'comment "skeleton from: %s"\n' "${br2_desc}"
233*4882a593Smuzhiyun            printf 'source "%s/provides/skeleton.in"\n' "${br2_ext}"
234*4882a593Smuzhiyun            printf '\n'
235*4882a593Smuzhiyun        else
236*4882a593Smuzhiyun            printf '# No skeleton from: %s\n\n' "${br2_desc}"
237*4882a593Smuzhiyun        fi >>"${outputdir}/.br2-external.in.skeleton"
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun        if [ -f "${br2_ext}/provides/init.in" ]; then
240*4882a593Smuzhiyun            printf 'comment "init from: %s"\n' "${br2_desc}"
241*4882a593Smuzhiyun            printf 'source "%s/provides/init.in"\n' "${br2_ext}"
242*4882a593Smuzhiyun            printf '\n'
243*4882a593Smuzhiyun        else
244*4882a593Smuzhiyun            printf '# No init from: %s\n\n' "${br2_desc}"
245*4882a593Smuzhiyun        fi >>"${outputdir}/.br2-external.in.init"
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun        if [ -f "${br2_ext}/linux/Config.ext.in" ]; then
248*4882a593Smuzhiyun            printf 'comment "linux extension from: %s"\n' "${br2_desc}"
249*4882a593Smuzhiyun            printf 'source "%s/linux/Config.ext.in"\n' "${br2_ext}"
250*4882a593Smuzhiyun            printf '\n'
251*4882a593Smuzhiyun        else
252*4882a593Smuzhiyun            printf '# No linux extension from: %s\n\n' "${br2_desc}"
253*4882a593Smuzhiyun        fi >>"${outputdir}/.br2-external.in.linux"
254*4882a593Smuzhiyun    done
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun    printf 'endmenu\n' >>"${outputdir}/.br2-external.in.menus"
257*4882a593Smuzhiyun}
258*4882a593Smuzhiyun
259*4882a593Smuzhiyunerror() { local fmt="${1}"; shift; printf "BR2_EXTERNAL_ERROR = ${fmt}" "${@}"; exit 1; }
260*4882a593Smuzhiyun
261*4882a593Smuzhiyunmy_name="${0##*/}"
262*4882a593Smuzhiyunmain "${@}"
263