#!/bin/sh # # CCDEPS-OSF (C) 2002 Emile van Bergen. Distribution of this file is allowed # under the conditions detailed in the GNU General Public License (GPL). See # the file COPYING for more information. # # This script compiles and/or links one or more source or object files into a # object file or executable target, and outputs all extra dependencies found # while doing so in a file named target.d, which can be used by GNU Make. # # The script should be invoked the same way as your C compiler, that is, # specifying the target using a -o option and the source or object files as # non-option arguments. It will generate dependencies in the form # # target target.d: dir/file1.c dir/file2.c header1.h header2.h # dir/file1.c dir/file2.c header1.h header2.h: # # This version is intended for Compaq's C compiler for Tru64 Unix (OSF1), # which can do compilation and dependency generation in one step. # The name/version of the exact compiler to run can be overridden using the # CC environment variable (default is cc). cmdline="$*" while [ x"$1" != x ] do case "$1" in -o) tgt="$2" ; shift ;; # target specifier option -x|-u|-b|-V) shift ;; # options with arg after space -c) componly=1 ;; # we're compiling only -*) ;; # standard options *) fil="$fil $1" ;; # source or object files esac shift done if [ x"$CC" = x ] then CC=cc export CC fi # If we're not processing any .c files (link only), run cc as-is and we're done expr "$fil" : ".*\.c" >/dev/null || exec $CC $cmdline # Otherwise, run the cc with the -MD option, which generates a .d file # named after each (intermediate) target, in a bit funky manner like this: # # cc -MD -o a/y.o -c a/x.c # generates a/y.o.d having target y.o: (no dir) # cc -MD -o a/y a/x.c # generates a/y.d having target a/y:, which # # also depends on a nonexistent x.o, # # and generates x.o.d having target x.o: # cc -MD -o a/y a/x.c a/z.a # generates a/y.d having target a/y:, which # # depends on a/z.a and on a nonexistent x.o, # # and generates x.o.d having target x.o: # # What we do is this: we ignore linker generated dependencies, as they are # already known anyway (see the command line - ugh) and I'm not intested in # any dependencies on standard system libraries. This also gets rid of the # dependency on the nonexisting file. # # So, we need to distinguish two cases: if the compiler was called with -c, # our .o.d is already in the correct place and we only need to fix the target # so that it includes the directory and the .d file itself. # # If the compiler was called to compile and link in one go, our .o.d. files # (one for each .c) are in the current directory. We need to roll them into # one, in the correct place, and fix up the target as above. # # In short, we find our .o.d files named after the .c files but in the current # directory if no -c was given; and named after the target if -c was given. # # In both cases we also add all prerequisites as bare targets, preventing # errors when files are missing due to renaming or restructuring headers, # but causing the files dependent on them to be considered out of date. # (GNU Make feature). # # Makefiles must include the .d files like this: -include $(OBJS_$(d):.o=.d) # or, when compiling and linking in one step: -include $(TGTS_$(d):%=%.d) $CC -MD $cmdline # set $tmp to the cc-generated .d file(s) we'll process into $dep ($tgt.d) if [ "$componly" ] then tmp=$tgt.d else tmp=`echo $fil | sed -e 's/[^ ]*\.[^c]//' -e 's/\.c/\.o\.d/g' -e 's%.*/%%g'` fi dep=$tgt.d rm -f $dep.tmp for tf in $tmp do sed -e "s%.*:%$tgt $dep:%" < $tf >> $dep.tmp sed -e 's%^.*:[ ]*%%' -e 's% *\\$%%' -e 's%$%:%' \ < $tf >> $dep.tmp rm -f $tf mv $dep.tmp $dep done