Open ale5000-git opened 1 month ago
Empty commands are allowed in GNU, BSD, Schily and Unix Version 7 make
.
Only BSD make
and pdpmake
didn't support them.
Now pdpmake
does, both here and in busybox-w32.
Thanks, I have tested it with this Makefile:
.PHONY: dummy9 dummy10
dummya:
dummyb:
echo 'Random text'
dummyc: dummya
dummy1:;
dummy2: ;
dummy3: dummya;
dummy4: dummya ;
dummy5: dummyb
dummy6: dummyb ;
dummy7: ;dummyb
dummy8: ; dummyb
dummy9:
and I have created a corresponding file with the name of the target plus .sh
and the result with pdpmake is:
$ make dummya
cp dummya.sh dummya
chmod a+x dummya
$ make dummyb
echo 'Random text'
Random text
$ make dummyc
cp dummyc.sh dummyc
chmod a+x dummyc
$ make dummy1
$ make dummy2
$ make dummy3
$ make dummy4
$ make dummy5
echo 'Random text'
Random text
cp dummy5.sh dummy5
chmod a+x dummy5
$ make dummy6
echo 'Random text'
Random text
$ make dummy7; echo $?
dummyb
sh: dummyb: not found
make: (makefile:16): failed to build 'dummy7' exit 127
2
$ make dummy8; echo $?
dummyb
sh: dummyb: not found
make: (makefile:17): failed to build 'dummy8' exit 127
2
$ make dummy9
cp dummy9.sh dummy9
chmod a+x dummy9
$ make dummy10
cp dummy10.sh dummy10
chmod a+x dummy10
While with GNU make I get:
$ make dummya
cat dummya.sh >dummya
chmod a+x dummya
$ make dummyb
echo 'Random text'
Random text
$ make dummyc
cat dummyc.sh >dummyc
chmod a+x dummyc
$ make dummy1
make: 'dummy1' is up to date.
$ make dummy2
make: 'dummy2' is up to date.
$ make dummy3
make: 'dummy3' is up to date.
$ make dummy4
make: 'dummy4' is up to date.
$ make dummy5
echo 'Random text'
Random text
cat dummy5.sh >dummy5
chmod a+x dummy5
$ make dummy6
echo 'Random text'
Random text
$ make dummy7; echo $?
dummyb
make: dummyb: No such file or directory
make: *** [Makefile:16: dummy7] Error 127
2
$ make dummy8; echo $?
dummyb
make: dummyb: No such file or directory
make: *** [Makefile:17: dummy8] Error 127
2
$ make dummy9
make: Nothing to be done for 'dummy9'.
$ make dummy10
make: Nothing to be done for 'dummy10'.
So it is improved a lot but there are still differences.
@rmyorston I have created a repo with almost all combinations for testing: https://github.com/ale5000-git/make-test
I don't see make dummy6
succeeding with pdpmake
.
There are differences in the messages issued but those aren't significant.
The only significant difference is that pdpmake
creates the phony target dummy5
. (So does Schily make
, though it doesn't have an inference rule for .sh
, so one has to be provided for the purposes of this test.)
The issue with phony targets is unrelated to empty commands. The GNU make
documentation says:
The implicit rule search (see Using Implicit Rules) is skipped for .PHONY targets.
This is not the case in pdpmake
.
Phony targets are new in POSIX 2024. I can't immediately find anything in the standard that requires inference rules to be skipped for phony targets. I may need to read it more closely.
I don't see
make dummy6
succeeding withpdpmake
.
Right, probably I have mistyped something somewhere. Now I have updated the test results.
1) I noticed there is also the difference of cp
vs cat
, is it not specified in POSIX?
2) PHONY: https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html
A phony target is one that is not really the name of a file; rather it is just a name for a recipe to be executed when you make an explicit request.
If the PHONY target is one that is not really the name of a file, then the inference rules
that presume that it is a real file (since it use cp/cat on a real file) it make sense to skip them.
Probably it is implied even if not directly specified (just my guess).
the difference of cp vs cat, is it not specified in POSIX?
It is. The default .sh
rule in POSIX uses cp
, so that's what pdpmake
uses.
It certainly makes sense to skip inference rules for phony targets. Though it is possible to write an inference rule that doesn't create a file, just as it is with a target rule.
It needs more consideration.
Is it possible to just skip the ones that access files?
Since it cite improve performance
, it should include also test -e filename.sh
, not just file creation but any type of disk access.
Is it possible to just skip the ones that access files?
I don't think it's feasible to try that. The commands associated with a rule can be of arbitrary complexity.
The most relevant thing in POSIX is probably:
If a phony target's commands are executed, that phony target shall then be considered up-to-date until the execution of make completes.
This might be taken to imply that the commands are to come from a target rule, but it doesn't exclude the possibility that they're obtained from an inference rule. The latter would still be "a phony target's commands". In the absence of an explicit exclusion of inference rules it's safest to suppose they are allowed (even if only accidentally).
GNU make
doesn't allow the use of implicit rules for phony targets. This includes both inference rules and the .DEFAULT
target.
The man page for BSD make
says:
Suffix-transformation rules are not applied to .PHONY targets.
There's no mention of the .DEFAULT
target, but by experiment I find that it can be used for a phony target.
My plan is to disallow the use of inference rules and the .DEFAULT
target for phony targets as a non-POSIX extension. This matches what GNU make
does.
When the POSIX 2024 standard is being enforced it will allow the use of inference rules and the .DEFAULT
target for phony targets.
POSIX 2017 doesn't support phony targets so there can be no special treatment for them.
I just started and I still don't understand everything about make but wouldn't it make sense to skip just the default inference rules (the one from make itself) and leave enabled the ones specified in the Makefile?
The problem isn't where the inference rules come from, it's what they do.
I'm sure Makefile authors are just as capable of writing problematic inference rules as POSIX.
What I mean is (trying to predict what a generic Makefile author want): If Makefile authors write inference rules specifically in the Makefile maybe they want them applied but instead the default ones that they didn't write maybe they want to avoid them with PHONY.
But it is just my guess.
I've implemented my plan, so inference rules and the .DEFAULT
target aren't used for phony targets as a non-POSIX extension.
The make
in busybox-w32 has been updated to match.
If there is a file named
./my_file.sh
then usingmake my_file
will do this:On GNU make it can be prevented with
my_file: ;
inside the Makefile but it doesn't seems to work with pdpmake.On GNU make for an empty recipe it always say:
make: 'my_file' is up to date.
More info: https://www.gnu.org/software/make/manual/html_node/Empty-Recipes.html