RE: basename function does nothing when it appears in prerequisites
I understand the explanation, but I do not understand why, if it applies to the $(basename) function, it does not apply to the $(addsuffix) function. If addsuffix behaved like basename, then the dependency list for the target foo.yy would be ".zz" instead of "foo.yy.zz" (which it is by experiment -- that's why this was in the test makefile). > %% Manoj Srivastava <[EMAIL PROTECTED]> writes: > > ms> The following sample makefile should not produce the error it does > ms> produce (output follows the makefile). The $(basename ...) > ms> function should work when it appears in the prerequisites section > ms> of a rule, but it does nothing. > > No, it shouldn't. Make is behaving correctly. > > All variable and function expansion for targets and prerequisite lists > occurs when the makefile is read in, well before any sort of pattern > expansion occurs; so these functions are operating on the static string > "%", not the string it will expand to after pattern matching. > > See the GNU make manual for discussion of how make reads makefiles and > when different parts of the makefile are expanded. > > ms> foo.yy: %: $(addsuffix .zz, %) > > ms> foo.xx: %: $(basename %) ___ Bug-make mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-make
Re: basename function does nothing when it appears in prerequisites
>> On Sun, 9 Sep 2001 16:18:15 -0400, Paul D Smith <[EMAIL PROTECTED]> wrote: P> In this case, what is basename of "%"? Just "%" itself, so you end up P> with this: P> foo.xx: %: % Thank you for the clear explanation. It is not the first time you have provided one for me! My memory is short, but my files are long. We had a long and illuminating corespondence on very similar matters in feb-mar 1999, though of course I did not recognize the current issue as similar until now -- the truth about % seems to drain from my head over time. I have two further comments. 1) In our previous correspondence you explained how the design of make forbids using % in variables and function arguments. It does seem to me, however, that a makefile like the following could be processed sequentially in one pass without ambiguity. It seems to me that $(remote-%-home) could in fact be resolved more easily than make-%-manifests, which make does resolve. Perhaps the difficulty is in distinguishing the OK cases from the problematic ones. I don't need a reply to this, it is just a thought after reviewing our corresondence on the general issue. remote-data-home = buzz # or := if better remote-web-home = booze remote-lists-home = boss targets = data web lists $(addsuffix .test, $(targets)): %.test: make-%-manifests $(remote-%-home) 2) On behalf of those with short memories like mine, I have the following suggestions for emending the Make manual. The top of node "Functions" in make.info (4 April 2000) says this: "Functions" allow you to do text processing in the makefile to compute the files to operate on or the commands to use. You use a function in a "function call", where you give the name of the function and some text (the "arguments") for the function to operate on. The result of the function's processing is substituted into the makefile at the point of the call, just as a variable might be substituted. The phrase "at the point of the call" is ambiguous (it could be time or space). Neither interpretation adds any information -- when or where else could the substitution be? I suggest the following revised final sentence. You may find it too verbose; what I think is important is the cross-reference. (I'm not sure how the text of the cross-ref should/does read in texinfo format, though.) The result of the function's processing is substituted into the makefile [*] when `make' expands the construct in which it appears. Some constructs are expanded when `make' first reads the makefile and others are expanded later. (For details, see *note How `make' Reads a Makefile: Reading Makefiles.) [*] If you think retaining mention of the "point in space" is important, I suggest adding "where the function appears" here. I also recommend adding a cross reference to the "Reading Makefiles" node somewhere in this paragraph in the node "Pattern Rules": Note that expansion using `%' in pattern rules occurs *after* any variable or function expansions, which take place when the makefile is read. *Note How to Use Variables: Using Variables, and *Note Functions for Transforming Text: Functions. You might consider adding a sentence like the following, which explains the consequences: `%' in a pattern rule is therefore treated as a literal `%' when it appears in a function argument or variable name. ___ Bug-make mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-make
functions `index' and `foreachstar'
I just put a patch onto Savannah with two new experimental functions `index' and `foreachstar' (dumbly named!), and I am writing this mail to explain it a bit. Well, I started to explain, and I ended up rambling and theorizing -- and not just a little, and now I want to go make sure Miami loses to Oakland, so I'm going to give a brief explanation :) `$(index FIND,IN)' Searches IN for an occurrence of FIND. If it occurs, the value of the function is the index of IN in FIND, starting with 1; otherwise, the value is 0. Compare the function `findstring'. You can use this function in a conditional to test for the presence of a specific substring in a given string. Thus, the two examples, $(index a,a b c) $(index a,b c) produce the values `1' and `0', respectively. When $(index $(a), $(x)) is not `0', $(word $(index $(a), $(x)), $(x)) is always equal to $(a). `$(foreachstar ...)' Like foreach, but separate components with newline instead of space, for use with $(eval ..). I really need to think of a better name for this function! I wrote the new functions before seeing the thread last month about the bug in the `eval' function and the debate about it. I think I have been after the same sort of goal. I've just now installed the post-3.80 patches on my system, and soon will experiment to see what might work now that didn't work before. When I read about the new features in 3.80 and began to experiment, one of the tasks I set for myself was to write a target that caused the name and value of every variable to be echoed in a simple way. It proved too hard for me! Can anyone do this? It's typical, I think, of what one wants `eval' to help do. I wrote the two functions `index' and `foreachstar' to try to take `eval' that last few yards to being the feature of our dreams. Basically, the `index' function, working with `word' or `wordlist', can help implement the kind of record-structure that seems to me is the main stumbling block, insofar as before `eval' it could only be done if the data themselves had a structure such that %-patterns would inherently provide your array/record structure. For example: targets = publicprivate professional target.machines = webserver.com localhost toolndie.com target.porno-p = noyes no target.dirs = web web/me web/me/work # argument TARGET, expands to the stamp associated with it stamp-of = $(word $(index $(1), $(targets)), $(target.stamps)) target.stamps = $(foreach t, $(target), $(call stamp-of, $(t))) (I haven't worked out this example carefully enough to assure that it can't be done another way, but if it can, I've almost definitely proved that I did need `index' in situations that are about like this.) Below is a test Makefile and its output. The error at the end comes up when Make tries to print out a variable value that has a newline in it -- the evaluator doesn't read past the newline. That's a problem to resolve. (Incidentally, I run with "env -i" because something weird is going on with Make having variables defined after my shell functions -- I've submitted a bug report to Debian, but it may affect you if you try this at home.) begin Makefile # testing new functions $(index ...) and $(foreach* ...) nums = one two three four five all: index foreach dumpvars index: @echo "triplets are:" @echo ' $$(index ...)' @echo ' expected result of $$(index ...)' @echo ' $$(findstring ...) for comparison' @echo @echo 'blorkle! I don'"'"'t like how $$(findstring ...) works!' @echo @echo -- @echo "[$(index one, $(nums))]" @echo "[1]" @echo "[$(findstring one, $(nums))]" @echo -- @echo "[$(index bobo, $(nums))]" @echo "[0]" @echo "[$(findstring bobo, $(nums))]" @echo -- @echo "[$(index five, $(nums))]" @echo "[5]" @echo "[$(findstring five, $(nums))]" @echo -- @echo "[$(index on, $(nums))]" @echo "[0]" @echo "[$(findstring on, $(nums))]" @echo -- @echo "[$(index fo, $(nums))]" @echo "[0]" @echo "[$(findstring fo, $(nums))]" @echo -- @echo "[$(index hree, $(nums))]" @echo "[0]" @echo "[$(findstring hree, $(nums))]" @echo -- @echo "[$(index ne tw, $(nums))]" @echo "[0]" @echo "[$(findstring ne tw, $(nums))]" @echo -- define doit @echo $(1) endef # eval has to deal with a whole rule etc or it barfs # can't have comments beggining at boln in this def: "missing separator" # this line ditto: # $(foreachstar x, $(nums),\t@echo $(x)) define fofo foreach: @echo "should see \"$(nums)\" one per line" @e