bugmake - Bugs: bug #43757, Target-specific assigments...


bug #43757: Target-specific assigments influencing whether target considered intermediate.

Submitted by:  Kaz Kylheku <kkylheku>
Submitted on:  Fri 05 Dec 2014 01:20:14 AM UTC  
Severity:  3 - Normal Item Group:  Enhancement
Status:  None Privacy:  Public
Assigned to:  None Open/Closed:  Open
Component Version:  3.81 Operating System:  POSIX-Based
Fixed Release:  None Triage Status:  None

Add a New Comment (Rich Markup)

You are not logged in

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


Mon 13 Jul 2015 08:21:20 PM UTC, comment #3: 

I'm not sure in what way you disagree: I looked at the code and described how it works.  There's a file object which is created for that file, so that the target-specific variables have a place to live.  Because that file object exists, when intermediate checks are done the target is considered to be not intermediate.  So, the fact that the target name appears in the target-specific variable IS disabling its intermediate-ness.  That's just a fact.

It's not eligible for a default command goal because the part of the code which checks for default command goals is only invoked in the parser where we define a real target, and this clearly doesn't define a real target.  But defining a real target is not the same as being "mentioned" as a target.

I did say "it's quite possible ... GNU make should not treat targets in target-specific variable assignments as "mentioned"" and left this report open as an enhancement request.  So apparently you agree with that.

Paul D. Smith <psmith>
Project Administrator
Mon 13 Jul 2015 06:32:57 PM UTC, comment #2: 

I must say I cannot agree with the analysis of the previous comment.

A target listed in a target-specific variable assignment is, at best, syntactically a target, not semantically.  Obviously, it cannot be semantically because the variable assignment isn't a prerequisite, and doesn't declare a rule. "Target" is the name for a semantic role of an object with respect to an update rule, and possibly some prerequisites.

A target-specific variable assignment only scopes some variables around a target, if that target happens to be updated.

It is buggy behavior to have some targets be considered permanent, just because I want to customize their update recipe with some target-specific variables.

The "mention" concept should depend on semantics, not syntax.

Of course, I read that line in the manual, but I wouldn't guess that an assignment means "mentioned as a target".

Lastly, here is something else. Suppose I take a Makefile whose default target is "all", and add this line at the very top:

   foo: BAR := xyzzy

If I run "make" now with no arguments, it still says "nothing to be done for `all'".

Clearly, Make is not considering foo to be "mentioned as a target", otherwise it would have to consider foo to be the first target in the Makefile, and hence the default target.

Kaz Kylheku <kkylheku>
Mon 13 Jul 2015 04:29:26 AM UTC, comment #1: 

The problem is this; the GNU make manual says: "a file cannot be intermediate if it is mentioned in the makefile as a target or prerequisite".  That includes a being mentioned as a target in a target-specific variable assignment.

By mentioning the target, you have disabled intermediate file status for that target.  That's why using a pattern-specific variable assignment doesn't "disable" intermediate-ness: that's not explicitly mentioning a target.

It's quite possible this is not ideal, and GNU make should not treat targets in target-specific variable assignments as "mentioned" in the context of intermediate files.  I'll leave this bug open as an enhancement request.

Paul D. Smith <psmith>
Project Administrator
Fri 05 Dec 2014 01:20:14 AM UTC, original submission:  


I have a Makefile in which tests are executed by running a "make tests" target.

The test rules work with files having several suffixes: .ok, .out, .expected and .txr

The foo.ok file is a timestamp, which is updated by a rule that only succeeds if "foo.out" matches "foo.expected".

%.ok depends on %.out, and %.out depends on %.txr: a foo.txr script is run with some arguments to produce foo.out.

Now some of the %.out targets have target specific assignments to set up some command line arguments and whatnot for the test.

STRANGE BEHAVIOR: it seems that those %.out targets which do not have target-specific assignments are not considered to be intermediate files.  They are not deleted.  Those %.out targets which have no target-specific assignments are deleted.

Example run:

    # this .out file has a target-specific assignment
    $ rm tests/009/json.out
    $ make tests/009/json.ok
    mkdir -p tests/009/
    ./txr --gc-debug  tests/009/json.txr /home/kaz/txr/tests /009/webapp.json /home/kaz/txr/tests/009/pass1.json > tests/009/json.out
    diff -u tests/009/json.expected tests/009/json.out

Notice there is no removal of the intermediate .out file here! If I remove the target-specific assignment then the behavior is different:

    $ make tests/009/json.ok
    mkdir -p tests/009/
    ./txr --gc-debug  tests/009/json.txr  > tests/009/json.out
    diff -u tests/009/json.expected tests/009/json.out
    rm tests/009/json.out

Note the rm command at the end, issued by GNU Make.

Now for the following different .out file, there is a target-specific assignment, but of a slightly different form.

    $ make tests/011/txr-case.ok
    mkdir -p tests/011/
    ./txr   tests/011/txr-case.txr  > tests/011/txr-case.out
    diff -u tests/011/txr-case.expected tests/011/txr-case.out
    rm tests/011/txr-case.out

Note the "rm" command here, eliminating the intermediate file.

In the non-removal case (tests/009/json.out) even interrupting make does not ensure that the .out file is gone.

The target specific assignments are:

    tests/009/json.out: TXR_ARGS := $(addprefix $(top_srcdir)/tests/009/,webapp.json pass1.json)

    tests/011/%: TXR_DBG_OPTS :=

One is a concrete, one is a pattern.

The relevant rules are just:

    %.out: %.txr
           mkdir -p $(dir $@)
           $(if $(TXR_SCRIPT_ON_CMDLINE),\
             $(TXR) $(TXR_DBG_OPTS) $(TXR_OPTS) -c "$$(cat $<)" \
               $(TXR_ARGS) > $@,\
             $(TXR) $(TXR_DBG_OPTS) $(TXR_OPTS) $< $(TXR_ARGS) > $@)

    %.ok: %.out
           diff -u $(<:.out=.expected) $<
           @touch $@

    %.expected: %.out
           cp $< $@

Am I running into a documented behavior?

Kaz Kylheku <kkylheku>


(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 kkylheku (Submitted the item)

    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.




    Follows 1 latest change.

    Date Changed by Updated Field Previous Value => Replaced by
    2015-07-13 psmith Item GroupBug => Enhancement

    Back to the top

    Powered by Savane 3.5