Odd Kviteberg
Odd Kviteberg

Reputation: 115

Lists on Makefile

How can I get single elements from a list defined in a Makefile. For example:

FILES:= file0 \
        file1

all: $(FILES)

$(FILES):
    echo "write on file 0 something" > file0
    echo "write on file 1 something else" > file1

Now I need to write something like this (using the first element of the list):

    echo "write on file 0 something" > "${FILES[0]}"

Thanks in advance

Upvotes: 0

Views: 342

Answers (2)

HardcoreHenry
HardcoreHenry

Reputation: 6387

A potential hint:, $@ will refer to the target that is currently being built. So if you have:

FILES := file0 file1

$(FILES):
    @echo Compiling $@

it will output

Compiling file0
Compiling file1

(assuming both files need to be rebuilt). Now, if you want to have a file specific string attached to each file, you can use token pasting to create target specific variables as so:

FILES := file0 file1

STRING_file0 := write on file 0 something
STRING_file1 := write on file 1 something else

$(FILES):
    @echo "$(STRING_$@)" > $@

In this case it will first expand the $@ within the braces, which results in @echo "$(STRING_file0)" > $@ for example, and then it would expand $(STRING_file0) to be write on file 0 something. Finally it would expand the second $@ to be file0, and would therefore pass

@echo "write on file 0 something" > file0

on the shell when it is building file0. I think this is the behavior you're after. This can, of course be done with functions as well as @MadScientist suggested.

Upvotes: 0

MadScientist
MadScientist

Reputation: 100926

This is not right:

$(FILES):
        echo "write on file 0 something" > file0
        echo "write on file 1 something else" > file1

You seem to be assuming that this syntax means that one invocation of this recipe will build all the output files. That's not what it means. It means that make will try to build each target and to build it, it will run a separate instance of the recipe. It's the same as writing:

file0:
        echo "write on file 0 something" > file0
        echo "write on file 1 something else" > file1
file1:
        echo "write on file 0 something" > file0
        echo "write on file 1 something else" > file1

Since this makefile doesn't really do anything useful we can't advise you on how to fix it.

But the answer to your question, assuming you're using GNU make (you don't say) might be found in the GNU make function documentation, specifically this section.

Upvotes: 1

Related Questions