Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use eval in Makefile [duplicate]

I am learning makefile. I have problem in understanding usage of eval in makefile.

This is my Makefile:

testt:
    @R=5
    $(eval $(echo $R))

when I run make testt, nothing is displayed. Could you please show me what is the reason ? Thanks a lot.

like image 769
AlexTP Avatar asked Apr 08 '13 18:04

AlexTP


2 Answers

When make reads in your makefile, it stores the block of shell commands for testt as a single recursively expanded variable. Nothing untoward has happened yet.

After reading in your makefile, make now decides what to build. testt is the first target so it has a go at that. You have no file called testt in your file system, so make decides it has to run the block of shell commands.

At this point it tries to expand the variable that it squirreled away earlier. It starts off with

@R=5
$(eval $(echo $R))

First is expands $R. The expansion is empty, leaving make with

@R=5
$(eval $(echo ))

Now, it expands $(echo ). This variable does not exist either, and make has got as far as

@R=5
$(eval )

Make does know about $(eval ...), but its output is always empty. So now make has

@R=5

The expansion is finished, and make now passes each line separately and sequentially to fresh invocations of the shell, checking the return code of each. So, the shell sees R=5. This command (a simple assignment to a shell variable) completes without error. Make does not echo this to stdout due to the @ prefix. All done.

Always run make with --warn-undefined-variables.

$ make --warn-undefined-variables
Makefile:3: warning: undefined variable `R'
Makefile:3: warning: undefined variable `echo '
make: Nothing to be done for `testt'.

(Notice that extra space at the end of the variable name: `echo ' (yes, you can have variable names that include spaces).)

Oh, and while I'm at it, $(eval ...) is truly useful, but do not use it in shell commands. It rarely makes sense.

like image 88
bobbogo Avatar answered Oct 13 '22 17:10

bobbogo


I don't know that stackoverflow is the best place for the level of information you're looking for here. It's best for answering specific questions, but based on this example you need to get some much more fundamental understandings first.

FYI, the first line in your test is setting the shell variable R. Then that line ends, which exits from that shell invocation, and now your variable setting is lost. Then in the next line you access the make variable R by referencing $R. That was never set anywhere so is always an empty string. Then you try to give that to a make function $(echo ...), but there is no such function in make so that expands to the empty string as well. Then you pass the resulting empty string to the $(eval ...) function, and evaluating the empty string results in another empty string, which is then provided to the shell as a command to run, which does nothing.

If you wanted to ask a specific question ("how do I do XYZ?") then we can give an answer... but it would require significant sections of the GNU make manual to help at this level. Also you can ask on the [email protected] mailing list.

like image 22
MadScientist Avatar answered Oct 13 '22 15:10

MadScientist