[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Evaluating a variable only once after a recipe has run
From: |
Kaz Kylheku (gmake) |
Subject: |
Re: Evaluating a variable only once after a recipe has run |
Date: |
Sat, 18 Apr 2020 07:31:38 -0700 |
User-agent: |
Roundcube Webmail/0.9.2 |
On 2020-04-18 06:52, R. Diez wrote:
Instead of trying to uses the execution of a target recipe to try to
calculate this optimized variable (which isn't how make works,
and will likely be fruitless) you can calculate it using a conditional
expression which looks for the presence of that target in
$(MAKECMDGOALS).
THAT_VAR := $(if $(filter that-target,$(MAKECMDGOALS)),$(shell
...))
In fact MAKECMDGOALS can even be tested with ifeq/ifneq to
conditionally
include makefile text:
ifneq($(filter that-target,$(MAKECMDGOALS)),)
# chunk of makefile syntax here
THAT_VAR := $(subst ... $(shell ...))
endif
That does not cut it either, I'm afraid. Say that the makefile has
already run the cross-compiler recipe. The next invocation may not
request it as a goal any more.
Even if it is requested as a goal, it cannot work that way, because
the variable is calculated before any recipes are run.
The whole cross-compiler recipe will have to be handled by the logic
which also sets the variable.
Perhaps something like this:
ifneq ($(MAKECMDGOALS),cross-toolchain) # prevent runaway recursion
ifneq ($(filter that-target,$(MAKECMDGOALS)),)
THAT_VAR := $(shell "make cross-toolchain; /path/to/tool --arg")
endif
endif
It's fairly gross that the Makefile rule base will be read twice
though due to the recursion, since the whole point of this exercise
is to optimize something. The optimization is still obtained for
targets which don't need the variable, but those which do are
impacted.
In this situation I would rather farm out the cross toolchain
build into a script, or a smaller Makefile or something. Or use some
conditionals to trim the rule base when cross-toolchain is the
only target.
The variable is not actually needed for
the cross-compiler recipe, but for all targets that depend on it. The
variable's definition uses the cross-compiler, but any other target
later one may use that variable.
I would have to filter for any target that ultimately depends on the
cross-compiler target, and that is not really feasible.
Isn't it? Since we can just add more words to the filter, it doesn't
seem like a difficulty.
ifneq($(filter a-target b-target c-target,$(MAKECMDGOALS))
ABCVAR := ...
endif
Do you think there will be more than (let's pick a number) 17 of these
targets,
in the foreseeable lifetime of the project?
If those targets are part of some extensible system like per-directory
include makefiles, that does get ugly. But even that is solvable,
because
all the per-directory include makfefiles can be included first. They can
declare their target via some variable like this:
# local per-directory include file
TARGETS_NEEDING_VAR += my_local_target
my_local_target: prereq
cmd $(THAT_VAR) ...
These all get included, before we do the filter in the top-level
Makefile logic:
ifneq($(filter $(TARGETS_NEEDING_VAR),$(MAKECMDGOALS))
THAT_VAR := ...
endif
Given all the lists of targets that get manualy maintained in all kinds
of makefiles
it doesn't seem like a big deal. E.g. OBJS := definitions with hundreds
of entries and whatnot.
To catch errors (someone adds a new target and doesn't add it to the
filter),
we can add an else clause which defines the variable in such a way that
bad
syntax will almost certainly result.
else
THAT_VAR = ("
endif
or some better idea to make the dependent recipes fail. Or else
--warn-undefined-variables could be of use, possibly.
In the end, this is just an optimization anyway. Possibly, a negative
test
might be possible: test for the exclusive presence of certain targets
which certainly do not need that variable and define it under all other
circumstances.
Maybe the targets can follow some naming pattern which can be exploited
to condense the filter expression.
- Evaluating a variable only once after a recipe has run, R. Diez, 2020/04/18
- Re: Evaluating a variable only once after a recipe has run, Kaz Kylheku (gmake), 2020/04/18
- Re: Evaluating a variable only once after a recipe has run, R. Diez, 2020/04/18
- Re: Evaluating a variable only once after a recipe has run,
Kaz Kylheku (gmake) <=
- Re: Evaluating a variable only once after a recipe has run, R. Diez, 2020/04/18
- Re: Evaluating a variable only once after a recipe has run, R. Diez, 2020/04/18
- Re: Evaluating a variable only once after a recipe has run, Paul Smith, 2020/04/18
- Re: Evaluating a variable only once after a recipe has run, R. Diez, 2020/04/18
- Re: Evaluating a variable only once after a recipe has run, Paul Smith, 2020/04/18
Re: Evaluating a variable only once after a recipe has run, Paul Smith, 2020/04/18