1

I have a shell command where it outputs multiple lines. I want to store it in a variable in makefile for later processing in the target.

A simplified example:

I have this file called zfile1

#zfile1
some text
$echo 123
more text
$$$#&^$
more text

The makefile:

a:
    @$(eval v1 = $(shell cat zfile1))
#   need to process the variable here, example:
    @echo "$(v1)"
#   I want to prevent expansion of values in the file and print in multi-line
Topa
  • 90
  • 1
  • 8
  • Maybe do it in one step and pipe the output to the next command, e.g. `cat zfile | other_process`? – Olaf Dietsche Feb 27 '20 at 17:09
  • @OlafDietsche My real use-case scenario is not that simple. I have multiple outputs from different shell commands and I need to make sure all of them are working before piping anything to the next command. – Topa Feb 27 '20 at 17:25

2 Answers2

0

If you have GNU make 4.2 or above you can use the $(file <zfile1) function. See https://www.gnu.org/software/make/manual/html_node/File-Function.html

If you don't have a new-enough version of GNU make, you can't do it. Of course in your example there's no real need to put the contents of the file into a make variable at all: you can just have your recipe use the file itself. But maybe your real use-case isn't so simple.

ETA

You should never use either the make function eval or the make function shell in a recipe [1].

You can just write:

v1 := $(file <zfile1)

.ONESHELL:
a:
        @echo "$(v1)"

You must have the .ONESHELL because otherwise each line of the recipe (after it expands into multiple lines) is considered a separate recipe line. Note that .ONESHELL is in effect for the entire make process so could cause other recipes to break if they rely on each line being invoked in a different shell.

Another option is to export the result into the environment, and use a shell variable like this:

export v1 := $(file <zfile1)

a:
        @echo "$$v1"

There are probably better ways to do it but since you've only given us this example and not what you really want to do, that's about all we can say.

[1] There are times where it can be useful but if you have a sufficiently sophisticated requirement to need this you'll probably know how to use it.

MadScientist
  • 92,819
  • 9
  • 109
  • 136
0

I think you're making things too complicated.

Start by writing your recipes as proper self-contained shell scripts.

You can then either store the whole script in a file and run it from make, or you can include it directly in your makefile as a single logical line, as in the following:

a:
    @v1=$$(< zfile1); \
    echo $$v1

Note the need to "escape" the dollar sign by repeating it.

You could also use global make variables, depending on the actual logic of your real-world use.

Greg A. Woods
  • 2,663
  • 29
  • 26