#!/bin/bash set -e # The name and location of the br2-external tree, once validated. declare BR2_NAME declare BR2_EXT # URL to manual for help in converting old br2-external trees. # Escape '#' so that make does not consider it a comment. MANUAL_URL='https://buildroot.org/manual/manual.html\#br2-external-converting' main() { local OPT OPTARG local br2_ext ofile ofmt while getopts :hkmo: OPT; do case "${OPT}" in h) help; exit 0;; o) ofile="${OPTARG}";; k) ofmt="kconfig";; m) ofmt="mk";; :) error "option '%s' expects a mandatory argument\n" "${OPTARG}";; \?) error "unknown option '%s'\n" "${OPTARG}";; esac done # Forget options; keep only positional args shift $((OPTIND-1)) # Accept 0 or 1 br2-external tree. if [ ${#} -gt 1 ]; then error "only zero or one br2-external tree allowed.\n" fi br2_ext="${1}" case "${ofmt}" in mk|kconfig) ;; *) error "no output format specified (-m/-k)\n";; esac if [ -z "${ofile}" ]; then error "no output file specified (-o)\n" fi exec >"${ofile}" do_validate "${br2_ext}" do_${ofmt} } # Validates the br2-external tree passed as argument. Makes it cannonical # and store it in global variable BR2_EXT. # # Note: since this script is always first called from Makefile context # to generate the Makefile fragment before it is called to generate the # Kconfig snippet, we're sure that any error in do_validate will be # interpreted in Makefile context. Going up to generating the Kconfig # snippet means that there were no error. # do_validate() { local br2_ext="${1}" local br2_name n # No br2-external tree is valid if [ -z "${br2_ext}" ]; then return fi if [ ! -d "${br2_ext}" ]; then error "'%s': no such file or directory\n" "${br2_ext}" fi if [ ! -r "${br2_ext}" -o ! -x "${br2_ext}" ]; then error "'%s': permission denied\n" "${br2_ext}" fi if [ ! -f "${br2_ext}/external.desc" ]; then error "'%s': does not have a name (in 'external.desc'). See %s\n" \ "${br2_ext}" "${MANUAL_URL}" fi br2_name="$(sed -r -e '/^name: +(.*)$/!d; s//\1/' "${br2_ext}/external.desc")" if [ -z "${br2_name}" ]; then error "'%s/external.desc': does not define the name\n" "${br2_ext}" fi # Only ASCII chars in [A-Za-z0-9_] are permitted n="$(sed -r -e 's/[A-Za-z0-9_]//g' <<<"${br2_name}" )" if [ -n "${n}" ]; then # Escape '$' so that it gets printed error "'%s': name '%s' contains invalid chars: '%s'\n" \ "${br2_ext}" "${br2_name//\$/\$\$}" "${n//\$/\$\$}" fi if [ ! -f "${br2_ext}/external.mk" ]; then error "'%s/external.mk': no such file or directory\n" "${br2_ext}" fi if [ ! -f "${br2_ext}/Config.in" ]; then error "'%s/Config.in': no such file or directory\n" "${br2_ext}" fi BR2_NAME="${br2_name}" BR2_EXT="$(cd "${br2_ext}"; pwd -P )" } # Generate the .mk snippet that defines makefile variables # for the br2-external tree do_mk() { printf '#\n# Automatically generated file; DO NOT EDIT.\n#\n' printf '\n' printf 'BR2_EXTERNAL ?= %s\n' "${BR2_EXT}" printf 'BR2_EXTERNAL_NAME = \n' printf 'BR2_EXTERNAL_MK =\n' printf '\n' if [ -z "${BR2_NAME}" ]; then printf '# No br2-external tree defined.\n' return fi printf 'BR2_EXTERNAL_NAME = %s\n' "${BR2_NAME}" printf 'BR2_EXTERNAL_MK = %s/external.mk\n' "${BR2_EXT}" printf 'BR2_EXTERNAL_%s_PATH = %s\n' "${BR2_NAME}" "${BR2_EXT}" } # Generate the kconfig snippet for the br2-external tree. do_kconfig() { printf '#\n# Automatically generated file; DO NOT EDIT.\n#\n' printf '\n' if [ -z "${BR2_NAME}" ]; then printf '# No br2-external tree defined.\n' return fi printf 'menu "User-provided options"\n' printf '\n' printf 'comment "%s (in %s)"\n' "${BR2_NAME}" "${BR2_EXT}" printf '\n' printf 'config BR2_EXTERNAL_%s_PATH\n' "${BR2_NAME}" printf '\tstring\n' printf '\tdefault "%s"\n' "${BR2_EXT}" printf '\n' printf 'source "$BR2_EXTERNAL_%s_PATH/Config.in"\n' "${BR2_NAME}" printf '\n' printf "endmenu # User-provided options\n" } help() { cat <<-_EOF_ Usage: ${my_name} <-m|-k> -o FILE PATH With -m, ${my_name} generates the makefile fragment that defines variables related to the br2-external tree passed as positional argument. With -k, ${my_name} generates the kconfig snippet to include the configuration options specified in the br2-external tree passed as positional argument. Using -k and -m together is not possible. The last one wins. Options: -m Generate the makefile fragment. -k Generate the kconfig snippet. -o FILE FILE in which to generate the kconfig snippet or makefile fragment. Returns: 0 If no error !0 If any error _EOF_ } error() { local fmt="${1}"; shift; printf "BR2_EXTERNAL_ERROR = ${fmt}" "${@}"; exit 1; } my_name="${0##*/}" main "${@}"