On Tue, 2011-09-06 at 16:31 -0500, Brandon Casey wrote: > all:: > > SHELL_PATH = /bin/sh > > SHELL = $(SHELL_PATH) > > some_file: shell_compatibility_test FORCE > @echo making some_file > @$(SHELL) true
Are you sure you don't mean "$(SHELL) -c true" here? The above will never succeed unless "true" is a shell script. > -include some_file > > all:: shell_compatibility_test > @echo building all > > please_set_SHELL_PATH_to_a_more_modern_shell: > @echo testing shell $(SHELL) > @$$(:) > > shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell > > .PHONY: all > .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell > .PHONY: FORCE That is an... interesting... approach. > With make 3.81, make prints: > > make: Nothing to be done for `all'. > > Since "all" is a PHONY target, its commands should always be executed > right? Perhaps make is remembering the previous failure of > shell_compatibility_test and ignoring the second all:: target? It's because you're using "-include some_file", and some_file depends on shell_compatibility_test, and shell_compatibility_test depends on please_set_SHELL_PATH_to_a_more_modern_shell. Since the "some_file" target does not exist, make attempts to rebuild it so that it can be included; once the target is rebuilt then make will re-exec itself and read that file in, then continue on. But, your commands fail and so the build of those target fails. But, since you're running under "-include", where the "-" is telling make that when it tries to build the included makefile, it should ignore failures, no error is reported. So make does ignore the failure and doesn't print anything. Now make sees that none of the included makefiles were modified, so it does NOT re-exec itself and just continues on. However make already knows it can't build those targets and so the next time you try to use that target make won't try to build it. There's a good argument to be made that when make comes across a target which it tried and failed to build during the makefile rebuild phase, it should realize that the target failed the first time and treat it as a failure this time as well. It looks like your makefile was depending on the behavior of some cobwebby corners of the GNU make feature set, and those corners have since been dusted. > On make 3.82, it prints: > > make: *** No rule to make target > `please_set_SHELL_PATH_to_a_more_modern_shell', needed by > `shell_compatibility_test'. Stop. > > ?? The rule exists, but somehow marked as missing because of a prevous > failure via the some_file target? I don't get this message so I don't know why you're seeing that. > If I remove the dependency on shell_compatibility_test from the > some_file target Now you've broken the link, so that make doesn't try to build shell_compatibility_test during the first phase (when it's trying to rebuild the makefiles). So then when it tries to run that target during the normal builds, it will not have been run yet, and will fail. However, I suspect that this change will defeat the original intent of this bit of code. Without any docs as to why things were done this way I can't be sure but my suspicion is that it's trying to force the build to fail immediately in the case of a "bad shell", regardless of which target was invoked. But I could be wrong. _______________________________________________ Bug-make mailing list Bug-make@gnu.org https://lists.gnu.org/mailman/listinfo/bug-make