问题
So I have a makefile with a target dependency like this:
all: $(foreach lang, $(LANGS), $(foreach models,$(MODELS),targetName$(model).xml$(lang)))
and the targetName target looks like this:
targetName%.xml%: MODEL\=% targetName.xml*
But it doesn't work. I get this error:
make[1]: *** No rule to make target `targetNameMYMODEL.xmlen', needed by `all'. Stop.
however, calling 'all' with a hardcoded language in the targetName target like this works:
all: $(foreach lang, $(LANGS), $(foreach models,$(MODELS),targetName$(model).xmlen))
and calling 'all' without the language in either all or targetName works fine as well. I'm thinking perhaps Makefile doesn't like having two percent signs in the target name.
Also, since I sort of inherited this makefile, can someone tell me what that MODEL\=% means? There is another target that looks like this: MODEL%: ; but i'm not sure what the \=% means.
Edit: So to clarify further based on this reponse:
I have a list of, say, 5 Models and a list of say 5 Languages, the goal is to generate 25 files, one for each combination of languages and models.
targetName%.xml target would originally build a file called targetName.xml but now I need it to build something like targetName.xml That's why I needed the two % signs.
I'm cycling through these two lists with a nested foreach as shown above, but I'm having a hard time passing those variables around to targets. I've tried exporting the language variable from the foreach statement, I've tried putting the contents of the targetName%.xml in a for loop to loop through the languages there. The latter doesn't work because there are Makefile commands (like eval for example) in the 'do' portion of the loop.
回答1:
You're right, Make doesn't like two % symbols in the target name. That's just one of the ways in which Make's wildcard handling isn't all one might wish for. There is a way to generate all of the pattern rules iterating over the values of one variable (and using % for the other) automatically; it's a little ugly, but if that's what you want we can show you.
But this line is a mess:
targetName%.xml%: MODEL\=% targetName.xml*
Apart from the problem of two wildcards in the target, the last preq, targetName.xml* will mean exactly that: a target (or file) called targetName.xml*. The asterisk will not be expanded, not to a list of all existing files that start with targetName.xml, or anything else.
Then there's MODEL\=%, which indicates that the author of this makefile was a little confused (and didn't believe in testing). If the value of the wildcard is foo, then this will indicate a prerequisite which is a target (or file) named MODEL=foo. The \ "escapes" the =, so that Make will not abort, but that is simply suppression of a healthy error message. I think what the author had in mind was something like this:
targetName%.xml: MODEL=%
targetName%.xml: $(wildcard targetName.xml*)
do some things
The first rule is not specifying a prerequisite, it is setting a target-specific variable. So when Make tries to build targetNamefoo.xml by doing some things, the variable MODEL will have the value foo in the context of that command. The second rule has a preq list, generated by wildcard; you can't mix target-specific variables and preqs in one line.
We can give further advice, but it would help if we could see a little more clearly what you're trying to do.
来源:https://stackoverflow.com/questions/11035930/can-i-have-more-than-one-sign-in-a-makefile-target