[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: can't compute prerequisites in static pattern rule
From: |
Noel Yap |
Subject: |
Re: can't compute prerequisites in static pattern rule |
Date: |
Tue, 16 Dec 2003 12:19:11 -0500 |
CC'ing address@hidden
Evgeny Sologubov wrote:
>
> Hello, Noel,
> Tuesday, December 16, 2003, 5:02:03 PM, You wrote:
> >>[...]
> NY> For example, in the end, I think what you want is to generate
> NY> a dependency file for a project. The usual way to do this is to
> NY> include that dependency file within the makefile. This inclusion
> NY> cannot be done generically, but this really shouldn't be a
> NY> problem since, presumably, you should know what project
> NY> you're trying to build, anyway. Is this not so?
>
> Assume that I have four projects situated in four folders: .\Main,
> .\Lib1, .\Lib2 and .\Lib3
> Where
> 1. Main depends on Lib1
> 2. Lib1 depends on Lib2 and Lib3
> 3. Lib2 depends on Lib3
>
> As you can see project Main doesn't know a bit about projects Lib2 and Lib3.
> I wanted to create such universal rule to recursively build "Main" and
> all of the Libs it (directly or indirectly) depends on:
I see. I think you might benefit from reading
http://aegis.sourceforge.net/auug97.pdf.
> all: prj-Main
> prj-%: $(addprefix prj-, $(shell cat -s %/Makefile.dep))
> $(MAKE) -C $*
>
> where files %/Makefile.dep contain names of prerequisites.
> E.g. Lib1/Makefile.dep = "Lib2 Lib3".
>
> It comes to mind only 2 ways how I can rewrite it:
> 1. Just place all the knowledge about dependencies into my main Makefile.
> So it will look like that:
> all: Main
> Main: Lib1
> $(MAKE) -C $@
> ....
> Lib17: Lib15 Lib13 ... Lib1
> $(MAKE) -C $@
In the past, I've created a file that describes the dependencies, something
like:
# contents of GNUdependencies.mk
ifndef $(__FILE__)
$(__FILE__) := 1
$(__FILE__).dependencies := \
lib/l0 \
lib/l1
$(__FILE__)!returns := $(__FILE__).dependencies
endif
and I've got an infrastructure that would include this file and process the
dependencies (which typically means including their dependencies makefiles).
There's more to it, of course, the largest of which describes how to build each
library.
> 2. Makefile of every project must invoke making of all the Libs it
> depends on.
This is more a recursive make way of thinking.
In the non-recursive way of thinking, each "module" includes its dependencies'
makefiles which describe how they're built and include their dependencies'
makefiles.
> I believe that 2nd way better than 1st because of "incapsulation" of
> prerequisites info. But there is some problem with it - making of Lib3
> will be invoked twice (by Lib1 and by Lib2) and that could cause
> noticeable time penalties (especially when number of Libs much greater
> than 3)!
This penalty goes away if the DAG is built correctly. OTOH, there's an added
penalty of opening the Lib3 makefile multiple times (which also exists in
recursive make). This penalty can be alleviated by caching the contents of the
makefile. For example,
the above GNUdependencies.mk becomes:
define $(__FILE__)!contents
../install/common/make/l2/GNUdependencies.mk: ../src/lib/l2/GNUdependencies.mk
| ../install/common/make/l2/.
clean: FILES += ../install/common/make/l2/GNUdependencies.mk
ifndef $(__FILE__)
$(__FILE__) := 1
$(__FILE__).dependencies := \
lib/l0 \
lib/l1
$(__FILE__)!returns := $(__FILE__).dependencies
endif
endef
$(__FILE__)!contents := $(value $(__FILE__)!contents)
$(eval $($(__FILE__)!contents))
in my build. Those that include this makefile will do:
$(call include-makefile,../install/common/make/l2/GNUdependencies.mk)
which calls:
# 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.
# customization of return value assignment allowed if $(3) elements define a
!assign property; default is :=.
# $(1) is the include method, either "include" or "-include"
# $(2) is the file to be included
# $(3) is the list of macros to set from return value list
# $(4) is the list of macros to pass into included makefile
# $(5) is the includer
define _include-makefile
__FILE__ := $(2)
# call a series of binary assignment operators or functions
# $(1) is the list of macro names that will take on values
# $(2) is the list of macro names whose values are taken
ifndef _include-makefile_assign-from-indirect
define _include-makefile_assign-from-indirect
$$(if $$(firstword $$(1)),
$$(eval $$(call call-binary,$$(firstword $$($$(firstword $$(1))!assign)
:=),$$(firstword $$(1)),$$($$(firstword $$(2)))))
$$(call _include-makefile_assign-from-indirect,$$(call
pop-front,$$(1)),$$(call pop-front,$$(2))))
endef
endif
$(2)!outputs := $(3)
$(2)!inputs := $(4)
ifndef $(2)!contents
$(2): | $(dir $(2)).
$(1) $(2)
else
$$(eval $$($(2)!contents))
endif
$(if $(strip $(3)), \
$$(eval $$(call _include-makefile_assign-from-indirect, \
$(3), \
$$($(2)!returns))))
__FILE__ := $(5)
endef
# include makefile passing in its name as __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.
# customization of return value assignment allowed if $(3) elements define a
!assign property; default is :=.
# $(1) is the file to be included
# $(2) is the list of macros to set from return value list
# $(3) is the list of macros to pass into included makefile
include-makefile = $(foreach \
m, \
$(1), \
$(eval $(call _include-makefile,include,$(m),$(2),$(3),$(__FILE__))))
> I'd appreciate any ideas about ways to solve that problem.
> thanks in advance.
I hope the above is enough to give you some ideas (and not enough to scare you
away). I'm sure you have some more questions, so, ask away.
HTH,
Noel
--
NOTICE: If received in error, please destroy and notify sender. Sender does
not waive confidentiality or privilege, and use is prohibited.
- can't compute prerequisites in static pattern rule, Evgeny Sologubov, 2003/12/16
- Re: can't compute prerequisites in static pattern rule, Noel Yap, 2003/12/16
- Re[2]: can't compute prerequisites in static pattern rule, Evgeny Sologubov, 2003/12/16
- Re: can't compute prerequisites in static pattern rule,
Noel Yap <=
- Re[4]: can't compute prerequisites in static pattern rule, Evgeny Sologubov, 2003/12/17
- Re: can't compute prerequisites in static pattern rule, Noel Yap, 2003/12/17
- Re[2]: can't compute prerequisites in static pattern rule, Evgeny Sologubov, 2003/12/17
- Re: Re[2]: can't compute prerequisites in static pattern rule, Paul D. Smith, 2003/12/17
- Re: can't compute prerequisites in static pattern rule, Noel Yap, 2003/12/17
- Re[2]: can't compute prerequisites in static pattern rule, Evgeny Sologubov, 2003/12/17