Can I use pattern in phony target? - makefile

I'd like to declare a-test, b-test, c-test as phony targets. Can I declare:
.PHONY : *-test
instead of
.PHONY : a-test b-test c-test
Also, how about declaring .PHONY : %-test?

Related

Is it a good practice to list multiple .PHONY directives in Makefile?

I understand Makefile allows multiple .PHONY targets in the file:
.PHONY: target1
...
.PHONY: target2
but is it a good practice?
Why don't we just list all the phony targets in a single top-line such as:
.PHONY: target1 target2

Specify all Makefile targets as .PHONY with wildcard

All targets in my Makefile aren't real files, is it valid to specify just .PHONY: %. Or should I list all targets?
You need to list all the targets that are meant to be phony targets as prerequisites of the .PHONY target instead of just writing .PHONY: %.
.PHONY: % doesn't do what you think it does (i.e., turning every target into a phony target).
As an example, consider the following makefile:
.PHONY: %
foo:
#echo creating $#
#touch $#
For this makefile above:
$ make
creating foo
$ make
make: 'foo' is up to date.
Therefore, the target foo is not turned into a phony target by having .PHONY: % in your makefile. Otherwise, foo's recipe would have been executed, since phony targets are always outdated.

Wildcard symbol in Makefile executing some targets but not others

From what I've been able to find, the wildcard symbol in a Makefile target : prerequisite line is a pattern rule that states "for every target X.o, if there exists a file named X.c (for example), do the following commands"
What I can't seem to figure out is why, in the Makefile below only one of the wildcard arguments is executed.
all : foo.o
%.o : %.c
echo first %.o : %.c
%.o : %.c
echo second %.o : %.c
foo.o: foo.c foo.h bar.h baz.h
When I run all, I get this output:
echo second %.o : %.c
second %.o : %.c
According to what I know, both wildcard statements should be displayed, as they both match the pattern. Can anyone explain why they aren't?
The second %.o: %.c rule overrides the first one. That is why output for the first rule is not output.
From the gnu-make manual:
You can override a built-in implicit rule (or one you have defined yourself) by defining a new pattern rule with the same target and prerequisites, but a different recipe.

Give a name to a rule in Makefile

Simply put I want to give a name to a rule in my Makefile:
A.ext : B.ext
compute A.ext from B.ext
so that I get something like this:
.PHONY : my_rule
A.ext : my_rule
my_rule : B.ext
compute A.ext from B.ext
But this is not yet equivalent to the first, since my_rule is always executed even if B.ext hasn't changed. How can I achieve equivalence?
This is the trimmed output of make -d:
Considering target file `A.ext'.
Considering target file `my_rule'.
File `my_rule' does not exist.
Considering target file `B.ext'.
Finished prerequisites of target file `B.ext'.
No need to remake target `B.ext'.
Finished prerequisites of target file `my_rule'.
Must remake target `my_rule'.
(The reason I want this is that I have another rule C.ext :| my_rule.)
.PHONY : my_rule
my_rule: A.ext
A.ext : B.ext
compute A.ext from B.ext
Or better:
.PHONY : my_rule
my_rule: A.ext
A.ext : B.ext
compute $# from $<

Makefile pattern rule for no extension?

I have a bunch of applications that are built with the same type of make rule:
apps = foo bar baz
all: $(apps)
foo: foo.o $(objects)
$(link)
bar: bar.o $(objects)
$(link)
baz: baz.o $(objects)
$(link)
If they had an extension (for example .x) I could make a pattern rule like:
%.x: %.o $(objects)
$(link)
and I wouldn't have to write out a new rule for each app.
But they don't have an extension, and I'm pretty sure that:
%: %.o $(objects)
$(link)
won't work (because it specifies that to build any file you can use this rule).
Is there anyway to specify one rule that will cover all the $(apps) build rules?
This looks like a job for a static pattern rule:
$(apps) : % : %.o $(objects)
$(link)
%: %.o $(objects)
$(link)
The above should work.
You can limit the scope of the rule by converting it into a static pattern rule, so that it is only considered for your list of targets:
$(apps) : % : %.o $(objects) # only consider this for $(apps) targets
$(link)
not an answer to what you are looking for , but a reason that might explain why such level of generic code might not yield good results. ....
static patterns rely on the presence of a stem to match and build a dependency chain.
pretty much in the same manner as the implicit rules (which are used for targets that dont have any recipie.)
i see what you were trying to achive , making a generic rule that will satisfy all the target checks for object and link in your code.
something like this ::
% : % : $(rule1)
echo / generic code ;
so that it gets invoked for all apps in differnt scenarios
since you dont want to add a extension (this becomes the root of some issues )
the issue with this is that the target will get reflected in the dependency as well since there will be no way of differentiating the dependencies form the targets.
hence if you did try that i think you will get here ...
$ make -nf mk.t
mk.t:18: *** mixed implicit and static pattern rules. Stop.
:) , i will give this a try again tomorrow to see if i can get this working in a real generic way. Nice question though.

Resources