bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Make: Unexpected Behavior with Dependencies and include Statement


From: John Westing
Subject: Re: Make: Unexpected Behavior with Dependencies and include Statement
Date: Wed, 23 Sep 2015 15:00:51 -0500

>> 1. For the code that I'm supporting includes are rarely changed.

> All the more reason to ensure dependencies are updated automatically, as
> people will forget to do it otherwise.

Point taken.

> You are doing exactly Basic Auto-dependencies.  But that works because
> of the re-exec if include files are rebuilt

I don't think that's true, as the author explains in regards to the basic method:

"Let’s address the first problem above: the re-invocation of make. If you think about it, this re-invocation is really not necessary. Since we know some prerequisite of the target changed, we must rebuild the target; having a more up-to-date list won’t affect that decision. What we really need is to ensure that the prerequisite list is up-to-date for the next invocation of make, when we need to decide whether to update it again."

>> 3. I want to have a nodepend rule that will not rebuild dependencies
>> in order to save time

> I don't know what you mean by this... how do you think this would work?
> If you run "make nodepend" then it would do the same thing as "make all"
> but it wouldn't rebuild dependencies?  Or something?"

I was thinking to build the objects but not the dependencies. We do a lot of one-time only builds, where we don't need dependencies at all. Actually previously we were just using batch and shell scripts for builds, which are time consuming to support and maintain. In my defense I didn't make the decision to do this.

> I guess you could do something hacky like this:
> ..."

I want it be maintainable by others too. What I'm hearing is that it's not a good idea to use dependencies as targets.

> It does, actually.  You've modified the generated a.d file so that you
> declare that a.d depends on a.h.  Then you touch a.h.

> Now when make reads the makefile and sees "include a.d" it will try to
> rebuild a.d because it's an included makefile; it doesn't matter that
> the goal target is "a.o", make will try to build all the included
> makefiles.  Then after a.d is built, make re-execs and builds the
> original goal target "a.o".

So make will always check if included targets are up to date and run them if they are not, got it. Now it makes sense.

I'll use this advanced method from the article.

Thank you for your help.


On Wed, Sep 23, 2015 at 1:15 PM, Paul Smith <address@hidden> wrote:
On Wed, 2015-09-23 at 12:48 -0500, John Westing wrote:
> Here are a few points:
>
> 1. For the code that I'm supporting includes are rarely changed.

All the more reason to ensure dependencies are updated automatically, as
people will forget to do it otherwise.

> 2. By default I will always rebuild dependencies (the all rule I
> showed). For this case I thought about it for a few minutes I don't
> think dependencies will become out of date if auto-remaking doesn't
> occur (as the author pointed out for in the advanced case), can you
> give me a counter example? What I'm doing is very similar to the Basic
> Auto Dependencies case from the article.

You are doing exactly Basic Auto-dependencies.  But that works because
of the re-exec if include files are rebuilt, which you want to avoid
doing... then it won't work anymore.

> Plus I'm not using gcc for my final compiler and can't combine the
> dependency creation with compiling.

You can combine them in the same rule, even if they can't be created as
a side-effect of compiling itself like GCC does.  The article discusses
some ways of doing this.  I'll bet the added overhead of generating the
dependencies for a file you're already recompiling anyway is hardly
noticeable... preprocessing is generally a cheap operation.

If you are really concerned about it most compilers will allow you to
run the preprocessor step and save the output to a file, then run the
compiler on the preprocessor output file.  In between you can process
the output file to generate dependencies.  This way there's hardly any
extra processing.

> 3. I want to have a nodepend rule that will not rebuild dependencies
> in order to save time

I don't know what you mean by this... how do you think this would work?
If you run "make nodepend" then it would do the same thing as "make all"
but it wouldn't rebuild dependencies?  Or something?

I guess you could do something hacky like this:

  .PHONY: nodepend
  nodepend: all

  ifeq (nodepend,$(filter nodepend,$(MAKECMDGOALS)))
    $(shell cat *.d > alldeps.mk)
    alldeps.mk: ;
    include alldeps.mk
  else
    include $(wildcard *.d)
  endif

This concatenates all the .d files into a single file and ensures that
make won't successfully rebuild that file, and includes that if you run
"make nodepend".  If you run other targets it includes the .d files.
Then if you stayed with the basic method it could work.

Personally I urge you to take another look at the advanced method and do
some experimentation to determine whether the overhead of tracking
dependencies is worth the confusion of NOT tracking dependencies.  I
have a strong suspicion this is a case of premature optimization, unless
your build system or environment is very unusual.

> Also, though it seems to be related, I don't think autoremaking
> answers my second question. Why does rebuilding running "make a.o"
> also rebuild a.d? a.o doesn't depend on a.d.

It does, actually.  You've modified the generated a.d file so that you
declare that a.d depends on a.h.  Then you touch a.h.

Now when make reads the makefile and sees "include a.d" it will try to
rebuild a.d because it's an included makefile; it doesn't matter that
the goal target is "a.o", make will try to build all the included
makefiles.  Then after a.d is built, make re-execs and builds the
original goal target "a.o".



reply via email to

[Prev in Thread] Current Thread [Next in Thread]