[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: different behavior on 3.82, 3.81, 3.80-and-older

From: Paul Smith
Subject: Re: different behavior on 3.82, 3.81, 3.80-and-older
Date: Tue, 6 Sep 2011 18:15:05 -0400

On Tue, 2011-09-06 at 16:31 -0500, Brandon Casey wrote:

> all::
> SHELL_PATH = /bin/sh
> 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

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

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.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]