Re: new feature idea: ingesting processed rulesets

2023-06-07 Thread Paul Smith
On Tue, 2023-05-23 at 09:13 +, Zoltán Turányi wrote:
> So here is the idea. What if a subsequent invocation of make (in a
> subdir)– instead of building the target it is given – would just
> parse the makefile, create a full ruleset internally and inject this
> ruleset into the parent make’s ruleset. Then the subsequent
> invocation can simply return and let the parent instance of make
> actually complete the build. This would enable correct
> parallelization with full respect of the dependencies. This can, of
> course only be done if the subsequent invocation of make is the last
> thing its action is doing. (Or one can somehow split the action to
> run the remaining part after the subsequent make’s target is
> complete.)

I didn't have much to add beyond the comments made earlier, except to
say that the right way to implement stuff like this is as non-recursive
make as already discussed.

So the only way a feature like this could be useful, is if it could
allow a recursive build system to get the benefits of a non-recursive
system "for free", without having to undertake the effort of reworking
the makefiles to actually be non-recursive.

However, I think this will be extremely difficult, because makefile
targets are so free-form and prerequisites and targets are not actually
necessary files at all.  If you're talking about the target "all", and
it's redefined in the sub-make, you need to be sure that all references
to that target in the sub-make go to _that_ version of "all", and
references to "all" in a different make go to _those_ versions of
"all".  But, sometimes you do want the parent makefile to be able to
refer to the targets in the child: sometimes you want it to be the same
thing, and sometimes a different thing.

And, you have the same problem with variables, pattern rules, etc. as
well.


Also your implementation is not right; the well-formed parent makefile
would look something like this:

  all: main.o sub1/lib1.o sub2/lib2.o
  ... link $^

  main.o: main.c sub1/lib1.h sub2/lib2.h
  ... compile

  sub1/lib1.o sub2/lib2.o : % : FORCE
  $(MAKE) -C $(@D) $(@F)

  FORCE:
  .PHONY: FORCE




Re: Order-only prerequisites

2023-06-07 Thread Paul Smith
On Wed, 2023-06-07 at 04:20 +0200, Frank Heckenbach wrote:
> What I want to achieve is that a and b can be made independently,
> but when both of them are made, a is always made first. I assumed
> that's what order-only prerequisites are for

That's not what it's for.  In fact, you can't achieve that in GNU Make
(certainly not easily) or any other make I'm aware of.  That's because
such a feature would be quite difficult to implement without
fundamentally changing the way make is typically designed.

The documentation of order-only prequisites says what they're for:

> A normal prerequisite makes two statements: first, it imposes an
> order in which recipes will be invoked: the recipes for all
> prerequisites of a target will be completed before the recipe for the
> target is run.  Second, it imposes a dependency relationship: if any
> prerequisite is newer than the target, then the target is considered
> out-of-date and must be rebuilt.
> 
> [Order-only prerequisites] impose a specific ordering on the rules to
> be invoked _without_ forcing the target to be updated if one of those
> rules is executed.

Makes treats order-only prereqs identically to "normal" prereqs in
every way, EXCEPT that at the time where it checks to see whether the
target needs to be rebuilt it doesn't consider the timestamps of the
order-only prerequisites.  That's all there is.



Re: Order-only prerequisites

2023-06-07 Thread Henrik Carlqvist
On Wed, 07 Jun 2023 08:29:15 +0200
> As I said, a way to specify in which order recipes are invoked
> (here, a before b) if they are invoked, without influencing whether
> they are invoked (only a, only b or a and b, as given on the command
> line).

So you really don't want any target to depend upon another target? Then why do
you care about the order? If order is important, what would happen if make is
run with -j and starts several jobs in parallell? 

In practice, targets are built in the order that they are given on the command
line or as dependencies in a rule. However, there is no guarantee that any
Make is implemented that way. If you really have a need to specify the order
of things you probably have that need because of some dependency between
targets.

regards Henrik



Re: Order-only prerequisites

2023-06-07 Thread Frank Heckenbach
Henrik Carlqvist wrote:

> > Consider this makefile:
> > 
> > .PHONY: a b
> > a:; @echo a
> > b:; @echo b
> > b: | a
> 
> Your problem with this Makefile is that it never creates any files a or b.

That's why I made them phony. But that was just for demonstration.
I get the same effects with this makefile (when a and b don't exist
before):

a:; touch a
b:; touch b
b: | a

except for "'a' is up to date." instead of "Nothing to be done for 'a'.".

> > If so, is there another way to achieve what I want?
> 
> This totally depends upon what you want.

As I said, a way to specify in which order recipes are invoked
(here, a before b) if they are invoked, without influencing whether
they are invoked (only a, only b or a and b, as given on the command
line).