tags:

views:

53

answers:

1

I have a project whose makefile uses features exclusive to GNU Make. Sadly, there are platforms we must support where GNU make is still not the default when running make.

One of my colleagues was bitten by this, when a non-GNU make implementation silently failed to build our code correctly (it expanded an automatic variable to an empty string). I want to prevent that from happening again, by generating an explicit error message instead.

What can I write in a Makefile to distinguish GNU make from non-GNU make, print a clear error, and exit?

I've already figured out a workaround in renaming my real makefile to GNUmakefile, and putting a small stub in Makefile, but I'd rather something more direct.

The answers by Beta and Dan Moulding look really nice and simple, but on AIX 6.1, the make implementation can't handle either of them:

$ cat testmake

foo:
        touch foo

ifeq ($(shell $(MAKE) -v | grep GNU),)
$(error this is not GNU Make)
endif

ifeq "${MAKE_VERSION}" ""
$(info GNU Make not detected)
$(error ${MIN_MAKE_VER_MSG})
endif


$ /usr/bin/make -f testmake
"testmake", line 5: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 6: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 7: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 8: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 11: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 12: make: 1254-055 Dependency line needs colon or double colon operator.
"testmake", line 13: make: 1254-055 Dependency line needs colon or double colon operator.
make: 1254-058 Fatal errors encountered -- cannot continue.

I run into similar issues on both archaic and modern versions (Solaris 8 & 10) of Sun's make. That one's less critical, but would be nice to manage.

+1  A: 

I don't know of any internal feature that is definitely unique to GNUMake, but here's a kludge: call "make -v" and parse the output for "GNU" (since it seems unlikely that a non-GNU Make would have MAKE set to a GNU Make):

ifeq ($(shell $(MAKE) -v | grep GNU),)
$(error this is not GNU Make)
endif

EDIT:
Like Dan Moulding, I am starting to see the real size of this problem. As written, it requires a Makefile that is syntactically correct in all versions of Make. I don't have access to Sun Make (and I can't find manuals for it) so I don't know whether that's even possible, or how to write it if it is, or how to test it if I did.

But I can suggest an approach that might work. Maybe something like this can be made universal:

default:
  ./runGNUMake.pl

That's it, that's the whole makefile. Then write the runGNUMake script in Perl (or bash, or whatever you like) that will do something like my "make -v" kludge and then either print the error message or run "make -f realMakefile".

Beta
I had thought of doing this in an external script that ran before make, but I hadn't thought of embedding it in the makefile itself.
Novelocrat
Doesn't work on AIX 6.1 :-(
Novelocrat
Novelocrat: really? How does it fail, does a non-GNU Make have a `MAKE` that appears to be set to a GNU Make, or does a GNU Make appear to be non-GNU? ( I guess we could call those "false positive" and "false negative" respectively.)
Beta
I edited the question to show the failure. It doesn't like `ifeq`.
Novelocrat