[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Advanced Auto-Dependency Generation. A slight improvement.
From: |
Nick Patavalis |
Subject: |
Advanced Auto-Dependency Generation. A slight improvement. |
Date: |
Wed, 1 Feb 2006 02:07:24 +0200 |
User-agent: |
Mutt/1.5.9i |
Hi,
I just read the excellent article `Advanced Auto-Dependency
Generation`_ by Paul D. Smith. The proposed technique of generating
dependency lists when compiling the sources, and using the dependency
lists created by the *previous build*, is truly ingenious.
.._Advanced Auto-Dependency Generation:
http://make.paulandlesley.org/autodep.html
There is, though, a minor glitch. With the proposed implementation, if
a dependency file somehow gets deleted while the corresponding object
file remains standing, in this case, dependency tracking *silently
stops working*. The orphaned ``.o`` file will be rebuild *only* when
the primary source file (the corresponding ``.c`` source) changes,
regardless of what happens to the secondary source files (the included
headers). This is bad.
Luckily there seems to be a simple solution:
- Make the object files depend on the corresponding dependency files
- Provide rules with empty command-sets targeting the dependency
files.
The following Makefile demonstrates this solution. Apart from the
trick discussed above it deviates from Smith's implementation at the
following:
- Uses a single GCC invocation per object-target to build both: the
dependency list, and the object file.
- Suffixes the dependency files by ``.d`` instead of by ``.P``
- Make the timestamps of the dependency files identical to the
timestamps of the corresponding object files using the "touch"
command.
- If a build command fails, or gets canned, it removes the
corresponding ``.d``, ``.P`` and ``.o`` files
Well here it is: ::
##################################################################
CC=gcc -c
SRCS = file1.c file2.c
all: $(SRCS:.c=.o)
%.o : %.c %.d
trap "rm -f '$@' '$*.d' '$*.P'; exit 1" ERR HUP INT TERM; \
$(CC) -MMD $(CPPFLAGS) $(CFLAGS) -o '$@' '$<'; \
sed 's%^$@ *:%$*.d $@:%' '$*'.d > '$*'.P; \
cp '$*'.P '$*'.d; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/d' -e 's/$$/:/' < '$*'.P >> '$*'.d; \
rm -f '$*'.P; \
touch -r '$@' '$*'.d;
%.d: ;
-include $(SRCS:.c=.d)
##################################################################
As I'm far from being a Make expert, I'm eagerly expecting the
comments and feedback of more experienced users. Is what I'm doing
correct? Could I do do something better? Do you see any problems with
my approach? The "trap" command looks particularly ugly, but I could
not think of any other way to clean-up the left-overs when the command
fails or gets canned by the user.
Regards
/npat
P.S. A couple of hours ago, I tried to post the same message using
GMANE (http://www.gmane.org/). It seems that I have failed since
the message disappeared without a trace. I also tried the same
thing yesterday with similar results. Has anyone else observed
this? Or is it some configuration problem at my side?
Anyway... sorry if this gets to you twice.
--
Act from reason, and failure makes you rethink and study harder. Act
from faith, and failure makes you blame someone and push harder.
-- Erik Naggum
- Advanced Auto-Dependency Generation. A slight improvement.,
Nick Patavalis <=