mkdeps.sh revision 236769
1236769Sobrien: 2236769Sobrien# NAME: 3236769Sobrien# mkdeps - generate dependencies 4236769Sobrien# 5236769Sobrien# SYNOPSIS: 6236769Sobrien# mkdeps [options] file ... 7236769Sobrien# 8236769Sobrien# DESCRIPTION: 9236769Sobrien# This script updates "makefile" with dependencies for 10236769Sobrien# "file"(s). It borrows ideas from various makedepend scripts 11236769Sobrien# and should be compatible with most. 12236769Sobrien# 13236769Sobrien# By default we use grep to extract include file names from 14236769Sobrien# source files. We source an "rc" file '$Mydir/.${Myname}rc' which 15236769Sobrien# can contain variable assignments such as: 16236769Sobrien#.nf 17236769Sobrien# 18236769Sobrien# cpp_c=/usr/lib/cpp 19236769Sobrien# cpp_cc=g++ -E 20236769Sobrien# ... 21236769Sobrien# 22236769Sobrien#.fi 23236769Sobrien# If the variable 'cpp_$suffix' is set, we use it as our cpp in 24236769Sobrien# place of grep. The program referenced by these variables are 25236769Sobrien# expected to produce output like: 26236769Sobrien#.nf 27236769Sobrien# 28236769Sobrien# # 10 \"/usr/include/stdio.h\" 1 29236769Sobrien# 30236769Sobrien#.fi 31236769Sobrien# This allows us to skip most of our processing. For lex,yacc 32236769Sobrien# and other source files, grep is probably just as quick and 33236769Sobrien# certainly more portable. 34236769Sobrien# 35236769Sobrien# If the "rc" file does not exist, we create it and attempt to 36236769Sobrien# find cpp or an equivalent cc invocation to assign to 'cpp_c'. 37236769Sobrien# 38236769Sobrien# AUTHOR: 39236769Sobrien# Simon J. Gerraty <sjg@zen.void.oz.au> 40236769Sobrien# 41236769Sobrien 42236769Sobrien# RCSid: 43236769Sobrien# $Id: mkdeps.sh,v 1.23 2002/11/29 06:58:59 sjg Exp $ 44236769Sobrien# 45236769Sobrien# @(#) Copyright (c) 1993 Simon J. Gerraty 46236769Sobrien# 47236769Sobrien# This file is provided in the hope that it will 48236769Sobrien# be of use. There is absolutely NO WARRANTY. 49236769Sobrien# Permission to copy, redistribute or otherwise 50236769Sobrien# use this file is hereby granted provided that 51236769Sobrien# the above copyright notice and this notice are 52236769Sobrien# left intact. 53236769Sobrien# 54236769Sobrien# Please send copies of changes and bug-fixes to: 55236769Sobrien# sjg@zen.void.oz.au 56236769Sobrien# 57236769Sobrien 58236769SobrienMyname=`basename $0 .sh` 59236769SobrienMydir=`dirname $0` 60236769Sobrien 61236769Sobriencase `echo -n .` in 62236769Sobrien-n*) N=; C="\c";; 63236769Sobrien*) N=-n; C=;; 64236769Sobrienesac 65236769Sobrien 66236769Sobriencc_include=-I/usr/include 67236769Sobrien 68236769SobrienTF=/tmp/dep.$$ 69236769SobrienEF=/tmp/deperr.$$ 70236769Sobrien> $EF 71236769Sobrien 72236769Sobriencase "$*" in 73236769Sobrien*-n*) # don't use rc file 74236769Sobrien rc=/dev/null 75236769Sobrien norc=yes;; 76236769Sobrien*) 77236769Sobrien rc=$Mydir/.${Myname}rc 78236769Sobrien ;; 79236769Sobrienesac 80236769Sobrien 81236769Sobrienupdate= 82236769SobrienInclude=include 83236769Sobrien 84236769Sobrienif [ x"$norc" = x -a -f $rc ]; then 85236769Sobrien . $rc 86236769Sobrienelse 87236769Sobrien # if /usr/lib/cpp or equivalent is available it is better than 88236769Sobrien # grepping .c files. 89236769Sobrien # See what (if anything) works on this system... 90236769Sobrien echo : > $rc 91236769Sobrien echo "# pre-processor for .c files" >> $rc 92236769Sobrien # try a couple of sane places first 93236769Sobrien for d in /usr/libexec /usr/lib /usr/bin /lib /usr/ccs/bin 94236769Sobrien do 95236769Sobrien cpp_c=$d/cpp 96236769Sobrien [ -x $cpp_c ] && break 97236769Sobrien done 98236769Sobrien 99236769Sobrien if [ -x $cpp_c ]; then 100236769Sobrien echo cpp_c=$cpp_c >> $rc 101236769Sobrien else 102236769Sobrien cpp_c= 103236769Sobrien # rats see if cc can be used 104236769Sobrien echo "#include <stdio.h>" > /tmp/f$$.c 105236769Sobrien echo "main() { return 0; }" >> /tmp/f$$.c 106236769Sobrien # try some sensible args to cc 107236769Sobrien for arg in -E -P -M 108236769Sobrien do 109236769Sobrien ok=`${REALCC:-${CC:-cc}} $arg /tmp/f$$.c 2>/dev/null | grep '^#.*stdio.h' | tail -1` 110236769Sobrien case "$ok" in 111236769Sobrien "") ;; 112236769Sobrien *) 113236769Sobrien cpp_c="${REALCC:-${CC:-cc}} $arg" 114236769Sobrien echo cpp_c="'$cpp_c'" >> $rc 115236769Sobrien break;; 116236769Sobrien esac 117236769Sobrien done 118236769Sobrien rm -f /tmp/f$$.c 119236769Sobrien fi 120236769Sobrienfi 121236769Sobrien 122236769Sobrienclean_up() { 123236769Sobrien trap "" 2 3 124236769Sobrien trap 0 125236769Sobrien if [ -s $EF ]; then 126236769Sobrien egrep -vi "included from|warning" $EF > ${EF}2 127236769Sobrien if [ -s ${EF}2 ]; then 128236769Sobrien cat $EF >&2 129236769Sobrien rm -f .depend 130236769Sobrien ests=1 131236769Sobrien fi 132236769Sobrien fi 133236769Sobrien rm -f $TF $EF* 134236769Sobrien exit ${ests:-0} 135236769Sobrien} 136236769Sobrien 137236769Sobrien# this lot does not work on HPsUX - complain to Hp. 138236769Sobrientrap clean_up 0 139236769Sobrientrap exit 2 3 140236769Sobrien 141236769Sobrienget_incs() { 142236769Sobrien case "$cpp" in 143236769Sobrien grep) 144236769Sobrien # set IGNORE="<" to skip system includes 145236769Sobrien egrep '^#[ ]*include' $* | egrep -v "$IGNORE" | \ 146236769Sobrien sed -e 's/^.*include[^"<]*["<]//' -e 's/[">].*//g';; 147236769Sobrien *) 148236769Sobrien # $cpp (eg. /usr/lib/cpp or cc -E) should produce output like: 149236769Sobrien # 1 "/usr/include/stdio.h" 2 150236769Sobrien # set IGNORE=/usr/include to skip system includes 151236769Sobrien $cpp $cpp_opts $cc_include $* 2>> $EF | egrep '^#.*\.h"' | sed 's,^#.*"\(.*\)".*,\1,' | 152236769Sobrien egrep -v "$IGNORE" | sort -u;; 153236769Sobrien esac 154236769Sobrien} 155236769Sobrien 156236769Sobriengen_deps() { 157236769Sobrien llen=$1 158236769Sobrien shift 159236769Sobrien 160236769Sobrien for ifile in $* 161236769Sobrien do 162236769Sobrien case "$cpp" in 163236769Sobrien grep) 164236769Sobrien # this lot is not needed if not using grep. 165236769Sobrien for dir in $srcdir $dirlist /usr/include 166236769Sobrien do 167236769Sobrien [ -f "$dir/$ifile" ] && break 168236769Sobrien done 169236769Sobrien 170236769Sobrien if [ ! -f "$dir/$ifile" ]; then 171236769Sobrien # produce a useful error message (useful to emacs or error) 172236769Sobrien iline=`grep -n ".*include.*[\"<]$ifile[\">]" $file | cut -d: -f1` 173236769Sobrien echo "\"$file\", line $iline: cannot find include file \"$ifile\"" >> $EF 174236769Sobrien # no point adding to dependency list as the resulting makefile 175236769Sobrien # would not work anyway... 176236769Sobrien continue 177236769Sobrien fi 178236769Sobrien ifile=$dir/$ifile 179236769Sobrien 180236769Sobrien # check whether we have done it yet 181236769Sobrien case `grep "$ifile" $TF` in 182236769Sobrien "") echo "$ifile" >> $TF;; 183236769Sobrien *) continue;; # no repeats... 184236769Sobrien esac 185236769Sobrien ;; 186236769Sobrien esac 187236769Sobrien 188236769Sobrien len=`expr "$ifile " : '.*'` 189236769Sobrien if [ "`expr $llen + $len`" -gt ${width:-76} ]; then 190236769Sobrien echo "\\" >> .depend 191236769Sobrien echo $N " $C" >> .depend 192236769Sobrien llen=8 193236769Sobrien fi 194236769Sobrien echo $N "$ifile $C" >> .depend 195236769Sobrien llen=`expr $llen + $len` 196236769Sobrien 197236769Sobrien case "$cpp" in 198236769Sobrien grep) 199236769Sobrien # this lot is not needed unless using grep. 200236769Sobrien ilist=`get_incs $ifile` # recurse needed? 201236769Sobrien [ "$ilist" ] && llen=`gen_deps $llen $ilist` 202236769Sobrien ;; 203236769Sobrien esac 204236769Sobrien done 205236769Sobrien echo $llen 206236769Sobrien} 207236769Sobrien 208236769Sobrienfor f in makefile Makefile 209236769Sobriendo 210236769Sobrien test -s $f && { MAKEFILE=$f; break; } 211236769Sobriendone 212236769Sobrien 213236769SobrienMAKEFILE=${MAKEFILE:-makefile} 214236769SobrienIGNORE=${IGNORE:-"^-"} # won't happen 215236769Sobrienobj=o 216236769Sobriencpp_opts= # incase cpp != grep 217236769Sobrienvpath= 218236769Sobrienappend= 219236769SobrienprogDep= 220236769Sobrien 221236769Sobrienset -- `getopt "AanNV:s:w:o:I:D:b:f:i:p" "$@"` 222236769Sobrienfor key in "$@" 223236769Sobriendo 224236769Sobrien case $key in 225236769Sobrien --) shift; break;; 226236769Sobrien -A) Include=;; # cat .depend >> $MAKEFILE 227236769Sobrien -a) append=yes; shift;; 228236769Sobrien -n) shift;; # ignore rc 229236769Sobrien -N) update=no; shift;; # don't update $MAKEFILE 230236769Sobrien -I) cpp_opts="$cpp_opts$1$2 "; dirlist="$dirlist $2"; shift 2;; 231236769Sobrien -o) obj=$2; shift 2;; 232236769Sobrien -s) shift 2;; # can't handle it anyway... 233236769Sobrien -w) width=$2; shift 2;; 234236769Sobrien -f) MAKEFILE=$2; shift 2;; 235236769Sobrien -b) BASEDIR=$2; shift 2;; 236236769Sobrien -i) IGNORE="$2"; shift 2;; # ignore headers matching this... 237236769Sobrien -D) cpp_opts="$cpp_opts$1$2 "; shift 2;; 238236769Sobrien -V) VPATH="$2"; shift 2;; # where to look for files 239236769Sobrien -p) progDep=yes; shift;; 240236769Sobrien esac 241236769Sobriendone 242236769Sobrien 243236769Sobrien[ "$VPATH" ] && vpath=`IFS=:; set -- $VPATH; echo $*` 244236769Sobrien 245236769Sobrien[ "$append" ] || > .depend 246236769Sobrien 247236769Sobrienfor file in $* 248236769Sobriendo 249236769Sobrien cpp= 250236769Sobrien suffix=`expr $file : '.*\.\([^.]*\)'` 251236769Sobrien 252236769Sobrien eval cpp=\"\${cpp_${suffix}:-grep}\" 253236769Sobrien 254236769Sobrien if [ ! -f $file -a "$vpath" ]; then 255236769Sobrien for d in . $vpath 256236769Sobrien do 257236769Sobrien [ -f $d/$file ] && { file=$d/$file; break; } 258236769Sobrien done 259236769Sobrien fi 260236769Sobrien srcdir=`dirname $file` 261236769Sobrien base=`basename $file .$suffix` 262236769Sobrien 263236769Sobrien ilist=`get_incs $file` 264236769Sobrien 265236769Sobrien if [ "$ilist" ]; then 266236769Sobrien > $TF 267236769Sobrien if [ "$progDep" ]; then 268236769Sobrien echo "$base: $file \\" >> .depend 269236769Sobrien else 270236769Sobrien echo "$base.$obj: $file \\" >> .depend 271236769Sobrien fi 272236769Sobrien echo $N " $C" >> .depend 273236769Sobrien llen=8 274236769Sobrien llen=`gen_deps $llen $ilist` 275236769Sobrien echo >> .depend 276236769Sobrien echo >> .depend 277236769Sobrien elif [ "$progDep" ]; then 278236769Sobrien echo "$base: $file" >> .depend 279236769Sobrien echo >> .depend 280236769Sobrien fi 281236769Sobriendone 282236769Sobrien 283236769Sobrienif [ -s .depend ]; then 284236769Sobrien # ./foo.h looks ugly 285236769Sobrien mv .depend $TF 286236769Sobrien { test "$BASEDIR" && sed -e "s;$BASEDIR;\$(BASEDIR);g" $TF || cat $TF; } | 287236769Sobrien sed 's;\([^.]\)\./;\1;g' > .depend 288236769Sobrien 289236769Sobrien # 290236769Sobrien # Save the manually updated section of the makefile 291236769Sobrien # 292236769Sobrien if [ x$update != xno ]; then 293236769Sobrien trap "" 2 # don't die if we got this far 294236769Sobrien 295236769Sobrien # if make doesn't support include, then append our deps... 296236769Sobrien depended=`grep 'include.*\.depend' $MAKEFILE` 297236769Sobrien test "$depended" && clean_up 298236769Sobrien 299236769Sobrien sed '/^# DO NOT DELETE.*depend.*$/,$d' < $MAKEFILE > $TF 300236769Sobrien mv $TF $MAKEFILE 301236769Sobrien cat <<! >> $MAKEFILE 302236769Sobrien# DO NOT DELETE THIS LINE -- make depend depends on it 303236769Sobrien# Do not edit anything below, it was added automagically by $Myname. 304236769Sobrien 305236769Sobrien! 306236769Sobrien 307236769Sobrien case "$Include" in 308236769Sobrien "") cat .depend >> $MAKEFILE;; 309236769Sobrien .include) echo '.include ".depend"' >> $MAKEFILE;; 310236769Sobrien include) echo include .depend >> $MAKEFILE;; 311236769Sobrien esac 312236769Sobrien fi 313236769Sobrienfi 314236769Sobrienclean_up 315