Discussion:
AC_PROG_CC wrongly setting $GCC=yes while clang is used
Bastien Chevreux
2014-09-07 20:52:43 UTC
Permalink
Hello there,

having used gcc for ages, I decided to try and play around with clang for one of my C/C++ projects. Unfortunately, it looks as if autoconf 2.69 gets things horribly wrong with clang.

I’m literally forcing it to find only clang, but it still insists on trying to tell me I’m running a gcc. In my configure.ac I have:


AC_PROG_CC([clang])
echo "I have dollarGCC= $GCC"
exit

which results in the following output:

checking for clang... clang
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether clang accepts -g... yes
checking for clang option to accept ISO C89... none needed
checking whether clang understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of clang... gcc3
I have dollarGCC= yes

I’m not sure how to continue from here. I looked at the config log, but only see the following:

configure:3334: checking for clang
configure:3350: found /usr/bin/clang
configure:3361: result: clang
configure:3392: checking for C compiler version
configure:3401: clang --version >&5
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix
configure:3412: $? = 0
configure:3401: clang -v >&5
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix
configure:3412: $? = 0
configure:3401: clang -V >&5
clang: error: argument to '-V' is missing (expected 1 value)
clang: error: no input files
configure:3412: $? = 1
configure:3401: clang -qversion >&5
clang: error: unknown argument: '-qversion' [-Wunused-command-line-argument-hard-error-in-future]
clang: note: this will be a hard error (cannot be downgraded to a warning) in the future
clang: error: no input files
configure:3412: $? = 1
configure:3432: checking whether the C compiler works
configure:3454: clang -mmacosx-version-min=10.6 conftest.c >&5
configure:3458: $? = 0
configure:3506: result: yes
configure:3509: checking for C compiler default output file name
configure:3511: result: a.out
configure:3517: checking for suffix of executables
configure:3524: clang -o conftest -mmacosx-version-min=10.6 conftest.c >&5
configure:3528: $? = 0
configure:3550: result:
configure:3572: checking whether we are cross compiling
configure:3580: clang -o conftest -mmacosx-version-min=10.6 conftest.c >&5
configure:3584: $? = 0
configure:3591: ./conftest
configure:3595: $? = 0
configure:3610: result: no
configure:3615: checking for suffix of object files
configure:3637: clang -c -mmacosx-version-min=10.6 conftest.c >&5
configure:3641: $? = 0
configure:3662: result: o
configure:3666: checking whether we are using the GNU C compiler
configure:3685: clang -c -mmacosx-version-min=10.6 conftest.c >&5
configure:3685: $? = 0
configure:3694: result: yes

Am I doing something wrong and if yes, any idea how this can be fixed?

Best,
Bastien
Paul Smith
2014-09-08 04:24:26 UTC
Permalink
Post by Bastien Chevreux
having used gcc for ages, I decided to try and play around with clang
for one of my C/C++ projects. Unfortunately, it looks as if autoconf
2.69 gets things horribly wrong with clang.
In what way? IIUC, configure has discovered that clang is close enough
to the GCC user interface that it can treat clang as GCC, for the
purposes of generating autoconf and automake scripts.

Is there actually any failure here? Do the resulting Makefiles invoke
clang properly for compiling and linking? Do they correctly handle
automatic dependencies? If something fails or doesn't work right please
post those error messages, etc.

In particular, this:

configure:3666: checking whether we are using the GNU C compiler
configure:3685: clang -c -mmacosx-version-min=10.6 conftest.c >&5
configure:3685: $? = 0
configure:3694: result: yes

Appears to show that clang is defining the __GNUC__ built-in compiler
flag, presumably for compatibility with GCC source code. So IF there's
any real problem here, which I'm not sure there is, the problem is in
clang claiming to be something it's not.
Thomas Jahns
2014-09-08 08:44:00 UTC
Permalink
Post by Bastien Chevreux
configure:3666: checking whether we are using the GNU C compiler
configure:3685: clang -c -mmacosx-version-min=10.6 conftest.c >&5
configure:3685: $? = 0
configure:3694: result: yes
Appears to show that clang is defining the __GNUC__ built-in compiler
flag, presumably for compatibility with GCC source code. So IF there's
any real problem here, which I'm not sure there is, the problem is in
clang claiming to be something it's not.
Happens just the same for icc and since the Intel compiler supports enough of
the pragma's and non-std features of gcc, this works out fine for me so far.

Regards, Thomas
Eric Blake
2014-09-08 14:29:45 UTC
Permalink
Post by Thomas Jahns
Post by Bastien Chevreux
configure:3666: checking whether we are using the GNU C compiler
configure:3685: clang -c -mmacosx-version-min=10.6 conftest.c >&5
configure:3685: $? = 0
configure:3694: result: yes
Appears to show that clang is defining the __GNUC__ built-in compiler
flag, presumably for compatibility with GCC source code. So IF there's
any real problem here, which I'm not sure there is, the problem is in
clang claiming to be something it's not.
Happens just the same for icc and since the Intel compiler supports enough of
the pragma's and non-std features of gcc, this works out fine for me so far.
Maybe it's as simple as patching autoconf to change the message to
"checking whether the compiler understands GNU C extensions", to match
the reality of how it works these days.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Paul Eggert
2014-09-08 16:27:24 UTC
Permalink
Post by Eric Blake
Maybe it's as simple as patching autoconf to change the message
Thanks, good idea. I installed the attached.
Marko Lindqvist
2014-09-08 16:37:23 UTC
Permalink
Post by Eric Blake
Post by Thomas Jahns
Post by Bastien Chevreux
configure:3666: checking whether we are using the GNU C compiler
configure:3685: clang -c -mmacosx-version-min=10.6 conftest.c >&5
configure:3685: $? = 0
configure:3694: result: yes
Appears to show that clang is defining the __GNUC__ built-in compiler
flag, presumably for compatibility with GCC source code. So IF there's
any real problem here, which I'm not sure there is, the problem is in
clang claiming to be something it's not.
Happens just the same for icc and since the Intel compiler supports enough of
the pragma's and non-std features of gcc, this works out fine for me so far.
Maybe it's as simple as patching autoconf to change the message to
"checking whether the compiler understands GNU C extensions", to match
the reality of how it works these days.
The $GCC example brings up another problem, though. Even though
autoconf itself works perfectly by treating clang as gcc (and clang++
as g++), user scripts may not. Is there need to update documentation
abour $GCC to say that it should not be taken literally, but just to
mean some kind of gcc compatibility.


- ML
Paul Eggert
2014-09-08 17:17:48 UTC
Permalink
Post by Marko Lindqvist
Is there need to update documentation
abour $GCC to say that it should not be taken literally, but just to
mean some kind of gcc compatibility.
Thanks, good suggestion. I installed the attached patch.
Bastien Chevreux
2014-09-08 18:36:03 UTC
Permalink
Post by Marko Lindqvist
Post by Eric Blake
Maybe it's as simple as patching autoconf to change the message to
"checking whether the compiler understands GNU C extensions", to match
the reality of how it works these days.
The $GCC example brings up another problem, though. Even though
autoconf itself works perfectly by treating clang as gcc (and clang++
as g++), user scripts may not. Is there need to update documentation
abour $GCC to say that it should not be taken literally, but just to
mean some kind of gcc compatibility.
So I’ve learned quite a deal in this thread: once I knew the specifics of the autoconf test I had lots of fun reading up a number of pages all across the net as I’ve not been the first to fall into this trap (see e.g. http://rem.eifzilla.de/archives/2012/08/10/identify-theft-by-clang ).

I think part of the problem is the wording in the GCC manual regarding __GNUC__ (https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html):
If all you need to know is whether or not your program is being compiled by GCC,
***or a non-GCC compiler that claims to accept the GNU C dialects,***
you can simply test __GNUC__.

The problem is this “or compiler that claims” sentence: I think they shot themselves in the foot by allowing that. No wonder clang, icc (and maybe others) start to define __GNUC__ themselves … without ever reaching 100% compatibility this is bound to fail at some point.

Would it be worthwhile to forward this to the GNU compiler maintainers so that they could maybe correct their course by maybe introducing a define which is ‘reserved’ for telling that, yes, this is indeed a GNU compiler?

A developer (maybe a non-autoconf-expert like me) who needs to write a configure.ac only every once in a while and who does not know all these nitty gritty little details will very probably fall into the trap of assuming that the autoconf $GCC is yes when autoconf assures me within reasonable bounds that the compiler is indeed from the GNU CC. Especially when looking at tons of already existing autoconf scripts as examples which all go like this:

if test $GCC = yes ; then
# ok, we have gcc, set special flags for it

else
# need to test /set flags for other compilers
...
fi

I very much would expect, as programmer, to have autoconf AC_PROG_CC set
- for gcc/g++ et al: GCC=yes ; GNUC=yes
- clang, icc (and maybe other that define __GNUC__): GCC=no; GNUC=yes

Which brings me to what sparked my initial mail to the list: is there somewhere in the autoconf system a macro which gives back the compiler family of the used compiler so that one can take some action? Something which would set a variable (e.g. COMPILER_FAMILY) so that one can write something like this:

case $COMPILER_FAMILY in
gnu)

;;
clang)

;;
icc)

;;
sunc)

;;
hpc)

;;
# (and others)
esac

Best,
Bastien
Paul Eggert
2014-09-08 18:57:50 UTC
Permalink
Post by Bastien Chevreux
Which brings me to what sparked my initial mail to the list: is there somewhere in the autoconf system a macro which gives back the compiler family of the used compiler so that one can take some action?
That would not be The Autoconf Way. :-)

The Autoconf approach is to test for features, not to test for compiler
version and then infer features from the version. If you need webbed
feet, then test for webbed feet; don't ask "Are you a duck?".
Bastien Chevreux
2014-09-08 19:34:47 UTC
Permalink
Post by Paul Eggert
Post by Bastien Chevreux
Which brings me to what sparked my initial mail to the list: is there somewhere in the autoconf system a macro which gives back the compiler family of the used compiler so that one can take some action?
That would not be The Autoconf Way. :-)
The Autoconf approach is to test for features, not to test for compiler version and then infer features from the version. If you need webbed feet, then test for webbed feet; don't ask "Are you a duck?”.
I do see your point.

But it makes things *really* interesting for a configure.ac writer to take some action already during ./configure if one knows that, e.g., optimising with "-OMG” helps to speed your code 10 times for supercompiler 1.2.0 onwards, but not for 1.7.0 to 1.8.3 because of some weird compiler bug. And then users complain your program is worthless because of wrong results you didn’t even know could be produced. Been there, seen that, not funny.

And I’d say that often configure-writers do not think (or cannot think) of everything when writing checks. Continuing your example:

------
checking for webbed feet … yes
checking for pecker … yes
checking for can swim … yes
checking for can lay eggs … yes
perfect, your duck environment is ready, just type make.
$ make
error: ‘platypus’: unknown parameter ‘—quack’
------

Yeah, I know, he should’ve checked for ‘can quack’. Or ‘can fly’. Or ‘has feathers'. But not everyone knows that Down Under there are mammals who got pretty good at imitating duck features lately.

Joke aside: would there be, from the autoconf maintainers' side, the interest in actually having a module which would give back the compiler family? I’m thinking of writing one based on what I can see at http://sourceforge.net/p/predef/wiki/Compilers/

Best,
B.
Marko Lindqvist
2014-09-08 20:30:30 UTC
Permalink
Post by Bastien Chevreux
Down Under there are mammals who got pretty good at imitating duck features lately.
That's exactly the reason for autoconf-way:

checking for duck ... no
Configure failed! Needs to be able to swim, and you've got shark.

vs

checking for can swim ... yes


or


checking for duck ... yes
...
weird compiler error as there's no big enough lake nearby


vs

checking for living at lake ... no



- ML
Bastien Chevreux
2014-09-08 20:51:55 UTC
Permalink
Post by Bastien Chevreux
Down Under there are mammals who got pretty good at imitating duck features lately.
[…]
OK, before this duck thing gets a bit out of hand, back to a more day-to-day-like problem:

I would need to test whether the compiler accepts “-OMG”
AND
I would need a way to test whether the compiler is specifically GCC (not clang, not icc) between 3.2.0 and 3.4.2

as I would need to disable -OMG on GCC version 3.2.0 to 3.4.2 because of user report of miscompilations and/or buggy code there.

How do I do that the autoconf way with the tools I have in 2.69 and the macros of the autoconf archive? I already do have code for testing the version numbers, it’s the specific GCC/clang and -OMG tests which are a bit more problematic.

Best,
B.

PS: “-OMG" and the GCC versions are simplified, made up examples
Marko Lindqvist
2014-09-08 21:07:25 UTC
Permalink
Post by Bastien Chevreux
Post by Bastien Chevreux
Down Under there are mammals who got pretty good at imitating duck features lately.
[…]
I'm ginving theoretical autoconf-way answer. I admit that in some
individual cases the Right Thing(tm) might be too much work in
practice, and the "check version number" hack is justifiable.
Post by Bastien Chevreux
I would need to test whether the compiler accepts “-OMG”
Test if compiler accepts "-OMG"
Post by Bastien Chevreux
AND
I would need a way to test whether the compiler is specifically GCC (not clang, not icc) between 3.2.0 and 3.4.2
as I would need to disable -OMG on GCC version 3.2.0 to 3.4.2 because of user report of miscompilations and/or buggy code there.
Test if compiler miscompiles with "-OMG"



- ML
Bastien Chevreux
2014-09-08 21:25:48 UTC
Permalink
Post by Marko Lindqvist
I'm ginving theoretical autoconf-way answer. I admit that in some
individual cases the Right Thing(tm) might be too much work in
practice, and the "check version number" hack is justifiable.
Indeed it may be. Delivering the source code with a 352 MiB (compressed, some 2.4 GiB uncompressed) test data set that triggers the error and which computes 17 hrs (on faster faster machines with Xeons and north of 64 GiB RAM (your mileage may vary)) until the result can be checked against the known good outcome in autoconf falls into this category I suppose. I’m not sure the Debian guys would approve having this in their weekly builds :-)

B.
Marko Lindqvist
2014-09-08 21:38:01 UTC
Permalink
Post by Bastien Chevreux
Post by Marko Lindqvist
I'm ginving theoretical autoconf-way answer. I admit that in some
individual cases the Right Thing(tm) might be too much work in
practice, and the "check version number" hack is justifiable.
Indeed it may be. Delivering the source code with a 352 MiB (compressed, some 2.4 GiB uncompressed) test data set that triggers the error and which computes 17 hrs (on faster faster machines with Xeons and north of 64 GiB RAM (your mileage may vary)) until the result can be checked against the known good outcome in autoconf falls into this category I suppose. I’m not sure the Debian guys would approve having this in their weekly builds :-)
B.
Maybe gcc regression test set has a bit lighter test added against
the bug in question, added when it was fixed.


- ML
Bastien Chevreux
2014-09-08 21:53:20 UTC
Permalink
Post by Marko Lindqvist
Maybe gcc regression test set has a bit lighter test added against
the bug in question, added when it was fixed.
If only one knew exactly which one of the bugs or features they fixed it was. There are dozens/hundreds, digging through all possible error reports and trying to correlate a compiler regression test with the test set I have could take days, weeks or maybe months, who knows.

And that’s the point: as a developer of a program who uses a compiler just as a mean to get things done, I’m totally not interested in this … and I shouldn’t. It’s enough for me to know that a given compiler is buggy between version X and Y when a given flag is used to simply not use that flag there. Maybe also give the user who used ./configure a warning that the program will run a bit slower with the given compiler.

But that’s all there should be to it.

B.
Russ Allbery
2014-09-09 01:55:34 UTC
Permalink
Post by Bastien Chevreux
And that’s the point: as a developer of a program who uses a compiler
just as a mean to get things done, I’m totally not interested in this …
and I shouldn’t. It’s enough for me to know that a given compiler is
buggy between version X and Y when a given flag is used to simply not
use that flag there.
For this particular situation, which I think is relatively rare, I would
just parse the output of gcc -v.
--
Russ Allbery (***@eyrie.org) <http://www.eyrie.org/~eagle/>
Russ Allbery
2014-09-08 22:26:18 UTC
Permalink
Post by Bastien Chevreux
Would it be worthwhile to forward this to the GNU compiler maintainers
so that they could maybe correct their course by maybe introducing a
define which is ‘reserved’ for telling that, yes, this is indeed a GNU
compiler?
That's what __GNUC__ was for. However, from the perspective of the
authors of the other compilers, this is a bug -- they want to be able to
compile code that uses GCC extensions, which is why they're implementing
those extensions. So they *want* their compiler to be detected as capable
of supporting GCC extensions.

So, if GCC added a new define, the other compilers would just start
defining that symbol as well.

I'm afraid the only hope you have, if you depend on extensions that are
not implemented by other compilers, is to test explicitly for those
extensions.
--
Russ Allbery (***@eyrie.org) <http://www.eyrie.org/~eagle/>
Thomas Jahns
2014-09-09 08:10:35 UTC
Permalink
Post by Russ Allbery
Post by Bastien Chevreux
Would it be worthwhile to forward this to the GNU compiler maintainers
so that they could maybe correct their course by maybe introducing a
define which is ‘reserved’ for telling that, yes, this is indeed a GNU
compiler?
That's what __GNUC__ was for. However, from the perspective of the
authors of the other compilers, this is a bug -- they want to be able to
compile code that uses GCC extensions, which is why they're implementing
those extensions. So they *want* their compiler to be detected as capable
of supporting GCC extensions.
So, if GCC added a new define, the other compilers would just start
defining that symbol as well.
I'm afraid the only hope you have, if you depend on extensions that are
not implemented by other compilers, is to test explicitly for those
extensions.
It should also be noted that among those compilers which define __GNUC__ but may
not have all the features some author expects are earlier versions of gcc.

I'd rather not rely on $GCC for anything and rather test the feature instead.

Regards, Thomas

Peter Johansson
2014-09-08 23:33:55 UTC
Permalink
perhaps not kosher and yadda yadday, but

http://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html#ax_compiler_vendor
--
Peter Johansson
Bastien Chevreux
2014-09-09 07:31:35 UTC
Permalink
Post by Peter Johansson
perhaps not kosher and yadda yadday, but
http://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html#ax_compiler_vendor
Ummm … thank you. Why on earth did I not see this? Thank you. I think I was to focussed on the fact that GNU’s not a ‘vendor’. Thank you.

Bastien

PS: did I already say thank you? No? Well then: thank you.
David A. Wheeler
2014-09-08 19:53:34 UTC
Permalink
Post by Bastien Chevreux
case $COMPILER_FAMILY in
gnu)
?
;;
clang)
?
;;
icc)
?
;;
sunc)
?
;;
hpc)
?
;;
# (and others)
esac
I think that would be un-autotools-like. After all, tomorrow some compiler (say clang) may add support for something, or change how it does something. It's usually better to probe for a specific capability, and *not* assume that "only GCC supports X" (or similar).

Typically you use the existing mechanisms to probe for particular functions or .h files. Dale Visser's recent patch makes it easy to probe if a specific compiler flag is accepted (if accepted, I hope it will be).

--- David A. Wheeler
David A. Wheeler
2014-09-08 22:05:52 UTC
Permalink
OK, before this duck thing gets a bit out of hand...
Oh, it's *way* too late for that :-).
I would need to test whether the compiler accepts ?-OMG?
AND
I would need a way to test whether the compiler is specifically GCC (not clang, not icc) between 3.2.0 and 3.4.2
as I would need to disable -OMG on GCC version 3.2.0 to 3.4.2 because of user report of miscompilations and/or buggy code there.
...
I'm ginving theoretical autoconf-way answer. I admit that in some
individual cases the Right Thing(tm) might be too much work in
practice, and the "check version number" hack is justifiable.
I would need to test whether the compiler accepts ?-OMG?
Test if compiler accepts "-OMG"
AND
I would need a way to test whether the compiler is specifically GCC (not clang, not icc) between 3.2.0 and 3.4.2
as I would need to disable -OMG on GCC version 3.2.0 to 3.4.2 because of user report of miscompilations and/or buggy code there.
Test if compiler miscompiles with "-OMG"
I agree with Marko Lindqvist's answer; if possible, it's better to directly detect if the miscompile happens. Sometimes it's too hard, but typically you can have a short-and-simple test case. Version testing is a bad idea, even in this case. Many Linux distributions backport "important" bug fixes, so comparing version numbers doesn't always work anyway!

However, compiler flags are special. Unknown compiler flags can be tricky to detect. E.G.:
gcc -o hello -IS_DUCK hello.c
will silently work, and report no error code.

Portably adding compiler flags is one of the nice features of Dale Visser's recent proposed patch (e.g., it adds AC_APPEND_FLAG_IFVALID), which I hope will be added.

--- David A. Wheeler
Loading...