Changeset 7dc8595 for BLFS


Ignore:
Timestamp:
11/17/2015 08:22:04 PM (9 years ago)
Author:
Pierre Labastie <pierre@…>
Branches:
2.4, ablfs-more, legacy, new_features, trunk
Children:
82bd7a6
Parents:
5fb012d
Message:

Automate the process of choosing action when there are circular dependencies.
This has to be tested, but hopefully, it should allow to find a coherent
build order when there are not too many circular dependencies

Location:
BLFS
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • BLFS/gen_pkg_book.sh

    r5fb012d r7dc8595  
    9191  local -i index
    9292  local DepDir=$1
    93   rm -f $DepDir/*.dep
     93  rm -f $DepDir/*.{o,}dep
     94  for (( index=0 ; index < ${#TARGET[*]} ; index ++ )); do
     95    echo 1 ${TARGET[${index}]} >> $DepDir/root.odep
     96  done
    9497  echo 1 > $DepDir/root.dep
    95   for (( index=0 ; index < ${#TARGET[*]} ; index ++ )); do
    96     echo ${TARGET[${index}]} >> $DepDir/root.dep
    97   done
     98  echo 1 >> $DepDir/root.dep
     99  cat $DepDir/root.odep >> $DepDir/root.dep
    98100}
    99101
     
    146148pushd $DepDir > /dev/null
    147149set +e
    148 generate_dependency_tree root.dep
     150generate_dependency_tree root.dep 1
    149151echo
    150152LIST="$(tree_browse root.dep)"
  • BLFS/libs/func_dependencies

    r5fb012d r7dc8595  
    99# would just have to build the tree using the packages.xml file, and to     #
    1010# provide a function for browsing it. But we need to be able to detect      #
    11 # circular dependencies and to possibly change the tree depending on the    #
    12 # user # decision. This is why we keep with each node a record of the path  #
    13 # from the root to the node, which we call *link*.                          #
     11# circular dependencies and to possibly change the tree depending on        #
     12# priorities. This is why we keep with each node a record of the path       #
     13# from the root to the node, which we call *link* and a record of the       #
     14# successive priorities which we call *priolink*.                           #
     15#                                                                           #
    1416# Layout of the tree:                                                       #
    15 # Each node is a file <nodeName>.dep, which contains the names of the       #
    16 # child nodes, one per line, except the first line is the *link*:           #
    17 # the link is a series of numbers (n1 n2 ... nN), describing the path from  #
    18 # the root to <nodeName>: n1 is the position of the first node of the path  #
    19 # in root.dep, n2 is the position of the second node of the path in         #
    20 # <node1>.dep and so on. The link is not needed for normal tree operations  #
    21 # (building a subtree or browsing the tree), but it allows to               #
    22 # check whether a dependency is circular, and to find its parent.           #
     17#                                                                           #
     18# A node of the tree is represented by a file <nodeName>.dep. We keep all   #
     19# those files in the same directory. The root node file is "root.dep".      #
     20# Files <nodeName>.dep have the following layout:                           #
     21#   - the first line is the link: the link is an array of numbers           #
     22#     (n1 n2 ... nN), describing the path from the root to <nodeName>: n1   #
     23#     is the position of the first node of the path in root.dep, n2 is the  #
     24#     position of the second node of the path in <node1>.dep and so on. The #
     25#     link is not needed for normal tree operations (building a subtree or  #
     26#     browsing the tree), but it allows to check whether a dependency is    #
     27#     circular, and to find its parent.                                     #
     28#   - the second line is an array of priorities (p1 p2 ... pN), giving the  #
     29#     priority (1=required, 2=recommended, 3=optional) of each dependency   #
     30#     in the link.                                                          #
     31#   - each subsequent line is of the form "p <depname>", where p is the     #
     32#     priority as above, and <depname> is the name of the dependency. The   #
     33#     position which is recorded in the link is the number of the line      #
     34#     minus 2.                                                              #
     35#                                                                           #
    2336# Circular dependencies:                                                    #
     37#                                                                           #
    2438# In case we find a cirdular dependency, it has the form :                  #
    2539# parent->dependency_0->...->dependency_n->dependency_0                     #
     
    3852# A string of spaces for indenting:
    3953declare -a spaceSTR="                                                                   "
     54# When we are backing up from a circular dependency, `exchange_triplet'
     55# shall contain (parent dependency_0 dependency_n):
    4056declare -a exchange_triplet
    41 
    42 # When we are backing up from a circular dependency, `exchange_triplet'
    43 # shall contain (parent dependency_0 dependency_n)
    4457
    4558#----------------------------#
     
    5164    input vars: $1 : file with a list of targets (child nodes)
    5265                     the first line of the file is the link
    53     externals:  vars: BLFS_XML
    54                       DEP_LEVEL
     66                $2 : priority (1=req, 2=rec, 3=opt)
     67    externals:  vars: DEP_LEVEL contains the 1 if we want to build the
     68                                tree only for required dependencies,
     69                                2 if we want also recommended ones,
     70                                and 3 if we want optional ones too.
    5571    returns:    0 if the tree has been successfully created
    5672                1 if we are backing up to the parent of a circular dep
     
    6379
    6480local DepFile=$1
     81local priority=$2
    6582local -a rootlink
     83local -a priolink
    6684local -a otherlink
    6785local -i depth
     
    7290local srootlink
    7391local dep_level
     92local priostring
     93local dpriostring
     94local i
    7495
    7596{
     
    7798read -u6 -a rootlink
    7899depth=${#rootlink[*]}
     100read -u6 -a priolink
    79101dep_level=$DEP_LEVEL
    80102# For now, process optional deps only for the root packages.
    81103if (( $DEP_LEVEL > 2 )) && (( $depth > 1 )); then dep_level=2; fi
    82104srootlink="${rootlink[*]} "
     105case $priority in
     106    1) priostring=required ;;
     107    2) priostring=recommended ;;
     108    3) priostring=optional ;;
     109esac
    83110# start of DepFile
    84 echo -en "\nNode: $depth${spaceSTR:0:$depth}${RED}$DepFile${OFF}"
    85 
    86 while read -u6 id_of_dep; do
     111echo -en "\nNode: $depth${spaceSTR:0:$depth}${RED}$DepFile${OFF} $priostring"
     112
     113while read -u6 prio_of_dep id_of_dep; do
     114case $prio_of_dep in
     115    1) dpriostring=required ;;
     116    2) dpriostring=recommended ;;
     117    3) dpriostring=optional ;;
     118esac
    87119# count entries in file
    88120  (( count++ ))
     
    98130# and otherlink=(1 1)
    99131    if [[ ${srootlink#"${otherlink[*]} "} != ${srootlink} ]]; then # cir. dep
     132      echo -en "\nCirc: $((depth+1))${spaceSTR:0:$((depth+1))}${YELLOW}${id_of_dep}${OFF} $dpriostring"
    100133# First look for the other parent of this dependency.
    101134# The parent has the same link without the last entry.
    102135# We do not need otherlink anymore so just destroy the last element
    103       unset otherlink[${#otherlink[*]}-1]
     136      unset otherlink[-1]
    104137      parent=$(grep ^"${otherlink[*]}"\$ -l *)
    105138      parent=${parent%.dep}
    106       echo -en "\nCirc: $depth${spaceSTR:0:$depth}${BLUE}Circular dependency detected:${OFF}"
    107       echo -en "\nCirc: $depth${spaceSTR:0:$depth}${BOLD}${id_of_dep}${OFF} is a dependency \
    108 of ${BOLD}${parent}${OFF}"
    109       echo -en "\nCirc: $depth${spaceSTR:0:$depth}${BOLD}${DepFile%.dep}${OFF} is a dependency \
    110 of ${BOLD}${id_of_dep}${OFF}"
    111       echo -en "\nCirc: $depth${spaceSTR:0:$depth}${BOLD}${id_of_dep}${OFF} is a dependency \
    112 of ${BOLD}${DepFile%.dep}${OFF}"
    113 # we propose exchange always
    114       echo -en "\nCirc: $depth${spaceSTR:0:$depth}Do you want to build ${id_of_dep} first? yes/no (no):"
    115       read ANSWER
    116       if [ x$ANSWER = "xyes" ] ; then  # exchange:
    117 # set triplet and return 1
    118         exchange_triplet=($parent $id_of_dep ${DepFile%.dep})
    119         return 1
    120       else # no exchange: prune and remove the line(s) from odep...
     139# Find lowest priority in branch from parent to DepFile:
     140      p2=0
     141      for (( i=${#otherlink[*]}; i < $depth ; i++ )) ; do
     142        if (( ${priolink[i]} > $p2 )); then p2=${priolink[i]}; fi
     143      done
     144      if (( $prio_of_dep >= $p2 )); then # prune
    121145        lines_to_remove="$lines_to_remove $id_of_dep"
    122146        sed -i "/$id_of_dep/d" ${DepFile/.dep/.odep}
     147      else #backup with prio priority
     148        exchange_triplet=($parent $id_of_dep ${DepFile%.dep})
     149        return $priority
    123150      fi
    124     else # not circular: prune
     151    else # not circular: prune tree (but not .odep, since it may happen that
     152         # the tree is destroyed and rebuilt in another order
    125153      lines_to_remove="$lines_to_remove $id_of_dep"
    126154    fi # circular or not
     
    144172# but is empty.
    145173    if [[ -s ${id_of_dep}.odep ]]; then # this dependency has dependencies
    146       sed "1i${rootlink[*]} $count" < ${id_of_dep}.odep \
    147                                     > ${id_of_dep}.dep # add the link
    148       generate_dependency_tree ${id_of_dep}.dep
     174      sed "1i${rootlink[*]} $count\\
     175${priolink[*]} $prio_of_dep" < ${id_of_dep}.odep \
     176                             > ${id_of_dep}.dep # add link and priolink
     177      generate_dependency_tree ${id_of_dep}.dep $prio_of_dep
    149178# Test return value, in case we exchange dependencies
    150       case $? in
     179      p2=$?
     180      case $p2 in
    151181       0) # Normal return
    152182         ;;
    153        1) # We are backing up to parent
    154          if [[ ${exchange_triplet} == ${DepFile%.dep} ]] # we are the parent
    155            then tree_erase ${id_of_dep}.dep
     183       [123]) # We are backing up to parent
     184         if [[ ${exchange_triplet} == ${DepFile%.dep} ]] ; then
     185# We are the parent!
     186# First, we have to find the parent of our new direct dep, and remove
     187# the new direct dep from the parent.odep:
     188           otherlink=($(head -n1 ${exchange_triplet[2]}.dep))
     189           unset otherlink[-1]
     190           parent=$(grep -l ^"${otherlink[*]}"\$ *.dep)
     191           sed -i /[[:digit:]]\ ${exchange_triplet[2]}\$/d ${parent/.dep/.odep}
     192           tree_erase ${id_of_dep}.dep
    156193# We want that our direct dep be ${exchange_triplet[2]} and that id_of_dep
    157194# be pulled in as an indirect dep, so exchange.
     
    167204           id_of_dep=${exchange_triplet[2]}
    168205           flag=true # we have to regenerate the tree for the new dependency
    169          else # we are not the parent. let's just back up one step
    170 # echo backing up to ${exchange_triplet} at ${DepFile%.dep}
    171            return 1
     206         else
     207# We are not the parent. If our priority is greater than p2
     208# we have to change the triplet and return priority, else return current p2.
     209# echo (DEBUG) backing up to ${exchange_triplet} at ${DepFile%.dep}
     210           if (( $priority > $p2 )); then
     211             exchange_triplet[2]=${DepFile%.dep}
     212             return $priority
     213           else
     214             return $p2
     215           fi
    172216         fi
    173217         ;;
     
    176220         # and print
    177221      echo "${rootlink[*]} $count" > ${id_of_dep}.dep
    178       echo -en "\nLeaf: $(($depth+1))${spaceSTR:0:$(($depth+1))}${CYAN}${id_of_dep}${OFF}"
     222      echo -en "\nLeaf: $(($depth+1))${spaceSTR:0:$(($depth+1))}${CYAN}${id_of_dep}${OFF} $dpriostring"
    179223    fi
    180224  done
     
    191235# that line
    192236for line in $lines_to_remove
    193   do lineno=$(sed -n /^$line\$/= $DepFile | tail -n1)
     237  do lineno=$(sed -n /^[[:digit:]]\ $line\$/= $DepFile | tail -n1)
    194238  sed -i ${lineno}d $DepFile
    195239done
     
    204248
    205249#echo file=$file
    206 for f in $(grep '[^0-9 ]' $file); do
     250for f in $(grep '[^0-9 ]' $file | sed 's/.* //'); do
    207251#  echo f=$f
    208252  if grep -q '[^0-9 ]' ${f}.dep ; then
     
    223267#echo file=$file
    224268rootlink=($(head -n1 $file))
    225 for f in $(grep '[^0-9 ]' $file); do
     269for f in $(grep '[^0-9 ]' $file | sed 's/.* //'); do
    226270#  echo "    f"=$f
    227271  if [ -f ${f}.dep ]; then
  • BLFS/xsl/dependencies.xsl

    r5fb012d r7dc8595  
    2121
    2222  <xsl:template match="package">
    23     <xsl:apply-templates select="./dependency[@status='required']"/>
     23    <xsl:apply-templates select="./dependency[@status='required']">
     24      <xsl:with-param name="priority" select="1"/>
     25    </xsl:apply-templates>
    2426    <xsl:if test="$dependencies &gt; '1'">
    25       <xsl:apply-templates select="./dependency[@status='recommended']"/>
     27      <xsl:apply-templates select="./dependency[@status='recommended']">
     28        <xsl:with-param name="priority" select="2"/>
     29      </xsl:apply-templates>
    2630      <xsl:if test="$dependencies = '3'">
    27         <xsl:apply-templates select="./dependency[@status='optional']"/>
     31        <xsl:apply-templates select="./dependency[@status='optional']">
     32          <xsl:with-param name="priority" select="3"/>
     33        </xsl:apply-templates>
    2834      </xsl:if>
    2935    </xsl:if>
     
    3137
    3238  <xsl:template match="module">
    33     <xsl:apply-templates select="./dependency[@status='required']"/>
     39    <xsl:apply-templates select="./dependency[@status='required']">
     40      <xsl:with-param name="priority" select="1"/>
     41    </xsl:apply-templates>
    3442    <xsl:if test="$dependencies &gt; '1'">
    35       <xsl:apply-templates select="./dependency[@status='recommended']"/>
     43      <xsl:apply-templates select="./dependency[@status='recommended']">
     44        <xsl:with-param name="priority" select="2"/>
     45      </xsl:apply-templates>
    3646      <xsl:if test="$dependencies = '3'">
    37         <xsl:apply-templates select="./dependency[@status='optional']"/>
     47        <xsl:apply-templates select="./dependency[@status='optional']">
     48          <xsl:with-param name="priority" select="3"/>
     49        </xsl:apply-templates>
    3850      </xsl:if>
    3951    </xsl:if>
     
    4153
    4254  <xsl:template match="dependency">
     55    <xsl:param name="priority"/>
    4356    <xsl:variable name="depname">
    4457      <xsl:choose>
     
    6881      </xsl:choose>
    6982    </xsl:variable>
    70     <xsl:apply-templates select="dependency"/>
     83    <xsl:apply-templates select="dependency">
     84      <xsl:with-param name="priority" select="1"/>
     85    </xsl:apply-templates>
    7186    <xsl:if test="number($install_it)">
     87      <xsl:value-of select="$priority"/>
     88      <xsl:text> </xsl:text>
    7289      <xsl:value-of select="$depname"/>
    7390      <xsl:text>&#xA;</xsl:text>
Note: See TracChangeset for help on using the changeset viewer.