1 |
#!/bin/sh |
2 |
# |
3 |
# CCDEPS-GCC (C) 2002 Emile van Bergen. Distribution of this file is allowed |
4 |
# under the conditions detailed in the GNU General Public License (GPL). See |
5 |
# the file COPYING for more information. |
6 |
# |
7 |
# This script compiles and/or links one or more source or object files into a |
8 |
# object file or executable target, and outputs all extra dependencies found |
9 |
# while doing so in a file named target.d, which can be used by GNU Make. |
10 |
# |
11 |
# The script should be invoked the same way as your C compiler, that is, |
12 |
# specifying the target using a -o option and the source or object files as |
13 |
# non-option arguments. It will generate dependencies in the form |
14 |
# |
15 |
# target target.d: dir/file1.c dir/file2.c header1.h header2.h |
16 |
# dir/file1.c dir/file2.c header1.h header2.h: |
17 |
# |
18 |
# This version is intended for GCC, which can do compilation and dependency |
19 |
# generation in one step. The name of the GCC version (default gcc) can be |
20 |
# overridden using the CC environment variable. |
21 |
# |
22 |
# CHANGELOG |
23 |
# |
24 |
# 2003/1/8: EvB: adapted for gcc 3.2, still handles 2.95 as well. |
25 |
# |
26 |
# This was necessary because gcc 3.2 handles -MD differently than gcc 2.95: |
27 |
# where the old version generated a .d file for each source, in the current |
28 |
# directory, the new one does almost completely what this script intended to |
29 |
# do: generate one .d file in the same directory and with the same file name |
30 |
# as the target. |
31 |
# |
32 |
# The only fixups 3.2's .d files still need are: |
33 |
# |
34 |
# - changing the file name; gcc 3.2 strips the suffix of the target before |
35 |
# appending the .d, so targets x and x.o will both produce x.d, which is |
36 |
# not what we want; |
37 |
# |
38 |
# - adding the implicit dependencies as prerequisiteless targets, so that |
39 |
# make will just consider the target out of date if one does not exist |
40 |
# anymore; |
41 |
# |
42 |
# - adding the .d file as depending on the same prerequisites as our real |
43 |
# target so that it will be considered out of date if one of the files |
44 |
# mentioned in it are updated or missing. |
45 |
# |
46 |
# Basically, this version does all that by simply including the file |
47 |
# <strippedtarget>.d file in the list of .d files we look for. We may end |
48 |
# up generating the same file name, but that already was handled correctly. |
49 |
# Otherwise we perform the normal routine, so that we /know/ the targets will |
50 |
# be correct, directories and all, regardless of variations in gcc behaviour. |
51 |
|
52 |
cmdline="$*" |
53 |
|
54 |
while [ x"$1" != x ] |
55 |
do |
56 |
case "$1" in |
57 |
-o) tgt="$2" ; shift ;; # target specifier option |
58 |
-x|-u|-b|-V) shift ;; # options with arg after space |
59 |
-*) ;; # standard options |
60 |
*) fil="$fil $1" ;; # source or object files |
61 |
esac |
62 |
shift |
63 |
done |
64 |
|
65 |
CC=gcc |
66 |
|
67 |
# If we're not processing any .c files (link only), run gcc as-is and we're done |
68 |
|
69 |
expr "$fil" : ".*\.c" >/dev/null || exec $CC $cmdline |
70 |
|
71 |
# Otherwise, run the gcc with the -MD option, which generates a .d file |
72 |
# in the current directory for each .c or .cc source file processed. |
73 |
# |
74 |
# These files are post-processed (replacing the incorrectly named target |
75 |
# with the real target specified with -o, and adding the .d file), concatenated |
76 |
# into one .d file that is named based on the target name, and put in the |
77 |
# correct directory. Further, all prerequisites are added as bare targets, |
78 |
# preventing errors when files are missing due to renaming or restructuring |
79 |
# headers, but causing the files dependent on them to be considered out of |
80 |
# date. (GNU Make feature). |
81 |
# |
82 |
# Makefiles must include the .d files like this: -include $(OBJS_$(d):.o=.d) |
83 |
# or, when compiling and linking in one step: -include $(TGTS_$(d):%=%.d) |
84 |
|
85 |
dep=$tgt.d |
86 |
rm -f $dep |
87 |
|
88 |
$CC -MMD $cmdline |
89 |
res=$? |
90 |
|
91 |
dgcc3=`echo $tgt | sed -e 's/\.[^.]*$//'`.d |
92 |
dgcc=`echo $fil | sed -e 's/[^ ]*\.[^c]//' -e 's/\.c/\.d/g' -e 's%.*/%%g'` |
93 |
|
94 |
if [ $res != 0 ] |
95 |
then |
96 |
rm -f $dgcc3 $dgcc |
97 |
exit $res |
98 |
fi |
99 |
|
100 |
for tf in $dgcc3 $dgcc |
101 |
do |
102 |
if [ -f $tf ] && mv $tf $dep.tmp |
103 |
then |
104 |
sed -e "s%.*:%$tgt $dep:%" < $dep.tmp >> $dep |
105 |
sed -e 's%^.*:%%' -e 's%^ *%%' -e 's% *\\$%%' -e 's%$%:%' \ |
106 |
< $dep.tmp >> $dep |
107 |
rm -f $dep.tmp |
108 |
found=1 |
109 |
fi |
110 |
done |
111 |
|
112 |
[ "$found" = "1" ] && exit 0 |
113 |
|
114 |
echo ERROR: $0: Cannot find any compiler-generated dependency files\! |
115 |
exit 1 |
116 |
|