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


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

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

Add a New Comment Rich Markup

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

Fix pushed to Git.

Paul D. Smith <psmith>
Group administrator
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>
Group administrator
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)

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    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 -email is unavailable-

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code