Hi all,
Regarding the generation of .d files, I may be a bit paranoid, but I
like to regenerate them unconditionally at the beginning of every make
invocation. I wouldn't trust on .d from my last build, since they may
be outdated.
Why do I do this? Because, if you remove a file from your tree, an old
.d file will require that file and make your build fail, requiring you
to clean before making again.
To be more precise, consider the following case:
old tree:
//foo.h
int a;
//foobar.h
#include "foo.h"
//unchanged.h
#include "foobar.h"
new tree:
//bar.h
int a;
//foobar.h
#include "bar.h"
//unchanged.h
#include "foobar.h"
foobar.d (or foobar.h.d, depending on your naming conventions) will
state that foobar.h depends on foo.h, which doesn't exist anymore, and
thus the build will fail.
My build system works no matter what, since it always has the latest
dependencies list. I don't even remember the last time that I had to do
a 'make clean'. I've only done recently at some points, to test the
Makefile itself, but not because I needed it.
See part of my Makefile implementation below, if you're interested in it.
However, there's a downside to this: The payment for this robustness is
a non-negligible time cost. The single-process time for a no-op make is
around 10 s (i.e., if I run 2 consecutive makes, the second will take 10
seconds no matter what). I can reduce that to 1.5 s with 'make -j', but
it's still a considerable overhead. But, considering that a full
project build is around 10 minutes, I can assume that.
To have an idea of the overhead compared to the project size, here are
some numbers of the library to which those correspond:
$ sloccount include/ src/
[...]
SLOC Directory SLOC-by-Language (Sorted)
14322 src ansic=11812,cpp=2510
9237 include ansic=9237
[...]
generated using David A. Wheeler's 'SLOCCount'.
$ find include/ src/ -type f | wc -l
720
Cheers,
Alex
---
[...]
UNITS_c := $(sort $(shell find $(SRCDIR_m) -type f | grep '\.c$$'))
UNITS_cxx := $(sort $(shell find $(SRCDIR_m) -type f | grep '\.cxx$$'))
UNITS_h := $(sort $(shell find $(INCLUDEDIR__m)/ -type f | grep '\.h$$'))
UNITS_hxx := $(sort $(shell find $(INCLUDEDIR__m)/ -type f | grep
'\.hxx$$'))
UNITS_src := $(patsubst $(SRCDIR_m)/%, $(builddir__m)/%, $(UNITS_c)
$(UNITS_cxx))
[...]
UNITS_c_d := $(addsuffix .d,$(filter %.c,$(UNITS_src)))
UNITS_cxx_d := $(addsuffix .d,$(filter %.cxx,$(UNITS_src)))
UNITS_h_d := $(patsubst $(INCLUDEDIR)/%, $(builddir)/%.d, $(UNITS_h))
UNITS_hxx_d := $(patsubst $(INCLUDEDIR)/%, $(builddir)/%.d, $(UNITS_hxx))
UNITS_d := $(UNITS_c_d) $(UNITS_cxx_d) $(UNITS_h_d) $(UNITS_hxx_d)
[...]
.PHONY: $(UNITS_d)
$(UNITS_h_d): $(builddir)/%.d: $(INCLUDEDIR)/% Makefile | $$(@D)/.
$(CC) $(CFLAGS) -I $(INCLUDEDIR) -M -MT $<.gch -MF $@ $<
$(UNITS_hxx_d): $(builddir)/%.d: $(INCLUDEDIR)/% Makefile | $$(@D)/.
$(CXX) $(CXXFLAGS) -I $(INCLUDEDIR) -M -MT $<.gch -MF $@ $<
$(UNITS_c_d): $(builddir_)/%.d: $(SRCDIR)/% Makefile | $$(@D)/.
$(CC) $(CFLAGS) -I $(INCLUDEDIR) -M -MT $(builddir_)/$*.i -MF $@ $<
$(UNITS_cxx_d): $(builddir_)/%.d: $(SRCDIR)/% Makefile | $$(@D)/.
$(CXX) $(CXXFLAGS) -I $(INCLUDEDIR) -M -MT $(builddir_)/$*.i -MF $@ $<
[...]
include $(UNITS_d)
--
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/