How to use eval in Makefile [duplicate] How to use eval in Makefile [duplicate] shell shell

How to use eval in Makefile [duplicate]


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-variablesMakefile: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.


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 help-make@gnu.org mailing list.


Instruct the evaluation to use the shell with the "shell" command inside the makefile $(shell xxx) evaluation.

Not sure why this is required, but the Makefile differs from the command line - portability, but if this is not an issue then use the shell directive.

$(eval $(shell echo $R))

Reference "Managing Projects with GNU make", O'Reilly,2004, Third addition, p.89:

$(eval $(shell echo Shell echo 1>&2))