help-make
[Top][All Lists]
Advanced

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

Re: how vpath should behave


From: Britton Kerin
Subject: Re: how vpath should behave
Date: Sat, 22 May 2021 15:34:18 -0800

On Thu, May 20, 2021 at 6:19 AM Paul Smith <psmith@gnu.org> wrote:
>
> I'm adding help-make back; hope you don't mind.  I prefer to keep all
> discussion of make on the lists.
>
> On Wed, 2021-05-19 at 16:45 -0800, Britton Kerin wrote:
> > > They are there to find _SOURCES_ (that is, files that make does not
> > > build itself but that already exist before make starts).
> >
> > Ok but it seems somewhat weird and asymmetric to restrict it in this
> > way.  Elsewhere make specializes in letting you incrementally turn
> > sources into targets and tack things onto either end of the pipeline
> > however you want.  It seems that the surprising behaviors of vpath
> > comes from this asymmetry.
>
> I don't disagree, necessarily, but it's a result of how make works,
> where it starts from the FINAL GOAL and works BACKWARD.  This means it
> knows what target it wants to build: make doesn't work FORWARD where it
> finds some source file and runs a command then sees what target got
> built.  My blog post tries to explain this.  There is, of course, no
> way to change this absolutely foundational design choice.
>
> Make always assumes that your recipe builds the target that it asked
> you to build (the value of $@), so it needs to compute the value of $@
> _BEFORE_ the recipe runs.  Something like vpath, which says "go and
> find the file", cannot do that for built targets obviously.
>
> I guess one possibility would be to create an entirely new "thing", say
> "TPATH" (for target path), which would be searched AFTER a recipe is
> run.  This would mean that the $@ value would always be exactly what
> appears in the makefile, and then after the recipe runs we check to see
> if that exists.  If it does, fine; if not then we search directories in
> TPATH for the target to see if it exists; if so then we change all
> prerequisites that mention this target to use this new path.
>
> I think there are a lot of opportunities for confusion and weird side-
> effects here but I'd have to think about it more deeply than this off-
> the-cuff idea.

I'm sure your idea of how this would work out in total is better than mine.

In thinking things over in a better mental state I think all I'm
wanting of is some sort
of syntactic sugar for things like this:

FC = cp # Fake Compile

define SUBDIR_STATIC_PATTERN_RULE
$(TARGETS:%=$(SD)/%): $(SD)/$(TARGET_PATTERN): $(PREREQ_PATTERNS:%=$(SD)/%)
        $(RECIPE)
endef

SD = subdir
TARGETS = foo.o
TARGET_PATTERN = %.o
PREREQ_PATTERNS = %.c
define RECIPE
        $$(FC) $$< $$@
endef
$(eval $(SUBDIR_STATIC_PATTERN_RULE))

In truth the eval form isn't that bad, if still somewhat less pretty than the
native rule syntax in the current dir.  It has the advantage that it can be
evaled multiple times to build in e.g. arch1, arch2 or  the like without
collisions.   Still some directive like "cd" (or some similar name more
appropriate for declarative programming) which interprets rules like the
above would probably be significantly more accessible for average make users
(I've been very slow to learn eval).  Then subdir.mk in subdir could be included
and use such a directive, resulting in a single non-fragmented DAG (i.e. no
recursive make considered harmful problems).

On the down side it's also pretty limited since a lot of rules will likely
involve communication between the current dir and subdirs and it wouldn't help
with rewriting them.  Something like "cpath %.o objdir" could maybe be
interpreted to mean "all %.o get objdir/ prefix" for it's scope, but i'm not
sure anything along these lines would be general/simple enough to be worth it.

Britton



reply via email to

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