Yeah, one of my favorite things I've done with eval is:
# sets __FILE__ macro to file to be included, then includes the file.
# allows included file to know where it is in relation to includer.
# caching of included makefile is allowed if $(2).contents is defined as the contents
of the makefile.
# $(1) is the include method, either "include" or "-include"
# $(2) is the file to be included
# $(3) is the includer
define _include-makefile
__FILE__ := $(2)
ifndef $(2).contents
$(2): | $(dir $(2)).
$(1) $(2)
else
$$(eval $$($(2).contents))
endif
__FILE__ := $(3)
endef
# include makefile passing in its name as __FILE__
# $(1) is the file to be included
include-makefile = $(foreach m,$(1),$(eval $(call
_include-makefile,include,$(m),$(__FILE__))))
which does two things:
1. The macro __FILE__ is defined for the included makefile which:
1. allows the included makefile to know where it is in relation to the includer
thereby allowing for relocatable makefiles
2. allows for macro definitions that are "local" to the included makefile by using
macro names like $(__FILE__).sources.
2. The $(2).contents allows for the makefile contents to be cached decreasing the
number of file opens/closes occurring. For example, I've created the following rule
for makefiles that are meant to be published for inclusion by other makefiles:
.SUFFIXES: .mk
$(build.DIR)/common/%.mk: $(src.DIR)/%.mk
@( \
echo 'define $$(__FILE__).contents'; \
echo "$@: $< | $(@D)/."; \
echo; \
echo clean: FILES += $@; \
echo; \
cat $<; \
echo endef; \
echo; \
echo '$$(__FILE__).contents := $$(value $$(__FILE__).contents)'; \
echo; \
echo '$$(eval $$($$(__FILE__).contents))'; \
) >$@
Anyway, enough bragging. When I'm all done with the framework I'm working on, I'm
planning on writing a paper entitled "Recursive Make Considered Harmful, Part II:
Advanced Non-Recursive Make", but this may still be months in the making.
I've been rambling, to summarize, $(eval) is one of the greatest things to come out of
the GNU make project in years. I personally thank Paul lots and lots.
Noel
Ram Bhamidipaty wrote:
>
> Thanks! I just started to read the manual for 3.80 - $(eval) looks great. Once
> I can upgrade this will make a lot of things nicer.
>
> Thanks for your input.
> -Ram
>
> Noel Yap writes:
> > Oops, sorry. $(eval) is new in gmake-3.80. I haven't checked the distribution,
> but the last I heard, you might also have to install a patch to get it to work
> correctly.
> >
> > If you can't upgrade to 3.80 (eval is such an awesome feature it's letting me do
> stuff I'd wanted to do, but was unable, for years so I recommend the upgrade), the
> only other thing I can think of is to autogenerate the makefiles for these rules.
> This is
> > probably overkill in your case since:
> >
> > - if you have only a few rules, you might as well write them out yourself
> although I'd suggest two things:
> > - use an action macro rather than hardcoding the actions into the rules; this
> reduces the redundancy
> > - define the action macros within a separate makefile; this allows the action
> macros to be used outside of your rules
> > - if you have a lot of rules, the inclusion of all these makefiles may slow
> down the build
> >
> > You can also take an in-between approach where you manually generate one
> makefile, then paste the contents into your existing makefile.
> >
> > HTH,
> > Noel
> >
> > Ram Bhamidipaty wrote:
> > >
> > > Noel Yap writes:
> > > > I'm not sure about your syntax. I think you might mean:
> > > >
> > > > $(ROOT)etc/dir1/%: %
> > > > cp $< $@
> > > > chmod 644 $@
> > > >
> > > > and so on.
> > > >
> > > > Anyway the way I'd go about this would be:
> > > >
> > > > $(foreach d,etc/dir1 etc/dir2 etc/dirN,$(eval $(ROOT)$(d)/%: % ; cp $< $@
> && chmod 644 $@))
> > > >
> > > > I haven't tested it, but it should at least be close to what I
> > > > think you want.
> > >
> > > Thank you - I'll give this a try - btw - what does $(eval ...) do? I could
> > > not find a reference for it in the manual for version 3.79 of gnu make.
> > >
> > > -Ram
> >
> > --
> > NOTICE: If received in error, please destroy and notify sender. Sender does not
> waive confidentiality or privilege, and use is prohibited.
--
NOTICE: If received in error, please destroy and notify sender. Sender does not waive
confidentiality or privilege, and use is prohibited.
_______________________________________________
Help-make mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/help-make