bugmake - Bugs: bug #51974, call on multiline (define/endef)...

 
 

bug #51974: call on multiline (define/endef) behavior not well-documented

Submitted by:  J. Hart <oss542>
Submitted on:  Sat 09 Sep 2017 08:45:50 PM UTC  
 
Severity:  3 - Normal Item Group:  Documentation
Status:  Fixed Privacy:  Public
Assigned to:  None Open/Closed:  Closed
Component Version:  4.2.1 Operating System:  POSIX-Based
Fixed Release:  4.3 Triage Status:  None

Add a New Comment (Rich Markup)
   

You are not logged in

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

 

( Jump to the original submission)

Thu 09 Apr 2020 10:58:06 AM UTC, comment #7: 

Either the 'new' documentation is not entirely correct, or there is a bug in the current expansion logic (or I am misunderstanding something).

The documentation states:


4. Expand elements of the line which appear in an immediate expansion context (see How make Reads a Makefile).
5. Scan the line for a separator character, such as ‘:’ or ‘=’, to determine whether the line is a macro assignment or a rule (see Recipe Syntax).
6. Internalize the resulting operation and read the next line.

An important consequence of this is that a macro can expand to an entire rule, if it is one line long.


The last statement assumes that a line containing only a variable reference, such as

$(myrule)

presents an immediate expansion context, although it does not meet any of the stated forms of an immediate expansion context.

If it were, then this should also work:

myassignment = var = val

$(myassignment)

Step 5 of the list above would apply to the last line of this example (it expands to 'var = val'). However, make fails with a "missing separator" error. A slightly different error, "empty variable name", results from this variation:

myassignment = var := val

$(myassignment)

Jouke Witteveen <jwitteveen>
Sun 19 May 2019 11:46:53 PM UTC, comment #6: 

I added a new section to the GNU make manual which discusses how lines are parsed, and updated the define/endef section to be a bit more detailed.

Paul D. Smith <psmith>
Project Administrator
Sun 10 Sep 2017 01:54:06 PM UTC, comment #5: 

For J. Hart: I do also recommend that you ask questions first on the -email is unavailable- or -email is unavailable- mailing lists to be sure the behavior you're seeing is really incorrect, before filing bugs here.

The make parser doesn't "go backwards": it will first read a line, then expand the line, then interpret the line.  It doesn't go back after expanding the line to re-interpret the newline characters, so the entire results of expansion is treated as a single logical line by the make parser.  I did try, when first implementing eval, to instead just have things re-interpreted after expansion always but it ended up being a real mess.  Requiring an explicit eval is not always intuitive at first but it actually makes things much more coherent in general.

I do agree that the behavior could be better documented so I've modified this to a doc bug.

Paul D. Smith <psmith>
Project Administrator
Sun 10 Sep 2017 12:23:08 AM UTC, comment #4: 

I can't dispute Anonymous's advice, which was what I first thought of too, but I don't think it's clearly documented, neither in the GNU make manual nor in this vein of bugs, how makefile fragments like these are being parsed.  Perhaps this example will help explain what was going on in the other cases:

mad@shuttle:~/tmp/make-51972$ cat case-6.make
define MACRO
A: B
hello
endef
$(MACRO)
mad@shuttle:~/tmp/make-51972$

(The pointlessness of $(call) with no arguments is documented.)

Look away now if you want to guess the behavior on &quot;make -f case-6.make&quot;.

mad@shuttle:~/tmp/make-51972$ make -f case-6.make
make: *** No rule to make target 'B
hello', needed by 'A'.  Stop.
mad@shuttle:~/tmp/make-51972$

The result of the variable expansion clearly is being parsed as makefile syntax, in that it has defined a rule (one without a recipe), but the line breaks aren't being treated how they would be in a makefile fragment.  Is that reasonable?  I'll buy it.  But is it obvious?

Martin Dorey <mdorey>
Sat 09 Sep 2017 11:56:40 PM UTC, comment #3: 

As the other poster points out here, $(eval) was required to parse the result of the $(call) reference.  This resolves this issue.                                                            Many thanks for your patience and advice.

J. Hart <oss542>
Sat 09 Sep 2017 11:14:19 PM UTC, comment #2: 

case 4:
Makefile:

define EXELNK1
$(1): OBJ1=xOBJ1
endef
define EXELNK2
$(1): OBJ2=xOBJ2
endef
$(call EXELNK1, utl1)
$(call EXELNK2, utl1)
utl1:;@echo "jfh1:pt1:$(OBJ1):$(OBJ2):"

result of invoking make : works as expected

J. Hart <oss542>
Sat 09 Sep 2017 08:58:14 PM UTC, comment #1: 

This is also not a bug but rather an example where you need to use $(eval).

I suggest you email your question about how to do what you want to the help-make mailing list:
    https://lists.gnu.org/mailman/listinfo/help-make

instead of filing bugs...which are not bugs but rather make doing exactly what it's documented to do.

Anonymous
Sat 09 Sep 2017 08:45:50 PM UTC, original submission:  

case 1:
Makefile :

define EXELNK1
$(1): OBJ1=xOBJ1
$(1): OBJ2=xOBJ2
endef
$(call EXELNK1, utl1)
utl1:;@echo "jfh1:pt1:$(OBJ1):$(OBJ2):"

result of invoking make :
expected: jfh1:pt1:xOBJ1:xOBJ2:
actual:

/bin/sh: -c: line 0: unexpected EOF while looking for matching `"'
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [Makefile:6: utl1] Error 2

case 2:
Makefile:

define EXELNK1
$(1): OBJ1=xOBJ1
endef
$(call EXELNK1, utl1)
utl1:;@echo "jfh1:pt1:$(OBJ1):$(OBJ2):"

result of invoking make : works as expected

case 3:
Makefile:

define EXELNK1
$(1): OBJ2=xOBJ2
endef
$(call EXELNK1, utl1)
utl1:;@echo "jfh1:pt1:$(OBJ1):$(OBJ2):"

result of invoking make : works as expected

J. Hart <oss542>

 

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

Attach Files:
   
   
Comment:
   

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 jwitteveen (Posted a comment)
  • -email is unavailable- added by psmith (Posted a comment)
  • -email is unavailable- added by mdorey (Posted a comment)
  • -email is unavailable- added by oss542 (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.

     

     

     

    Follow 5 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2019-05-19 psmith StatusNone => Fixed
        Open/ClosedOpen => Closed
        Fixed ReleaseNone => 4.3
    2017-09-10 psmith Item GroupBug => Documentation
        Summarymultiline (define/endef) containing target-specific assignments causes errors in /bin/sh => call on multiline (define/endef) behavior not well-documented

    Back to the top


    Powered by Savane 3.7