threads / discuss / 28969

A flaw in dep generation with gcc -MMD?

Subject: A flaw in dep generation with gcc -MMD?

## tl;dr

19 messages between Nov 18, 2011 and Nov 19, 2011.

replies: 18people: 6as markdown or json

Nguyen Thai Ngoc Duy· Nov 18, 2011, 02:24 UTC · lore
Hi,
My builtin/.depend/add.o.d says
add.o: .... cache.h ...

Shouldn't it be "builtin/add.o: ... cache.h ..."? I tried to touch cache.h and "make builtin/add.o". It did not remake builtin/add.o. If I modify add.o.d by hand and remake, it works.

-- 
Duy
Jonathan Nieder· Nov 18, 2011, 03:41 UTC · re: Nguyen Thai Ngoc Duy · lore

Re: A flaw in dep generation with gcc -MMD?

Nguyen Thai Ngoc Duy wrote:
> My builtin/.depend/add.o.d says
>
> add.o: .... cache.h ...
Interesting.  What compiler do you use?

Thanks for finding it, Jonathan

 $ head -1 builtin/.depend/add.o.d
 builtin/add.o: builtin/add.c cache.h git-compat-util.h compat/bswap.h \
 $ gcc --version | head -1
 gcc (Debian 4.6.2-4) 4.6.2
Nguyen Thai Ngoc Duy· Nov 18, 2011, 03:56 UTC · re: Jonathan Nieder · lore

Re: A flaw in dep generation with gcc -MMD?

On Fri, Nov 18, 2011 at 10:41 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:
Show 7 quoted lines
> Nguyen Thai Ngoc Duy wrote:
>
>> My builtin/.depend/add.o.d says
>>
>> add.o: .... cache.h ...
>
> Interesting.  What compiler do you use?

$ gcc --version gcc (Gentoo 4.4.4-r2 p1.2, pie-0.4.5) 4.4.4

>  $ head -1 builtin/.depend/add.o.d
>  builtin/add.o: builtin/add.c cache.h git-compat-util.h compat/bswap.h \
>  $ gcc --version | head -1
>  gcc (Debian 4.6.2-4) 4.6.2

Hmm.. I guess it's my compiler's fault then. Next question, how can I disable this feature?

-- 
Duy
Miles Bader· Nov 18, 2011, 04:49 UTC · re: Nguyen Thai Ngoc Duy · lore

Re: A flaw in dep generation with gcc -MMD?

Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:
>> Interesting.  What compiler do you use?
>
> $ gcc --version
> gcc (Gentoo 4.4.4-r2 p1.2, pie-0.4.5) 4.4.4
FWIW, gcc 4.4.6 on debian does the correct thing too...
-Miles
-- 
Yo mama's so fat when she gets on an elevator it HAS to go down.
Nguyen Thai Ngoc Duy· Nov 18, 2011, 11:34 UTC · re: Miles Bader · lore

Re: A flaw in dep generation with gcc -MMD?

On Fri, Nov 18, 2011 at 11:49 AM, Miles Bader <miles@gnu.org> wrote:
Show 8 quoted lines
> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:
>>> Interesting.  What compiler do you use?
>>
>> $ gcc --version
>> gcc (Gentoo 4.4.4-r2 p1.2, pie-0.4.5) 4.4.4
>
> FWIW, gcc 4.4.6 on debian does the correct thing too...
>

OK it's not gcc problem. I upgraded to 4.5.3 and still had the same problem. I used ccache though. Without ccache, gcc produced correct .o.d files.

-- 
Duy
Nguyen Thai Ngoc Duy· Nov 18, 2011, 14:12 UTC · re: Nguyen Thai Ngoc Duy · lore

Re: A flaw in dep generation with gcc -MMD?

On Fri, Nov 18, 2011 at 6:34 PM, Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:
> OK it's not gcc problem. I upgraded to 4.5.3 and still had the same
> problem. I used ccache though. Without ccache, gcc produced correct
> .o.d files.

"gcc -MF depfile -MMD -MP -c -o path/to/file.o" will produce "depfile" with target given by "-o". When ccache runs, it executes "gcc -MF depfile -MMD -MP -E" instead to get the final content for hashing. Notice that "-c -o" combination is replaced by "-E". The latter produces target without leading path.

Not sure if I should report this to ccache or gcc. In the meantime, may be we should recognize the situation and switch off COMPUTE_HEADER_DEPENDENCIES when ccache is used (maybe hard).

-- 
Duy
Samuel Bronson· Nov 18, 2011, 18:30 UTC · re: Nguyen Thai Ngoc Duy · lore

Re: A flaw in dep generation with gcc -MMD?

Nguyen Thai Ngoc Duy <pclouds <at> gmail.com> writes:
> 
> On Fri, Nov 18, 2011 at 6:34 PM, Nguyen Thai Ngoc Duy <pclouds <at> gmail.com> 
wrote:
Show 13 quoted lines
> > OK it's not gcc problem. I upgraded to 4.5.3 and still had the same
> > problem. I used ccache though. Without ccache, gcc produced correct
> > .o.d files.
> 
> "gcc -MF depfile -MMD -MP -c -o path/to/file.o" will produce "depfile"
> with target given by "-o". When ccache runs, it executes "gcc -MF
> depfile -MMD -MP -E" instead to get the final content for hashing.
> Notice that "-c -o" combination is replaced by "-E". The latter
> produces target without leading path.
> 
> Not sure if I should report this to ccache or gcc. In the meantime,
> may be we should recognize the situation and switch off
> COMPUTE_HEADER_DEPENDENCIES when ccache is used (maybe hard).

I'm pretty sure you should report this against ccache; GCC seems to be behaving as documented. (I believe there is another flag that ccache should be passing in to tell GCC what target to use in the depfile.)

Of course, it'd be wise to make sure that this problem still occurs in the most recent version of ccache you can conveniently try it with before reporting...

Jonathan Nieder· Nov 18, 2011, 21:16 UTC · re: Samuel Bronson · lore

Re: A flaw in dep generation with gcc -MMD?

Hi,
(restoring cc list.  Unfortunately gmane's web interface doesn't
 provide a built-in way to reply-to-all.  [1] has a hackish
 workaround.)
Samuel Bronson wrote:
> Nguyen Thai Ngoc Duy writes:
Show 5 quoted lines
>> "gcc -MF depfile -MMD -MP -c -o path/to/file.o" will produce "depfile"
>> with target given by "-o". When ccache runs, it executes "gcc -MF
>> depfile -MMD -MP -E" instead to get the final content for hashing.
>> Notice that "-c -o" combination is replaced by "-E". The latter
>> produces target without leading path.
[...]
> I'm pretty sure you should report this against ccache; GCC seems to be
> behaving as documented.
Seems to have been fixed by v3.0pre0~187:
 commit e8354384
 Author: Andrea Bittau <a.bittau@cs.ucl.ac.uk>
 Date:   Sun Nov 1 19:39:58 2009 +0100
     Fix handling of the -MD and -MDD options
     From <http://lists.samba.org/archive/ccache/2007q2/000272.html>:
     The -MD and -MDD options automatically determine where the dependency file
     should land and what the target should look like based on the -o option.
     However, ccache drops -o and things mess up. The original patch was posted by
     Kaz Kylheku but I reworked it to make it work properly. Here is his post:
     http://lists.samba.org/archive/ccache/2006q4/000249.html
Workaround incoming in a few moments.

Thanks, Jonathan

Andreas Schwab· Nov 18, 2011, 19:27 UTC · re: Nguyen Thai Ngoc Duy · lore

Re: A flaw in dep generation with gcc -MMD?

Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:
> OK it's not gcc problem. I upgraded to 4.5.3 and still had the same
> problem. I used ccache though. Without ccache, gcc produced correct
> .o.d files.
I'm also using ccache (version 3.1.3) and get correct dependencies.
Andreas.
-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
Nguyen Thai Ngoc Duy· Nov 19, 2011, 04:53 UTC · re: Andreas Schwab · lore

Re: A flaw in dep generation with gcc -MMD?

On Sat, Nov 19, 2011 at 2:27 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
Show 7 quoted lines
> Nguyen Thai Ngoc Duy <pclouds@gmail.com> writes:
>
>> OK it's not gcc problem. I upgraded to 4.5.3 and still had the same
>> problem. I used ccache though. Without ccache, gcc produced correct
>> .o.d files.
>
> I'm also using ccache (version 3.1.3) and get correct dependencies.

I use ccache-2.4. Jonathan pointed out 3.x has been fixed elsewhere in this thread . I'm going to ask Gentoo to stablize one of 3.x version.

-- 
Duy
Jonathan Nieder· Nov 18, 2011, 04:57 UTC · re: Nguyen Thai Ngoc Duy · lore

[PATCH] Makefile: add option to disable automatic dependency generation

Duy noticed that now that the COMPUTE_HEADER_DEPENDENCIES feature is turned on automatically for compilers that support it (see v1.7.8-rc0~142^2~1, 2011-08-18), there is no easy way to force it off. For example, setting COMPUTE_HEADER_DEPENDENCIES to the empty string in config.mak just tells the makefile to treat it as undefined and run a test command to see if the -MMD option is supported.

Introduce a new NO_COMPUTE_HEADER_DEPENDENCIES variable that forces the feature off. The new semantics:

 - If NO_COMPUTE_HEADER_DEPENDENCIES is set to a nonempty string,
   the -MMD option will not be used.  The build relies on hard-coded
   dependencies in the "ifndef USE_COMPUTED_HEADER_DEPENDENCIES"
   section of the Makefile instead.
 - If COMPUTE_HEADER_DEPENDENCIES is empty and NO_COMPUTE_... is
   nonempty, the build uses gcc's on-the-fly dependency generation
   feature.
 - If neither is nonempty, the makefile runs a quick test command
   to decide whether the compiler supports the -MMD option and
   whether to enable this feature.
Inspired-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Nguyen Thai Ngoc Duy wrote:
> Hmm.. I guess it's my compiler's fault then. Next question, how can I
> disable this feature?

"make COMPUTE_HEADER_DEPENDENCIES=" works. But there's no way aside from "override COMPUTE_HEADER_DEPENDENCIES=" to do that in config.mak. And yuck.

By the way, I'm not convinced it's your compiler's fault. It might be my compiler's fault. More reading to do...

 Makefile |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)
diff --git a/Makefile b/Makefile
index ee34eab8..e4a658f6 100644
--- a/Makefile
+++ b/Makefile
@@ -250,6 +250,13 @@ all::
 #   DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
 #   DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'
 #
+# Define COMPUTE_HEADER_DEPENDENCIES if your compiler supports the -MMD option
+# and you want to avoid rebuilding objects when an unrelated header file
+# changes.
+#
+# Define NO_COMPUTE_HEADER_DEPENDENCIES if you want to disable automatic
+# dependency generation even though your compiler is detected to support it.
+#
 # Define CHECK_HEADER_DEPENDENCIES to check for problems in the hard-coded
 # dependency rules.
 #
@@ -1245,10 +1252,16 @@ endif
 endif
 
 ifdef CHECK_HEADER_DEPENDENCIES
+NO_COMPUTE_HEADER_DEPENDENCIES = YesPlease
+endif
+
+ifdef NO_COMPUTE_HEADER_DEPENDENCIES
 COMPUTE_HEADER_DEPENDENCIES =
 USE_COMPUTED_HEADER_DEPENDENCIES =
-else
+endif
+
 ifndef COMPUTE_HEADER_DEPENDENCIES
+ifndef NO_COMPUTE_HEADER_DEPENDENCIES
 dep_check = $(shell $(CC) $(ALL_CFLAGS) \
 	-c -MF /dev/null -MMD -MP -x c /dev/null -o /dev/null 2>&1; \
 	echo $$?)
-- 
1.7.8.rc2
Jonathan Nieder· Nov 18, 2011, 05:00 UTC · re: Jonathan Nieder · lore

Re: [PATCH] Makefile: add option to disable automatic dependency generation

Jonathan Nieder wrote:
>  - If COMPUTE_HEADER_DEPENDENCIES is empty and NO_COMPUTE_... is
>    nonempty, the build uses gcc's on-the-fly dependency generation
>    feature.
Erm.  This should say:
  "- If COMPUTE_HEADER_DEPENDENCIES is nonempty and NO_COMPUTE_... is
     empty,"
Sorry for the noise.
Junio C Hamano· Nov 18, 2011, 06:12 UTC · re: Jonathan Nieder · lore

Re: [PATCH] Makefile: add option to disable automatic dependency generation

Jonathan Nieder <jrnieder@gmail.com> writes:
Show 9 quoted lines
> Duy noticed that now that the COMPUTE_HEADER_DEPENDENCIES feature is
> turned on automatically for compilers that support it (see
> v1.7.8-rc0~142^2~1, 2011-08-18), there is no easy way to force it off.
> For example, setting COMPUTE_HEADER_DEPENDENCIES to the empty string
> in config.mak just tells the makefile to treat it as undefined and
> run a test command to see if the -MMD option is supported.
>
> Introduce a new NO_COMPUTE_HEADER_DEPENDENCIES variable that forces
> the feature off.

Eek. At least at the end user UI level, couldn't we do this as a tristate? E.g. "YesPlease" (or anything that begins with Y if you are ambitious) to explicitly enable, empty (or "auto") to autodetect, and anything else to decline?

Even better, couldn't we either (1) rearrange .dep/ files somehow, so that compiler difference does not matter, or (2) have dep_check to perform a trial run to detect versions of compilers that produce the output that we cannot use?

Jonathan Nieder· Nov 18, 2011, 06:21 UTC · re: Junio C Hamano · lore

Re: [PATCH] Makefile: add option to disable automatic dependency generation

Junio C Hamano wrote:
> Eek. At least at the end user UI level, couldn't we do this as a tristate?
> E.g. "YesPlease" (or anything that begins with Y if you are ambitious) to
> explicitly enable, empty (or "auto") to autodetect, and anything else to
> decline?
Ah, I didn't mind the UI so much.  Handling
	COMPUTE_HEADER_DEPENDENCIES_FORCE = (yes | no | auto)

should be doable. I'd suggest making any other value error out, so typos don't result in mysterious behavior.

> Even better, couldn't we either (1) rearrange .dep/ files somehow, so that
> compiler difference does not matter

Yes, I'm working on an incantation all the compilers like (it shouldn't be hard --- adding an -MQ option should be enough, but I want to understand the bug first). But even with such a fix, I think it will be important to have a way to turn the feature off. When someone using a compiler without -MMD support reports a bug, wouldn't it be nice to be able to reproduce it?

Jonathan Nieder· Nov 18, 2011, 09:58 UTC · re: Junio C Hamano · lore

[PATCH v2] Makefile: add option to disable automatic dependency generation

Now that the COMPUTE_HEADER_DEPENDENCIES feature is turned on automatically for compilers that support it (see v1.7.8-rc0~142^2~1, 2011-08-18), there is no easy way to force it off. For example, setting COMPUTE_HEADER_DEPENDENCIES to the empty string in config.mak just tells the makefile to treat it as undefined and run a test command to see if the -MMD option is supported.

So allow setting COMPUTE_HEADER_DEPENDENCIES=no to explicitly force the feature off. The new semantics:

 - "yes" means to explicitly enable the feature
 - "no" means to disable it
 - "auto" means to autodetect

The default is still "auto". Any value other than these three will cause the build to error out with a descriptive message so typos and stale settings in config.mak don't result in mysterious behavior.

	Makefile:1278: *** please set COMPUTE_HEADER_DEPENDENCIES to
	yes, no, or auto (not "1").  Stop.

So now when someone using a compiler without -MMD support reports trouble building git, you can reproduce it by running "make COMPUTE_HEADER_DEPENDENCIES=no".

Suggested-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Improved-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Junio C Hamano wrote:
> Eek. At least at the end user UI level, couldn't we do this as a tristate?
Nice idea.  Here it is.
 Makefile |   31 ++++++++++++++++++++++++-------
 1 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/Makefile b/Makefile
index 34ac7957..b1c80a67 100644
--- a/Makefile
+++ b/Makefile
@@ -250,6 +250,12 @@ all::
 #   DEFAULT_EDITOR='$GIT_FALLBACK_EDITOR',
 #   DEFAULT_EDITOR='"C:\Program Files\Vim\gvim.exe" --nofork'
 #
+# Define COMPUTE_HEADER_DEPENDENCIES to "yes" if you want dependencies on
+# header files to be automatically computed, to avoid rebuilding objects when
+# an unrelated header file changes.  Define it to "no" to use the hard-coded
+# dependency rules.  The default is "auto", which means to use computed header
+# dependencies if your compiler is detected to support it.
+#
 # Define CHECK_HEADER_DEPENDENCIES to check for problems in the hard-coded
 # dependency rules.
 #
@@ -1246,21 +1252,32 @@ endif
 endif
 
 ifdef CHECK_HEADER_DEPENDENCIES
-COMPUTE_HEADER_DEPENDENCIES =
+COMPUTE_HEADER_DEPENDENCIES = no
 USE_COMPUTED_HEADER_DEPENDENCIES =
-else
+endif
+
 ifndef COMPUTE_HEADER_DEPENDENCIES
+COMPUTE_HEADER_DEPENDENCIES = auto
+endif
+
+ifeq ($(COMPUTE_HEADER_DEPENDENCIES),auto)
 dep_check = $(shell $(CC) $(ALL_CFLAGS) \
 	-c -MF /dev/null -MMD -MP -x c /dev/null -o /dev/null 2>&1; \
 	echo $$?)
 ifeq ($(dep_check),0)
-COMPUTE_HEADER_DEPENDENCIES=YesPlease
-endif
+override COMPUTE_HEADER_DEPENDENCIES = yes
+else
+override COMPUTE_HEADER_DEPENDENCIES = no
 endif
 endif
 
-ifdef COMPUTE_HEADER_DEPENDENCIES
+ifeq ($(COMPUTE_HEADER_DEPENDENCIES),yes)
 USE_COMPUTED_HEADER_DEPENDENCIES = YesPlease
+else
+ifneq ($(COMPUTE_HEADER_DEPENDENCIES),no)
+$(error please set COMPUTE_HEADER_DEPENDENCIES to yes, no, or auto \
+(not "$(COMPUTE_HEADER_DEPENDENCIES)"))
+endif
 endif
 
 ifdef SANE_TOOL_PATH
@@ -1907,7 +1924,7 @@ OBJECTS := $(GIT_OBJS) $(XDIFF_OBJS) $(VCSSVN_OBJS)
 dep_files := $(foreach f,$(OBJECTS),$(dir $f).depend/$(notdir $f).d)
 dep_dirs := $(addsuffix .depend,$(sort $(dir $(OBJECTS))))
 
-ifdef COMPUTE_HEADER_DEPENDENCIES
+ifeq ($(COMPUTE_HEADER_DEPENDENCIES),yes)
 $(dep_dirs):
 	@mkdir -p $@
 
@@ -1920,7 +1937,7 @@ Please unset CHECK_HEADER_DEPENDENCIES and try again)
 endif
 endif
 
-ifndef COMPUTE_HEADER_DEPENDENCIES
+ifneq ($(COMPUTE_HEADER_DEPENDENCIES),yes)
 ifndef CHECK_HEADER_DEPENDENCIES
 dep_dirs =
 missing_dep_dirs =
-- 
1.7.8.rc2
Jonathan Nieder· Nov 18, 2011, 10:02 UTC · re: Jonathan Nieder · lore

[PATCH] Makefile: add missing header file dependencies

When the streaming filter API was introduced in v1.7.7-rc0~60^2~7 (2011-05-20), we forgot to add its header to LIB_H. Most translation units depend on streaming.h via cache.h.

v1.7.5-rc0~48 (Fix sparse warnings, 2011-03-22) introduced undeclared dependencies by url.o on url.h and thread-utils.o on thread-utils.h.

Noticed by make CHECK_HEADER_DEPENDENCIES=1.
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Some makefile buglets found while testing.
 Makefile |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index ee34eab8..34ac7957 100644
--- a/Makefile
+++ b/Makefile
@@ -518,6 +518,7 @@ LIB_H += compat/win32/syslog.h
 LIB_H += compat/win32/poll.h
 LIB_H += compat/win32/dirent.h
 LIB_H += connected.h
+LIB_H += convert.h
 LIB_H += csum-file.h
 LIB_H += decorate.h
 LIB_H += delta.h
@@ -2009,13 +2010,13 @@ builtin/branch.o builtin/checkout.o builtin/clone.o builtin/reset.o branch.o tra
 builtin/bundle.o bundle.o transport.o: bundle.h
 builtin/bisect--helper.o builtin/rev-list.o bisect.o: bisect.h
 builtin/clone.o builtin/fetch-pack.o transport.o: fetch-pack.h
-builtin/grep.o builtin/pack-objects.o transport-helper.o: thread-utils.h
+builtin/grep.o builtin/pack-objects.o transport-helper.o thread-utils.o: thread-utils.h
 builtin/send-pack.o transport.o: send-pack.h
 builtin/log.o builtin/shortlog.o: shortlog.h
 builtin/prune.o builtin/reflog.o reachable.o: reachable.h
 builtin/commit.o builtin/revert.o wt-status.o: wt-status.h
 builtin/tar-tree.o archive-tar.o: tar.h
-connect.o transport.o http-backend.o: url.h
+connect.o transport.o url.o http-backend.o: url.h
 http-fetch.o http-walker.o remote-curl.o transport.o walker.o: walker.h
 http.o http-walker.o http-push.o http-fetch.o remote-curl.o: http.h url.h
 
-- 
1.7.8.rc2
Nguyen Thai Ngoc Duy· Nov 18, 2011, 10:07 UTC · re: Jonathan Nieder · lore

Re: [PATCH v2] Makefile: add option to disable automatic dependency generation

On Fri, Nov 18, 2011 at 4:58 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
Show 28 quoted lines
> Now that the COMPUTE_HEADER_DEPENDENCIES feature is turned on
> automatically for compilers that support it (see v1.7.8-rc0~142^2~1,
> 2011-08-18), there is no easy way to force it off.  For example,
> setting COMPUTE_HEADER_DEPENDENCIES to the empty string in config.mak
> just tells the makefile to treat it as undefined and run a test
> command to see if the -MMD option is supported.
>
> So allow setting COMPUTE_HEADER_DEPENDENCIES=no to explicitly force
> the feature off.  The new semantics:
>
>  - "yes" means to explicitly enable the feature
>  - "no" means to disable it
>  - "auto" means to autodetect
>
> The default is still "auto".  Any value other than these three will
> cause the build to error out with a descriptive message so typos and
> stale settings in config.mak don't result in mysterious behavior.
>
>        Makefile:1278: *** please set COMPUTE_HEADER_DEPENDENCIES to
>        yes, no, or auto (not "1").  Stop.
>
> So now when someone using a compiler without -MMD support reports
> trouble building git, you can reproduce it by running "make
> COMPUTE_HEADER_DEPENDENCIES=no".
>
> Suggested-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> Improved-by: Junio C Hamano <gitster@pobox.com>
> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Tested-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
-- 
Duy
Jonathan Nieder· Nov 18, 2011, 23:23 UTC · re: Nguyen Thai Ngoc Duy · lore

[PATCH] Makefile: explicitly set target name for autogenerated dependencies

"gcc -MF depfile -MMD -MP -c -o path/to/file.o" produces a makefile snippet named "depfile" describing what files are needed to build the target given by "-o". When ccache versions before v3.0pre0~187 (Fix handling of the -MD and -MDD options, 2009-11-01) run, they execute

	gcc -MF depfile -MMD -MP -E

instead to get the final content for hashing. Notice that the "-c -o" combination is replaced by "-E". The result is a target name without a leading path.

Thus when building git with such versions of ccache with COMPUTE_HEADER_DEPENDENCIES enabled, the generated makefile snippets define dependencies for the wrong target:

	$ make builtin/add.o
	GIT_VERSION = 1.7.8.rc3
	    * new build flags or prefix
	    CC builtin/add.o
	$ head -1 builtin/.depend/add.o.d
	add.o: builtin/add.c cache.h git-compat-util.h compat/bswap.h strbuf.h \

After a change in a header file, object files in a subdirectory are not automatically rebuilt by "make":

	$ touch cache.h
	$ make builtin/add.o
	$

Luckily we can prevent trouble by explicitly supplying the name of the target to ccache and gcc, using the -MQ option. Do so.

Reported-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Hi,
Nguyen Thai Ngoc Duy wrote:
Show 5 quoted lines
> My builtin/.depend/add.o.d says
>
> add.o: .... cache.h ...
>
> Shouldn't it be "builtin/add.o: ... cache.h ..."?

The following seems to do the trick for me. Thanks again for catching it.

 Makefile |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index ee34eab8..71ad4b26 100644
--- a/Makefile
+++ b/Makefile
@@ -1250,7 +1250,8 @@ USE_COMPUTED_HEADER_DEPENDENCIES =
 else
 ifndef COMPUTE_HEADER_DEPENDENCIES
 dep_check = $(shell $(CC) $(ALL_CFLAGS) \
-	-c -MF /dev/null -MMD -MP -x c /dev/null -o /dev/null 2>&1; \
+	-c -MF /dev/null -MQ /dev/null -MMD -MP \
+	-x c /dev/null -o /dev/null 2>&1; \
 	echo $$?)
 ifeq ($(dep_check),0)
 COMPUTE_HEADER_DEPENDENCIES=YesPlease
@@ -1912,7 +1913,7 @@ $(dep_dirs):
 
 missing_dep_dirs := $(filter-out $(wildcard $(dep_dirs)),$(dep_dirs))
 dep_file = $(dir $@).depend/$(notdir $@).d
-dep_args = -MF $(dep_file) -MMD -MP
+dep_args = -MF $(dep_file) -MQ $@ -MMD -MP
 ifdef CHECK_HEADER_DEPENDENCIES
 $(error cannot compute header dependencies outside a normal build. \
 Please unset CHECK_HEADER_DEPENDENCIES and try again)
-- 
1.7.8.rc3
Nguyen Thai Ngoc Duy· Nov 19, 2011, 05:13 UTC · re: Jonathan Nieder · lore

Re: [PATCH] Makefile: explicitly set target name for autogenerated dependencies

On Sat, Nov 19, 2011 at 6:23 AM, Jonathan Nieder <jrnieder@gmail.com> wrote:
Show 18 quoted lines
> Luckily we can prevent trouble by explicitly supplying the name of the
> target to ccache and gcc, using the -MQ option.  Do so.
>
> Reported-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
> ---
> Hi,
>
> Nguyen Thai Ngoc Duy wrote:
>
>> My builtin/.depend/add.o.d says
>>
>> add.o: .... cache.h ...
>>
>> Shouldn't it be "builtin/add.o: ... cache.h ..."?
>
> The following seems to do the trick for me.  Thanks again for catching
> it.
Works for me too.
-- 
Duy

← back to recent threads