On Mon, Aug 9, 2010 at 9:58 PM, Philip Guenther <[email protected]> wrote: > On Mon, Aug 9, 2010 at 7:13 PM, Peng Yu <[email protected]> wrote: > ... >>> Right. In make every global variable (like PREFIX here) has one and >>> only one value. When you change that value, then it has the new value. >>> This is a very fundamental aspect of make: you simply cannot expect to >>> create complex makefiles until you completely internalize how expansion >>> works. >> >> Are you considering adding the local variable feature to macros? I >> know that it may not easy to implement such feature in a backward >> compatible way. But having such feature helps writing more complex and >> more flexible Makefiles. > > Given the way that variable expansion works in make, 'local' variables > would be a *HUGE* trap. If you think you have headaches from $(eval), > combining them with local variables will make your code completely > impossible to debug or maintain. Just think about how deferred > expansion works: the scope of a "local" variable would have to include > contexts outside of the macro's expansion, or else they would have to > be so completely limited as to be almost pointless. I.e., they would > either be a misnomer or a bad choice. > > What you probably want is simply a way to generate a relatively unique > name for a variable. Fortunately, you can do that right now by > including some unique argument in the variable names. In this case, > $1 should work, no? > ----- > PREFIX.$1 = $1 > all$1: > echo all:$$(PREFIX.$1) > ----
I had thought about this walkaround. But the problem is that $1 may have some characters that are not allowed in variable names. > Of course, this example is completely ridiculous (you have $1, so USE > IT!), but given the example that's the best that can be shown. This is not ridiculous. I'd rather than have a more descriptive name rather than $1, if it is supported by make. >>> You need to read the GNU make manual section on "How make reads a >>> makefile" again (and again): afterwards you'll understand (hopefully, >>> unless the manual is not well written) the concept of immediate >>> expansion vs. deferred expansion. >> >> I found the following way of defining PREFIX as a macro that takes an >> argument ($1). >> >> ######## >> .PHONY: all >> >> define myfun >> PREFIX=$$(patsubst %,%,$$(1)) > > This only works because PREFIX has the same definition in each case. > I.e., it's a completely pointless variable. Why do you want a > variable PREFIX when you already have the value in $1? As I said, I made a simple example for demonstration purpose. What if I have PREFIX:=a very long command It would be inconvenient to spell out each instance of PREFIXes. > ... >>> or even better, skip eval and call altogether and use simply: >>> >>> all%: >>> echo $@ > > Yes, this is *EXACTLY* what should be done. It sometimes seems that > people use $(eval) because they think it's simpler than pattern rules, > or maybe that it's easier to think about, but the opposite is true. > > >>> Eval, in particular, is very tricky to use and so you should >>> never even attempt to use it unless you're absolutely sure that any >>> lesser option simply won't work. >> >> Yes. My real case is too complex to be described here. If I did, >> probably you will get lost. So I made a simple example to capture the >> gist of my real case. But making my example even simpler won't help my >> real case. > > If your case is so complex that you can't describe it, then it's too > complicated, period. You need to find a way that *you* understand > that can break it down into smaller problems that you can solve. For > many many years, the answers to that have been > - just write out all the rules > - write a program (in shell, awk, m4, whatever) to generate > the makefile...that has them all written out It is not that I can't describe. Describing it in a complex context doesn't really help people understand the problem better. People don't have time to read. Remember, you still haven't got time to reply my long email that I send you previously on recursive make :-). Therefore, I'd rather not to make the description more complex than it should be. > Note that $(eval) is basically the latter, but you're writing that > program in a weird language with deferred expansion and confusing > lexical rules. It's like using the most uncomfortable screwdriver to > insert screws, just because it came in the box of screws. > > >> The complexity of the usage eval probably should be better expanded in >> the manual. The current explanation of eval in the manual is probably >> too sparse, considering that there could be many tricks in using eval >> for high-order programming (just as eval in Lisp and Perl). > > Umm, Lisp programs put 'eval' in the very back corner of their > toolbox, with barbed-wire around it, because 99 times out of 100 (or > (more!) it's the Wrong Thing. The Right Thing there is generally > defmacro...which is not what make has. The perl people do the same > thing with _their_ "expand and re-evaluate as perl code" operator > (which is one of the two uses of their eval) for similar reasons: > variable references, closures, and compiled regexps solved 99/100 of > their problems. > > >>> Alternatively you could use target-specific variables but it seems like >>> overkill. >> >> Yes, that is the reason that I am looking for some walkaround for >> 'local' variables. > > I don't get it. "I'm looking for a workaround for my problem. This > is a workaround, but I don't want to use it." ? Because this walkaround don't cover corner cases. What if you have special variables that are not allowed in targets in the $1? Something like the following won't work. all$1: -- Regards, Peng _______________________________________________ Help-make mailing list [email protected] http://lists.gnu.org/mailman/listinfo/help-make
