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 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 122# some Linux systems have deprecated egrep in favor of grep -E 123# but not everyone supports that 124case "`echo bmake | egrep 'a|b' 2>&1`" in 125bmake) ;; 126*) egrep() { grep -E "$@"; } 127esac 128 129clean_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. 145trap clean_up 0 146trap exit 2 3 147 148get_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 163gen_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 215for f in makefile Makefile 216do 217 test -s $f && { MAKEFILE=$f; break; } 218done 219 220MAKEFILE=${MAKEFILE:-makefile} 221IGNORE=${IGNORE:-"^-"} # won't happen 222obj=o 223cpp_opts= # incase cpp != grep 224vpath= 225append= 226progDep= 227 228set -- `getopt "AanNV:s:w:o:I:D:b:f:i:p" "$@"` 229for key in "$@" 230do 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 248done 249 250[ "$VPATH" ] && vpath=`IFS=:; set -- $VPATH; echo $*` 251 252[ "$append" ] || > .depend 253 254for file in $* 255do 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 288done 289 290if [ -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 320fi 321clean_up 322