diff options
-rw-r--r-- | Makefile | 2 | ||||
-rwxr-xr-x | tools/kgit-init | 2 | ||||
-rwxr-xr-x | tools/kgit-scc | 132 | ||||
-rwxr-xr-x[-rw-r--r--] | tools/scc | 1933 | ||||
-rwxr-xr-x | tools/spp | 452 | ||||
-rwxr-xr-x | tools/updateme | 34 |
6 files changed, 646 insertions, 1909 deletions
@@ -2,7 +2,7 @@ kern_tools_LIST = kgit kgit-init kgit-meta \ kgit-checkpoint kgit-clean \ generate_cfg kconf_check configme \ createme updateme patchme get_defconfig scc \ - pre_config merge_config.sh + pre_config merge_config.sh spp INSTALL=install RM=rm diff --git a/tools/kgit-init b/tools/kgit-init index ac949a4..75d58fd 100755 --- a/tools/kgit-init +++ b/tools/kgit-init @@ -34,7 +34,7 @@ install_resources() # guilt-* # generate_cfg, kconf_check, configme - tools_list="kgit kgit-* guilt-* scc buildall get_defconfig merge_config.sh pre_config \ + tools_list="kgit kgit-* guilt-* scc spp buildall get_defconfig merge_config.sh pre_config \ generate_cfg kconf_check configme patchme updateme createme" mkdir -p $meta_dir/scripts/ diff --git a/tools/kgit-scc b/tools/kgit-scc index 1bda14f..7d88a06 100755 --- a/tools/kgit-scc +++ b/tools/kgit-scc @@ -124,15 +124,20 @@ search_includes() find_feature_descriptions() { flist=$@ - out_list= + out_list="" for feat in $flist; do # exact matches in the search directories for the passed # list of features - out_list="$out_list `search_includes \".*/$feat\" any`" + f=`search_includes ".*/$feat" any` + if [ -n "$out_list" ]; then + out_list=`echo "$out_list"; echo "$f"` + else + out_list=`echo "$f"` + fi done - echo $out_list + echo "$out_list" } get_feat_list() @@ -283,7 +288,7 @@ if [ -n "$2" ]; then full_build=t fi top_meta_dir=meta -meta_dir=meta/cfg/meta +meta_dir=meta/cfg/scratch exec_dir=$meta_dir/obj if [ -n "$src" ]; then @@ -449,66 +454,7 @@ fi prep_feature_desc=`find_feature_descriptions $prep_features` -# only compile if we are doing a common build -if [ -z "$use_per_build_obj_dir" ]; then - if [ -n "$compile" ]; then - count=0 - old_dir=`pwd` - for dir in $search_dirs; do - if [ -d $dir ]; then - echo " phase # $phase_count) compiling $dir" - feat_list=`get_feat_list $dir` - jcount=0 - for f in $prep_feature_desc $feat_list; do - if [ -n "$use_per_build_obj_dir" ]; then - small_feat=`basename $f .scc` - grep -q -e ".*scc_leaf.*" -e ".*define.*KTYPE" $f - if [ $? -ne 0 ]; then - continue - fi - else - small_feat= - fi - - echo " $count) scc `basename $f`" - ( - cd $output/$exec_dir - if [ -n "$small_feat" ] && [ ! -d $small_feat ]; then - mkdir $small_feat - cd $small_feat - fi - - if [ -n "$use_per_build_obj_dir" ]; then - # compile all files, all the time - scc $inc_dirs $repo_dir $f - else - scc --noauto $inc_dirs $repo_dir $f - fi - ) & - op=$! - bops="$bops $op" - let jcount=$jcount+1 - - if [ "$jcount" -ge "$jobs" ]; then - wait_for_jobs \ - "Waiting for $jcount compile jobs to complete ..." \ - $bops - bops= - jcount=0 - fi - let count=$count+1 - - cd $old_dir - done - wait_for_jobs \ - "Waiting for $jcount compile jobs to complete ..." $bops - fi - let phase_count=$phase_count+1 - done - fi -fi - -if [ -n "$link" ]; then +if [ -n "$link" ] || [ -n "$compile" ]; then count=1 executables="" old_dir=`pwd` @@ -520,7 +466,7 @@ if [ -n "$link" ]; then echo " phase # $phase_count) linking $dir" feat_list=`get_feat_list $dir t` - total=$(echo "$feat_list" | wc -l) + total=$(echo "$feat_list" "$prep_feature_desc" | tr ' ' '\n' | wc -l) bops= jcount=0 @@ -529,7 +475,7 @@ if [ -n "$link" ]; then outname=`basename $f .scc` # this is where we put 'jcount' jobs into the background - echo " [$count/$total] scc -o $outname `basename $f`" + echo " [$count/$total] scc --force -o $outname-meta $repo_dir `basename $f`" ( if [ -n "$use_per_build_obj_dir" ]; then if [ ! -d $output/$exec_dir/$outname ];then @@ -541,11 +487,12 @@ if [ -n "$link" ]; then fi # the magic - if [ -n "$use_per_build_obj_dir" ]; then - scc $inc_dirs $repo_dir -o $outname $f - else - scc $inc_dirs $repo_dir --noauto -o $outname $f + scc --force -o $outname-meta $inc_dirs $repo_dir $f + if [ $? -ne 0 ]; then + echo "ERROR: could not generate $outname-meta" + exit 1 fi + mv $outname-meta ../.. ) & op=$! bops="$bops $op" @@ -574,55 +521,10 @@ if [ -n "$link" ]; then done fi -if [ -n "$exec" ]; then - old_dir=`pwd` - bops= - if [ -n "$exec_dir" ]; then - echo " phase # $phase_count) running executables" - - count=0 - cd $output/$exec_dir - jcount=0 - for e in $executables; do - - # background the jobs - echo " $count) $e > $e""-meta" - ( - if [ -n "$use_per_build_obj_dir" ]; then - sh ./$e/$e > ../"$e""-meta" - else - sh ./$e > ../"$e""-meta" - fi - ) & - op=$! - bops="$bops $op" - let jcount=$jcount+1 - - if [ "$jcount" -ge "$jobs" ]; then - wait_for_jobs \ - "Waiting for $jcount meta-gen jobs to complete ..." \ - $bops - bops= - jcount=0 - fi - - let count=$count+1 - done - - wait_for_jobs \ - "Waiting for meta-gen jobs to complete ..." $bops - - cd $old_dir - - let phase_count=$phase_count+1 - fi -fi - if [ -n "$apply" ]; then if [ -n "$full_build" ]; then echo " phase # $phase_count) running meta series" - old=`pwd` cd $output diff --git a/tools/scc b/tools/scc index ec1ddd9..95e8da5 100644..100755 --- a/tools/scc +++ b/tools/scc @@ -1,8 +1,8 @@ #!/bin/bash -# (scc), (series & configuration compiler) +# "scc" script. -# Copyright (c) 2008-2012 Wind River Systems, Inc. +# Copyright (c) 2010-2013 Wind River Systems, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as @@ -13,579 +13,173 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +version="0.2" -# global/default values -current_patch_dir="" -current_feature_dir="" - -feature_ext="scc" -obj_ext="sco" - -last_cmd="" -processed_files="" -excluded_features="" -inherit_flag=t -version=1.2 -scc_strict=t - -# ---------------------------------------------------------------------- -# start command line processing support functions -# ---------------------------------------------------------------------- - -error_message() -{ - echo "------------------------------------------------------------"; - echo "$1"; - echo "------------------------------------------------------------"; -} - -strlen() -{ - for i in "$@"; do - echo ${#i} - done -} - -dump_and_pad() -{ - s="$1"; - pad=$2; - len=`strlen "$s"`; - - echo -n "$s"; - while [ $len -lt $pad ]; do - echo -n " "; - let len=$len+1; - done -} - -# ---------------------------------------------------------------------- -# ---------------------------------------------------------------------- - -handle_cparm() +usage() { - prev_parm=$1; - parm=$2; - t=$3; # test(s) - d=0; - split=0; - ret=1; - - #echo "-----[ handle_cparm ]----"; - #echo "checking: prev parm: \"$prev_parm\" with parm: \"$parm\" and test \"$t\""; - - ## Use tests of this form to look for a particular test - ## Try and pull out the regex in question, if the test is passed - ## the produced string won't match the passed in string - ## if [ "${t#*nodash*}" != "$t" ] - ## then - ## echo "dash test!"; - ## fi - ## if [ "${t#*options*}" != "$t" ] - ## then - ## echo "options test!"; - ## fi - - ## 1st. Is there a parameter that we are checking ? - if [ -n "$parm" ] - then - ## Look for dashes in the parameter. - - ## Pull anything off that may follow dashes at the end. - ## if this is empty, we have a --parm - dash=${parm%%--*}; - if [ "$dash" == "" ] - then - d=1; - fi - - ## Were they testing for "nodash" ? - if [ "${t#*nodash*}" != "$t" ] && [ $d -eq 1 ] - then - usage 1; - error_message "Error. Invalid parameter \"$parm\". You must supply a value to \"$prev_parm\""; - exit; - fi - else - ## if there wasn't a parameter and a test was specified, one was - ## expected ... that means we have an erro. - ## old: equal=${parm%%*=*}; - #equal=${prev_parm#*=}; - - equal=${prev_parm%%*=*}; +cat << EOF - if [ -n "$t" ] - then - # no equals sign - if [ -n "$equal" ] - then - usage 1; - error_message "Error. Empty value was passed to \"$prev_parm\""; - exit; - fi + scc [--help] [--force] [-i] [-w] [-o outfile] [-D<var>=<value>] [-I<path>] [-v] infiles - fi - fi - - ## 2nd. We've passed an potential tests. Does the parameter need to - ## be split ? If this regex retuns anything there wasn't a equals - ## sign in the input. - equal=${parm%%*=*}; - if [ "$equal" == "" ] - then - split=1 - fi + --help: This message + --force: force overwrite output file if it already exists + -D: define <var> to <value> which will be available to sub scripts + -I: include path <path> will be searched for files + -i: leave intermediate files on failure + -w: only warn on missing files + -v: verbose output + -o: outfile file for processed results. stdout is used if not passed - ## Remove any leading "--"'s before processing. - parm=${parm#--*}; - prev_parm=${prev_parm#--*}; - parm=${parm#-*}; - prev_parm=${prev_parm#-*}; + infiles files to preprocess, and output into outfile or stdout - if [ $split -eq 1 ] - then - split_parm "$prev_parm" "$t" - else - activate_parm "$prev_parm" "$parm" "$t" - fi +EOF } -split_parm() -{ - p=$1; # the parm - t=$2; # test - - #echo ""; - #echo "-----[ split_parm ]----"; - - parm=${p%%=*}; - parm=${parm#--*}; - #echo "parm is: $parm"; - - value=${p#*=}; - #echo "value is: $value"; - - ## If you came here, we had the syntax "parm=xxx". So - ## if we don't find a xxx, that means you were bad - - if [ "${t#*empty_is_fine*}" == "" ]; then - if [ "$value" == "" ]; then - echo "Error. You must supply a non-zero value to option \"$parm\""; - exit; - fi - fi; +if [ -z "$1" ]; then + usage + exit 1 +fi - activate_parm "$parm" "$value" "$t" -} +while [ $# -gt 0 ]; do + case "$1" in + --help) + usage + exit + ;; + -D*|--D*) + if [ "$1" == "-D" ] || [ "$1" == "--D" ]; then + x=$2; shift; + else + x=`echo $1 | sed s%^-*D%%` + fi + defines="$defines $x" + ;; + -I*|--I*) + if [ "$1" == "-I" ] || [ "$1" == "--I" ]; then + x=$2; shift; + else + x=`echo $1 | sed s%^-*I%%` + fi + if [ -n "$x" ] && [ -d "$x" ]; then + include_paths="$include_paths -I$x" + fi + ;; + --force|-f) + force=t + ;; + -i) + intermediate=t + ;; + -o) + outfile=$2 + shift + ;; + -v) verbose=t + ;; + *) break + ;; + esac + shift +done -activate_parm() +err() { - p=$1; - v=$2; - t=$3; - - # echo "handling: \"$p\" \"$v\""; - # Let's build a variable name: $parm_options, i.e. arch_options - computed=`printf "\$%s_options" $p`; - # Use 'eval' to see if that variable was declared and had a value - val=`eval echo "$computed"`; - good=0; - if [ -n "$val" ] && [ "${t#*options*}" != "$t" ] - then - # If it isn't a special test, we have a list of options - for opt in $val - do - #echo "testing .... $opt"; - if [ "$opt" == "$v" ] - then - good=1 - fi - done - else - good=1; - fi - - if [ $good -eq 0 ] - then - echo "Error. Invalid option \"$v\" for \"$p\" was supplied"; - exit; - fi - - case $p in - help) help=$v ;; - verbose) verbose=t ;; - version) version_dump=t ;; - o) OUT_FILE="$v" ;; - entry) entry_point="$v" ;; - I) include_paths="$include_paths $v" ;; - sig) do_signature=t ;; - dirs) do_dirs=t ;; - noauto) noauto=t ;; - *) error_message "Unknown argument \"$1\"" - exit ;; - esac + echo "$@" 1>&2 } -## -------------------[ Parse command line options ]------------------- - - -usage() -{ - type=$1; - -if [ "$type" == "scc" ]; then -cat <<'EOF'; - scc files are actually small sourced shell scripts. - Not all shell features should be used in these scripts, in - particular no output should be generated, since it is - interpreted by the calling framework. Conditionals and any - other shell commands can be used, but ensure that only - basic/standard commands are used. - - A feature script may denote where in the link order it should be - located. This is only used by scripts that are not being included - by a parent / entry point script and wish to be executed. The - available sections are: INIT, MAIN, FINAL and should be denoted in - a .scc file as: # scc.section <section name> - - Any variable passed to scc via -D=<macro> is available in individual - feature scripts. To see what variables are available, locate the - invokation of scc and search for defines. - - The following built-in functions are available: - - o kernel: (optional) Documents the kernel to which a feature is applicable - o dir: Changes the current working patch directory, subsequent - calls to "patch" use this as their base directory. - o patch: Outputs a patch to be included in a feature's patch - set. Only the name of the patch is supplied, the path - is calculated from the currently set patch directory - o include: Indicates that a particular feature should be - included and processed in order. There is an optional - parameter 'after <feat name>' to indicate that the order - of processing shouldn't be used and a feature must be - included 'after' feature 'feat name'. Include paths are - relative to the root of the directories passed via -I +# args are the input files +infiles=$@ +shift -EOF +if [ -z "$infiles" ]; then + err "ERROR: a input file must be supplied" + exit 1 else - cat <<'EOF'; -usage: scc [options] [file ...] - -compile a patch series from a set of scc files, patch lists and includes - - -h print this help. if arguments passed, individual help is - displayed - -o file create a single output file, "-" outputs to stdout - --e[ntry] sym(s) set the entry point function name(s) - --s[ig] file dump the signature for a "compiled" scc runtime file - --d[irs] file dump the directories that were used during compilation of - a particular object or runtime file - -I<path> include path. - -Dmacro[=defn] Define a macro/variable. visibile inside scc files - --noauto Do not automatically compile the dependency chain - --vars comma separated list of variables to make available to - scc feature scripts. - eg: KTRIPLET=board-<x>-<y>,PLATFORM=<myplat> - -v run verbosely - --version show the scc version - -EOF -fi; - - exit; -} - -process_command_line() -{ - help=""; - FEATURES=""; - CMD_TRANSFORMS=""; - - if [ "$1" == "" ]; then - usage - exit - fi - - while [ -n "$1" ]; do - case $1 in - -*) # options that start with '-' - case $1 in - -D*|--D*) - if [ "$1" == "-D" ] || [ "$1" == "--D" ]; then - x=$2; shift; - else - x=`echo $1 | sed s%^-*D%%` - fi - defines="$defines $x" ;; - -*=*) handle_cparm "$1" "" "nodash options" ;; - --noauto) handle_cparm noauto ;; - -d|--d|--dirs) handle_cparm "dirs" ;; - -vars|--vars) handle_cparm "$1" "$2" "nodash" - shift ;; - -o|--o) handle_cparm "$1" "$2" - shift ;; - -s|--s|--sig) handle_cparm "sig" ;; - -e|--e|-entry) handle_cparm "entry" "$2" - shift ;; - -I*|--I*) if [ "$1" == "-I" ] || [ "$1" == "--I" ]; then - x=$2; shift; - else - x=`echo $1 | sed s%^\-*I%%` - fi - handle_cparm "I" "$x" ;; - -v|--v) handle_cparm verbose ;; - -ver*|--ver*) handle_cparm version ;; - -h|--h|--help) handle_cparm help ;; - *) error_message "Unknown argument \"$1\"" - exit ;; - esac ;; - *) # options that don't start with a '-' and weren't grabbed - # by a dash option handler - args="$args $1" ;; - esac - shift + for f in $infiles; do + if [ ! -f "$f" ]; then + err "ERROR. input file \"$f\" does not exist" + exit 1 + fi done - - if [ -n "$help" ]; then - usage "$help" +fi +if [ -n "$outfile" ] && [ -f "$outfile" ]; then + if [ -z "$force" ]; then + err "ERROR: output file \"$outfile\" exists, and --force was not passed" + exit 1 fi -} - +fi ## -## -------------------------------------------------------------- -## Above this point is command line processing. -## Below this point is the implementation of the script -## -------------------------------------------------------------- -## - -_strip_ext() -{ - # this isn't quite "basename" we want the full - # path, just no extension, i.e. without basename's - # habit of removing the last element no matter what - local name=$1 - local ext=$2 - - if [ -n "$ext" ]; then - echo "$name" | sed "s%$ext$%%" - else - echo $name - fi -} - -# arg1: string to make safe to call as a shell function -_safe_funcname() -{ - echo $1 | sed -e 's/\./_/g' -e 's/\-/_/g' -e 's/^\([0-9]\)/xx\1/' -} - -# output to the current script -_dump() -{ - if [ -n "$patch_script" ]; then - echo "$@" >> "$patch_script" - else - echo "$@" - fi -} - -## used in the feature scripts -## deprecated: use "define KERNEL_VERSION <value>" -set_kernel_version() -{ - KERNEL_VERSION=$1 -} - -## used in the feature scripts -## arg1: the board to test -## return: 0 board is present -## 1 board is not present +## create variables for use in scripts ## -## Note: this is deprecated. if [ "$KMACHINE" ] should be used -## instead -check_board() -{ - echo $KMACHINE | grep -q $1 - - return $? -} +if [ -n "$defines" ]; then + vars=$(echo $defines | sed 's/,/ /g') + for v in "$vars"; do + # eval makes it available for this script + eval $v + # echo makes it available for other scripts + dump_vars=$(echo "$dump_vars"; echo export $v) + done +fi -## used in the feature scripts to trigger strict patch checking -scc_strict() +header() { - scc_strict=$1 + echo "#" + echo "# scc v$version" + echo "# processed: `date`" + echo "#" + echo "# This is a scc output file, do not edit" + echo "#" } -# No longer supported. This was used to override an existing -# patch with a new one. This leads to dynamic branching in a -# git tree, which is considered bad. -override() -{ - true -} -# prevent a future include of a feature from doing anything -# arg1: feature name to exclude -exclude_feature() +# used by feature scripts. call this to set a variable +# in the preamble of a created executable. subscripts +# can use these values to make decisions +define() { - fname=$1 + var=$1 + value="$2" - excluded_features=`echo "$excluded_features"; echo "$fname"` + echo "# _define $var '$value'" } -# prevent a cfg include, or if a feature name is passed, prevent the -# feature from including any config values -exclude_cfg() +# used in feature scripts +# - associates a kernel config frag with the feature +kconf() { - fname=$1 - flags=$2 + type=$1 + frag=$2 + flags=$3 - if [ "$flags" = "inhibit" ]; then - # clear the global flag - exclude_cfg_flag= - # remove ourself from the excluded cfgs - excluded_cfgs=`echo "$excluded_cfgs" | sed 's%$fname%%'` - else - excluded_cfgs=`echo "$excluded_cfgs"; echo "$fname"` - fi + echo "# _kconf $type $frag" } -# 0: feature is ok -# 1: feature should be excluded -check_excluded_feature() +reloc_dir() { - feat=$1 - my_pick="" - - if [ -n "$feat" ]; then - if [ -n "$excluded_features" ]; then - tgts=$(echo "$excluded_features" | grep -E "^$feat$") - # pick the first ... - my_pick=$(echo "$tgts" | head -n1) - if [ -n "$my_pick" ]; then - # take it out of the pool. - excluded_features=$(echo "$excluded_features" | grep -v -E "^$my_pick$") - return 1 - fi - fi - fi - - return 0 + dir=$1 + + echo "# _reloc_dir $dir" } -# 0: feature is ok -# 1: feature should be excluded -check_excluded_cfg() +process_file() { - frag=$1 - my_pick="" - - if [ -n "$frag" ]; then - if [ -n "$excluded_cfgs" ]; then - echo $frag | grep -q -E "\.cfg$" - if [ $? -eq 0 ]; then - # if it's a fragment, only include this one, not all .. - single_cfg_only=t - fi - - tgts=$(echo "$excluded_cfgs" | grep -E "^$frag$") - # pick the first ... - my_pick=$(echo "$tgts" | head -n1) - if [ -n "$my_pick" ]; then - # take it out of the pool. - excluded_cfgs=$(echo "$excluded_cfgs" | grep -v -E "^$my_pick$") - - # as long as this is enabled, no configuration fragments will be processed - if [ -z "$single_cfg_only" ]; then - exclude_cfg_flag=t - fi + local in=$1 + local containing_file=$2 + local inherited_inhibit_cfg=$3 + local ret=0 + local done="" - return 1 - fi - fi - else - # fragment is empty, but is the whole feature inhibited ? - if [ -n "$current_feature" ]; then - echo $nocfg_features | grep -q -w "$current_feature_dir/$current_feature.scc" - if [ $? -eq 0 ]; then - exclude_cfg_flag=t - fi - fi - - return 1 - fi + . $in return 0 } -# used in feature scripts -# - sets the current working patch directory -dir() -{ - current_patch_dir=$1 -} - -get_dir() -{ - echo $current_patch_dir -} - -# used in feature scripts, "force" has a different meaning depending -# on the wrapped command -force() -{ - case $1 in - kconf) - eval $@ force - ;; - *) - eval $@ - ;; - esac -} - -# used in feature scripts -# - associates a kernel config frag with the feature -kconf() +## used in the feature scripts +## deprecated: use "define KERNEL_VERSION <value>" +set_kernel_version() { - type=$1 - frag=$2 - flags=$3 - - this_frag=$current_feature_dir/$frag - - # are features being excluded ? - if [ -n "$exclude_cfg_flag" ] && [ "$flags" != "force" ]; then - return - fi - # is just this .cfg being excluded ? - if [ "$flags" != "force" ]; then - check_excluded_cfg $frag - if [ $? -eq 1 ]; then - return - fi - fi - - if [ ! -f "$this_frag" ]; then - this_frag=`search_include_paths $frag` - fi - - if [ ! -f "$this_frag" ]; then - echo "[ERROR] kernel configuration fragment fragment '$frag' cannot be found" - exit 1 - fi - - if [ "$last_cmd" == "patch" ]; then - _dump " \\" - _dump -n " echo \"# _kconf $type $this_frag\";" - else - _dump " _cmds=\$(echo \"\$_cmds\" ; echo \"# _kconf $type $this_frag\")" - fi + KERNEL_VERSION=$1 } # Used in feature scripts @@ -605,12 +199,7 @@ merge() # - encodes a generic git command git() { - if [ "$last_cmd" == "patch" ]; then - _dump " \\" - _dump -n " echo \"# _git $@\";" - else - _dump " _cmds=\$(echo \"\$_cmds\" ; echo \"# _git $@\")" - fi + echo "# _git $@" } # used in feature scripts @@ -619,12 +208,7 @@ git() # arg3 and up: flags branch() { - if [ "$last_cmd" == "patch" ]; then - _dump " \\" - _dump -n " echo \"# _branch_begin $@\"" - else - _dump " _cmds=\$(echo \"\$_cmds\" ; echo \"# _branch_begin $@\")" - fi + echo "# _branch_begin $@" } @@ -633,424 +217,8 @@ branch() # arg2: branch name scc_leaf() { - parent_branch=$1 - branch_name=$2 - - # if the parent branch name has a ':', it means we are tracking - # a particular end point of that branch. If that ISN'T the end - # of the branch and auto-rebase needs to be triggered - echo $parent_branch | grep -q ":" - if [ $? -eq 0 ]; then - tracking_commit=`echo $parent_branch | cut -d: -f2` - parent_branch=`echo $parent_branch | cut -d: -f1` - potential_rebase="$branch_name:$tracking_commit" - fi - - # this is really just a documented include AND branch + branch name - include $parent_branch "" "" - - if [ -z "$branch_name" ]; then - branch $current_feature - else - branch $branch_name - fi -} - -# example: scc_stage linux-omap-2.6 +omap_merge -# -# Stages a tree for a future merge -# -# arg1: tree -# arg2: branch -# -scc_stage() -{ - src_tree=$1 - src_branch=$2 - - # look for the tree in our search paths - for p in "." "$current_feature_dir" $include_paths; do - if [ -e $p/$src_tree ]; then - src_tree_dir=`readlink -f "$p/$src_tree"` - fi - done - - if [ ! -e "$src_tree_dir" ]; then - # this block actually runs in the src tree - git show-ref --quiet --verify -- "refs/heads/$src_branch-merge"; - _dump " _cmds=\$(echo \"\$_cmds\" ; echo \"if [ \\\$? -eq 1 ]; then\")" - _dump " _cmds=\$(echo \"\$_cmds\" ; echo \" echo \"WARNING: src tree $src_tree was not found, creating a dummy branch\"\")" - git branch $src_branch-merge master - _dump " _cmds=\$(echo \"\$_cmds\" ; echo \"fi\")" - else - git show-ref --quiet --verify -- "refs/heads/$src_branch-merge"; - _dump " _cmds=\$(echo \"\$_cmds\" ; echo \"if [ \\\$? -eq 1 ]; then\")" - git fetch --no-tags $src_tree_dir +$src_branch:$src_branch-merge - _dump " _cmds=\$(echo \"\$_cmds\" ; echo \"fi\")" - fi -} - - -_add_cmd() -{ - addition=$1 - - _dump " _cmds=\$(echo \"\$_cmds\" ; echo \"$addition\")" -} - -# used in feature scripts -# -# arg1: the tree to merge -# arg2: the source branch -# arg3: the message to commit changes with -scc_merge() -{ - src_tree=$1 - branch=$2 - message="$3" - - if [ -z "$message" ]; then - message="merge of $src_tree $branch" - fi - - scc_stage $src_tree $branch - - git branch --no-merged standard \| grep -q $branch-merge - _add_cmd "if [ \\\$? -eq 0 ]; then" - git merge -m "\\\\'$message\\\\'" $branch-merge - _add_cmd " git ls-files -m | xargs grep -q '<<<'" - _add_cmd " if [ \\\$? -ne 0 ]; then" - _add_cmd " git ls-files -m | xargs git add" - git commit --quiet -s -m "\\\\'$message\\\\'" - _add_cmd " else" - _add_cmd " exit 1" - _add_cmd " fi" - _add_cmd "fi" -} - -# rebases a series of commits onto a new base -# -# arg1: target branch (i.e. the new base) -# arg2: oldest commit (from mini tree or wherever) on branch -# arg3: the current branch name (i.e. the last commit) -# -# example: scc_rebase standard <my first commit id> my_bsp-standard -# -scc_rebase() -{ - target_base=$1 - oldest_commit=$2 - newest_commit=$3 - - # This runs in the source tree. The branch being rebased should - # be active and checked out. - git rebase --onto $target_base $oldest_commit $newest_commit -} - -# used in feature scripts. -# -# checks for a commit_id. returns 0 if it matches, 1 if it doesn't -# -# arg1: branch -# arg2: commit id -# -scc_check() -{ - _add_cmd "revlist=`git rev-list $2..$1`" - _add_cmd "if [ -n \"\$revlist\" ]; then" - _add_cmd " return 1" - _add_cmd "fi" - _add_cmd "return 0" -} - - -# used in feature scripts -scc_feat() -{ - set_current_feature $1 -} - -# used in feature scripts. -# internal use only, this will dump a block of "whatever" -# to the output script(s). This is a hidden method to add -# functionality and work around issues -__scc_block_start() -{ - section=$1 - - if [ "$last_cmd" == "patch" ]; then - # there was an open command replacement, let's close it - _dump '`'; - last_cmd=block - fi - - _dump "" - _dump \# scc block code starts here -} - -__scc_block_end() -{ - _dump \# scc block code ends here - _dump "" -} - -# used in feature scripts -# arg1: the tag name -tag() -{ - if [ "$last_cmd" == "patch" ]; then - _dump " \\" - _dump -n " echo \"# _git tag $1\";" - else - _dump " _cmds=\$(echo \"\$_cmds\" ; echo \"# _git tag $1\")" - fi -} - -# arg1: phase -# arg2: script -scc_hook() -{ - phase=$1 - hook=`search_include_paths $2` - - if [ "$last_cmd" == "patch" ]; then - _dump " \\" - _dump -n " echo \"# _hook $phase $hook\";" - else - _dump " _cmds=\$(echo \"\$_cmds\" ; echo \"# _hook $phase $hook\")" - fi -} - -# used in feature scripts -patch() -{ - this_patch=$1 - patch_type=$2 # not currently used - - # figure out the prefix for the patch - if [ -n "$current_patch_dir" ]; then - if [ "$current_patch_dir" != "$current_feature_dir" ]; then - tmp=$current_feature_dir/$current_patch_dir/$1 - else - tmp=$current_patch_dir/$1 - fi - else - tmp=$1 - fi - - tmp=$(echo $tmp | tr -s /) - - # check to see if we can find the patch ... unless we - # were told to not search at all. - if [ -z "$no_patch_search" ]; then - if [ ! -e "$tmp" ]; then - name_only=`basename $tmp` - tmp2=`search_include_paths $name_only` - if [ -z "$tmp2" ]; then - if [ "$scc_strict" = "t" ]; then - echo "" - echo "ERROR: patch $tmp is not available" - echo "" - exit 1 - else - if [ -n "$verbose" ]; then - echo "WARNING: could not find patch $tmp" - fi - fi - return - fi - tmp=$tmp2 - fi - fi - - if [ -n "$verbose" ]; then - echo "# patch [$inherit_flag]: $tmp" - fi - - if [ -n "$tmp" ]; then - if [ "$last_cmd" == "patch" ]; then - # last command was patch, so there is already an open command - # replacement, let's just continue in it (after a line break) - _dump " \\" - _dump -n " echo \"# _patch $tmp\";" - else - # this leaves the command replacement string open, in case more - # patch commands are detected - _dump -n " _cmds=\`echo \"\$_cmds\"; echo \"# _patch $tmp\";" - fi - fi - last_cmd=patch -} - -add_feature_to_process() -{ - to_process="$to_process $1" -} - -add_feature_modifer() -{ - feature=$1 - modifier=$2 - flags=$3 - - case $modifier in - nocfg) - nocfg_features="$nocfg_features $feature" - if [ "$flags" = "inherit" ]; then - nocfg_flags="$nocfg_flags do_not_clear" - fi - ;; - *) ;; - esac -} - -# used by feature scripts. call this to set a variable -# in the preamble of a created executable. subscripts -# can use these values to make decisions -define() -{ - var=$1 - value="$2" - - eval $var="\"$value\"" - - # add to the preamble - dump_vars=$(echo "$dump_vars"; echo export $var=\'"$value"\') - - # propagate it to the generated scripts - if [ "$last_cmd" == "patch" ]; then - # there was an open command replacement, let's close it - _dump '`' - fi - _dump " _cmds=\$(echo \"\$_cmds\"; echo \"# _define $var '$value'\");" - - last_cmd=define -} - -# used by feature scripts -include() -{ - fname=$1 - modifier=$2 - tgt_feat=$3 - - # if the feature name is actually "nocfg", then flip the modifier and - # feature name. We do these to allow "include nocfg foo.scc", instead - # of: include foo.scc nocfg. We can have a better syntax, and keep - # compatibility with old include directives - if [ "$fname" = "nocfg" ]; then - modifier=$1 - fname=$2 - fi - - fname=$(_strip_ext "$fname" ".$feature_ext") - - if [ -n "$fname" ]; then - check_excluded_cfg $fname - # has this feature been explictly blocked?, if - - check_excluded_feature $fname - if [ $? -eq 0 ]; then - if [ "$modifier" = "after" ]; then - # a before or after trigger was passed - conditional_after_list=$(echo "$conditional_after_list"; - echo "$fname $tgt_feat") - return # flee. nothing to do now. - else - to_call="$fname" - - x=$(echo "$conditional_after_list" | grep $fname) - # if x is non-empty then this feature had a conditional - # include so special processing is required - if [ -n "$x" ]; then - after_func=$(echo "$x" | sed 's/ .*$//') - to_call="$fname $after_func" - fi - fi - - for f in $to_call; do - # the function we'd call also shouldn't have the path - # in it, if it was included with a partial path - out_name=`basename $f .$feature_ext` - - full_path=`search_include_paths $f` - if [ -z "$full_path" ]; then - if [ "$scc_strict" = "t" ]; then - echo "" - echo "ERROR: included file $f is not available" - echo "" - exit 1 - fi - fi - path_sum=`echo $full_path | md5sum | cut -d' ' -f1` - - if [ "$modifier" = "nocfg" ]; then - add_feature_modifer $full_path $modifier $tgt_feat - fi - - # the function we'd call should not have '.' in it, since - # shell won't allow this - out_name=$(_safe_funcname $out_name"_$path_sum") - - if [ "$last_cmd" == "patch" ]; then - # there was an open command replacement, let's close - # it - _dump '`' - fi - - if [ "$f" == "$after_func" ]; then - _dump " _auto_branch=\"\$_auto_branch $out_name\"" - fi - - _dump " output=\"\$_cmds\" # save current work for function call"; - _dump " $out_name; # call function"; - - _last_call=$out_name - _dump ' _cmds="$output"; # restore current work ' - - add_feature_to_process $f - - last_cmd=include - done; - else - # the feature was excluded. This is a branch point. - if [ "$last_cmd" == "patch" ]; then - # there was an open command replacement, let's close - # it - _dump '`' - fi - - force_branch_name="`basename $fname`_excluded-auto" - _dump " _cmds=\$(echo \"\$_cmds\"; echo \"# _force_branch $force_branch_name\")" - last_cmd= - fi - fi -} - -exclude() -{ - kconf_only=$1 - in_name=$2 - - # if "kconf" was not passed as argument #1, then we need - # to make the feture/exclude name be the first argument - if [ -z "$2" ]; then - in_name=$1 - fi - - echo "excluding $in_name .. cfg only: $kconf_only" - - fname=`_strip_ext "$in_name" ".$feature_ext"` - - echo $in_name | grep -q -E "\.cfg$" - if [ $? -eq 0 ]; then - exclude_cfg $in_name - elif [ "$kconf_only" = "kconf" ]; then - exclude_cfg $in_name - else - ## a global feature exclude - exclude_feature $fname - fi + # do not use + true } # patch triggers are no longer supported. In a git context, they need @@ -1077,831 +245,38 @@ do_exclude() true } -do_include() -{ - archs=$1 - plats=$2 - tgt_patch=$3 - - # echo "# do_include: arch:$archs,plat:$plat,patch:$tgt_patch"; - - if [ "$archs" == "all" ] || [ "$plats" == "all" ]; then - patch "$tgt_patch" - else - # there was an open command replacement, let's close it - if [ "$last_cmd" == "patch" ]; then - _dump '`;' - last_cmd=patch_trigger - fi; - if [ -n "$archs" ]; then - _dump " if [ \"\$KERNEL_ARCH\" == \"$archs\" ]; then " - _dump -n " " - patch "$tgt_patch" - _dump '`;' - _dump " fi" - elif [ -n "$plats" ]; then - _dump " if [ \"\$PLATFORM\" == \"$plats\" ]; then " - _dump -n " " - patch "$tgt_patch" - _dump '`;' - _dump " fi" - fi - fi -} - -do_transform() +# used in feature scripts +# arg1: the tag name +tag() { - archs=$1 - plats=$2 - sed_expr=$3 - - # echo "# do_transform: arch:$archs,plat:$plat,patch:$tgt_patch"; - - # we need to add something to the transform .. a branch indication - # if it suceeds - - # so we are finding out what the input sed-type expression had as the - # replacement value, and we are adding our own branch tag + the original - # as the new replacement value - input_replace=`echo $sed_expr | cut -d/ -f3` - new_sed_expr=`echo $sed_expr | sed "s%$input_replace%\\\\\# _force_branch $current_feature\-force force\\\\\n$input_replace%"` - - # there was an open command replacement, let's close it - if [ "$last_cmd" == "patch" ]; then - _dump '`;' - fi; - if [ "$archs" == "all" ] || [ "$plats" == "all" ]; then - _dump " _cmds=\$(echo \"\$_cmds\" | sed \"s$new_sed_expr\");" - _dump " _potential_auto_branch=$current_feature-force" - else - if [ -n "$archs" ]; then - _dump " if [ \"\$KERNEL_ARCH\" == \"$archs\" ]; then " - _dump " _cmds=\$(echo \"\$_cmds\" | sed \"s$new_sed_expr\");" - _dump " _potential_auto_branch=$current_feature-force" - _dump " fi"; - elif [ -n "$plats" ]; then - _dump " if [ \"\$PLATFORM\" == \"$plats\" ]; then " - _dump " _cmds=\$(echo \"\$_cmds\" | sed s\"$new_sed_expr\");" - _dump " _potential_auto_branch=$current_feature-force" - _dump " fi" - fi - fi + echo "# _git tag $1" } -# arg1: short name of the active feature -# arg2: long name of the active feature -set_current_feature() -{ - short_feature_name=$1 - abs_feature_name=$2 - - # if we aren't processing an input file, it's config may be inhibited - echo "$in_files" | grep -q $abs_feature_name - if [ $? -ne 0 ]; then - # clear the cfg exclusion flag - if [ -n "$nocfg_flags" ]; then - echo $nocfg_flags | grep -q -w "do_not_clear" - if [ $? -ne 0 ]; then - exclude_cfg_flag= - fi - else - exclude_cfg_flag= - fi - else - exclude_cfg_flag= - fi - - # set the feature name - current_feature=$short_feature_name -} - -# arg1: feature file to process -process_feature() +# used in feature scripts +patch() { - pfeat=$1 - small_feat=$2 - - # reset scc_strict per-feature - scc_strict=t - - if [ ! -e "$pfeat" ]; then - return - fi - if [ -n "$verbose" ]; then - echo "# processing $pfeat" - fi - processed_files="$processed_files $pfeat" - - _path_sum=`echo $absfile | md5sum | cut -d' ' -f1` - small_feat="$small_feat""_""$_path_sum" + this_patch=$1 + patch_type=$2 # not currently used - small_feat=$(_safe_funcname "$small_feat") - last_cmd="" - _dump ""; - _dump "# --->--->--->--->--->>--->--->--->--->>--->--->--->--->--->--->"; - _dump "# Generated from $pfeat"; - _dump "# Note: this function processes \$_cmds and updates it"; - _dump "# --->--->--->--->--->>--->--->--->--->>--->--->--->--->--->--->"; - - if [ -n "$small_feat" ]; then - _dump "$small_feat()"; - _dump "{"; - if [ "$small_feat" == "$initial_feature" ]; then - _dump ' _cmds="";'; - else - _dump ' _cmds="$output";'; - fi - _dump " _cmds=\$(echo \"\$_cmds\"; echo \"# _mark $small_feat start\")" - - if [ -n "$pfeat" ]; then - current_feature_dir=$(dirname $pfeat) - - dir $current_feature_dir - # check to see if kernel configs should be inhibited - check_excluded_cfg - . $pfeat; - if [ $? -ne 0 ]; then - echo " feature file $pfeat contains an error ... aborting"; - exit 1; - fi; - - # there was an open command replacement, let's close it - if [ "$last_cmd" == "patch" ]; then - _dump '`;'; - fi; - - fi - - _dump " _cmds=\$(echo \"\$_cmds\"; echo \"# _mark $small_feat end\")" - _dump " output=\"\$_cmds\";"; - - _dump " $small_feat""_rc_files"; - - _dump "}"; - _dump "# scc entry_func: $small_feat" - fi - - if [ -n "$verbose" ]; then - echo "# done processing $pfeat"; - fi + echo "# _patch $this_patch" } -get_dirs() -{ - local files=$@ - local dirs="" - - for i in $files; do - # call the same function as the name of the file - if [ -e $i ]; then - grep -q "# scc runtime file" $i - if [ $? -ne 0 ]; then - grep -q "# scc object file" $i - if [ $? -ne 0 ]; then - echo "ERROR. not a scc runtime or object file" - exit 1 - else - object=t - fi - else - runtime=t - fi - - if [ -n "$runtime" ]; then - # no dependency check, this should be a standalone file - rfiles=`cat $i | grep -E '^\. \`dirname'` - IFS=' -' - for r in $rfiles; do - file_to_check=`echo $r | sed -e 's%\. \`.*\/%%'` - cfgs=`grep -E _cfg $file_to_check | \ - sed -e s'%^ *echo \"\# _cfg '%%g \ - -e s'%\";.*$%%g'` - echo "$cfgs" - done - IFS=' ' - else - IFS=' -' - cfgs=`grep -E _cfg $i | \ - sed -e s'%^ *echo \"\# _cfg '%%g \ - -e s'%\";.*$%%g'` - echo "$cfgs" - IFS=' ' - fi - else - echo "ERROR $i does not exist" - exit 1 - fi - done -} - -get_sig() -{ - local files=$@ - - for i in $files; do - # call the same function as the name of the file - if [ -e $i ]; then - grep -q "# scc runtime file" $i - if [ $? -ne 0 ]; then - grep -q "# scc object file" $i - if [ $? -ne 0 ]; then - echo "ERROR. not a scc runtime or object file" - exit 1 - else - object=t - fi - else - runtime=t - fi - - if [ -n "$runtime" ]; then - # no dependency check, this should be a standalone file - sig=$(sh $i | md5sum | cut -d' ' -f1) - echo "$i: $sig" - else - grep "depends:" $i -q - if [ $? -eq 0 ]; then - echo "WARNING. $i has dependencies, no signature calculated" - exit 1 - else - sig=$(sh $i | md5sum | cut -d' ' -f1) - echo "$sig" - fi - fi - else - echo "ERROR $i does not exist" - exit 1 - fi - done -} - -_dump_extended_info() -{ - local name=$1 - - name=$(_safe_funcname $name) - - # this dumps all the .scc file directories we processed - # someone will find this interesting - _dump ""; - _dump "$name""_rc_files()"; - _dump "{"; - _dump ' _cmds="$output"'; - _dump ' _cmds=`echo "$_cmds"; \'; - for f in $processed_files; do - out=$(dirname $f) - _dump " echo \"# _cfg $out\"; \\" - done; - _dump '`;'; - _dump ' output="$_cmds"'; - _dump "}"; - _dump ""; -} - - -expand_target() -{ - local tgt=$1 - - tgt=$(_strip_ext "$tgt" ".$feature_ext") - base=`basename $tgt` - possible= - - for p in "." "$current_feature_dir" $include_paths; do - - if [ -n "$possible" ]; then - continue - fi - - # target file + default feature extension - if [ -f $p/$tgt.$feature_ext ]; then - possible=`readlink -f "$p/$tgt.$feature_ext"` - # raw target file - elif [ -f $p/$tgt ]; then - possible=`readlink -f "$p/$tgt"` - # special processing test the include directory + - # the name of the feature. This saves us doing a massive - # set of includes for sub categories includes - elif [ -f $p/$tgt/$tgt.$feature_ext ]; then - possible=`readlink -f "$p/$tgt/$tgt.$feature_ext"` - elif [ -f $p/$tgt/$tgt ]; then - possible=`readlink -f "$p/$tgt/$tgt"` - # more special processing. test if the included - # feature is actually just the name of a directory - # AND there is not file with the same name present. - # if that is true, then test for: - # <tgt>/<tgt>.extension - # in that directory - elif [ -f $p/$tgt/$base.$feature_ext ]; then - possible=`readlink -f "$p/$tgt/$base.$feature_ext"` - elif [ -f $p/$tgt/$base ]; then - possible=`readlink -f "$p/$tgt/$base.$feature_ext"` - fi - done - - if [ -n "$possible" ]; then - echo "$possible" - fi -} - -search_include_paths() -{ - local tgt=$1 - local exclude_files=$@ - - if [ -z "$exclude_files" ]; then - exclude_files="/dev/null" - fi - - tgt=$(_strip_ext "$tgt" ".$feature_ext") - base=`basename $tgt` - - for p in "." "$current_feature_dir" $include_paths; do - # target file + default feature extension - if [ -f $p/$tgt.$feature_ext ]; then - possible=`readlink -f "$p/$tgt.$feature_ext"` - # raw target file - elif [ -f $p/$tgt ]; then - possible=`readlink -f "$p/$tgt"` - # special processing test the include directory + - # the name of the feature. This saves us doing a massive - # set of includes for sub categories includes - elif [ -f $p/$tgt/$tgt.$feature_ext ]; then - possible=`readlink -f "$p/$tgt/$tgt.$feature_ext"` - elif [ -f $p/$tgt/$tgt ]; then - possible=`readlink -f "$p/$tgt/$tgt"` - # more special processing. test if the included - # feature is actually just the name of a directory - # AND there is not file with the same name present. - # if that is true, then test for: - # <tgt>/<tgt>.extension - # in that directory - elif [ -f $p/$tgt/$base.$feature_ext ]; then - possible=`readlink -f "$p/$tgt/$base.$feature_ext"` - elif [ -f $p/$tgt/$base ]; then - possible=`readlink -f "$p/$tgt/$base.$feature_ext"` - fi - - if [ -n "$possible" ]; then - echo "$exclude_files" | grep -q "$possible" - if [ $? -ne 0 ]; then - echo $possible - return - fi - possible= - fi - done -} - - -check_link_section() -{ - local file=$1 - - section=`cat $file | grep scc.section | awk '{print $3}'` - - if [ -n "$section" ]; then - echo "$section" - else - echo "MAIN" - fi -} - -# this compiles the passed scc files into "objects" -compile_files() -{ - local in_files=$@ - local files - - to_compile="$in_files" - to_link="" - all_files= - in_files= - - # phase1: we do a depth-first search of the files passed on the command - # line. During the search, we record all files are that are - # included by the commmand line files (can be inhibited by - # --noauto). This in order list is the complete set of files to - # compile - for f in $to_compile; do - if [ ! -e "$f" ]; then - f=`search_include_paths $f` - fi - - if [ -z "$f" ]; then - continue - fi - f=`readlink -f $f` - - # this ensures that everything on the original $in_files - # is now absolute - in_files="$in_files $f" - - if [ -z "$noauto" ]; then - # queue for compilation (if --noauto wasn't passed) - - sub_files=$f - all_files="$all_files $f" - while [ -n "$sub_files" ]; do - new_sub= - for s in $sub_files; do - if [ ! -e $s ]; then - s=`search_include_paths $s` - fi - - current_feature_dir=$(dirname $s) - # generate the list of files that need to be compiled. - # We do that by looking for any commands in a given file - # that can trigger another file to be build. Which currently - # is only 'include' (scc_leaf is deprecated) - z= - for q in `cat $s | grep -E '^[[:space:]]*include' | awk '{print $2}'` ; do - z=`echo $z $q` - done - - abs= - for t in $z; do - # remove a feature extenstion (if present) - t=$(_strip_ext "$t" ".$feature_ext") - - # add it again .. :) - t="$t"".$feature_ext" - - # this searches the include paths for the missing - # feature. But it also passes in all the features - # we've processed to ensure that we don't repeat - feat_name=`expand_target $t` - - if [ -z "$feat_name" ]; then - echo "warning: feature $t was not found ($current_feature_dir)" - else - echo "$all_files" | grep -q "$feat_name" - if [ $? -eq 0 ]; then - echo "NOTE: feature $t is included multiple times ($current_feature_dir)" - fi - abs="$abs $feat_name" - fi - done - new_sub="$new_sub $abs" - done - - all_files="$all_files $new_sub" - sub_files="$new_sub" - done - else # --noauto - if [ -e $f ]; then - all_files="$all_files $f" - else - tt=`search_include_paths $f` - if [ -z "$tt" ]; then - # we couldn't find it, is it on an inclue path? - echo "warning: could not find $f" - else - all_files="$all_files $tt" - fi - fi - fi - done - - # phase2: compile the list of "all_files" that was built in phase1 - to_compile=$all_files - files=$all_files - count=0 - for absfile in $files; do - processed_files="" - echo $all_processed | grep -q $absfile - if [ $? -eq 0 ]; then - continue - fi - - if [ -n "$verbose" ]; then - echo "compiling: $absfile" - fi - _section=`check_link_section $absfile` - - # prepare to pick a file for output ... - _basename=`basename $absfile .$feature_ext` - - _tmpname=$_basename.$obj_ext.tmp - _path_sum=`echo $absfile | md5sum | cut -d' ' -f1` - - # this redirects all calls to _dump to the file - patch_script=$_tmpname - - # dump some information - _dump "# scc object file" - _dump "# scc version $version" - _dump "# scc id $_path_sum" - - to_process="" - - # output has been redirected to $patch_script - set_current_feature "$_basename" "$absfile" - process_feature "$absfile" "$_basename" - - if [ -n "$to_process" ]; then - # dump anything that was picked up in - # process_feature as a dependency - _dump "# scc depends: $to_process" - fi - # this adds extended information to the output file - all_processed="`echo \"$all_processed\"; echo \"$processed_files\"`" - _dump_extended_info "$_basename""_""$_path_sum" - _dump "# .section $_section" - - objname=$count-$_basename-$_path_sum.$obj_ext - mv $_tmpname "$objname" - count=`expr $count + 1` - to_link="$to_link $objname" - - echo "$in_files" | grep -q "$absfile" - if [ $? -eq 0 ]; then - forced_link="$forced_link $objname" - fi - done - - # call the "link" phase - if [ -n "$OUT_FILE" ]; then - link_file $in_files - fi -} - -link_file() -{ - local files=$@ - - # this links an "excutable" - if [ -z "$OUT_FILE" ]; then - return 1 - fi - - rm -f $OUT_FILE - patch_script=$OUT_FILE - - if [ -d "$patch_script" ]; then - echo "ERROR. $patch_script is a directory, select a new executable name" - exit 1 - fi - - _dump "# scc runtime file" - _dump "# scc version $version" - - for i in $include_paths; do - # add one "horrible" special case. this tool is pretty - # generic, but there is one binding from build systems - # with templates that can cause strange relocations. In - # particular, include paths that go too deep which will - # cause a potential name collision, so let's pop one - # directory level off each path. - - # strip a trailing / - abs_dir=`readlink -f $i` - abs_dir2=`cd $i; pwd` - if [ x"$abs_dir" != x"$abs_dir2" ]; then - # there is some sort of symlink trickery going on. - # add both dirs to the relocation list - abs_dir="$abs_dir $abs_dir2" - fi - - for d in $abs_dir; do - one_less_dir=${d%/} - # strip last path component - one_less_dir=${one_less_dir%/*} - - _dump "echo \"# _reloc_dir $one_less_dir\"" - done - done - - dump_header - _dump "" - - # this simply sources all the required files. the - # only magic involves some "fixups". - # - if we find an undefined dependency, we have to find an - # object that matches the patter. Remember: Order matters - # when you compile for inheritance. - _sourced="" - for i in $to_link; do - simple_name=`echo $i | sed 's%^\.%%' | sed 's%\.o$%%' | sed 's%~[0-9]*$%%'` - obj=$i - - # find the full object file dependency list ... - more_depends= - full_depends= - if [ -e $obj ]; then - more_depends=`grep -E "scc depends:" $obj | cut -d':' -f2` - fi - while [ -n "$more_depends" ]; do - x=$more_depends - more_depends="" - for req in $x; do - req=`basename $req` - echo $req | grep -q _undefined_ - if [ $? -eq 0 ]; then - if [ -n "$verbose" ]; then - echo "# resolving unresolved symbol(s) in $i" - fi - search_req=`echo "$req" | sed 's%_undefined_%%g'` - - options=`ls *-$search_req-*.sco` - my_num=`echo $i | cut -f1 -d-` - next_num=`expr $my_num + 1` - link_tgt=`echo "$options" | grep -E "$next_num-$search_req-*"` - - if [ -z "$link_tgt" ]; then - echo "ERROR. could not find an object to link" - exit 1 - fi - # rewrite the original object file to call the one we - # just found - path_sum=`echo $link_tgt | cut -f3 -d- | sed 's/.sco//g'` - cat $i | \ - sed "s%undefined_%$path_sum%g" \ - > $i.tmp - mv -f $i.tmp $i - fi - - # check to see if we've already processed this requirement - echo "$full_depends" | grep -q -w -E "$link_tgt\$" - if [ $? -ne 0 ]; then - if [ -e "$link_tgt" ]; then - y=`grep -E "scc depends:" $link_tgt | cut -d':' -f2` - else - echo "ERROR. object $link_tgt does not exist. cannot link" - exit 1 - fi - - more_depends="$more_depends $y" - fi - full_depends="$full_depends $link_tgt" - done - done - - # loop all the dependencies and output their source lines - # parent sources have already been changed to <blah>~1 - for required in $full_depends; do - required=`_strip_ext $required ".$obj_ext"` - echo "$_sourced" | grep -q -E "^$required\$" - if [ $? -ne 0 ]; then - _dump ". \`dirname \$0\`/$required.$obj_ext" - _sourced=`echo "$_sourced"; echo $required` - - grep -q "# .section INIT" $required.$obj_ext - if [ $? -eq 0 ]; then - __init_funcs="$__init_funcs $required" - fi - grep -q "# .section FINAL" $required.$obj_ext - if [ $? -eq 0 ]; then - __fin_funcs="$__fin_funcs $required" - fi - fi - done - - # check to make sure that the original file we were - # passed wasn't picked up. If it wasn't add a source - # of it to the output - if [ -e $obj ]; then - echo "$_sourced" | grep -q -E "^`basename $obj .$obj_ext`$" - if [ $? -ne 0 ]; then - _dump ". \`dirname \$0\`/$obj" - _sourced=`echo "$_sourced"; echo $simple_name` - - grep -q "# .section INIT" $obj - if [ $? -eq 0 ]; then - __init_funcs="$__init_funcs $simple_name" - fi - grep -q "# .section FINAL" $obj - if [ $? -eq 0 ]; then - __fin_funcs="$__fin_funcs $simple_name" - fi - fi - fi - done - - _dump '' - # call the main launch point .. - - # init functions ... - for i in $__init_funcs; do - _dump "$i" - done - - _dump '# scc main entry point. produces "$output"' - - # files compiled on the command line, that haven't already - # been called - for f in $forced_link; do - e_point=$(cat $f | grep "\# scc entry_func" | cut -d' ' -f4) - if [ -z "$e_point" ]; then - e_point=$(_safe_funcname `echo $f | sed 's%^\.%%' | sed 's%\.o$%%' | sed 's%~[0-9]*$%%'`) - fi - - echo "" $__fin_funcs $__init_funcs $entry_point | grep -q $e_point - if [ $? -ne 0 ]; then - _dump "$e_point" - fi - done - - # final functions ... - for i in $__fin_funcs; do - _dump "$i" - done - - # The first clause of this block is to allow any generated script to - # respond to a command line option "branch_point" or "branchpoints". When - # that is passed, the script will dump all the branchpoints that would be - # created by executing the script. - # - # The second clause is when the output script is run normally to output a - # meta script. In that case any 'auto branch' points are features that - # were noted during processing of the script by changed patches / - # includes / excludes, etc. Those auto branches are still in the output - # as feature start tags "_mark $feature_name start", and the must be - # replaced by a branch in the final output. - # - _dump '' - _dump 'if [ -n "$1" ] && ([ "$1" = "branch_points" ] || [ "$1" = "branchpoints" ]) ; then' - _dump ' if [ -n "$_auto_branch" ]; then' - _dump ' echo "$_auto_branch"' - _dump ' fi' - _dump ' echo "$output" | grep _force_branch' - _dump 'else' - _dump ' # this replaces the feature markers with branch points' - _dump ' for b in $_auto_branch; do' - _dump ' output=$(echo "$output" | sed "s/_mark $b start/_force_branch $b-auto/" )' - _dump ' done' - _dump ' echo "$output"' - _dump ' echo "# _branches_local: $_auto_branch"' - _dump 'fi' -} - -dump_header() -{ - _dump -n "# scc date "; _dump `date` - _dump "" - _dump "output=\"\"" - _dump "export patch_prefix=patches" - _dump "export meta_dir=$meta_dir" - - _dump "$dump_vars" -} - -### command processing starts here -process_command_line "$@" - -if [ -n "$version_dump" ]; then - echo "scc version: $version" - exit 0 -fi - -meta_dir=$KMETA -if [ -z "$meta_dir" ]; then - meta_dir=meta -fi - -## -## create variables for use in scripts -## -if [ -n "$defines" ]; then - vars=$(echo $defines | sed 's/,/ /g') - for v in "$vars"; do - # eval makes it available for this script - eval $v - # echo makes it available for other scripts - dump_vars=$(echo "$dump_vars"; echo export $v) - done +# preprocess the input files into a single large meta-script +spp --force -o $outfile.pre $include_paths $infiles +if [ $? -ne 0 ]; then + err "ERROR: could not process input files: $infiles" + exit 1 fi -# test for tools used by scc from the command line -# if they aren't found look for them. -tools_used_by_scc="patch gzip bzip2" -for t in $tools_used_by_scc; do - caps_t=$(echo $t | tr '[a-z]' '[A-Z]') - b="echo \$$caps_t" - x=`eval $b` - if [ "$x" == "" ]; then - cmd=`which $t` - #_dump "export $caps_t=$cmd"; - dump_vars=$(echo "$dump_vars"; echo "export $caps_t=$cmd") +# process the meta-script into a meta-series +header > $outfile +process_file $outfile.pre $outfile.pre >> $outfile +ret=$? +if [ $ret -ne 0 ]; then + if [ -z "$intermediate" ]; then + rm -f $outfile + rm -f $outfile.pre fi -done - -# if no args were passed, dump the usage. -if [ -n "$args" ]; then - - if [ -n "$do_signature" ]; then - get_sig $args - exit 0 - fi - if [ -n "$do_dirs" ]; then - get_dirs $args - exit 0 - fi - - compile_files $args -else - usage - exit 1 fi + +exit $ret diff --git a/tools/spp b/tools/spp new file mode 100755 index 0000000..7acf236 --- /dev/null +++ b/tools/spp @@ -0,0 +1,452 @@ +#!/bin/bash + +# "spp" preprocessor script. + +# Copyright (c) 2010-2013 Wind River Systems, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. + +version="0.1" + +usage() +{ +cat << EOF + + spp [--help] [--force] [-i] [-w] [-o outfile] [-D<var>=<value>] [-I<path>] [-v] infiles + + --help: This message + --force: force overwrite output file if it already exists + -D: define <var> to <value> which will be available to sub scripts + -I: include path <path> will be searched for files + -i: leave intermediate files on failure + -w: only warn on missing files + -v: verbose output + -o: outfile file for processed results. stdout is used if not passed + + infiles files to preprocess + + +EOF +} + +if [ -z "$1" ]; then + usage + exit 1 +fi + +while [ $# -gt 0 ]; do + case "$1" in + --help) + usage + exit + ;; + -D*|--D*) + if [ "$1" == "-D" ] || [ "$1" == "--D" ]; then + x=$2; shift; + else + x=`echo $1 | sed s%^-*D%%` + fi + defines="$defines $x" + ;; + -I*|--I*) + if [ "$1" == "-I" ] || [ "$1" == "--I" ]; then + x=$2; shift; + else + x=`echo $1 | sed s%^-*I%%` + fi + if [ -n "$x" ] && [ -d "$x" ]; then + include_paths="$include_paths $x" + fi + ;; + --force|-f) + force=t + ;; + -i) + intermediate=t + ;; + -o) + outfile=$2 + shift + ;; + -v) verbose=t + ;; + *) break + ;; + esac + shift +done + +err() +{ + echo "$@" 1>&2 +} + +# args are the input files +infiles=$@ + +processed_files="" + +if [ -z "$infiles" ]; then + err "ERROR: at least one input file must be supplied" + exit 1 +else + for f in $infiles; do + if [ ! -f "$f" ]; then + err "ERROR. input file \"$f\" does not exist" + exit 1 + fi + done +fi +if [ -n "$outfile" ] && [ -f "$outfile" ]; then + if [ -z "$force" ]; then + err "ERROR: output file \"$outfile\" exists, and --force was not passed" + exit 1 + fi +fi + +## +## create variables for use in scripts +## +if [ -n "$defines" ]; then + vars=$(echo $defines | sed 's/,/ /g') + for v in "$vars"; do + # eval makes it available for this script + eval $v + # echo makes it available for other scripts + dump_vars=$(echo "$dump_vars"; echo export $v) + done +fi + +search_include_paths() +{ + local tgt=$1 + local includes="$@" + local exclude_files="" + local base + local feature_ext="scc" + + if [ -n "$verbose" ]; then + echo "search_includes: $tgt" + echo "include paths: " + for i in $includes; do + echo " $i" + done + fi + + # remove the feature extension (if present) from the input name + tgt=${tgt%\.$feature_ext} + base=`basename $tgt` + + if [ -z "$exclude_files" ]; then + exclude_files="/dev/null" + fi + + for p in "." $includes; do + # target file + default feature extension + if [ -f $p/$tgt.$feature_ext ]; then + possible=`readlink -f "$p/$tgt.$feature_ext"` + # raw target file + elif [ -f $p/$tgt ]; then + possible=`readlink -f "$p/$tgt"` + # special processing test the include directory + + # the name of the feature. This saves us doing a massive + # set of includes for sub categories includes + elif [ -f $p/$tgt/$tgt.$feature_ext ]; then + possible=`readlink -f "$p/$tgt/$tgt.$feature_ext"` + elif [ -f $p/$tgt/$tgt ]; then + possible=`readlink -f "$p/$tgt/$tgt"` + # more special processing. test if the included + # feature is actually just the name of a directory + # AND there is not file with the same name present. + # if that is true, then test for: + # <tgt>/<tgt>.extension + # in that directory + elif [ -f $p/$tgt/$base.$feature_ext ]; then + possible=`readlink -f "$p/$tgt/$base.$feature_ext"` + elif [ -f $p/$tgt/$base ]; then + possible=`readlink -f "$p/$tgt/$base.$feature_ext"` + fi + + if [ -n "$possible" ]; then + echo "$exclude_files" | grep -q "$possible" + if [ $? -ne 0 ]; then + echo $possible + return + fi + possible= + fi + done +} + +header() +{ + echo "#" + echo "# spp v$version" + echo "# processed: `date`" + echo "#" + echo "# This is a preprocessor output file, do not edit" + echo "#" + + for i in $include_paths; do + # strip a trailing / + abs_dir=`readlink -f $i` + abs_dir2=`cd $i; pwd` + if [ x"$abs_dir" != x"$abs_dir2" ]; then + # there is some sort of symlink trickery going on. + # add both dirs to the relocation list + abs_dir="$abs_dir $abs_dir2" + fi + + for d in $abs_dir; do + one_less_dir=${d%/} + # strip last path component + one_less_dir=${one_less_dir%/*} + + echo "reloc_dir $one_less_dir" + done + done + + echo "#" +} + +# arg1: duration +# remaining: the processed files +footer() +{ + local duration=$1 + shift + local infiles=$@ + + echo "# run time: $duration seconds" + echo "# processed files:" + for f in $infiles; do + echo "# _cfg $f" + done +} + +process_file() +{ + local in=$1 + local containing_file=$2 + shift + shift + local flags=$@ + local inherited_inhibit_cfg="" + local inherited_inhibit_patch="" + local ret=0 + local done="" + local kconf_type + local kconf_name + local arg1 + local OLDIFS + local fline + local include_name + local inhibit_cfg + local inhibit_patch + + if [ -z "$in" ]; then + return + fi + + # process the flags to this file processing + for flag in $flags; do + case $flag in + nocfg) inherited_inhibit_cfg=nocfg + ;; + nopatch) inherited_inhibit_patch=nopatch + ;; + esac + done + + if [ ! -f "$in" ]; then + local_includes=`dirname $containing_file` + new_in=`search_include_paths $in $include_paths $local_includes` + if [ ! -f "$new_in" ]; then + err "ERROR: could not find file $in, included from $containing_file" + return 1 + fi + in=$new_in + else + in=`readlink -f $in` + fi + + echo "$processed_files" | grep -q "$in" + if [ $? -eq 0 ]; then + echo "# NOTE: feature `basename $in` has already been processed" + fi + processed_files="$processed_files $in" + + + OLDIFS=$IFS + IFS=' +' + echo "# --> file: $in" + echo "# flags: $flags" + for fline in `cat $in`; do + done="" + + # include + echo $fline | grep -q "^[[:space:]]*include" + if [ $? -eq 0 ]; then + include_name=`echo $fline | cut -f2 -d' '` + + # if we were called with inhibit flags, passing them along is + # the default + inhibit_cfg=$inherited_inhibit_cfg + inhibit_patch=$inherited_inhibit_patch + + # if we have a "nocfg" or "nopatch" on the include directive, + # then we need to set the variables so they'll be passed down to + # the nested process call + echo "$fline" | grep -q "nocfg" + if [ $? -eq 0 ]; then + inhibit_cfg=nocfg + fi + echo "$fline" | grep -q "nopatch" + if [ $? -eq 0 ]; then + inhibit_patch=nopatch + fi + + IFS=$OLDIFS + process_file $include_name $in $inhibit_cfg $inhibit_patch + ret=$? + if [ $ret -eq 1 ]; then + return $ret + fi + + # we can clear the inhbit flag, only if it wasn't passed into + # us from above. This allows local .cfg files to be processed. + if [ -z "$inherited_inhibit_cfg" ]; then + inhibit_cfg="" + fi + if [ -z "$inherited_inhibit_patch" ]; then + inhibit_patch="" + fi + + done=t + IFS=' +' + fi + + ## patch + echo $fline | grep -q -e "^[[:space:]]*patch" + local patch_ret=$? + if [ -z "$done" ] && [ $patch_ret -eq 0 ]; then + IFS=$OLDIFS + local patch_name=`echo $fline | cut -f2 -d' '` + + if [ -n "$inherited_inhibit_patch" ]; then + echo "# inhibited patch" + echo "true `dirname $in`/$patch_name" + else + if [ ! -f `dirname $in`/$patch_name ]; then + local patch_name_new=`search_include_paths $patch_name` + if [ ! -f "$patch_name_new" ]; then + err "ERROR: could not find patch $patch_name, included from $containing_file" + return 1 + fi + patch_name=$patch_name_new + else + patch_name="`dirname $in`/$patch_name" + fi + + # output the patch + echo "patch $patch_name" + fi + + IFS=' +' + done=t + fi + + ## kconf + echo $fline | grep -q -e "^[[:space:]]*kconf" -e "^force[[:space:]]*kconf" + local kconf_ret=$? + if [ -z "$done" ] && [ $kconf_ret -eq 0 ]; then + IFS=$OLDIFS + arg1=`echo $fline | cut -f1 -d' '` + if [ "$arg1" = "force" ]; then + # "force" will insist that its config be processed + kconf_type=`echo $fline | cut -f3 -d' '` + kconf_name=`echo $fline | cut -f4 -d' '` + else + arg1="" + kconf_type=`echo $fline | cut -f2 -d' '` + kconf_name=`echo $fline | cut -f3 -d' '` + fi + + if [ -n "$inherited_inhibit_cfg" ] && [ -z "$arg1" ]; then + echo "# inhibited kconf" + echo "true `dirname $in`/$kconf_name" + else + if [ ! -f `dirname $in`/$kconf_name ]; then + local kconf_name_new=`search_include_paths $kconf_name` + if [ ! -f "$kconf_name_new" ]; then + err "ERROR: could not find kconf $kconf_name, included from $containing_file" + return 1 + fi + kconf_name=$kconf_name_new + else + kconf_name="`dirname $in`/$kconf_name" + fi + + # output the kconfig + echo "kconf $kconf_type $kconf_name # $arg1" + fi + IFS=' +' + done=t + fi + if [ -z "$done" ]; then + echo "$fline" + fi + done + IFS=$OLDIFS + echo "# <-- done file: $in" + echo "#" + + return 0 +} + + +start_time=`date +"%s"` + +if [ -n "$outfile" ]; then + header > $outfile +else + header +fi + +for f in $infiles; do + if [ -n "$outfile" ]; then + process_file $f $f >> $outfile + else + process_file $f $f + fi +done + +stop_time=`date +"%s"` +duration=`expr $stop_time - $start_time` + +if [ -n "$outfile" ]; then + footer $duration $infiles >> $outfile +else + footer $duration $infiles +fi + + +ret=$? +if [ $ret -ne 0 ]; then + if [ -z "$intermediate" ]; then + rm -f $outfile + fi +fi + +exit $ret diff --git a/tools/updateme b/tools/updateme index 41cc10a..9a28816 100755 --- a/tools/updateme +++ b/tools/updateme @@ -132,6 +132,17 @@ if [ -n "$defines" ]; then done fi +abs_path() { + infile=$1 + + if [ -z "$infile" ]; then + return + fi + if [ -e "$infile" ] || [ -d "$infile" ]; then + readlink -fn $infile + fi +} + gen_dirs() { top_dir=$1 @@ -220,7 +231,7 @@ migrate_cfg() { # we've generated the feature, make sure it can be found add_search_include_dir $meta_dir/cfg/scratch/obj/$dirname - extra_features="$extra_features $gen_feature_name" + extra_features="$extra_features `abs_path $meta_dir/cfg/scratch/obj/$dirname/$gen_feature_name`" fi } @@ -262,7 +273,7 @@ migrate_patch() { # we've generated the feature, make sure it can be found add_search_include_dir $meta_dir/cfg/scratch/obj/$dirname - extra_features="$extra_features $gen_feature_name" + extra_features="$extra_features `abs_path $meta_dir/cfg/scratch/obj/$dirname/$gen_feature_name`" fi } @@ -289,7 +300,7 @@ migrate_feature() { grep -q -E "^.*define.*KMACHINE" $feat if [ $? -ne 0 ]; then # add it to the features to be built into the meta-series - extra_features="$extra_features $featname" + extra_features="$extra_features `abs_path $meta_dir/cfg/scratch/obj/$dirname/$featname`" fi } @@ -421,7 +432,7 @@ do_update() { cd $meta_dir/cfg/scratch/obj echo "# autogenerated branch switch" > branch_switch.scc echo "branch $cmd_line_branch HEAD" >> branch_switch.scc - extra_features="branch_switch.scc $extra_features" + extra_features="`abs_path branch_switch.scc` $extra_features" cd $old_pwd fi @@ -430,12 +441,9 @@ do_update() { # this builds and applies the meta-series ( cd $meta_dir/cfg/scratch/obj - - scc -o $ktgt $includes $top_tgt $extra_features $addon_features - if [ -e "$ktgt" ]; then - bash ./$ktgt > ../$ktgt-meta - else - echo "ERROR. A meta series could not be created for branch $branch" + scc --force -o ../$ktgt-meta $includes $top_tgt $extra_features $addon_features + if [ $? -ne 0 ]; then + echo "ERROR. A meta series could not be created for $top_tgt" fi ) } @@ -469,16 +477,16 @@ do_addon_features() search_feat=`_strip_ext $f .scc` potential=`find $d | grep -E ".*$search_feat\.scc"` if [ -n "$potential" ]; then - addon_features="$addon_features $potential" + addon_features="$addon_features `abs_path $potential`" found_feat="$potential" else if [ -e "$d/$f" ]; then # if it is a directory, only pass the dir name. if [ -d "$d/$f" ]; then - addon_features="$addon_features $f" + addon_features="$addon_features `abs_path $f`" found_feat="$f" else - addon_features="$addon_features $d/$f" + addon_features="$addon_features `abs_path $d/$f`" found_feat="$d/$f" fi fi |