This repository has been archived on 2024-10-17. You can view files and clone it, but cannot push or open issues or pull requests.
MahiroOS-jhalfs/BLFS/libs/func_dependencies
Pierre Labastie d607ac3717 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.
2015-02-22 15:16:49 +00:00

197 lines
6.2 KiB
Bash

#!/bin/bash
#
# $Id$
#
# A string of spaces for indenting:
declare -a spaceSTR=" "
declare -a exchange_triplet
# In case we find a cirdular dependency, it has the form :
# parent->dependency_0->...->dependency_n->dependency_0
# If we want to build dependency_n before dependency_0,
# no problem: we just prune the tree at dependency_n.
# If we want to build first dependency_0, we need to
# put dependency_n as a dependency of parent. The triplet
# above shall contain (parent dependency_0 dependency_n)
#----------------------------#
generate_dependency_tree() { #
#----------------------------#
: <<inline_doc
function: Create a subtree of the dependency tree
(recursive function)
input vars: $1 : file with a list of targets
the first line of the file is an array
of links
externals: vars: BLFS_XML
DEP_LEVEL
modifies: vars: none
returns: nothing
output: files: for each pkg with dependencies in $1,
a file pkg.dep and its dependencies
on error: nothing
on success: nothing
inline_doc
local DepFile=$1
local -a rootlink
local -a otherlink
local -i depth
local -i count=0
local id_of_dep
local parent
local lines_to_remove=
local srootlink
local dep_level
{
# BEWARE : the order of options matters : read -a -u6 rootlink hangs forever
# (actually, the doc says -a array -u fd)
# We use fd number 6 for input from DepFile, because we need 0 for user input
read -u6 -a rootlink
depth=${#rootlink[*]}
dep_level=$DEP_LEVEL
if (( $DEP_LEVEL > 2 )) && (( $depth > 1 )); then dep_level=2; fi
srootlink="${rootlink[*]} "
# start of Depfile
echo -en "\nNode: $depth${spaceSTR:0:$depth}${RED}$DepFile${OFF}"
while read -u6 id_of_dep; do
# count entries in file
(( count++ ))
# Has this entry already been seen?
if [ -f ${id_of_dep}.dep ]; then # found ${id_of_dep}.dep already in tree
otherlink=($(head -n 1 ${id_of_dep}.dep))
if [ -z "${otherlink[*]}" ]
then echo otherlink empty for $id_of_dep.dep
echo This should not happen, but happens to happen...
exit 1
fi
# Do not use "${rootlink[*]}" =~ "${otherlink[*]}": case rootlink=(1 11)
# and otherlink=(1 1)
if [[ ${srootlink#"${otherlink[*]} "} != ${srootlink} ]]; then # circular dep
# First look for the other parent of this dependency.
# The parent has the same link without the last entry.
# We do not need otherlink anymore so just destroy the last element
unset otherlink[${#otherlink[*]}-1]
parent=$(grep ^"${otherlink[*]}"\$ -l *)
parent=${parent%.dep}
echo -en "\nCirc: $depth${spaceSTR:0:$depth}${BLUE}Circular dependency detected:${OFF}"
echo -en "\nCirc: $depth${spaceSTR:0:$depth}${BOLD}${id_of_dep}${OFF} is a dependency \
of ${BOLD}${parent}${OFF}"
echo -en "\nCirc: $depth${spaceSTR:0:$depth}${BOLD}${DepFile%.dep}${OFF} is a dependency \
of ${BOLD}${id_of_dep}${OFF}"
echo -en "\nCirc: $depth${spaceSTR:0:$depth}${BOLD}${id_of_dep}${OFF} is a dependency \
of ${BOLD}${DepFile%.dep}${OFF}"
# If idofdep is the parent of DepFile, we can exchange them if required
# if grep -q ${DepFile%.dep} ${id_of_dep}.dep; then
# we propose exchange always
echo -en "\nCirc: $depth${spaceSTR:0:$depth}Do you want to build ${id_of_dep} first? yes/no (no):"
read ANSWER
if [ x$ANSWER = "xyes" ] ; then # exchange:
# set triplet and return 1
exchange_triplet=($parent $id_of_dep ${DepFile%.dep})
return 1
else # no exchange: prune
lines_to_remove="$lines_to_remove $id_of_dep"
fi
# else
# lines_to_remove="$lines_to_remove $id_of_dep"
# fi
else # not circular: prune
lines_to_remove="$lines_to_remove $id_of_dep"
fi
continue
fi
flag=true
while [ $flag = true ]; do
flag=false
xsltproc --stringparam dependencies ${dep_level} \
--stringparam idofdep $id_of_dep \
-o ${id_of_dep}.dep \
../xsl/dependencies.xsl ../packages.xml
if [[ -f ${id_of_dep}.dep ]]; then
sort ${id_of_dep}.dep -o ${id_of_dep}.dep
sed -i "1i${rootlink[*]} $count" ${id_of_dep}.dep
generate_dependency_tree ${id_of_dep}.dep
# Test return value, in case we exchange dependencies
case $? in
0) # Normal return
;;
1) # We are backing up to parent
if [[ ${exchange_triplet} == ${DepFile%.dep} ]]
then tree_erase ${id_of_dep}.dep
# Just doing a sed -i "s@${id_of_dep}@${exchange_triplet[2]}@" $DepFile
# is not good if $DepFile contains several times the same line
# so first find the first line and then sed
lineno=$(sed -n /${id_of_dep}/= $DepFile | head -n1)
sed -i "${lineno}s@${id_of_dep}@${exchange_triplet[2]}@" $DepFile
id_of_dep=${exchange_triplet[2]}
flag=true
else
# echo backing up to ${exchange_triplet} at ${DepFile%.dep}
return 1
fi
;;
esac
else
echo "${rootlink[*]} $count" > ${id_of_dep}.dep
fi
done
done
echo -en "\n End: $depth${spaceSTR:0:$depth}${GREEN}$DepFile${OFF}"
} 6<$DepFile
# It may happen that a file is created with several times
# the same line. Normally, all those lines but one
# would be flagged to be removed (or all of them if
# the dependency appeared before). a simple sed /$line/d
# destroys all the lines. We should instead remove
# only one for each appearance of it in lines_to_remove.
# so first get the number of first line and then delete
# that line
for line in $lines_to_remove
do lineno=$(sed -n /^$line\$/= $DepFile | head -n1)
sed -i ${lineno}d $DepFile
done
return 0
}
#---------------#
tree_browse() { #
#---------------#
local file=$1
local f
#echo file=$file
for f in $(grep '[^0-9 ]' $file); do
# echo f=$f
if grep -q '[^0-9 ]' ${f}.dep ; then
tree_browse ${f}.dep
fi
echo $f
done
}
#--------------#
tree_erase() { #
#--------------#
local file=$1
local f
local -a rootlink
local -a rootlink2
#echo file=$file
rootlink=($(head -n1 $file))
for f in $(grep '[^0-9 ]' $file); do
# echo " f"=$f
if [ -f ${f}.dep ]; then
rootlink2=($(head -n1 ${f}.dep))
if [[ "${rootlink2[*]}" =~ "${rootlink[*]}" ]] ; then
tree_erase ${f}.dep
fi
fi
done
rm -f $file
}