xref: /dragonfly/contrib/bmake/mkdeps.sh (revision 6eef5f0c)
101e196c8SJohn Marino:
201e196c8SJohn Marino# NAME:
301e196c8SJohn Marino#	mkdeps - generate dependencies
401e196c8SJohn Marino#
501e196c8SJohn Marino# SYNOPSIS:
601e196c8SJohn Marino#	mkdeps [options] file ...
701e196c8SJohn Marino#
801e196c8SJohn Marino# DESCRIPTION:
901e196c8SJohn Marino#	This script updates "makefile" with dependencies for
1001e196c8SJohn Marino#	"file"(s).  It borrows ideas from various makedepend scripts
1101e196c8SJohn Marino#	and should be compatible with most.
1201e196c8SJohn Marino#
1301e196c8SJohn Marino#	By default we use grep to extract include file names from
1401e196c8SJohn Marino#	source files.  We source an "rc" file '$Mydir/.${Myname}rc' which
1501e196c8SJohn Marino#	can contain variable assignments such as:
1601e196c8SJohn Marino#.nf
1701e196c8SJohn Marino#
1801e196c8SJohn Marino#	cpp_c=/usr/lib/cpp
1901e196c8SJohn Marino#	cpp_cc=g++ -E
2001e196c8SJohn Marino#	...
2101e196c8SJohn Marino#
2201e196c8SJohn Marino#.fi
2301e196c8SJohn Marino#	If the variable 'cpp_$suffix' is set, we use it as our cpp in
2401e196c8SJohn Marino#	place of grep.  The program referenced by these variables are
2501e196c8SJohn Marino#	expected to produce output like:
2601e196c8SJohn Marino#.nf
2701e196c8SJohn Marino#
2801e196c8SJohn Marino#	# 10 \"/usr/include/stdio.h\" 1
2901e196c8SJohn Marino#
3001e196c8SJohn Marino#.fi
3101e196c8SJohn Marino#	This allows us to skip most of our processing.  For lex,yacc
3201e196c8SJohn Marino#	and other source files, grep is probably just as quick and
3301e196c8SJohn Marino#	certainly more portable.
3401e196c8SJohn Marino#
3501e196c8SJohn Marino#	If the "rc" file does not exist, we create it and attempt to
3601e196c8SJohn Marino#	find cpp or an equivalent cc invocation to assign to 'cpp_c'.
3701e196c8SJohn Marino#
3801e196c8SJohn Marino# AUTHOR:
3901e196c8SJohn Marino#	Simon J. Gerraty <sjg@zen.void.oz.au>
4001e196c8SJohn Marino#
4101e196c8SJohn Marino
4201e196c8SJohn Marino# RCSid:
43*6eef5f0cSAntonio Huete Jimenez#	$Id: mkdeps.sh,v 1.24 2022/09/09 18:44:56 sjg Exp $
4401e196c8SJohn Marino#
4501e196c8SJohn Marino#	@(#) Copyright (c) 1993 Simon J. Gerraty
4601e196c8SJohn Marino#
4701e196c8SJohn Marino#	This file is provided in the hope that it will
4801e196c8SJohn Marino#	be of use.  There is absolutely NO WARRANTY.
4901e196c8SJohn Marino#	Permission to copy, redistribute or otherwise
5001e196c8SJohn Marino#	use this file is hereby granted provided that
5101e196c8SJohn Marino#	the above copyright notice and this notice are
5201e196c8SJohn Marino#	left intact.
5301e196c8SJohn Marino#
5401e196c8SJohn Marino#	Please send copies of changes and bug-fixes to:
5501e196c8SJohn Marino#	sjg@zen.void.oz.au
5601e196c8SJohn Marino#
5701e196c8SJohn Marino
5801e196c8SJohn MarinoMyname=`basename $0 .sh`
5901e196c8SJohn MarinoMydir=`dirname $0`
6001e196c8SJohn Marino
6101e196c8SJohn Marinocase `echo -n .` in
6201e196c8SJohn Marino-n*)	N=; C="\c";;
6301e196c8SJohn Marino*)	N=-n; C=;;
6401e196c8SJohn Marinoesac
6501e196c8SJohn Marino
6601e196c8SJohn Marinocc_include=-I/usr/include
6701e196c8SJohn Marino
6801e196c8SJohn MarinoTF=/tmp/dep.$$
6901e196c8SJohn MarinoEF=/tmp/deperr.$$
7001e196c8SJohn Marino> $EF
7101e196c8SJohn Marino
7201e196c8SJohn Marinocase "$*" in
7301e196c8SJohn Marino*-n*)				# don't use rc file
7401e196c8SJohn Marino  rc=/dev/null
7501e196c8SJohn Marino  norc=yes;;
7601e196c8SJohn Marino*)
7701e196c8SJohn Marino  rc=$Mydir/.${Myname}rc
7801e196c8SJohn Marino  ;;
7901e196c8SJohn Marinoesac
8001e196c8SJohn Marino
8101e196c8SJohn Marinoupdate=
8201e196c8SJohn MarinoInclude=include
8301e196c8SJohn Marino
8401e196c8SJohn Marinoif [ x"$norc" = x -a -f $rc ]; then
8501e196c8SJohn Marino  . $rc
8601e196c8SJohn Marinoelse
8701e196c8SJohn Marino  # if /usr/lib/cpp or equivalent is available it is better than
8801e196c8SJohn Marino  # grepping .c files.
8901e196c8SJohn Marino  # See what (if anything) works on this system...
9001e196c8SJohn Marino  echo : > $rc
9101e196c8SJohn Marino  echo "# pre-processor for .c files" >> $rc
9201e196c8SJohn Marino  # try a couple of sane places first
9301e196c8SJohn Marino  for d in /usr/libexec /usr/lib /usr/bin /lib /usr/ccs/bin
9401e196c8SJohn Marino  do
9501e196c8SJohn Marino    cpp_c=$d/cpp
9601e196c8SJohn Marino    [ -x $cpp_c ] && break
9701e196c8SJohn Marino  done
9801e196c8SJohn Marino
9901e196c8SJohn Marino  if [ -x $cpp_c ]; then
10001e196c8SJohn Marino    echo cpp_c=$cpp_c >> $rc
10101e196c8SJohn Marino  else
10201e196c8SJohn Marino    cpp_c=
10301e196c8SJohn Marino    # rats see if cc can be used
10401e196c8SJohn Marino    echo "#include <stdio.h>" > /tmp/f$$.c
10501e196c8SJohn Marino    echo "main() { return 0; }" >> /tmp/f$$.c
10601e196c8SJohn Marino    # try some sensible args to cc
10701e196c8SJohn Marino    for arg in -E -P -M
10801e196c8SJohn Marino    do
10901e196c8SJohn Marino      ok=`${REALCC:-${CC:-cc}} $arg /tmp/f$$.c 2>/dev/null | grep '^#.*stdio.h' | tail -1`
11001e196c8SJohn Marino      case "$ok" in
11101e196c8SJohn Marino      "") ;;
11201e196c8SJohn Marino      *)
11301e196c8SJohn Marino        cpp_c="${REALCC:-${CC:-cc}} $arg"
11401e196c8SJohn Marino        echo cpp_c="'$cpp_c'" >> $rc
11501e196c8SJohn Marino        break;;
11601e196c8SJohn Marino      esac
11701e196c8SJohn Marino    done
11801e196c8SJohn Marino    rm -f /tmp/f$$.c
11901e196c8SJohn Marino  fi
12001e196c8SJohn Marinofi
12101e196c8SJohn Marino
122*6eef5f0cSAntonio Huete Jimenez# some Linux systems have deprecated egrep in favor of grep -E
123*6eef5f0cSAntonio Huete Jimenez# but not everyone supports that
124*6eef5f0cSAntonio Huete Jimenezcase "`echo bmake | egrep 'a|b' 2>&1`" in
125*6eef5f0cSAntonio Huete Jimenezbmake) ;;
126*6eef5f0cSAntonio Huete Jimenez*) egrep() { grep -E "$@"; }
127*6eef5f0cSAntonio Huete Jimenezesac
128*6eef5f0cSAntonio Huete Jimenez
12901e196c8SJohn Marinoclean_up() {
13001e196c8SJohn Marino  trap "" 2 3
13101e196c8SJohn Marino  trap 0
13201e196c8SJohn Marino  if [ -s $EF ]; then
13301e196c8SJohn Marino          egrep -vi "included from|warning" $EF > ${EF}2
13401e196c8SJohn Marino          if [ -s ${EF}2 ]; then
13501e196c8SJohn Marino	          cat $EF >&2
13601e196c8SJohn Marino                  rm -f .depend
13701e196c8SJohn Marino                  ests=1
13801e196c8SJohn Marino	  fi
13901e196c8SJohn Marino  fi
14001e196c8SJohn Marino  rm -f $TF $EF*
14101e196c8SJohn Marino  exit ${ests:-0}
14201e196c8SJohn Marino}
14301e196c8SJohn Marino
14401e196c8SJohn Marino# this lot does not work on HPsUX - complain to Hp.
14501e196c8SJohn Marinotrap clean_up 0
14601e196c8SJohn Marinotrap exit 2 3
14701e196c8SJohn Marino
14801e196c8SJohn Marinoget_incs() {
14901e196c8SJohn Marino  case "$cpp" in
15001e196c8SJohn Marino  grep)
15101e196c8SJohn Marino    # set IGNORE="<" to skip system includes
15201e196c8SJohn Marino    egrep '^#[ 	]*include' $* | egrep -v "$IGNORE" | \
15301e196c8SJohn Marino      sed -e 's/^.*include[^"<]*["<]//' -e 's/[">].*//g';;
15401e196c8SJohn Marino  *)
15501e196c8SJohn Marino    # $cpp (eg. /usr/lib/cpp or cc -E) should produce output like:
15601e196c8SJohn Marino    # 1 "/usr/include/stdio.h" 2
15701e196c8SJohn Marino    # set IGNORE=/usr/include to skip system includes
15801e196c8SJohn Marino    $cpp $cpp_opts $cc_include $* 2>> $EF | egrep '^#.*\.h"' | sed 's,^#.*"\(.*\)".*,\1,' |
15901e196c8SJohn Marino      egrep -v "$IGNORE" | sort -u;;
16001e196c8SJohn Marino  esac
16101e196c8SJohn Marino}
16201e196c8SJohn Marino
16301e196c8SJohn Marinogen_deps() {
16401e196c8SJohn Marino  llen=$1
16501e196c8SJohn Marino  shift
16601e196c8SJohn Marino
16701e196c8SJohn Marino  for ifile in $*
16801e196c8SJohn Marino  do
16901e196c8SJohn Marino    case "$cpp" in
17001e196c8SJohn Marino    grep)
17101e196c8SJohn Marino      # this lot is not needed if not using grep.
17201e196c8SJohn Marino      for dir in $srcdir $dirlist /usr/include
17301e196c8SJohn Marino      do
17401e196c8SJohn Marino        [ -f "$dir/$ifile" ] && break
17501e196c8SJohn Marino      done
17601e196c8SJohn Marino
17701e196c8SJohn Marino      if [ ! -f "$dir/$ifile" ]; then
17801e196c8SJohn Marino        # produce a useful error message (useful to emacs or error)
17901e196c8SJohn Marino        iline=`grep -n ".*include.*[\"<]$ifile[\">]" $file | cut -d: -f1`
18001e196c8SJohn Marino        echo "\"$file\", line $iline: cannot find include file \"$ifile\"" >> $EF
18101e196c8SJohn Marino        # no point adding to dependency list as the resulting makefile
18201e196c8SJohn Marino        # would not work anyway...
18301e196c8SJohn Marino        continue
18401e196c8SJohn Marino      fi
18501e196c8SJohn Marino      ifile=$dir/$ifile
18601e196c8SJohn Marino
18701e196c8SJohn Marino      # check whether we have done it yet
18801e196c8SJohn Marino      case `grep "$ifile" $TF` in
18901e196c8SJohn Marino      "") echo "$ifile" >> $TF;;
19001e196c8SJohn Marino      *)	continue;;		# no repeats...
19101e196c8SJohn Marino      esac
19201e196c8SJohn Marino      ;;
19301e196c8SJohn Marino    esac
19401e196c8SJohn Marino
19501e196c8SJohn Marino    len=`expr "$ifile " : '.*'`
19601e196c8SJohn Marino    if [ "`expr $llen + $len`" -gt ${width:-76} ]; then
19701e196c8SJohn Marino      echo "\\" >> .depend
19801e196c8SJohn Marino      echo $N "	$C" >> .depend
19901e196c8SJohn Marino      llen=8
20001e196c8SJohn Marino    fi
20101e196c8SJohn Marino    echo $N "$ifile $C" >> .depend
20201e196c8SJohn Marino    llen=`expr $llen + $len`
20301e196c8SJohn Marino
20401e196c8SJohn Marino    case "$cpp" in
20501e196c8SJohn Marino    grep)
20601e196c8SJohn Marino      # this lot is not needed unless using grep.
20701e196c8SJohn Marino      ilist=`get_incs $ifile` # recurse needed?
20801e196c8SJohn Marino      [ "$ilist" ] && llen=`gen_deps $llen $ilist`
20901e196c8SJohn Marino      ;;
21001e196c8SJohn Marino    esac
21101e196c8SJohn Marino  done
21201e196c8SJohn Marino  echo $llen
21301e196c8SJohn Marino}
21401e196c8SJohn Marino
21501e196c8SJohn Marinofor f in makefile Makefile
21601e196c8SJohn Marinodo
21701e196c8SJohn Marino  test -s $f && { MAKEFILE=$f; break; }
21801e196c8SJohn Marinodone
21901e196c8SJohn Marino
22001e196c8SJohn MarinoMAKEFILE=${MAKEFILE:-makefile}
22101e196c8SJohn MarinoIGNORE=${IGNORE:-"^-"}		# won't happen
22201e196c8SJohn Marinoobj=o
22301e196c8SJohn Marinocpp_opts=			# incase cpp != grep
22401e196c8SJohn Marinovpath=
22501e196c8SJohn Marinoappend=
22601e196c8SJohn MarinoprogDep=
22701e196c8SJohn Marino
22801e196c8SJohn Marinoset -- `getopt "AanNV:s:w:o:I:D:b:f:i:p" "$@"`
22901e196c8SJohn Marinofor key in "$@"
23001e196c8SJohn Marinodo
23101e196c8SJohn Marino  case $key in
23201e196c8SJohn Marino  --)	shift; break;;
23301e196c8SJohn Marino  -A)	Include=;;		# cat .depend >> $MAKEFILE
23401e196c8SJohn Marino  -a)	append=yes; shift;;
23501e196c8SJohn Marino  -n)	shift;;			# ignore rc
23601e196c8SJohn Marino  -N)	update=no; shift;;	# don't update $MAKEFILE
23701e196c8SJohn Marino  -I)	cpp_opts="$cpp_opts$1$2 "; dirlist="$dirlist $2"; shift 2;;
23801e196c8SJohn Marino  -o)	obj=$2; shift 2;;
23901e196c8SJohn Marino  -s)	shift 2;;		# can't handle it anyway...
24001e196c8SJohn Marino  -w)	width=$2; shift 2;;
24101e196c8SJohn Marino  -f)	MAKEFILE=$2; shift 2;;
24201e196c8SJohn Marino  -b)	BASEDIR=$2; shift 2;;
24301e196c8SJohn Marino  -i)	IGNORE="$2"; shift 2;;	# ignore headers matching this...
24401e196c8SJohn Marino  -D)	cpp_opts="$cpp_opts$1$2 "; shift 2;;
24501e196c8SJohn Marino  -V)	VPATH="$2"; shift 2;;	# where to look for files
24601e196c8SJohn Marino  -p)	progDep=yes; shift;;
24701e196c8SJohn Marino  esac
24801e196c8SJohn Marinodone
24901e196c8SJohn Marino
25001e196c8SJohn Marino[ "$VPATH" ] && vpath=`IFS=:; set -- $VPATH; echo $*`
25101e196c8SJohn Marino
25201e196c8SJohn Marino[ "$append" ] || > .depend
25301e196c8SJohn Marino
25401e196c8SJohn Marinofor file in $*
25501e196c8SJohn Marinodo
25601e196c8SJohn Marino  cpp=
25701e196c8SJohn Marino  suffix=`expr $file : '.*\.\([^.]*\)'`
25801e196c8SJohn Marino
25901e196c8SJohn Marino  eval cpp=\"\${cpp_${suffix}:-grep}\"
26001e196c8SJohn Marino
26101e196c8SJohn Marino  if [ ! -f $file -a "$vpath" ]; then
26201e196c8SJohn Marino    for d in . $vpath
26301e196c8SJohn Marino    do
26401e196c8SJohn Marino      [ -f $d/$file ] && { file=$d/$file; break; }
26501e196c8SJohn Marino    done
26601e196c8SJohn Marino  fi
26701e196c8SJohn Marino  srcdir=`dirname $file`
26801e196c8SJohn Marino  base=`basename $file .$suffix`
26901e196c8SJohn Marino
27001e196c8SJohn Marino  ilist=`get_incs $file`
27101e196c8SJohn Marino
27201e196c8SJohn Marino  if [ "$ilist" ]; then
27301e196c8SJohn Marino    > $TF
27401e196c8SJohn Marino    if [ "$progDep" ]; then
27501e196c8SJohn Marino      echo "$base:	$file \\" >> .depend
27601e196c8SJohn Marino    else
27701e196c8SJohn Marino      echo "$base.$obj:	$file \\" >> .depend
27801e196c8SJohn Marino    fi
27901e196c8SJohn Marino    echo $N "	$C" >> .depend
28001e196c8SJohn Marino    llen=8
28101e196c8SJohn Marino    llen=`gen_deps $llen $ilist`
28201e196c8SJohn Marino    echo >> .depend
28301e196c8SJohn Marino    echo >> .depend
28401e196c8SJohn Marino  elif [ "$progDep" ]; then
28501e196c8SJohn Marino    echo "$base:	$file" >> .depend
28601e196c8SJohn Marino    echo >> .depend
28701e196c8SJohn Marino  fi
28801e196c8SJohn Marinodone
28901e196c8SJohn Marino
29001e196c8SJohn Marinoif [ -s .depend ]; then
29101e196c8SJohn Marino  # ./foo.h looks ugly
29201e196c8SJohn Marino  mv .depend $TF
29301e196c8SJohn Marino  { test "$BASEDIR" && sed -e "s;$BASEDIR;\$(BASEDIR);g" $TF || cat $TF; } |
29401e196c8SJohn Marino    sed 's;\([^.]\)\./;\1;g' > .depend
29501e196c8SJohn Marino
29601e196c8SJohn Marino  #
29701e196c8SJohn Marino  # Save the manually updated section of the makefile
29801e196c8SJohn Marino  #
29901e196c8SJohn Marino  if [ x$update != xno ]; then
30001e196c8SJohn Marino    trap "" 2			# don't die if we got this far
30101e196c8SJohn Marino
30201e196c8SJohn Marino    # if make doesn't support include, then append our deps...
30301e196c8SJohn Marino    depended=`grep 'include.*\.depend' $MAKEFILE`
30401e196c8SJohn Marino    test "$depended" && clean_up
30501e196c8SJohn Marino
30601e196c8SJohn Marino    sed '/^# DO NOT DELETE.*depend.*$/,$d' < $MAKEFILE > $TF
30701e196c8SJohn Marino    mv $TF $MAKEFILE
30801e196c8SJohn Marino    cat <<! >> $MAKEFILE
30901e196c8SJohn Marino# DO NOT DELETE THIS LINE -- make depend depends on it
31001e196c8SJohn Marino# Do not edit anything below, it was added automagically by $Myname.
31101e196c8SJohn Marino
31201e196c8SJohn Marino!
31301e196c8SJohn Marino
31401e196c8SJohn Marino    case "$Include" in
31501e196c8SJohn Marino    "")	cat .depend >> $MAKEFILE;;
31601e196c8SJohn Marino    .include)	echo '.include ".depend"' >> $MAKEFILE;;
31701e196c8SJohn Marino    include)	echo include .depend >> $MAKEFILE;;
31801e196c8SJohn Marino    esac
31901e196c8SJohn Marino  fi
32001e196c8SJohn Marinofi
32101e196c8SJohn Marinoclean_up
322