mkdeps.sh revision 256281
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.23 2002/11/29 06:58:59 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 58Myname=`basename $0 .sh` 59Mydir=`dirname $0` 60 61case `echo -n .` in 62-n*) N=; C="\c";; 63*) N=-n; C=;; 64esac 65 66cc_include=-I/usr/include 67 68TF=/tmp/dep.$$ 69EF=/tmp/deperr.$$ 70> $EF 71 72case "$*" in 73*-n*) # don't use rc file 74 rc=/dev/null 75 norc=yes;; 76*) 77 rc=$Mydir/.${Myname}rc 78 ;; 79esac 80 81update= 82Include=include 83 84if [ x"$norc" = x -a -f $rc ]; then 85 . $rc 86else 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 120fi 121 122clean_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 131 fi 132 fi 133 rm -f $TF $EF* 134 exit ${ests:-0} 135} 136 137# this lot does not work on HPsUX - complain to Hp. 138trap clean_up 0 139trap exit 2 3 140 141get_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';; 147 *) 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 154} 155 156gen_deps() { 157 llen=$1 158 shift 159 160 for ifile in $* 161 do 162 case "$cpp" in 163 grep) 164 # this lot is not needed if not using grep. 165 for dir in $srcdir $dirlist /usr/include 166 do 167 [ -f "$dir/$ifile" ] && break 168 done 169 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 177 fi 178 ifile=$dir/$ifile 179 180 # check whether we have done it yet 181 case `grep "$ifile" $TF` in 182 "") echo "$ifile" >> $TF;; 183 *) continue;; # no repeats... 184 esac 185 ;; 186 esac 187 188 len=`expr "$ifile " : '.*'` 189 if [ "`expr $llen + $len`" -gt ${width:-76} ]; then 190 echo "\\" >> .depend 191 echo $N " $C" >> .depend 192 llen=8 193 fi 194 echo $N "$ifile $C" >> .depend 195 llen=`expr $llen + $len` 196 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` 202 ;; 203 esac 204 done 205 echo $llen 206} 207 208for f in makefile Makefile 209do 210 test -s $f && { MAKEFILE=$f; break; } 211done 212 213MAKEFILE=${MAKEFILE:-makefile} 214IGNORE=${IGNORE:-"^-"} # won't happen 215obj=o 216cpp_opts= # incase cpp != grep 217vpath= 218append= 219progDep= 220 221set -- `getopt "AanNV:s:w:o:I:D:b:f:i:p" "$@"` 222for key in "$@" 223do 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 241done 242 243[ "$VPATH" ] && vpath=`IFS=:; set -- $VPATH; echo $*` 244 245[ "$append" ] || > .depend 246 247for file in $* 248do 249 cpp= 250 suffix=`expr $file : '.*\.\([^.]*\)'` 251 252 eval cpp=\"\${cpp_${suffix}:-grep}\" 253 254 if [ ! -f $file -a "$vpath" ]; then 255 for d in . $vpath 256 do 257 [ -f $d/$file ] && { file=$d/$file; break; } 258 done 259 fi 260 srcdir=`dirname $file` 261 base=`basename $file .$suffix` 262 263 ilist=`get_incs $file` 264 265 if [ "$ilist" ]; then 266 > $TF 267 if [ "$progDep" ]; then 268 echo "$base: $file \\" >> .depend 269 else 270 echo "$base.$obj: $file \\" >> .depend 271 fi 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 280 fi 281done 282 283if [ -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 288 289 # 290 # Save the manually updated section of the makefile 291 # 292 if [ x$update != xno ]; then 293 trap "" 2 # don't die if we got this far 294 295 # if make doesn't support include, then append our deps... 296 depended=`grep 'include.*\.depend' $MAKEFILE` 297 test "$depended" && clean_up 298 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. 304 305! 306 307 case "$Include" in 308 "") cat .depend >> $MAKEFILE;; 309 .include) echo '.include ".depend"' >> $MAKEFILE;; 310 include) echo include .depend >> $MAKEFILE;; 311 esac 312 fi 313fi 314clean_up 315