2
1

br2-external 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #!/bin/bash
  2. set -e
  3. # The names and locations of the br2-external trees, once validated.
  4. declare -a BR2_EXT_NAMES
  5. declare -A BR2_EXT_PATHS
  6. declare -A BR2_EXT_DESCS
  7. # URL to manual for help in converting old br2-external trees.
  8. # Escape '#' so that make does not consider it a comment.
  9. MANUAL_URL='https://buildroot.org/manual/manual.html\#br2-external-converting'
  10. main() {
  11. local OPT OPTARG
  12. local br2_ext ofile ofmt
  13. while getopts :hkmo: OPT; do
  14. case "${OPT}" in
  15. h) help; exit 0;;
  16. o) ofile="${OPTARG}";;
  17. k) ofmt="kconfig";;
  18. m) ofmt="mk";;
  19. :) error "option '%s' expects a mandatory argument\n" "${OPTARG}";;
  20. \?) error "unknown option '%s'\n" "${OPTARG}";;
  21. esac
  22. done
  23. # Forget options; keep only positional args
  24. shift $((OPTIND-1))
  25. case "${ofmt}" in
  26. mk|kconfig)
  27. ;;
  28. *) error "no output format specified (-m/-k)\n";;
  29. esac
  30. if [ -z "${ofile}" ]; then
  31. error "no output file specified (-o)\n"
  32. fi
  33. exec >"${ofile}"
  34. do_validate ${@//:/ }
  35. do_${ofmt}
  36. }
  37. # Validates the br2-external trees passed as arguments. Makes each of
  38. # them canonical and store them in the global arrays BR2_EXT_NAMES
  39. # and BR2_EXT_PATHS.
  40. #
  41. # Note: since this script is always first called from Makefile context
  42. # to generate the Makefile fragment before it is called to generate the
  43. # Kconfig snippet, we're sure that any error in do_validate will be
  44. # interpreted in Makefile context. Going up to generating the Kconfig
  45. # snippet means that there were no error.
  46. #
  47. do_validate() {
  48. local br2_ext
  49. if [ ${#} -eq 0 ]; then
  50. # No br2-external tree is valid
  51. return
  52. fi
  53. for br2_ext in "${@}"; do
  54. do_validate_one "${br2_ext}"
  55. done
  56. }
  57. do_validate_one() {
  58. local br2_ext="${1}"
  59. local br2_name br2_desc n
  60. if [ ! -d "${br2_ext}" ]; then
  61. error "'%s': no such file or directory\n" "${br2_ext}"
  62. fi
  63. if [ ! -r "${br2_ext}" -o ! -x "${br2_ext}" ]; then
  64. error "'%s': permission denied\n" "${br2_ext}"
  65. fi
  66. if [ ! -f "${br2_ext}/external.desc" ]; then
  67. error "'%s': does not have a name (in 'external.desc'). See %s\n" \
  68. "${br2_ext}" "${MANUAL_URL}"
  69. fi
  70. br2_name="$(sed -r -e '/^name: +(.*)$/!d; s//\1/' "${br2_ext}/external.desc")"
  71. if [ -z "${br2_name}" ]; then
  72. error "'%s/external.desc': does not define the name\n" "${br2_ext}"
  73. fi
  74. # Only ASCII chars in [A-Za-z0-9_] are permitted
  75. n="$(sed -r -e 's/[A-Za-z0-9_]//g' <<<"${br2_name}" )"
  76. if [ -n "${n}" ]; then
  77. # Escape '$' so that it gets printed
  78. error "'%s': name '%s' contains invalid chars: '%s'\n" \
  79. "${br2_ext}" "${br2_name//\$/\$\$}" "${n//\$/\$\$}"
  80. fi
  81. if [ -n "${BR2_EXT_PATHS["${br2_name}"]}" ]; then
  82. error "'%s': name '%s' is already used in '%s'\n" \
  83. "${br2_ext}" "${br2_name}" "${BR2_EXT_PATHS["${br2_name}"]}"
  84. fi
  85. br2_desc="$(sed -r -e '/^desc: +(.*)$/!d; s//\1/' "${br2_ext}/external.desc")"
  86. if [ ! -f "${br2_ext}/external.mk" ]; then
  87. error "'%s/external.mk': no such file or directory\n" "${br2_ext}"
  88. fi
  89. if [ ! -f "${br2_ext}/Config.in" ]; then
  90. error "'%s/Config.in': no such file or directory\n" "${br2_ext}"
  91. fi
  92. # Register this br2-external tree
  93. BR2_EXT_NAMES+=( "${br2_name}" )
  94. BR2_EXT_PATHS["${br2_name}"]="${br2_ext}"
  95. BR2_EXT_DESCS["${br2_name}"]="${br2_desc:-${br2_name}}"
  96. }
  97. # Generate the .mk snippet that defines makefile variables
  98. # for the br2-external tree
  99. do_mk() {
  100. local br2_name br2_ext
  101. printf '#\n# Automatically generated file; DO NOT EDIT.\n#\n'
  102. printf '\n'
  103. # We can't use ${BR2_EXT_NAMES[@]} directly: it is not guaranteed
  104. # to be in the order paths were added (because it is an associative
  105. # array). So we need to iterate on BR2_EXT_NAMES, which is sorted
  106. # in the order names were added (because it is an indexed array).
  107. printf 'BR2_EXTERNAL ?='
  108. for br2_name in "${BR2_EXT_NAMES[@]}"; do
  109. printf ' %s' "${BR2_EXT_PATHS["${br2_name}"]}"
  110. done
  111. printf '\n'
  112. printf 'BR2_EXTERNAL_NAMES = \n'
  113. printf 'BR2_EXTERNAL_DIRS = \n'
  114. printf 'BR2_EXTERNAL_MKS = \n'
  115. if [ ${#BR2_EXT_NAMES[@]} -eq 0 ]; then
  116. printf '\n'
  117. printf '# No br2-external tree defined.\n'
  118. return
  119. fi
  120. for br2_name in "${BR2_EXT_NAMES[@]}"; do
  121. br2_desc="${BR2_EXT_DESCS["${br2_name}"]}"
  122. br2_ext="${BR2_EXT_PATHS["${br2_name}"]}"
  123. printf '\n'
  124. printf 'BR2_EXTERNAL_NAMES += %s\n' "${br2_name}"
  125. printf 'BR2_EXTERNAL_DIRS += %s\n' "${br2_ext}"
  126. printf 'BR2_EXTERNAL_MKS += %s/external.mk\n' "${br2_ext}"
  127. printf 'export BR2_EXTERNAL_%s_PATH = %s\n' "${br2_name}" "${br2_ext}"
  128. printf 'export BR2_EXTERNAL_%s_DESC = %s\n' "${br2_name}" "${br2_desc}"
  129. done
  130. }
  131. # Generate the kconfig snippet for the br2-external tree.
  132. do_kconfig() {
  133. local br2_name br2_ext
  134. printf '#\n# Automatically generated file; DO NOT EDIT.\n#\n'
  135. printf '\n'
  136. if [ ${#BR2_EXT_NAMES[@]} -eq 0 ]; then
  137. printf '# No br2-external tree defined.\n'
  138. return
  139. fi
  140. printf 'menu "External options"\n'
  141. printf '\n'
  142. for br2_name in "${BR2_EXT_NAMES[@]}"; do
  143. br2_desc="${BR2_EXT_DESCS["${br2_name}"]}"
  144. br2_ext="${BR2_EXT_PATHS["${br2_name}"]}"
  145. if [ ${#BR2_EXT_NAMES[@]} -gt 1 ]; then
  146. printf 'menu "%s"\n' "${br2_desc}"
  147. fi
  148. printf 'comment "%s (in %s)"\n' "${br2_desc}" "${br2_ext}"
  149. printf 'config BR2_EXTERNAL_%s_PATH\n' "${br2_name}"
  150. printf '\tstring\n'
  151. printf '\tdefault "%s"\n' "${br2_ext}"
  152. printf 'source "%s/Config.in"\n' "${br2_ext}"
  153. if [ ${#BR2_EXT_NAMES[@]} -gt 1 ]; then
  154. printf 'endmenu # %s\n' "${br2_name}"
  155. fi
  156. printf '\n'
  157. done
  158. printf "endmenu # User-provided options\n"
  159. }
  160. help() {
  161. cat <<-_EOF_
  162. Usage:
  163. ${my_name} <-m|-k> -o FILE PATH
  164. With -m, ${my_name} generates the makefile fragment that defines
  165. variables related to the br2-external trees passed as positional
  166. arguments.
  167. With -k, ${my_name} generates the kconfig snippet to include the
  168. configuration options specified in the br2-external trees passed
  169. as positional arguments.
  170. Using -k and -m together is not possible. The last one wins.
  171. Options:
  172. -m Generate the makefile fragment.
  173. -k Generate the kconfig snippet.
  174. -o FILE
  175. FILE in which to generate the kconfig snippet or makefile
  176. fragment.
  177. Returns:
  178. 0 If no error
  179. !0 If any error
  180. _EOF_
  181. }
  182. error() { local fmt="${1}"; shift; printf "BR2_EXTERNAL_ERROR = ${fmt}" "${@}"; exit 1; }
  183. my_name="${0##*/}"
  184. main "${@}"