From a0f533460bcb41a04d592345303348575f2e23e2 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sun, 11 Apr 2010 02:14:56 +0200 Subject: auto-generate package/Config.in The algorithm in package/pkgmaker works as follows: 1) for all package/*/Makefile a) parse PKG_NAME and PKG_SECTION b) skip if PKG_SECTION is 'kernel' (special ones) c) check if Config.in{,.lib,.manual} contain something d) fetch the first word of the first prompt from any result from c) e) fetch the verbose section name from package/SECTIONS.list based on PKG_SECTION, or just 'libs' if it's about Config.in.lib f) write results to package/package_section_list, in the form: ' ' 2) sort package/package_section_list first by , next by 3) create package/Config.in.auto using the result from 2) --- package/pkgmaker | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) (limited to 'package/pkgmaker') diff --git a/package/pkgmaker b/package/pkgmaker index ea89424e7..bb91dbe37 100644 --- a/package/pkgmaker +++ b/package/pkgmaker @@ -71,7 +71,7 @@ for dn in */Makefile; do typeset -u dnu=${dn//-/_} dnu=${dnu//+/X} - ( # fd 4 = Config.in; fd 5 = Config.in.lib + ( # fd 4 = Config.in; fd 5 = Config.in.lib; fd 6 = Config.in.kmod g5=0 # Handle master package (directory) @@ -264,3 +264,79 @@ EOF ) 4>Config.in 5>Config.in.lib 6>Config.in.kmod cd .. done + +# return good if given file exists and is non-empty +function non_empty_file() { + [[ -f "$1" ]] || return 1 + [[ -n "$(cat "$1")" ]] || return 1 + return 0 +} + +# print the verbose section name for a given section tag +function lookup_section_string() { + str="$(grep ^$1\ SECTIONS.list | cut -d ' ' -f '2-')" + [[ -n $str ]] && { echo $str; return; } + echo $1 +} + +# print the first prompt's first word's value in a given Config.in file +function get_first_prompt() { + prompt="$(grep -m 1 "prompt " $1 | sed -n 's/.*"\([^ \.]*\)[ \.].*"/\1/p')" + [[ -n $prompt ]] && echo $prompt +} + +# collect packages along with their section and +# create a list of '
' for later sorting +rm -f package_section_list +for dn in */Makefile; do + dn=${dn%/*} + pbar="Pass 3: $dn ..." + print -nu2 "$pbar\r" + + cd $dn + eval $($GMAKE dump="PKG_NAME PKG_SECTION") + cd .. + + # ignore section kernel, these are included inside target/config + [[ $PKG_SECTION = kernel ]] && continue + + PKG_SECTION=${PKG_SECTION:-none} + + has_config_in=false + if non_empty_file $dn/Config.in; then + prompt="$(get_first_prompt $dn/Config.in)" + prompt="${prompt:-$PKG_NAME}" + echo "$prompt $dn/Config.in $(lookup_section_string $PKG_SECTION)" + has_config_in=true + fi + if non_empty_file $dn/Config.in.lib; then + prompt="$(get_first_prompt $dn/Config.in.lib)" + prompt="${prompt:-$PKG_NAME}" + echo "$prompt $dn/Config.in.lib $(lookup_section_string libs)" + has_config_in=true + fi + if non_empty_file $dn/Config.in.manual; then + prompt="$(get_first_prompt $dn/Config.in.manual)" + prompt="${prompt:-$PKG_NAME}" + echo "$prompt $dn/Config.in.manual $(lookup_section_string $PKG_SECTION)" + has_config_in=true + fi + $has_config_in || print -u2 "$dn: No Config.in file found?!" +done >package_section_list + +# create the Config.in.auto from the sorted list from above +cursec="" +sort -k 3 -k 1 -f package_section_list | while read name file section; do + pbar="Pass 4: $name ..." + print -nu2 "$pbar\r" + + if [[ $cursec != $section ]]; then + [[ -n $cursec ]] && print "endmenu\n" + + print "menu \"$section\"" + cursec="$section" + fi + print "source \"package/$file\"" +done >Config.in.auto +print "endmenu\n" >>Config.in.auto +rm -f package_section_list -- cgit v1.2.3 From 2c5f2d9b3b3b26ecf783f30112fc6019c1c17167 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Sat, 12 Jun 2010 17:35:44 +0200 Subject: massive rewrite of the pkgmaker logic When adjusting for auto-generated package/Config.in, I found out that the splitting into Config.in{,.lib,.kmod} done by pkgmaker was rather subversive to my approach. Categorisation of packages and subpackages should be done via package section, which is enabled by this patch for subpackages, too. Instead of filling up the package subdirectories, use a common directory package/pkgconfigs.d/ to contain all auto-generated Config.in files. In order to allow simple assumption from config symbol to actual package from within menuconfig (the path to the Config.in file containing the current config symbol is printed as part of the help text), put all generated Config.in files for a certain package into a common subdirectory. pkgmaker now saves each generated config symbol (excluding the flavours) into it's own file, therefore allowing to sort subpackages of a package into a different section. --- package/pkgmaker | 81 +++++++++++++++++++------------------------------------- 1 file changed, 27 insertions(+), 54 deletions(-) (limited to 'package/pkgmaker') diff --git a/package/pkgmaker b/package/pkgmaker index bb91dbe37..5a4707937 100644 --- a/package/pkgmaker +++ b/package/pkgmaker @@ -40,12 +40,14 @@ for dn in */Makefile; do done # build Config.in files and resolve dependencies +rm -f package_sections +rm -rf pkgconfigs.d +mkdir pkgconfigs.d for dn in */Makefile; do dn=${dn%/*} - # skip if we take care of this one manually - [[ $dn != "base-files" ]] && [[ -s $dn/Config.in.manual ]] && continue pbar="Pass 2: $dn ..." print -nu2 "$pbar\r" + mkdir pkgconfigs.d/$dn cd $dn # PKG_NAME: package name (directory, free-format) @@ -61,9 +63,9 @@ for dn in */Makefile; do # CFLINE_*: one free-format Config.in line per subpackage option # PKGFD_*: flavour description, per package flavour option # PKG_{HOST,TARGET}_DEPENDS: add host or target dependencies - eval $($GMAKE dump="PKG_NAME PKG_FLAVOURS PKG_DESCR PKG_URL PKG_MULTI PKG_CXX \ + eval $($GMAKE dump="PKG_NAME PKG_FLAVOURS PKG_DESCR PKG_SECTION PKG_URL PKG_MULTI PKG_CXX \ ALL_PKGOPTS \$(foreach x,\${ALL_PKGOPTS},PKGNAME_\${x} \ - PKGDESC_\${x} PKGDEPS_\${x} PKGDFLT_\${x} CFLINE_\${x}) \ + PKGDESC_\${x} PKGDEPS_\${x} PKGDFLT_\${x} PKGSECT_\${x} CFLINE_\${x}) \ \$(foreach x,\${PKG_FLAVOURS},PKGFD_\${x}) \ PKG_HOST_DEPENDS PKG_TARGET_DEPENDS") @@ -71,8 +73,13 @@ for dn in */Makefile; do typeset -u dnu=${dn//-/_} dnu=${dnu//+/X} - ( # fd 4 = Config.in; fd 5 = Config.in.lib; fd 6 = Config.in.kmod - g5=0 + echo "pkgconfigs.d/$dn/Config.in ${PKG_SECTION:=none}" >>../package_sections + echo "$dn/Config.in.manual ${PKG_SECTION:=none}" >>../package_sections + + # skip if we take care of this one manually + [[ $dn != "base-files" ]] && [[ -s Config.in.manual ]] && { cd ..; continue; } + + exec 4>../pkgconfigs.d/$dn/Config.in # Handle master package (directory) print -u4 "config ADK_COMPILE_$dnu" @@ -165,20 +172,15 @@ for dn in */Makefile; do eval sppn=\$PKGNAME_$spcu # sppn: subpackage (ipkg) name eval desc=\$PKGDESC_$spcu # desc: subpackage description : ${desc:=$PKG_DESCR} # take from main pkg if empty + eval sect=\$PKGSECT_$spcu # sect: subpackage section + : ${sect:=$PKG_SECTION} # take from main pkg if empty eval deps=\$PKGDEPS_$spcu # deps: subpackage dependencies eval dflt=\$PKGDFLT_$spcu # dflt: config 'default' opt. eval xline=\$CFLINE_$spcu # xline: one free-format line - if [[ $spcu = LIB* ]]; then - h=5 # divert to Config.in.lib - (( g5++ )) && print -u5 # been here before - elif [[ $spcu = KMOD* ]]; then - h=6 - (( g6++ )) && print -u6 - else - h=4 # divert to Config.in - print -u4 - fi + echo "pkgconfigs.d/$dn/Config.in.$sppn $sect" >>../package_sections + exec 4>../pkgconfigs.d/$dn/Config.in.$sppn + h=4 print -u$h config ADK_PACKAGE_$spcu spnf=$sppn # spnf: subpackage name, filled @@ -261,7 +263,6 @@ EOF print "\t flavour ADK_PACKAGE_${dnu}_$pfcu for $PKG_NAME" done >&4 - ) 4>Config.in 5>Config.in.lib 6>Config.in.kmod cd .. done @@ -285,44 +286,16 @@ function get_first_prompt() { [[ -n $prompt ]] && echo $prompt } -# collect packages along with their section and -# create a list of '
' for later sorting -rm -f package_section_list -for dn in */Makefile; do - dn=${dn%/*} - pbar="Pass 3: $dn ..." +# prepare Config.in list for sorting +while read config_in section; do + pbar="Pass 3: $config_in ..." print -nu2 "$pbar\r" - cd $dn - eval $($GMAKE dump="PKG_NAME PKG_SECTION") - cd .. - - # ignore section kernel, these are included inside target/config - [[ $PKG_SECTION = kernel ]] && continue - - PKG_SECTION=${PKG_SECTION:-none} - - has_config_in=false - if non_empty_file $dn/Config.in; then - prompt="$(get_first_prompt $dn/Config.in)" - prompt="${prompt:-$PKG_NAME}" - echo "$prompt $dn/Config.in $(lookup_section_string $PKG_SECTION)" - has_config_in=true - fi - if non_empty_file $dn/Config.in.lib; then - prompt="$(get_first_prompt $dn/Config.in.lib)" - prompt="${prompt:-$PKG_NAME}" - echo "$prompt $dn/Config.in.lib $(lookup_section_string libs)" - has_config_in=true - fi - if non_empty_file $dn/Config.in.manual; then - prompt="$(get_first_prompt $dn/Config.in.manual)" - prompt="${prompt:-$PKG_NAME}" - echo "$prompt $dn/Config.in.manual $(lookup_section_string $PKG_SECTION)" - has_config_in=true - fi - $has_config_in || print -u2 "$dn: No Config.in file found?!" -done >package_section_list + non_empty_file $config_in || continue + prompt="$(get_first_prompt $config_in)" + [[ -n $prompt ]] || continue + echo "$prompt $config_in $(lookup_section_string $section)" +done package_section_list # create the Config.in.auto from the sorted list from above cursec="" @@ -339,4 +312,4 @@ sort -k 3 -k 1 -f package_section_list | while read name file section; do print "source \"package/$file\"" done >Config.in.auto print "endmenu\n" >>Config.in.auto -rm -f package_section_list +rm -f package_sections package_section_list -- cgit v1.2.3