source: BLFS/libs/func_dependencies@ d607ac3

2.4 ablfs-more legacy new_features trunk
Last change on this file since d607ac3 was d607ac3, checked in by Pierre Labastie <pierre@…>, 10 years ago

Fix dependency generator:
When the .dep file is scanned during the tree building, it outputs dependencies
in the file order, while when the tree is scanned later, dependencies are
output in alphabetical order. This may eventually lead to a wrong order
at the end. To be sure that both output are the same, just sort
the .dep file before scanning it.

  • Property mode set to 100644
File size: 6.2 KB
RevLine 
[3c10176]1#!/bin/bash
2#
3# $Id$
4#
5
[e576789]6# A string of spaces for indenting:
[3c10176]7declare -a spaceSTR=" "
[e576789]8declare -a exchange_triplet
9
10# In case we find a cirdular dependency, it has the form :
11# parent->dependency_0->...->dependency_n->dependency_0
12# If we want to build dependency_n before dependency_0,
13# no problem: we just prune the tree at dependency_n.
14# If we want to build first dependency_0, we need to
15# put dependency_n as a dependency of parent. The triplet
16# above shall contain (parent dependency_0 dependency_n)
[3c10176]17
18#----------------------------#
19generate_dependency_tree() { #
20#----------------------------#
21: <<inline_doc
[e576789]22 function: Create a subtree of the dependency tree
23 (recursive function)
24 input vars: $1 : file with a list of targets
25 the first line of the file is an array
26 of links
27 externals: vars: BLFS_XML
[3c10176]28 DEP_LEVEL
[e576789]29 modifies: vars: none
[3c10176]30 returns: nothing
[e576789]31 output: files: for each pkg with dependencies in $1,
32 a file pkg.dep and its dependencies
[3c10176]33 on error: nothing
34 on success: nothing
35inline_doc
36
[e576789]37local DepFile=$1
38local -a rootlink
39local -a otherlink
40local -i depth
41local -i count=0
42local id_of_dep
43local parent
44local lines_to_remove=
45local srootlink
46local dep_level
47
48{
49# BEWARE : the order of options matters : read -a -u6 rootlink hangs forever
50# (actually, the doc says -a array -u fd)
51# We use fd number 6 for input from DepFile, because we need 0 for user input
52read -u6 -a rootlink
53depth=${#rootlink[*]}
54dep_level=$DEP_LEVEL
55if (( $DEP_LEVEL > 2 )) && (( $depth > 1 )); then dep_level=2; fi
56srootlink="${rootlink[*]} "
57# start of Depfile
58echo -en "\nNode: $depth${spaceSTR:0:$depth}${RED}$DepFile${OFF}"
59
60while read -u6 id_of_dep; do
61# count entries in file
62 (( count++ ))
63# Has this entry already been seen?
64 if [ -f ${id_of_dep}.dep ]; then # found ${id_of_dep}.dep already in tree
65 otherlink=($(head -n 1 ${id_of_dep}.dep))
66 if [ -z "${otherlink[*]}" ]
67 then echo otherlink empty for $id_of_dep.dep
68 echo This should not happen, but happens to happen...
69 exit 1
70 fi
71# Do not use "${rootlink[*]}" =~ "${otherlink[*]}": case rootlink=(1 11)
72# and otherlink=(1 1)
73 if [[ ${srootlink#"${otherlink[*]} "} != ${srootlink} ]]; then # circular dep
74# First look for the other parent of this dependency.
75# The parent has the same link without the last entry.
76# We do not need otherlink anymore so just destroy the last element
77 unset otherlink[${#otherlink[*]}-1]
78 parent=$(grep ^"${otherlink[*]}"\$ -l *)
79 parent=${parent%.dep}
80 echo -en "\nCirc: $depth${spaceSTR:0:$depth}${BLUE}Circular dependency detected:${OFF}"
81 echo -en "\nCirc: $depth${spaceSTR:0:$depth}${BOLD}${id_of_dep}${OFF} is a dependency \
82of ${BOLD}${parent}${OFF}"
83 echo -en "\nCirc: $depth${spaceSTR:0:$depth}${BOLD}${DepFile%.dep}${OFF} is a dependency \
84of ${BOLD}${id_of_dep}${OFF}"
85 echo -en "\nCirc: $depth${spaceSTR:0:$depth}${BOLD}${id_of_dep}${OFF} is a dependency \
86of ${BOLD}${DepFile%.dep}${OFF}"
87# If idofdep is the parent of DepFile, we can exchange them if required
88# if grep -q ${DepFile%.dep} ${id_of_dep}.dep; then
89# we propose exchange always
90 echo -en "\nCirc: $depth${spaceSTR:0:$depth}Do you want to build ${id_of_dep} first? yes/no (no):"
91 read ANSWER
92 if [ x$ANSWER = "xyes" ] ; then # exchange:
93# set triplet and return 1
94 exchange_triplet=($parent $id_of_dep ${DepFile%.dep})
95 return 1
96 else # no exchange: prune
97 lines_to_remove="$lines_to_remove $id_of_dep"
98 fi
99# else
100# lines_to_remove="$lines_to_remove $id_of_dep"
101# fi
102 else # not circular: prune
103 lines_to_remove="$lines_to_remove $id_of_dep"
104 fi
105 continue
[3c10176]106 fi
[e576789]107 flag=true
108 while [ $flag = true ]; do
109 flag=false
110 xsltproc --stringparam dependencies ${dep_level} \
111 --stringparam idofdep $id_of_dep \
112 -o ${id_of_dep}.dep \
113 ../xsl/dependencies.xsl ../packages.xml
114
115 if [[ -f ${id_of_dep}.dep ]]; then
[d607ac3]116 sort ${id_of_dep}.dep -o ${id_of_dep}.dep
[e576789]117 sed -i "1i${rootlink[*]} $count" ${id_of_dep}.dep
118 generate_dependency_tree ${id_of_dep}.dep
119# Test return value, in case we exchange dependencies
120 case $? in
121 0) # Normal return
122 ;;
123 1) # We are backing up to parent
124 if [[ ${exchange_triplet} == ${DepFile%.dep} ]]
125 then tree_erase ${id_of_dep}.dep
126# Just doing a sed -i "s@${id_of_dep}@${exchange_triplet[2]}@" $DepFile
127# is not good if $DepFile contains several times the same line
128# so first find the first line and then sed
129 lineno=$(sed -n /${id_of_dep}/= $DepFile | head -n1)
130 sed -i "${lineno}s@${id_of_dep}@${exchange_triplet[2]}@" $DepFile
131 id_of_dep=${exchange_triplet[2]}
132 flag=true
133 else
134# echo backing up to ${exchange_triplet} at ${DepFile%.dep}
135 return 1
136 fi
137 ;;
[3c10176]138 esac
[e576789]139 else
140 echo "${rootlink[*]} $count" > ${id_of_dep}.dep
[3c10176]141 fi
142 done
[e576789]143done
144echo -en "\n End: $depth${spaceSTR:0:$depth}${GREEN}$DepFile${OFF}"
145} 6<$DepFile
146# It may happen that a file is created with several times
147# the same line. Normally, all those lines but one
148# would be flagged to be removed (or all of them if
149# the dependency appeared before). a simple sed /$line/d
150# destroys all the lines. We should instead remove
151# only one for each appearance of it in lines_to_remove.
152# so first get the number of first line and then delete
153# that line
154for line in $lines_to_remove
155 do lineno=$(sed -n /^$line\$/= $DepFile | head -n1)
156 sed -i ${lineno}d $DepFile
157done
158return 0
159}
[3c10176]160
[e576789]161#---------------#
162tree_browse() { #
163#---------------#
164local file=$1
165local f
166
167#echo file=$file
168for f in $(grep '[^0-9 ]' $file); do
169# echo f=$f
170 if grep -q '[^0-9 ]' ${f}.dep ; then
171 tree_browse ${f}.dep
[3c10176]172 fi
[e576789]173 echo $f
174done
175}
[3c10176]176
[e576789]177#--------------#
178tree_erase() { #
179#--------------#
180local file=$1
181local f
182local -a rootlink
183local -a rootlink2
184
185#echo file=$file
186rootlink=($(head -n1 $file))
187for f in $(grep '[^0-9 ]' $file); do
188# echo " f"=$f
189 if [ -f ${f}.dep ]; then
190 rootlink2=($(head -n1 ${f}.dep))
191 if [[ "${rootlink2[*]}" =~ "${rootlink[*]}" ]] ; then
192 tree_erase ${f}.dep
193 fi
194 fi
195done
196rm -f $file
[3c10176]197}
Note: See TracBrowser for help on using the repository browser.