On 2024-07-24 04:34, Paul Smith wrote:
> On Wed, 2024-07-24 at 18:44 +0900, Masahiro Yamada wrote:
>> ifdef GENERATE_B_AS_WELL
>> # When this flag is set, we want to generate %.b as well.
>> # I know I cannot update MAKECMDGOALS...
>> MAKECMDGOALS := $(patsubst %.a, %.b, $(MAKECMDGOALS))
>> endif
>>
>>
>> %.a:
>>         touch
>>
>> %.b: %.a
>>         cp $< $@
> 
>> Then, I hope the following would happen.
>>
>>
>> $ make x.a
>>    -> create x.a
>>
>>
>> $ make x.a GENERATE_B_AS_WELL=1
>>    -> create x.b as well as x.a
> 
> 
> Your example output cannot be generated by this makefile, so it's
> confusing as to what exactly you want to happen.
> 
> However, doesn't something like this work:
> 
>     a_prereq =
>     ifdef GENERATE_B_AS_WELL
>     a_prereq = %.b
>     endif
> 
>     %a: $(a_prereq)
>             touch $@
> 
>     %.b: %.a
>             cp $< $@

Suppose that, if the flag is set, we would like a certain
target to be built regardless of what targets have been
requested on the command line.

What we can do is:

1. Determine the name of a target that /is/ being built.

2. Make the extra target a prerequisite of that target.

For (1) we have two cases: if MAKECMDGOALS is empty, then
we have to know what the default target is and use that.
Otherwise we can take the $(firstword ...) of
MAKECMDGOALS.

Something like:

ifdef GENERATE_B_AS_WELL
  ifeq ($(MAKECMDGOALS),)
all : btarget
  else
$(firstword $(MAKECMDGOALS)) : btarget
  endif
endif

.PHONY: all alpha beta gamma btarget

all: alpha beta gamma

alpha:
        @echo $@ target

beta:
        @echo $@ target

gamma:
        @echo $@ target

btarget:
        @echo $@ target


Default target without flag:

$ make
alpha target
beta target
gamma target

alpha and beta targets without flag:

$ make alpha
alpha target
$ make beta
beta target

default with flag: btarget is made (first)

$ make GENERATE_B_AS_WELL=y
btarget target
alpha target
beta target
gamma target

alpha target with flag: btarget made first, as dependency of alpha.

$ make GENERATE_B_AS_WELL=y alpha
btarget target
alpha target

beta target, same:

$ make GENERATE_B_AS_WELL=y beta
btarget target
beta target

What is not obvious how to do is to insert the beta target
into the tree such that it is built last. For that we would
have to make it a top-level goal, like Masahiro ideally wants.

Of course we could always have a fragment which is conditionally
added to all the necessary targets:

define B_BUILD_STEPS  # conditionally defined based on flag
...
endef

B_BUILD_STEPS contain a hand coded check whether B needs to be
updated, not relying on make (E.g. using shell [ "$x" -nt "$y" ].

We add $(call B_BUILD_STEPS) into all the top-level targets.
 
  alpha:
     @echo $@ target
     $(call B_BUILD_STEPS)

Reply via email to