help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Make: Filtering prerequisites


From: Paul D. Smith
Subject: Re: Make: Filtering prerequisites
Date: Fri, 7 Apr 2006 11:10:37 -0400

%% "Smirnov Dmitry" <address@hidden> writes:

  sd> $(TARGETS): dir3/subdir3/% : $(foreach src,$(SOURCES),$(if $(findstring 
$(notdir $(src)),%),$(src), Notfound)

I really don't understand what you're trying to accomplish here.

It helps if you back up a few steps and provide your overall goal before
delving into details.

  sd> For example, if I write 

  sd> $(TARGETS): $(filter %$$(@F), anystring/$$(@F) anystring2/$$(@F))

  sd> it works,

... No, it doesn't.

  sd> But it fails if I replace it with 

  sd> $(TARGETS): $(filter %$$(@F), $(SOURCES) )

Your examples show a common confusion: you are not clear on when
expansion happens.  In make, variables (and functions, which have
exactly the same rules as variables) can be expanded at various times.
Knowing when they will be expanded in every context is critical if you
want to write a makefile of any complexity.

There's a section of the GNU make manual dedicated to this, called "How
make Reads a Makefile".  You should read that section before anything
else.

The important point to pick up from that for your purposes is that when
parsing targets and prerequisites, variable are expanded _immediately_,
as the makefile is read in, before any other processing is done.  That
includes any pattern substitution.  So your first example above:

 > $(TARGETS): dir3/subdir3/% : $(foreach src,$(SOURCES),$(if $(findstring 
 > $(notdir $(src)),%),$(src), Notfound)

The variables and functions are expanded before the "%" is replaced, and
your $(findstring ...,%) is looking for $(notdir $(src)) in the actual
literal string "%", which of course will never be true.

Similarly, here:

> $(TARGETS): $(filter %$$(@F), $(SOURCES) )

The $$(@F) is deferred (but in GNU make 3.81 you'll have to add a
special target to get this to work: see the NEWS file for that release),
but none of the other expansions are deferred... which means the
$(filter ...) is not deferred!  So, filter is looking for patterns
matching '%$(@F)'--or, words ending with the literal string '$(@F)', not
the expansion of $(@F)--in the $(SOURCES) variable, and of course it
doesn't exist.  So, the filter returns the empty string.


In this example you are getting the results you want, but by accident:

> $(TARGETS): $(filter %$$(@F), anystring/$$(@F) anystring2/$$(@F))

As above you're looking for words ending in the literal string '$(@F)',
but it so happens that both of the words in your match list _DO_ end in
the literal '$(@F)' so they both match.

  sd> If such filtering is impossible, could you please advice the
  sd> method to implement my goal...

What is your goal?  That's where you need to start.

If you upgrade to GNU make 3.81 there are some very powerful features
that will let you do what you are trying to do above (with some slightly
modified syntax).

However, that power is only needed 1% of the time; the other 99% of the
time there are much simpler and more straightforward solutions.  But
without any idea of what you're trying to do we can't suggest them.

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <address@hidden>          Find some GNU make tips at:
 http://www.gnu.org                      http://make.paulandlesley.org
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist




reply via email to

[Prev in Thread] Current Thread [Next in Thread]