xref: /freebsd/contrib/bmake/mkdeps.sh (revision 4fde40d9b540ea1a544cb4378a14f2f6da85ca6d)
13955d011SMarcel Moolenaar:
23955d011SMarcel Moolenaar# NAME:
33955d011SMarcel Moolenaar#	mkdeps - generate dependencies
43955d011SMarcel Moolenaar#
53955d011SMarcel Moolenaar# SYNOPSIS:
63955d011SMarcel Moolenaar#	mkdeps [options] file ...
73955d011SMarcel Moolenaar#
83955d011SMarcel Moolenaar# DESCRIPTION:
93955d011SMarcel Moolenaar#	This script updates "makefile" with dependencies for
103955d011SMarcel Moolenaar#	"file"(s).  It borrows ideas from various makedepend scripts
113955d011SMarcel Moolenaar#	and should be compatible with most.
123955d011SMarcel Moolenaar#
133955d011SMarcel Moolenaar#	By default we use grep to extract include file names from
143955d011SMarcel Moolenaar#	source files.  We source an "rc" file '$Mydir/.${Myname}rc' which
153955d011SMarcel Moolenaar#	can contain variable assignments such as:
163955d011SMarcel Moolenaar#.nf
173955d011SMarcel Moolenaar#
183955d011SMarcel Moolenaar#	cpp_c=/usr/lib/cpp
193955d011SMarcel Moolenaar#	cpp_cc=g++ -E
203955d011SMarcel Moolenaar#	...
213955d011SMarcel Moolenaar#
223955d011SMarcel Moolenaar#.fi
233955d011SMarcel Moolenaar#	If the variable 'cpp_$suffix' is set, we use it as our cpp in
243955d011SMarcel Moolenaar#	place of grep.  The program referenced by these variables are
253955d011SMarcel Moolenaar#	expected to produce output like:
263955d011SMarcel Moolenaar#.nf
273955d011SMarcel Moolenaar#
283955d011SMarcel Moolenaar#	# 10 \"/usr/include/stdio.h\" 1
293955d011SMarcel Moolenaar#
303955d011SMarcel Moolenaar#.fi
313955d011SMarcel Moolenaar#	This allows us to skip most of our processing.  For lex,yacc
323955d011SMarcel Moolenaar#	and other source files, grep is probably just as quick and
333955d011SMarcel Moolenaar#	certainly more portable.
343955d011SMarcel Moolenaar#
353955d011SMarcel Moolenaar#	If the "rc" file does not exist, we create it and attempt to
363955d011SMarcel Moolenaar#	find cpp or an equivalent cc invocation to assign to 'cpp_c'.
373955d011SMarcel Moolenaar#
383955d011SMarcel Moolenaar# AUTHOR:
393955d011SMarcel Moolenaar#	Simon J. Gerraty <sjg@zen.void.oz.au>
403955d011SMarcel Moolenaar#
413955d011SMarcel Moolenaar
423955d011SMarcel Moolenaar# RCSid:
43*4fde40d9SSimon J. Gerraty#	$Id: mkdeps.sh,v 1.24 2022/09/09 18:44:56 sjg Exp $
443955d011SMarcel Moolenaar#
453955d011SMarcel Moolenaar#	@(#) Copyright (c) 1993 Simon J. Gerraty
463955d011SMarcel Moolenaar#
473955d011SMarcel Moolenaar#	This file is provided in the hope that it will
483955d011SMarcel Moolenaar#	be of use.  There is absolutely NO WARRANTY.
493955d011SMarcel Moolenaar#	Permission to copy, redistribute or otherwise
503955d011SMarcel Moolenaar#	use this file is hereby granted provided that
513955d011SMarcel Moolenaar#	the above copyright notice and this notice are
523955d011SMarcel Moolenaar#	left intact.
533955d011SMarcel Moolenaar#
543955d011SMarcel Moolenaar#	Please send copies of changes and bug-fixes to:
553955d011SMarcel Moolenaar#	sjg@zen.void.oz.au
563955d011SMarcel Moolenaar#
573955d011SMarcel Moolenaar
583955d011SMarcel MoolenaarMyname=`basename $0 .sh`
593955d011SMarcel MoolenaarMydir=`dirname $0`
603955d011SMarcel Moolenaar
613955d011SMarcel Moolenaarcase `echo -n .` in
623955d011SMarcel Moolenaar-n*)	N=; C="\c";;
633955d011SMarcel Moolenaar*)	N=-n; C=;;
643955d011SMarcel Moolenaaresac
653955d011SMarcel Moolenaar
663955d011SMarcel Moolenaarcc_include=-I/usr/include
673955d011SMarcel Moolenaar
683955d011SMarcel MoolenaarTF=/tmp/dep.$$
693955d011SMarcel MoolenaarEF=/tmp/deperr.$$
703955d011SMarcel Moolenaar> $EF
713955d011SMarcel Moolenaar
723955d011SMarcel Moolenaarcase "$*" in
733955d011SMarcel Moolenaar*-n*)				# don't use rc file
743955d011SMarcel Moolenaar  rc=/dev/null
753955d011SMarcel Moolenaar  norc=yes;;
763955d011SMarcel Moolenaar*)
773955d011SMarcel Moolenaar  rc=$Mydir/.${Myname}rc
783955d011SMarcel Moolenaar  ;;
793955d011SMarcel Moolenaaresac
803955d011SMarcel Moolenaar
813955d011SMarcel Moolenaarupdate=
823955d011SMarcel MoolenaarInclude=include
833955d011SMarcel Moolenaar
843955d011SMarcel Moolenaarif [ x"$norc" = x -a -f $rc ]; then
853955d011SMarcel Moolenaar  . $rc
863955d011SMarcel Moolenaarelse
873955d011SMarcel Moolenaar  # if /usr/lib/cpp or equivalent is available it is better than
883955d011SMarcel Moolenaar  # grepping .c files.
893955d011SMarcel Moolenaar  # See what (if anything) works on this system...
903955d011SMarcel Moolenaar  echo : > $rc
913955d011SMarcel Moolenaar  echo "# pre-processor for .c files" >> $rc
923955d011SMarcel Moolenaar  # try a couple of sane places first
933955d011SMarcel Moolenaar  for d in /usr/libexec /usr/lib /usr/bin /lib /usr/ccs/bin
943955d011SMarcel Moolenaar  do
953955d011SMarcel Moolenaar    cpp_c=$d/cpp
963955d011SMarcel Moolenaar    [ -x $cpp_c ] && break
973955d011SMarcel Moolenaar  done
983955d011SMarcel Moolenaar
993955d011SMarcel Moolenaar  if [ -x $cpp_c ]; then
1003955d011SMarcel Moolenaar    echo cpp_c=$cpp_c >> $rc
1013955d011SMarcel Moolenaar  else
1023955d011SMarcel Moolenaar    cpp_c=
1033955d011SMarcel Moolenaar    # rats see if cc can be used
1043955d011SMarcel Moolenaar    echo "#include <stdio.h>" > /tmp/f$$.c
1053955d011SMarcel Moolenaar    echo "main() { return 0; }" >> /tmp/f$$.c
1063955d011SMarcel Moolenaar    # try some sensible args to cc
1073955d011SMarcel Moolenaar    for arg in -E -P -M
1083955d011SMarcel Moolenaar    do
1093955d011SMarcel Moolenaar      ok=`${REALCC:-${CC:-cc}} $arg /tmp/f$$.c 2>/dev/null | grep '^#.*stdio.h' | tail -1`
1103955d011SMarcel Moolenaar      case "$ok" in
1113955d011SMarcel Moolenaar      "") ;;
1123955d011SMarcel Moolenaar      *)
1133955d011SMarcel Moolenaar        cpp_c="${REALCC:-${CC:-cc}} $arg"
1143955d011SMarcel Moolenaar        echo cpp_c="'$cpp_c'" >> $rc
1153955d011SMarcel Moolenaar        break;;
1163955d011SMarcel Moolenaar      esac
1173955d011SMarcel Moolenaar    done
1183955d011SMarcel Moolenaar    rm -f /tmp/f$$.c
1193955d011SMarcel Moolenaar  fi
1203955d011SMarcel Moolenaarfi
1213955d011SMarcel Moolenaar
122*4fde40d9SSimon J. Gerraty# some Linux systems have deprecated egrep in favor of grep -E
123*4fde40d9SSimon J. Gerraty# but not everyone supports that
124*4fde40d9SSimon J. Gerratycase "`echo bmake | egrep 'a|b' 2>&1`" in
125*4fde40d9SSimon J. Gerratybmake) ;;
126*4fde40d9SSimon J. Gerraty*) egrep() { grep -E "$@"; }
127*4fde40d9SSimon J. Gerratyesac
128*4fde40d9SSimon J. Gerraty
1293955d011SMarcel Moolenaarclean_up() {
1303955d011SMarcel Moolenaar  trap "" 2 3
1313955d011SMarcel Moolenaar  trap 0
1323955d011SMarcel Moolenaar  if [ -s $EF ]; then
1333955d011SMarcel Moolenaar          egrep -vi "included from|warning" $EF > ${EF}2
1343955d011SMarcel Moolenaar          if [ -s ${EF}2 ]; then
1353955d011SMarcel Moolenaar	          cat $EF >&2
1363955d011SMarcel Moolenaar                  rm -f .depend
1373955d011SMarcel Moolenaar                  ests=1
1383955d011SMarcel Moolenaar	  fi
1393955d011SMarcel Moolenaar  fi
1403955d011SMarcel Moolenaar  rm -f $TF $EF*
1413955d011SMarcel Moolenaar  exit ${ests:-0}
1423955d011SMarcel Moolenaar}
1433955d011SMarcel Moolenaar
1443955d011SMarcel Moolenaar# this lot does not work on HPsUX - complain to Hp.
1453955d011SMarcel Moolenaartrap clean_up 0
1463955d011SMarcel Moolenaartrap exit 2 3
1473955d011SMarcel Moolenaar
1483955d011SMarcel Moolenaarget_incs() {
1493955d011SMarcel Moolenaar  case "$cpp" in
1503955d011SMarcel Moolenaar  grep)
1513955d011SMarcel Moolenaar    # set IGNORE="<" to skip system includes
1523955d011SMarcel Moolenaar    egrep '^#[ 	]*include' $* | egrep -v "$IGNORE" | \
1533955d011SMarcel Moolenaar      sed -e 's/^.*include[^"<]*["<]//' -e 's/[">].*//g';;
1543955d011SMarcel Moolenaar  *)
1553955d011SMarcel Moolenaar    # $cpp (eg. /usr/lib/cpp or cc -E) should produce output like:
1563955d011SMarcel Moolenaar    # 1 "/usr/include/stdio.h" 2
1573955d011SMarcel Moolenaar    # set IGNORE=/usr/include to skip system includes
1583955d011SMarcel Moolenaar    $cpp $cpp_opts $cc_include $* 2>> $EF | egrep '^#.*\.h"' | sed 's,^#.*"\(.*\)".*,\1,' |
1593955d011SMarcel Moolenaar      egrep -v "$IGNORE" | sort -u;;
1603955d011SMarcel Moolenaar  esac
1613955d011SMarcel Moolenaar}
1623955d011SMarcel Moolenaar
1633955d011SMarcel Moolenaargen_deps() {
1643955d011SMarcel Moolenaar  llen=$1
1653955d011SMarcel Moolenaar  shift
1663955d011SMarcel Moolenaar
1673955d011SMarcel Moolenaar  for ifile in $*
1683955d011SMarcel Moolenaar  do
1693955d011SMarcel Moolenaar    case "$cpp" in
1703955d011SMarcel Moolenaar    grep)
1713955d011SMarcel Moolenaar      # this lot is not needed if not using grep.
1723955d011SMarcel Moolenaar      for dir in $srcdir $dirlist /usr/include
1733955d011SMarcel Moolenaar      do
1743955d011SMarcel Moolenaar        [ -f "$dir/$ifile" ] && break
1753955d011SMarcel Moolenaar      done
1763955d011SMarcel Moolenaar
1773955d011SMarcel Moolenaar      if [ ! -f "$dir/$ifile" ]; then
1783955d011SMarcel Moolenaar        # produce a useful error message (useful to emacs or error)
1793955d011SMarcel Moolenaar        iline=`grep -n ".*include.*[\"<]$ifile[\">]" $file | cut -d: -f1`
1803955d011SMarcel Moolenaar        echo "\"$file\", line $iline: cannot find include file \"$ifile\"" >> $EF
1813955d011SMarcel Moolenaar        # no point adding to dependency list as the resulting makefile
1823955d011SMarcel Moolenaar        # would not work anyway...
1833955d011SMarcel Moolenaar        continue
1843955d011SMarcel Moolenaar      fi
1853955d011SMarcel Moolenaar      ifile=$dir/$ifile
1863955d011SMarcel Moolenaar
1873955d011SMarcel Moolenaar      # check whether we have done it yet
1883955d011SMarcel Moolenaar      case `grep "$ifile" $TF` in
1893955d011SMarcel Moolenaar      "") echo "$ifile" >> $TF;;
1903955d011SMarcel Moolenaar      *)	continue;;		# no repeats...
1913955d011SMarcel Moolenaar      esac
1923955d011SMarcel Moolenaar      ;;
1933955d011SMarcel Moolenaar    esac
1943955d011SMarcel Moolenaar
1953955d011SMarcel Moolenaar    len=`expr "$ifile " : '.*'`
1963955d011SMarcel Moolenaar    if [ "`expr $llen + $len`" -gt ${width:-76} ]; then
1973955d011SMarcel Moolenaar      echo "\\" >> .depend
1983955d011SMarcel Moolenaar      echo $N "	$C" >> .depend
1993955d011SMarcel Moolenaar      llen=8
2003955d011SMarcel Moolenaar    fi
2013955d011SMarcel Moolenaar    echo $N "$ifile $C" >> .depend
2023955d011SMarcel Moolenaar    llen=`expr $llen + $len`
2033955d011SMarcel Moolenaar
2043955d011SMarcel Moolenaar    case "$cpp" in
2053955d011SMarcel Moolenaar    grep)
2063955d011SMarcel Moolenaar      # this lot is not needed unless using grep.
2073955d011SMarcel Moolenaar      ilist=`get_incs $ifile` # recurse needed?
2083955d011SMarcel Moolenaar      [ "$ilist" ] && llen=`gen_deps $llen $ilist`
2093955d011SMarcel Moolenaar      ;;
2103955d011SMarcel Moolenaar    esac
2113955d011SMarcel Moolenaar  done
2123955d011SMarcel Moolenaar  echo $llen
2133955d011SMarcel Moolenaar}
2143955d011SMarcel Moolenaar
2153955d011SMarcel Moolenaarfor f in makefile Makefile
2163955d011SMarcel Moolenaardo
2173955d011SMarcel Moolenaar  test -s $f && { MAKEFILE=$f; break; }
2183955d011SMarcel Moolenaardone
2193955d011SMarcel Moolenaar
2203955d011SMarcel MoolenaarMAKEFILE=${MAKEFILE:-makefile}
2213955d011SMarcel MoolenaarIGNORE=${IGNORE:-"^-"}		# won't happen
2223955d011SMarcel Moolenaarobj=o
2233955d011SMarcel Moolenaarcpp_opts=			# incase cpp != grep
2243955d011SMarcel Moolenaarvpath=
2253955d011SMarcel Moolenaarappend=
2263955d011SMarcel MoolenaarprogDep=
2273955d011SMarcel Moolenaar
2283955d011SMarcel Moolenaarset -- `getopt "AanNV:s:w:o:I:D:b:f:i:p" "$@"`
2293955d011SMarcel Moolenaarfor key in "$@"
2303955d011SMarcel Moolenaardo
2313955d011SMarcel Moolenaar  case $key in
2323955d011SMarcel Moolenaar  --)	shift; break;;
2333955d011SMarcel Moolenaar  -A)	Include=;;		# cat .depend >> $MAKEFILE
2343955d011SMarcel Moolenaar  -a)	append=yes; shift;;
2353955d011SMarcel Moolenaar  -n)	shift;;			# ignore rc
2363955d011SMarcel Moolenaar  -N)	update=no; shift;;	# don't update $MAKEFILE
2373955d011SMarcel Moolenaar  -I)	cpp_opts="$cpp_opts$1$2 "; dirlist="$dirlist $2"; shift 2;;
2383955d011SMarcel Moolenaar  -o)	obj=$2; shift 2;;
2393955d011SMarcel Moolenaar  -s)	shift 2;;		# can't handle it anyway...
2403955d011SMarcel Moolenaar  -w)	width=$2; shift 2;;
2413955d011SMarcel Moolenaar  -f)	MAKEFILE=$2; shift 2;;
2423955d011SMarcel Moolenaar  -b)	BASEDIR=$2; shift 2;;
2433955d011SMarcel Moolenaar  -i)	IGNORE="$2"; shift 2;;	# ignore headers matching this...
2443955d011SMarcel Moolenaar  -D)	cpp_opts="$cpp_opts$1$2 "; shift 2;;
2453955d011SMarcel Moolenaar  -V)	VPATH="$2"; shift 2;;	# where to look for files
2463955d011SMarcel Moolenaar  -p)	progDep=yes; shift;;
2473955d011SMarcel Moolenaar  esac
2483955d011SMarcel Moolenaardone
2493955d011SMarcel Moolenaar
2503955d011SMarcel Moolenaar[ "$VPATH" ] && vpath=`IFS=:; set -- $VPATH; echo $*`
2513955d011SMarcel Moolenaar
2523955d011SMarcel Moolenaar[ "$append" ] || > .depend
2533955d011SMarcel Moolenaar
2543955d011SMarcel Moolenaarfor file in $*
2553955d011SMarcel Moolenaardo
2563955d011SMarcel Moolenaar  cpp=
2573955d011SMarcel Moolenaar  suffix=`expr $file : '.*\.\([^.]*\)'`
2583955d011SMarcel Moolenaar
2593955d011SMarcel Moolenaar  eval cpp=\"\${cpp_${suffix}:-grep}\"
2603955d011SMarcel Moolenaar
2613955d011SMarcel Moolenaar  if [ ! -f $file -a "$vpath" ]; then
2623955d011SMarcel Moolenaar    for d in . $vpath
2633955d011SMarcel Moolenaar    do
2643955d011SMarcel Moolenaar      [ -f $d/$file ] && { file=$d/$file; break; }
2653955d011SMarcel Moolenaar    done
2663955d011SMarcel Moolenaar  fi
2673955d011SMarcel Moolenaar  srcdir=`dirname $file`
2683955d011SMarcel Moolenaar  base=`basename $file .$suffix`
2693955d011SMarcel Moolenaar
2703955d011SMarcel Moolenaar  ilist=`get_incs $file`
2713955d011SMarcel Moolenaar
2723955d011SMarcel Moolenaar  if [ "$ilist" ]; then
2733955d011SMarcel Moolenaar    > $TF
2743955d011SMarcel Moolenaar    if [ "$progDep" ]; then
2753955d011SMarcel Moolenaar      echo "$base:	$file \\" >> .depend
2763955d011SMarcel Moolenaar    else
2773955d011SMarcel Moolenaar      echo "$base.$obj:	$file \\" >> .depend
2783955d011SMarcel Moolenaar    fi
2793955d011SMarcel Moolenaar    echo $N "	$C" >> .depend
2803955d011SMarcel Moolenaar    llen=8
2813955d011SMarcel Moolenaar    llen=`gen_deps $llen $ilist`
2823955d011SMarcel Moolenaar    echo >> .depend
2833955d011SMarcel Moolenaar    echo >> .depend
2843955d011SMarcel Moolenaar  elif [ "$progDep" ]; then
2853955d011SMarcel Moolenaar    echo "$base:	$file" >> .depend
2863955d011SMarcel Moolenaar    echo >> .depend
2873955d011SMarcel Moolenaar  fi
2883955d011SMarcel Moolenaardone
2893955d011SMarcel Moolenaar
2903955d011SMarcel Moolenaarif [ -s .depend ]; then
2913955d011SMarcel Moolenaar  # ./foo.h looks ugly
2923955d011SMarcel Moolenaar  mv .depend $TF
2933955d011SMarcel Moolenaar  { test "$BASEDIR" && sed -e "s;$BASEDIR;\$(BASEDIR);g" $TF || cat $TF; } |
2943955d011SMarcel Moolenaar    sed 's;\([^.]\)\./;\1;g' > .depend
2953955d011SMarcel Moolenaar
2963955d011SMarcel Moolenaar  #
2973955d011SMarcel Moolenaar  # Save the manually updated section of the makefile
2983955d011SMarcel Moolenaar  #
2993955d011SMarcel Moolenaar  if [ x$update != xno ]; then
3003955d011SMarcel Moolenaar    trap "" 2			# don't die if we got this far
3013955d011SMarcel Moolenaar
3023955d011SMarcel Moolenaar    # if make doesn't support include, then append our deps...
3033955d011SMarcel Moolenaar    depended=`grep 'include.*\.depend' $MAKEFILE`
3043955d011SMarcel Moolenaar    test "$depended" && clean_up
3053955d011SMarcel Moolenaar
3063955d011SMarcel Moolenaar    sed '/^# DO NOT DELETE.*depend.*$/,$d' < $MAKEFILE > $TF
3073955d011SMarcel Moolenaar    mv $TF $MAKEFILE
3083955d011SMarcel Moolenaar    cat <<! >> $MAKEFILE
3093955d011SMarcel Moolenaar# DO NOT DELETE THIS LINE -- make depend depends on it
3103955d011SMarcel Moolenaar# Do not edit anything below, it was added automagically by $Myname.
3113955d011SMarcel Moolenaar
3123955d011SMarcel Moolenaar!
3133955d011SMarcel Moolenaar
3143955d011SMarcel Moolenaar    case "$Include" in
3153955d011SMarcel Moolenaar    "")	cat .depend >> $MAKEFILE;;
3163955d011SMarcel Moolenaar    .include)	echo '.include ".depend"' >> $MAKEFILE;;
3173955d011SMarcel Moolenaar    include)	echo include .depend >> $MAKEFILE;;
3183955d011SMarcel Moolenaar    esac
3193955d011SMarcel Moolenaar  fi
3203955d011SMarcel Moolenaarfi
3213955d011SMarcel Moolenaarclean_up
322