bugmake - Bugs: bug #47151, make: -q fails for recursive makes


bug #47151: make: -q fails for recursive makes

Submitted by:  Manoj Srivastava <srivasta>
Submitted on:  Mon 15 Feb 2016 04:44:24 AM UTC  
Severity:  3 - Normal Item Group:  Bug
Status:  Fixed Privacy:  Public
Assigned to:  Paul D. Smith <psmith> Open/Closed:  Closed
Component Version:  4.1 Operating System:  POSIX-Based
Fixed Release:  4.2 Triage Status:  Medium Effort

Add a New Comment (Rich Markup)

You are not logged in

Please log in, so followups can be emailed to you.


Mon 29 Feb 2016 06:45:15 AM UTC, comment #2: 

Fix pushed to Git.

Paul D. Smith <psmith>
Project AdministratorIn charge of this item.
Sun 28 Feb 2016 09:35:13 PM UTC, comment #1: 

Well, this is kind of gross.

The reason for this is as follows: first, to know the result of "make -q" make just needs to locate at least one target that will be rebuilt.  Once it finds the first target that will be rebuilt, then it knows the exit code should be "1".

So, you ask it to build "foo".  It sees that "foo" depends on "bar", so it determines whether "bar" will be rebuilt.  Here's where it gets tricky: make has special handling for recipe lines that contain "$(MAKE)", and those which start with "+"; if you run "make -q" (or "make -n" etc.) then these lines will actually be invoked anyway.  See the documentation section "How the 'MAKE' Variable Works".

The idea is that in a recursive make environment if we want to know if any target needs to be built we need to recursively invoke make to see if it will build anything.

So, make is recursively invoked (with -q set) and we discover yes, we need to build "baz", so the recursive invocation of make exits with a "1" exit code.

Unfortunately the parent make doesn't really understand that, and it just says "oh, my target failed!" and so it then decides to exit with an exit code of "2" because something failed.

Yuck.  I agree that this is probably a bug.  Make needs to understand that it's invoking a recursive make with -q mode enabled, and if it exits with a "1" then it should treat that as a "must make target" exit code and itself exit with a "1", not a "2".  I've checked and this wrong behavior has existed as far back as I have compiled versions of GNU make (3.74, released in 1995).

As for why it works if you put some other line before the recursive make: in that case before make runs the recursive line it sees that there is some other recipe line that must be invoked, which is not marked as a recursive make invocation (it doesn't contain "$(MAKE)" and it doesn't start with "+").  So, make immediately knows that this target will be updated and it can stop right away without doing any recursive make, and exit with "1".

You may be confused because you think you added a make comment line, but you didn't: remember that ANY line which is indented with a TAB character, REGARDLESS of what it contains, is considered a recipe line.  So that is not interpreted as a makefile comment, because it's indented with a TAB.  Instead it's going to be expanded and passed to the shell.  If you remove the TAB before the comment line, so it's considered a makefile comment, you'll get the "old" behavior (exiting with error 2).

Paul D. Smith <psmith>
Project AdministratorIn charge of this item.
Mon 15 Feb 2016 04:44:24 AM UTC, original submission:  


This was reported by a debian user. Please retain a CC to -email is unavailable- so that the Debian BTS has a copy of your input.

Sample Makefile:

# --------------------------
foo: bar
        echo foo
        $(MAKE) baz
        echo "lala"
        echo baz
# --------------------------

$ make -q foo; echo $?
make baz
Makefile:4: recipe for target 'bar' failed
make: *** [bar] Error 1

The fine manual says

| If the exit status is one, then some updating needs to be done.
| If make encounters an error, the exit status is two, so you can
| distinguish an error from a target that is not up to date.

This is technically kindof correct, although why the error occurs is mysterious. In particular, adding a comment before the recursive make, i.e.

# lalala
$(MAKE) baz
echo "lala"

causes make -q bar to return 1.


Manoj Srivastava <srivasta>


(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

No files currently attached


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by psmith (Posted a comment)
  • -email is unavailable- added by srivasta (Submitted the item)
  • -email is unavailable- added by srivasta (Debian BTS)

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.




    Follow 6 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2016-02-29 psmith StatusNone => Fixed
        Assigned toNone => psmith
        Open/ClosedOpen => Closed
        Fixed ReleaseNone => 4.2
        Triage StatusNone => Medium Effort
    2016-02-15 srivasta Carbon-Copy- => Added 766140-forwarded@bugs.debian.org

    Back to the top

    Powered by Savane 3.5