[Top][All Lists]

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

Re: thoughts and questions on order-independent Makefile method

From: Enrique Olaizola
Subject: Re: thoughts and questions on order-independent Makefile method
Date: Tue, 2 May 2017 17:51:06 -0700

Don't 'multi-line' variables allow you to achieve your main goal?

-- i.e. What I would like to do is achieve a style in which the order of variable and
          rule declarations isn't relevant at all).

You could define a top-level makefile that either defines the multi-line variables or
includes another file(s) that define target specific ones.

Then, when defining each rule you simply reference the requisite multi-line rule(s).
I think this is more or less what Tim was suggesting.

Here's an example:
define build_product1
include shared_vars1
include shared_vars2
  @echo $(MESSAGE1)
  $(MAKE) -f target1_mk rule_target1
  @echo $(MESSAGE2)
  $(MAKE) -f target2_mk rule_target2
  # build more stuf...
# undef anything that might be redifined by another
# target

$(foreach goal,$(MAKECMDGOALS), $(eval $(call $(addprefix build_,$(goal)))))

Here all the required variables are defined in the shared_vars1 and shared_vars2.
I can call include either inside or outside the 'build_product1' variable and the result
is the same.

Alternatively each one of target*_mk could include its own special set of variables.

On Tue, May 2, 2017 at 6:08 AM, Tim Murphy <address@hidden> wrote:
If your build gets big enough you'll start to get to the point where the single-process parse is longer than the parallel build so be a little careful about how many evals you use - I'm speaking from experience.  It only matters if your build gets big though and if you use a single-makefile rather than submakes.

There's always ninja if you decide you want to generate makefiles from some other language.



On 2 May 2017 at 09:03, Martin Dorey <address@hidden> wrote:
I've had the same frustrations, though you've got further in some directions than I have.  It feels like we want to be writing in a slightly higher level language.  We could generate makefiles from this higher level language, but make seems close to what we want, if we're careful.  This seems to be the crux of what we can't do:

> So far as I can see there's no way to achieve late expansion of vars in targets

The way I do it is to abjure the usual syntax for defining rules.  I put the information in variables instead, then $(eval) the rules into existence after all the variables are done.  Having a single code site to intervene in all rules has given me a number of other performance and robustness benefits too.

On May 2, 2017, at 02:35, Britton Kerin <address@hidden> wrote:

Hi guys, I tried this on help-make  but was didn't get any response,
so I though I'd try again here.  I'm interested in submitting patches to
implement something like this, but I don't want to waste my time if it's
a total non-starter.  I'd like a --late-parse-rules (to parse all of rules
after variables)  and maybe --order-independent to verify no order-dependent
constructs in Makefile.  Or something like that.

Please let me know if it's a possibility.  Here's the original post again:

After a pretty large amount of Make I've concluded that one of the things that
tends to make make confusing is the fact that it uses linear order-dependent
code to express a DAG which isn't linear at all.  A Makefile is just be a
database of facts about a DAG, so order should be strictly a matter of style,
not semantics.

One example problem area is with include, where it frequently turns out to be
the case that a given include of e.g. generic_build_rules.mk has to be included
somewhere in the middle of a Makefile, since some code needs to go before the
include and other code after.

What I would like to do is achieve a style in which the order of variable and
rule declarations isn't relevant at all.  Rules for coming close as far as I
can see:

1. Never use simply expanded vars
2. Never use if etc, instead use $(if
3. Never use ?= (corollary to 2)
4. Enable .SECONDEXPANSION, and always use $$(VAR) in depends to get lazy eval

Are the any non-obvious bad consequences to these (particularly 4)?

The last part of the puzzle is what to do about targets themselves.  So far as
I can see there's no way to achieve late expansion of vars in targets.  So if
you have generic_build_rules.mk, and you want to introduce a target-specific
variable for a rule with a variable in it's target in a Makefile that includes
that file, you have an unavoidable order-dependency between the include and the
target-specific variable declaration.  Is there a way to avoid this that I'm

Static pattern rules are another sad case of inevitable order-dependence.
They're more robust and yield must less confusing error messages than implicit
rules, so it's sad no to be able to use them in an order-independent Makefile.

Would it possible to have something like .SECONDEXPANSION that applied to
targets and static pattern lists as well (or instead)?

This is an area I'd be willing to try to help with if it's deemed possible.


Bug-make mailing list

Bug-make mailing list

Bug-make mailing list

reply via email to

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