1

Ref: Relaxed constraints for mixing explicit and implicit rules in 4.1 ver

Even with gmake 4.1, I'm not able to work with make files having normal and implicit rules. But it works with

Given below code snippet:

test.c:

$ more Makefile

test %test: test.c
    gcc -o test test.c

$ more test.c

#include <stdio.h>
int main()
{
    printf("hellow world\n");
    return 0;
}

When I used build with above Makefile with target name addtest, it throw an error:

$ ../make_41_src/make-4.1/make -f Makefile addtest
Makefile:1: *** mixed implicit and normal rules: deprecated syntax
make: *** No rule to make target 'addtest'.  Stop.

$ ../make_41_src/make-4.1/make -version
GNU Make 4.1
Built for x86_64-unknown-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

And later when I split the target as below in Makefile, it works: $ more Makefile

test: test.c
    gcc -o test test.c
%test: test.c
    gcc -o test test.c

$ ../make_41_src/make-4.1/make -f Makefile addtest
gcc -o test test.c

And test bin is created.


with version 3.81, Makefile with implicit and normal rules works

$ make -version
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for x86_64-redhat-linux-gnu

$ more Makefile

test %test: test.c
    gcc -o test test.c

--

$ make -f Makefile addtest
gcc -o test test.c

test binary is created.

  • And the question is...? – Uwe Allner Feb 13 '15 at 18:44
  • The question is why, given the relaxing of the fatal error (from make 3.82 and 4.0) to a warning in make 4.1, that the makefile doesn't work. An actual reference to the underlying issue/change instead of the casual single sentence would have helped tremendously here. – Etan Reisner Feb 13 '15 at 19:11
  • Nothing about the change in 4.1 says it makes that rule work. It just says it makes it not a fatal error so it doesn't break *every* target. I imagine the parser/etc. changes in 3.82+ have combined so as to make that syntax simply invalid internally despite being allowed with a warning. I'd file this as an answer but it is speculation. You can wait and hope that MadScientist shows up to answer. – Etan Reisner Feb 13 '15 at 19:18
  • I have nothing to add to the discussion in the bug report (see Ross's answer below). The patch to resolve this was not created by me, nor was it tested by me (except to make sure it didn't cause other problems): my understanding is it was tested against the old versions of the Linux kernel so it's possible that their usage was different, and works, than yours, which still doesn't work. – MadScientist Feb 13 '15 at 22:35

1 Answers1

1

It appears the change in behaviour in between GNU make 4.0 and 4.1 was only made because it was a simple one line patch that allowed old Linux kernel makefiles to be used with 4.1. From the discussion on the bug report that prompted this change it looks like the assumption was that this change would restore the 3.81 functionality. However that wasn't the actual goal of the change, which was only to provide backwards compatibility with old Linux makefiles.

Here's what Paul D Smith, the comitter of the change and the current developer of GNU make, said about this in the bug report:

If it turns out that simply changing the fatal() to an error() is sufficient to resolve this, I'm willing to make that change (I won't add a flag for it; the message will simply say the syntax is unsupported and should be updated).

HOWEVER, I'm not willing to guarantee that this syntax will continue to be supported going forward. [...] If people need that level of backward-compatibility I recommend they simply keep around multiple versions of GNU make to support older code; make's installation is trivial, just the one program with no extra support files, and even after renaming it works flawlessly.

In this particular case I expect that even if the syntax still can be made to work now, when we support the ability to define explicit rules with multiple targets generated from a single recipe invocation, this syntax might not survive. The fact is that this usage IS illegal according to the documentation (it may not be explicitly proscribed but writing down all the things that are NOT legal is an impossibility--it's easily, IMO, inferrable that the syntax is not intended to be valid).

I am not willing, at this point, to embrace the idea of "fixing" it so this syntax works fully and making it legal. In my opinion it will be simply too confusing and difficult to manage all the edge cases around trying to combine two (or more, in the future) different rule models into a single statement. [...]

So the intent of the change wasn't to fix the feature, which he considers unintentional and broken, but a minimal change to resolve the issue reported.

You should either fix your makefiles so they no longer depend on a feature GNU make was never intended to have or switch to using GNU make 3.81. As Paul D Smith notes multiple versions of make can easily exist side by side.

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
  • Thanks for your reply. For my requirement, I feel going with two versions of Makefile in short term as code is legacy we have multiple Makefiles having this kind of targets definition. – Srinivas Bandi Feb 16 '15 at 05:37