Problems using make wildcard function to define class lists
David Holmes
david.holmes at oracle.com
Tue Aug 21 01:46:51 PDT 2012
On 16/08/2012 5:28 PM, Erik Joelsson wrote:
> $ in class names sure make life difficult for us. At least your initial
> example will change soon as I redid that completely for the cldr patch.
> It's good to be aware of these potential problems.
This is causing me a major headache. Took me a while to realize that not
only do I have to guard the $ from make I have to guard it from the
shell too - which is where all the weird values come from. (Those \$$$$
in the files make a lot more sense now - two make escapes plus a shell
escape.)
So I've been able to produce a construct that when echo'd shows the
expected class name. But when I feed that into where it is supposed to
go I still get garbage. The problem is that I have to know how many
times make will process the value before passing it to the shell in the
recipe, so that I can add the right number of escapes.
A possible, but ugly, solution is to do a subst $ DOLLAR on the wildcard
call and then subst back at the recipe. But boy is that an ugly hack. :(
David
> /Erik
>
> On 2012-08-16 08:01, David Holmes wrote:
>> On 16/08/2012 2:18 PM, David Holmes wrote:
>>> I'm trying to define my own include/exclude class lists based on this
>>> example in CreateJars.gmk:
>>>
>>> LOCALEDATA_INCLUDE_PATTERNS := \
>>> sun/text/resources/*_ar* \
>>> ...
>>> sun/util/resources/*_zh*
>>>
>>> LOCALEDATA_INCLUDES := $(patsubst $(JDK_OUTPUTDIR)/classes/%,%,\
>>> $(foreach i,$(LOCALEDATA_INCLUDE_PATTERNS), $(wildcard
>>> $(JDK_OUTPUTDIR)/classes/$i)))
>>>
>>> But I discovered that if the class file represents an inner class and so
>>> has $ in its name, then the value returned by the wildcard function has
>>> been processed as if the $XXX were a variable and so is generally
>>> replaced with an empty string! Eg:
>>>
>>> Foo$bar.class -> Foo.class
>>
>> Actually it is more weird than that. Given:
>>
>> $(wildcard $(JDK_OUTPUTDIR)/classes/sun/nio/cs/CharsetMapping*.class)
>>
>> where we have:
>>
>> > ls -1 classes/sun/nio/cs/CharsetMapping*.class
>> classes/sun/nio/cs/CharsetMapping$1.class
>> classes/sun/nio/cs/CharsetMapping$2.class
>> classes/sun/nio/cs/CharsetMapping$3.class
>> classes/sun/nio/cs/CharsetMapping$4.class
>> classes/sun/nio/cs/CharsetMapping.class
>> classes/sun/nio/cs/CharsetMapping$Entry.class
>>
>> the value from wildcard when printed is:
>>
>> classes/sun/nio/cs/CharsetMapping.class
>> classes/sun/nio/cs/CharsetMapping.class
>> classes/sun/nio/cs/CharsetMapping.class
>> classes/sun/nio/cs/CharsetMapping.class
>> classes/sun/nio/cs/CharsetMapping.class
>> classes/sun/nio/cs/CharsetMapping.class
>>
>> where all the $X values got substituted as empty variables. However
>> this set of values gets processed by ListPathsSafely to produce
>> _the.jars.exclude, and in there I find:
>>
>> sun/nio/cs/CharsetMappingRT_JAR_EXCLUDES.class
>> sun/nio/cs/CharsetMapping
>> .class
>> sun/nio/cs/CharsetMapping1.class
>> sun/nio/cs/CharsetMapping250.class
>> sun/nio/cs/CharsetMapping.class
>> sun/nio/cs/CharsetMappingntry.class
>>
>> So it seems that the actual values that come out of wildcard still
>> contain the $, and it is only when using the value that substitution
>> occurs. Hence inside the ListPathsSafely function I presume the $1, $2
>> etc try to map to function arguments which may not even exist.
>>
>> On the plus side this may mean that it is possible to process the
>> wildcard result to escape the $ characters so that they get used
>> verbatim.
>>
>> David
>> -----
>>
>>
>>> This would seem to make wildcard very error prone to use as you have to
>>> know that there are not, and never will be, files with $ in their name.
>>>
>>> wildcard also does not handle recursion in sub-directories.
>>>
>>> Given the above perhaps use of wildcard for .class files should be
>>> replaced by $(shell find ...) ?
>>>
>>> David
More information about the build-infra-dev
mailing list