nrelease - fix/improve livecd
[dragonfly.git] / contrib / bmake / mkdeps.sh
1 :
2 # NAME:
3 #       mkdeps - generate dependencies
4 #
5 # SYNOPSIS:
6 #       mkdeps [options] file ...
7 #
8 # DESCRIPTION:
9 #       This script updates "makefile" with dependencies for
10 #       "file"(s).  It borrows ideas from various makedepend scripts
11 #       and should be compatible with most.
12 #
13 #       By default we use grep to extract include file names from
14 #       source files.  We source an "rc" file '$Mydir/.${Myname}rc' which
15 #       can contain variable assignments such as:
16 #.nf
17 #   
18 #       cpp_c=/usr/lib/cpp
19 #       cpp_cc=g++ -E
20 #       ...
21 #
22 #.fi
23 #       If the variable 'cpp_$suffix' is set, we use it as our cpp in
24 #       place of grep.  The program referenced by these variables are
25 #       expected to produce output like:
26 #.nf
27 #
28 #       # 10 \"/usr/include/stdio.h\" 1
29 #
30 #.fi
31 #       This allows us to skip most of our processing.  For lex,yacc
32 #       and other source files, grep is probably just as quick and
33 #       certainly more portable.
34 #
35 #       If the "rc" file does not exist, we create it and attempt to
36 #       find cpp or an equivalent cc invocation to assign to 'cpp_c'.
37 #               
38 # AUTHOR:
39 #       Simon J. Gerraty <sjg@zen.void.oz.au>
40 #
41
42 # RCSid:
43 #       $Id: mkdeps.sh,v 1.24 2022/09/09 18:44:56 sjg Exp $
44 #
45 #       @(#) Copyright (c) 1993 Simon J. Gerraty
46 #
47 #       This file is provided in the hope that it will
48 #       be of use.  There is absolutely NO WARRANTY.
49 #       Permission to copy, redistribute or otherwise
50 #       use this file is hereby granted provided that 
51 #       the above copyright notice and this notice are
52 #       left intact. 
53 #      
54 #       Please send copies of changes and bug-fixes to:
55 #       sjg@zen.void.oz.au
56 #
57
58 Myname=`basename $0 .sh`
59 Mydir=`dirname $0`
60
61 case `echo -n .` in
62 -n*)    N=; C="\c";;
63 *)      N=-n; C=;;
64 esac
65
66 cc_include=-I/usr/include
67
68 TF=/tmp/dep.$$
69 EF=/tmp/deperr.$$
70 > $EF
71
72 case "$*" in
73 *-n*)                           # don't use rc file
74   rc=/dev/null
75   norc=yes;;
76 *)
77   rc=$Mydir/.${Myname}rc
78   ;;
79 esac
80
81 update=
82 Include=include
83
84 if [ x"$norc" = x -a -f $rc ]; then
85   . $rc
86 else
87   # if /usr/lib/cpp or equivalent is available it is better than
88   # grepping .c files.
89   # See what (if anything) works on this system...
90   echo : > $rc
91   echo "# pre-processor for .c files" >> $rc
92   # try a couple of sane places first
93   for d in /usr/libexec /usr/lib /usr/bin /lib /usr/ccs/bin
94   do
95     cpp_c=$d/cpp
96     [ -x $cpp_c ] && break
97   done
98   
99   if [ -x $cpp_c ]; then
100     echo cpp_c=$cpp_c >> $rc
101   else
102     cpp_c=
103     # rats see if cc can be used
104     echo "#include <stdio.h>" > /tmp/f$$.c
105     echo "main() { return 0; }" >> /tmp/f$$.c
106     # try some sensible args to cc
107     for arg in -E -P -M
108     do
109       ok=`${REALCC:-${CC:-cc}} $arg /tmp/f$$.c 2>/dev/null | grep '^#.*stdio.h' | tail -1`
110       case "$ok" in
111       "") ;;
112       *)
113         cpp_c="${REALCC:-${CC:-cc}} $arg"
114         echo cpp_c="'$cpp_c'" >> $rc
115         break;;
116       esac
117     done
118     rm -f /tmp/f$$.c
119   fi
120 fi
121
122 # some Linux systems have deprecated egrep in favor of grep -E
123 # but not everyone supports that
124 case "`echo bmake | egrep 'a|b' 2>&1`" in
125 bmake) ;;
126 *) egrep() { grep -E "$@"; }
127 esac
128
129 clean_up() {
130   trap "" 2 3
131   trap 0
132   if [ -s $EF ]; then
133           egrep -vi "included from|warning" $EF > ${EF}2
134           if [ -s ${EF}2 ]; then
135                   cat $EF >&2
136                   rm -f .depend
137                   ests=1
138           fi
139   fi
140   rm -f $TF $EF*
141   exit ${ests:-0}
142 }
143
144 # this lot does not work on HPsUX - complain to Hp.
145 trap clean_up 0
146 trap exit 2 3
147
148 get_incs() {
149   case "$cpp" in
150   grep)
151     # set IGNORE="<" to skip system includes
152     egrep '^#[  ]*include' $* | egrep -v "$IGNORE" | \
153       sed -e 's/^.*include[^"<]*["<]//' -e 's/[">].*//g';;
154   *)
155     # $cpp (eg. /usr/lib/cpp or cc -E) should produce output like:
156     # 1 "/usr/include/stdio.h" 2
157     # set IGNORE=/usr/include to skip system includes
158     $cpp $cpp_opts $cc_include $* 2>> $EF | egrep '^#.*\.h"' | sed 's,^#.*"\(.*\)".*,\1,' |
159       egrep -v "$IGNORE" | sort -u;;
160   esac
161 }
162
163 gen_deps() {
164   llen=$1
165   shift
166
167   for ifile in $*
168   do
169     case "$cpp" in
170     grep)
171       # this lot is not needed if not using grep.
172       for dir in $srcdir $dirlist /usr/include
173       do
174         [ -f "$dir/$ifile" ] && break
175       done
176
177       if [ ! -f "$dir/$ifile" ]; then
178         # produce a useful error message (useful to emacs or error)
179         iline=`grep -n ".*include.*[\"<]$ifile[\">]" $file | cut -d: -f1`
180         echo "\"$file\", line $iline: cannot find include file \"$ifile\"" >> $EF
181         # no point adding to dependency list as the resulting makefile
182         # would not work anyway...
183         continue
184       fi
185       ifile=$dir/$ifile
186       
187       # check whether we have done it yet
188       case `grep "$ifile" $TF` in
189       "") echo "$ifile" >> $TF;;
190       *)        continue;;              # no repeats...
191       esac
192       ;;
193     esac
194     
195     len=`expr "$ifile " : '.*'`
196     if [ "`expr $llen + $len`" -gt ${width:-76} ]; then
197       echo "\\" >> .depend
198       echo $N " $C" >> .depend
199       llen=8
200     fi
201     echo $N "$ifile $C" >> .depend
202     llen=`expr $llen + $len`
203     
204     case "$cpp" in
205     grep)
206       # this lot is not needed unless using grep.
207       ilist=`get_incs $ifile` # recurse needed?
208       [ "$ilist" ] && llen=`gen_deps $llen $ilist`
209       ;;
210     esac
211   done
212   echo $llen
213 }
214
215 for f in makefile Makefile
216 do
217   test -s $f && { MAKEFILE=$f; break; }
218 done
219
220 MAKEFILE=${MAKEFILE:-makefile}
221 IGNORE=${IGNORE:-"^-"}          # won't happen
222 obj=o
223 cpp_opts=                       # incase cpp != grep
224 vpath=
225 append=
226 progDep=
227
228 set -- `getopt "AanNV:s:w:o:I:D:b:f:i:p" "$@"`
229 for key in "$@"
230 do
231   case $key in
232   --)   shift; break;;
233   -A)   Include=;;              # cat .depend >> $MAKEFILE
234   -a)   append=yes; shift;;
235   -n)   shift;;                 # ignore rc
236   -N)   update=no; shift;;      # don't update $MAKEFILE
237   -I)   cpp_opts="$cpp_opts$1$2 "; dirlist="$dirlist $2"; shift 2;;
238   -o)   obj=$2; shift 2;;
239   -s)   shift 2;;               # can't handle it anyway...
240   -w)   width=$2; shift 2;;
241   -f)   MAKEFILE=$2; shift 2;;
242   -b)   BASEDIR=$2; shift 2;;
243   -i)   IGNORE="$2"; shift 2;;  # ignore headers matching this...
244   -D)   cpp_opts="$cpp_opts$1$2 "; shift 2;;
245   -V)   VPATH="$2"; shift 2;;   # where to look for files
246   -p)   progDep=yes; shift;;
247   esac
248 done
249
250 [ "$VPATH" ] && vpath=`IFS=:; set -- $VPATH; echo $*`
251
252 [ "$append" ] || > .depend
253
254 for file in $*
255 do
256   cpp=
257   suffix=`expr $file : '.*\.\([^.]*\)'`
258
259   eval cpp=\"\${cpp_${suffix}:-grep}\"
260   
261   if [ ! -f $file -a "$vpath" ]; then
262     for d in . $vpath
263     do
264       [ -f $d/$file ] && { file=$d/$file; break; }
265     done
266   fi
267   srcdir=`dirname $file`
268   base=`basename $file .$suffix`
269   
270   ilist=`get_incs $file`
271
272   if [ "$ilist" ]; then
273     > $TF
274     if [ "$progDep" ]; then
275       echo "$base:      $file \\" >> .depend
276     else
277       echo "$base.$obj: $file \\" >> .depend
278     fi
279     echo $N "   $C" >> .depend
280     llen=8
281     llen=`gen_deps $llen $ilist`
282     echo >> .depend
283     echo >> .depend
284   elif [ "$progDep" ]; then
285     echo "$base:        $file" >> .depend
286     echo >> .depend
287   fi
288 done
289
290 if [ -s .depend ]; then
291   # ./foo.h looks ugly
292   mv .depend $TF
293   { test "$BASEDIR" && sed -e "s;$BASEDIR;\$(BASEDIR);g" $TF || cat $TF; } |
294     sed 's;\([^.]\)\./;\1;g' > .depend 
295
296   #
297   # Save the manually updated section of the makefile
298   #
299   if [ x$update != xno ]; then
300     trap "" 2                   # don't die if we got this far
301
302     # if make doesn't support include, then append our deps...
303     depended=`grep 'include.*\.depend' $MAKEFILE`
304     test "$depended" && clean_up
305   
306     sed '/^# DO NOT DELETE.*depend.*$/,$d' < $MAKEFILE > $TF
307     mv $TF $MAKEFILE
308     cat <<! >> $MAKEFILE
309 # DO NOT DELETE THIS LINE -- make depend depends on it
310 # Do not edit anything below, it was added automagically by $Myname.
311
312 !
313   
314     case "$Include" in
315     "") cat .depend >> $MAKEFILE;;
316     .include)   echo '.include ".depend"' >> $MAKEFILE;;
317     include)    echo include .depend >> $MAKEFILE;;
318     esac
319   fi
320 fi
321 clean_up