bug-make
[Top][All Lists]
Advanced

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

make 3.81.91: dependency checking bug when multiple jobs are used


From: Kamil Mierzejewski
Subject: make 3.81.91: dependency checking bug when multiple jobs are used
Date: Wed, 28 Jul 2010 10:21:04 +0200
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.2.7) Gecko/20100713 Thunderbird/3.1.1

Hi,

I've encountered a strange bug. Firstly I would say there should be no connection between deps checking and number of jobs, but there seems to be one.

In my project, I have a large stack of intermediate targets. Everything looks OK if I run a single job. If I run with at least two jobs - something bad happens and make doesn't remake prerequisites of one of the intermediate targets before starting its recipe. Of course the recipe doesn't succeed.

After some investigation I came up with a fix, I don't really know why it works or even if it works as expected...

I noticed that the prerequisite which should be made but is not (lets call it A), is also a prerequisite of another target B and has caused starting it's own prerequisite C... When it comes to remaking another target D which also depends on A, updating A is pruned and D recipe is started.

While debugging update_file function (remake.c), I've noticed that my target A is pruned and the function returns 0, because the command_state is cs_not_started. In all other executions of pruning the command_state of pruned targets is cs_deps_running or cs_finished. Not thinking much I've added another condition of pruning - f->command_state!=cs_not_started and everything started to work. The code after my change looks like this:

/* Prune the dependency graph: if we've already been here on _this_
     pass through the dependency graph, we don't have to go any further.
     We won't reap_children until we start the next pass, so no state
     change is possible below here until then.  */
  if (f->considered == considered)
    {
      /* Check for the case where a target has been tried and failed but
         the diagnostics hasn't been issued. If we need the diagnostics
         then we will have to continue. */
if (!(f->updated && f->update_status > 0 && !f->dontcare && f->no_diag) && f->command_state!=cs_not_started )
        {
          DBF (DB_VERBOSE, _("Pruning file `%s'.\n"));
          return f->command_state == cs_finished ? f->update_status : 0;
        }
    }

I'm not really sure why (and if) it works, I've just noticed a difference, added an exception and got a working build. Maybe the pruning can be done, but should return another value - haven't checked.

It's not easy to provide a sample makefile illustrating this issue. I hope my explanation would be enough for GNU make developers.

Kamil



reply via email to

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