ed(1): Sync with FreeBSD.
[dragonfly.git] / contrib / bmake / mkdeps.sh
blobdd87c4f5020ec615808db232b4dd6346f0912a13
2 # NAME:
3 # mkdeps - generate dependencies
5 # SYNOPSIS:
6 # mkdeps [options] file ...
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.
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
18 # cpp_c=/usr/lib/cpp
19 # cpp_cc=g++ -E
20 # ...
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
28 # # 10 \"/usr/include/stdio.h\" 1
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.
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'.
38 # AUTHOR:
39 # Simon J. Gerraty <sjg@zen.void.oz.au>
42 # RCSid:
43 # $Id: mkdeps.sh,v 1.23 2002/11/29 06:58:59 sjg Exp $
45 # @(#) Copyright (c) 1993 Simon J. Gerraty
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.
54 # Please send copies of changes and bug-fixes to:
55 # sjg@zen.void.oz.au
58 Myname=`basename $0 .sh`
59 Mydir=`dirname $0`
61 case `echo -n .` in
62 -n*) N=; C="\c";;
63 *) N=-n; C=;;
64 esac
66 cc_include=-I/usr/include
68 TF=/tmp/dep.$$
69 EF=/tmp/deperr.$$
70 > $EF
72 case "$*" in
73 *-n*) # don't use rc file
74 rc=/dev/null
75 norc=yes;;
77 rc=$Mydir/.${Myname}rc
79 esac
81 update=
82 Include=include
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
95 cpp_c=$d/cpp
96 [ -x $cpp_c ] && break
97 done
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
109 ok=`${REALCC:-${CC:-cc}} $arg /tmp/f$$.c 2>/dev/null | grep '^#.*stdio.h' | tail -1`
110 case "$ok" in
111 "") ;;
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
122 clean_up() {
123 trap "" 2 3
124 trap 0
125 if [ -s $EF ]; then
126 egrep -vi "included from|warning" $EF > ${EF}2
127 if [ -s ${EF}2 ]; then
128 cat $EF >&2
129 rm -f .depend
130 ests=1
133 rm -f $TF $EF*
134 exit ${ests:-0}
137 # this lot does not work on HPsUX - complain to Hp.
138 trap clean_up 0
139 trap exit 2 3
141 get_incs() {
142 case "$cpp" in
143 grep)
144 # set IGNORE="<" to skip system includes
145 egrep '^#[ ]*include' $* | egrep -v "$IGNORE" | \
146 sed -e 's/^.*include[^"<]*["<]//' -e 's/[">].*//g';;
148 # $cpp (eg. /usr/lib/cpp or cc -E) should produce output like:
149 # 1 "/usr/include/stdio.h" 2
150 # set IGNORE=/usr/include to skip system includes
151 $cpp $cpp_opts $cc_include $* 2>> $EF | egrep '^#.*\.h"' | sed 's,^#.*"\(.*\)".*,\1,' |
152 egrep -v "$IGNORE" | sort -u;;
153 esac
156 gen_deps() {
157 llen=$1
158 shift
160 for ifile in $*
162 case "$cpp" in
163 grep)
164 # this lot is not needed if not using grep.
165 for dir in $srcdir $dirlist /usr/include
167 [ -f "$dir/$ifile" ] && break
168 done
170 if [ ! -f "$dir/$ifile" ]; then
171 # produce a useful error message (useful to emacs or error)
172 iline=`grep -n ".*include.*[\"<]$ifile[\">]" $file | cut -d: -f1`
173 echo "\"$file\", line $iline: cannot find include file \"$ifile\"" >> $EF
174 # no point adding to dependency list as the resulting makefile
175 # would not work anyway...
176 continue
178 ifile=$dir/$ifile
180 # check whether we have done it yet
181 case `grep "$ifile" $TF` in
182 "") echo "$ifile" >> $TF;;
183 *) continue;; # no repeats...
184 esac
186 esac
188 len=`expr "$ifile " : '.*'`
189 if [ "`expr $llen + $len`" -gt ${width:-76} ]; then
190 echo "\\" >> .depend
191 echo $N " $C" >> .depend
192 llen=8
194 echo $N "$ifile $C" >> .depend
195 llen=`expr $llen + $len`
197 case "$cpp" in
198 grep)
199 # this lot is not needed unless using grep.
200 ilist=`get_incs $ifile` # recurse needed?
201 [ "$ilist" ] && llen=`gen_deps $llen $ilist`
203 esac
204 done
205 echo $llen
208 for f in makefile Makefile
210 test -s $f && { MAKEFILE=$f; break; }
211 done
213 MAKEFILE=${MAKEFILE:-makefile}
214 IGNORE=${IGNORE:-"^-"} # won't happen
215 obj=o
216 cpp_opts= # incase cpp != grep
217 vpath=
218 append=
219 progDep=
221 set -- `getopt "AanNV:s:w:o:I:D:b:f:i:p" "$@"`
222 for key in "$@"
224 case $key in
225 --) shift; break;;
226 -A) Include=;; # cat .depend >> $MAKEFILE
227 -a) append=yes; shift;;
228 -n) shift;; # ignore rc
229 -N) update=no; shift;; # don't update $MAKEFILE
230 -I) cpp_opts="$cpp_opts$1$2 "; dirlist="$dirlist $2"; shift 2;;
231 -o) obj=$2; shift 2;;
232 -s) shift 2;; # can't handle it anyway...
233 -w) width=$2; shift 2;;
234 -f) MAKEFILE=$2; shift 2;;
235 -b) BASEDIR=$2; shift 2;;
236 -i) IGNORE="$2"; shift 2;; # ignore headers matching this...
237 -D) cpp_opts="$cpp_opts$1$2 "; shift 2;;
238 -V) VPATH="$2"; shift 2;; # where to look for files
239 -p) progDep=yes; shift;;
240 esac
241 done
243 [ "$VPATH" ] && vpath=`IFS=:; set -- $VPATH; echo $*`
245 [ "$append" ] || > .depend
247 for file in $*
249 cpp=
250 suffix=`expr $file : '.*\.\([^.]*\)'`
252 eval cpp=\"\${cpp_${suffix}:-grep}\"
254 if [ ! -f $file -a "$vpath" ]; then
255 for d in . $vpath
257 [ -f $d/$file ] && { file=$d/$file; break; }
258 done
260 srcdir=`dirname $file`
261 base=`basename $file .$suffix`
263 ilist=`get_incs $file`
265 if [ "$ilist" ]; then
266 > $TF
267 if [ "$progDep" ]; then
268 echo "$base: $file \\" >> .depend
269 else
270 echo "$base.$obj: $file \\" >> .depend
272 echo $N " $C" >> .depend
273 llen=8
274 llen=`gen_deps $llen $ilist`
275 echo >> .depend
276 echo >> .depend
277 elif [ "$progDep" ]; then
278 echo "$base: $file" >> .depend
279 echo >> .depend
281 done
283 if [ -s .depend ]; then
284 # ./foo.h looks ugly
285 mv .depend $TF
286 { test "$BASEDIR" && sed -e "s;$BASEDIR;\$(BASEDIR);g" $TF || cat $TF; } |
287 sed 's;\([^.]\)\./;\1;g' > .depend
290 # Save the manually updated section of the makefile
292 if [ x$update != xno ]; then
293 trap "" 2 # don't die if we got this far
295 # if make doesn't support include, then append our deps...
296 depended=`grep 'include.*\.depend' $MAKEFILE`
297 test "$depended" && clean_up
299 sed '/^# DO NOT DELETE.*depend.*$/,$d' < $MAKEFILE > $TF
300 mv $TF $MAKEFILE
301 cat <<! >> $MAKEFILE
302 # DO NOT DELETE THIS LINE -- make depend depends on it
303 # Do not edit anything below, it was added automagically by $Myname.
307 case "$Include" in
308 "") cat .depend >> $MAKEFILE;;
309 .include) echo '.include ".depend"' >> $MAKEFILE;;
310 include) echo include .depend >> $MAKEFILE;;
311 esac
314 clean_up