1#!/bin/sh
2# $Id: make_lock_map.sh 344587 2011-11-16 20:43:52Z ucko $
3
4PATH=/bin:/usr/bin
5export PATH
6
7act=false
8cache_dir='.#SRC-cache'
9lock_map='.#lock-map'
10files=Makefile.*.[la][ip][bp]
11test=test
12builddir=
13rel_srcdir=
14
15# These arguments enable complementing non-trivial lock maps with .hints
16# files (in .../build/build-system) defining order-only prerequisites for use
17# by Makefile.flat, which can then avoid intra-build contention altogether.
18while [ $# != 0 ]; do
19    case "$1" in
20        -bd ) builddir=$2   ; shift 2 ;;
21        -sd ) rel_srcdir=$2 ; shift 2 ;;
22    esac
23done
24
25common=_`basename $PWD`_common
26
27if [ -d "$cache_dir" ]; then
28    cd $cache_dir
29    for x in *; do
30        if test \! -f "../$x"; then
31            rm -f "$x"
32            act=true
33        fi
34    done
35    cd ..
36else
37    mkdir "$cache_dir"
38fi
39
40(test Makefile.in -ef Makefile.in) 2>/dev/null  ||  test=/usr/bin/test
41if nawk 'BEGIN { exit 0 }' 2>/dev/null; then
42    awk=nawk
43else
44    awk=awk
45fi
46
47for x in $files; do
48    if [ "x$x" = "x$files" ]; then
49        # echo "No application or library makefiles found in $PWD."
50        exit 0
51    elif $test \! -f "$cache_dir/$x" -o "$cache_dir/$x" -ot "$x"; then
52        $awk -F= '{ sub("#.*", "") }
53            /^[ 	]*(UNIX_)?SRC[ 	]*=.*/ {
54                src = $2
55                sub("^[ 	]*", "", src)
56                while (sub("\\\\$", "", src)) {
57                    print src
58                    getline src
59                    sub("^[ 	]*", "", src)
60                }
61                print src
62            }' $x | fmt -w 1 | sort -u > "$cache_dir/$x"
63        act=true
64    fi
65done
66
67if [ $act = true ]; then
68    for x in $files; do
69        for y in $files; do
70            if [ "$x" \!= "$y" ]  &&  \
71               [ -n "`comm -12 \"$cache_dir/$x\" \"$cache_dir/$y\"`" ]; then
72                echo "$x $common" | \
73                    sed -e 's/^Makefile\.\(.*\)\.[la][ip][bp] /\1 /'
74                break
75            fi
76        done
77    done > "$lock_map.new"
78    cmp -s "$lock_map" "$lock_map.new"  ||  mv -f "$lock_map.new" "$lock_map"
79    # Don't bother keeping empty maps around.
80    [ -s "$lock_map" ]  ||  rm "$lock_map"
81fi
82
83print_rdep_count()
84{
85    test -f Makefile.$1.$2  ||  return
86    target=`awk "/\.$4\.real :/ { x=\\$1 } /cd $d[ ;&].* $3_PROJ=$1 / { print x; exit }" $mff`
87    if [ -n "$target" ]; then
88        echo `grep -c " $target" $mff` $target Makefile.$1.$2
89    else
90        echo "WARNING: couldn't find $rel_srcdir/$x in $mff" >&2
91    fi
92}
93
94if [ "${rel_srcdir:-.}" != . -a -n "$builddir" -a \
95     -w "$builddir/build-system" ]; then
96    hintfile=$builddir/build-system/`echo "$rel_srcdir" | tr / _`.hints
97    if [ -f "$lock_map" ]; then
98        if $test "$hintfile" -nt "$lock_map"; then
99            exit 0 # Already up to date
100        fi
101        exec > "$hintfile.$$"
102cat <<EOF
103ifneq "" "\$(wildcard \$(top_srcdir)/src/$rel_srcdir/flat-hints.mk)"
104  include \$(top_srcdir)/src/$rel_srcdir/flat-hints.mk
105else
106EOF
107        d=`echo $rel_srcdir/ | sed -e 's,/,\\\\/,g'`
108        mff=$builddir/Makefile.flat
109        set _
110        shift
111        while read x y; do
112            print_rdep_count $x app APP exe
113            print_rdep_count $x lib LIB '(lib|dll)'
114        done < "$lock_map" | \
115        sort -rn | \
116        while read n x mf; do
117            v=`echo $x | tr .- __`
118            echo "  ifneq '' '\$(wildcard \$(top_srcdir)/src/$rel_srcdir/$mf)'"
119            echo "    $v = $x"
120            [ $# = 0 ]  ||  echo "    $x: $*"
121            echo "  endif"
122            set "$@" "\$($v)"
123        done
124        echo 'endif'
125        mv "$hintfile.$$" "$hintfile"
126    else
127        rm -f "$hintfile"
128    fi
129fi
130
131exit 0
132