Just got bitten by accidentally using the wrong gcc

Hi all,

I just forgot to ./configure with CC=gcc-4.2 CXX=g++-4.2, getting the
(broken-for-LLVM) gcc-4.1 as a compiler.
The error message that I got was this:
  make[1]: Entering directory `/home/jo/llvm-wrk/lib/VMCore'
  make[1]: *** No rule to make target
    `/home/jo/llvm-wrk/Release/bin/tblgen', needed by
    `/home/jo/llvm-wrk/lib/VMCore/Release/Intrinsics.gen.tmp'. Stop.
  make[1]: Leaving directory `/home/jo/llvm-wrk/lib/VMCore'
  make: *** [install] Error 1

It took me a while to figure out what went wrong.

I guess I'm not the only one to stumble upon this problem.

Would it be a good idea to make ./configure check whether there's an
incompatible tool configured, and carp if it finds one?

Regards,
Jo

Probably be a good idea. It's reasonably easy to check major/minor versions.

-eric

llvm's ./configure already does that for gcc < 3.

What are valid versions? Exactly 4.0 and 4.2? 4.0 and >=4.2?

dnl Verify that GCC is version 3.0 or higher
if test "$GCC" = "yes"
then
   AC_COMPILE_IFELSE([[#if !defined(__GNUC__) || __GNUC__ < 3
#error Unsupported GCC version
#endif
]], [], [AC_MSG_ERROR([gcc 3.x required, but you have a lower version])])
fi

Shantonu Sen
ssen@apple.com

llvm's ./configure already does that for gcc < 3.

What are valid versions? Exactly 4.0 and 4.2? 4.0 and >=4.2?

There's a list at http://llvm.org/docs/GettingStarted.html#brokengcc so
there is a reasonable basis.
The list isn't comprehensive, of course, and will likely grow in the
future. OTOH extending it as new problems come up should be easy to do.

dnl Verify that GCC is version 3.0 or higher
if test "$GCC" = "yes"
then
   AC_COMPILE_IFELSE([[#if !defined(__GNUC__) || __GNUC__ < 3
#error Unsupported GCC version
#endif
]], [], [AC_MSG_ERROR([gcc 3.x required, but you have a lower
version])])
fi

It might be simpler (and faster) to check the output of gcc -v.
Extending the list to other tools would be easier, too.

Anybody able to give model code for that?

Regards,
Jo

I just forgot to ./configure with CC=gcc-4.2 CXX=g++-4.2, getting the
(broken-for-LLVM) gcc-4.1 as a compiler.
The error message that I got was this:
make[1]: Entering directory `/home/jo/llvm-wrk/lib/VMCore'
make[1]: *** No rule to make target
   `/home/jo/llvm-wrk/Release/bin/tblgen', needed by
   `/home/jo/llvm-wrk/lib/VMCore/Release/Intrinsics.gen.tmp'. Stop.
make[1]: Leaving directory `/home/jo/llvm-wrk/lib/VMCore'
make: *** [install] Error 1

It took me a while to figure out what went wrong.

I guess I'm not the only one to stumble upon this problem.

Would it be a good idea to make ./configure check whether there's an
incompatible tool configured, and carp if it finds one?

Probably be a good idea. It's reasonably easy to check major/minor
versions.

Its not just a matter of checking major/minor versions. It also depends on the target and in some cases the OS.
http://llvm.org/docs/GettingStarted.html#brokengcc

So for example, GCC 3.3.3 on Suse or GCC 3.4.0 on linux/x86 (32-bit) has issues. Is it easy to check these kinds of things? Do we even want to?

I guess it could be done for things like 4.1.1 or a couple of others on the list.

-Tanya

Its not just a matter of checking major/minor versions. It also depends on
the target and in some cases the OS.
http://llvm.org/docs/GettingStarted.html#brokengcc

So for example, GCC 3.3.3 on Suse or GCC 3.4.0 on linux/x86
(32-bit) has issues. Is it easy to check these kinds of things?

uname identifies arch.

/etc/lsb-release identifies Linux distribution; I'm not sure how to
identify Apple and Cygwin.

$prog --version gives a version string for all $progs that follow GNU
conventions (most do).

Do we even want to?

Dunno, that's why I'm asking.

The one thing that counts for doing it is that ./configure is exactly
for dealing with all those little annoyances that different OSes, tool
versions etc. bring.

The thing that counts against them is that keeping the list of
broken-for-llvm tool versions is a neverending task - but then that's
normal for what ./configure does, so does this really count?

I guess it could be done for things like 4.1.1 or a couple of others on
the list.

For those cases where the script cannot fully determine the conditions,
it might be helpful to emit just a warning. Describe what the issue is,
how any problems would manifest, and let the user go ahead in such a
case.

Just my 2c.

Regards,
Jo

Joachim Durchholz wrote:

Hi,

There's a list at http://llvm.org/docs/GettingStarted.html#brokengcc so
there is a reasonable basis.
The list isn't comprehensive, of course, and will likely grow in the
future. OTOH extending it as new problems come up should be easy to do.

that list is not very reliable. For example it says that gcc-4.1 is
problematic, but I never had any problems with it on ubuntu linux. So
it's probably best to warn if a dubious tool is seen, rather than erroring
out.

Ciao,

Duncan.

I guess it could be done for things like 4.1.1 or a couple of others on
the list.

This gcc version always worked fine for me on ubuntu linux (though it
might have been 4.1.2, I don't recall).

Ciao,

Duncan.

Ah, right. It should be
  uname -m
  uname -p
  uname -i

uname without an option is the same as uname -s, which is the name of
the kernel ("Linux" for me).

BTW ./configure already gathers that information (indeed via these uname
calls).

Regards,
Jo

I have to report that the Ubuntu gcc-4.1 will fail. 'make' would run
without giving more than a few warnings, but 'make install' will
complain that it doesn't know how to build one of the intermediate
targets and error out (some VMCore/tablegen file IIRC, I don't have the
log anymore).

Of course, such a list cannot ever be reliable, so giving a warning is
probably the best strategy anyway.
Is there a real difference between an error and a warning
in ./configure, anyway?

Regards,
Jo

I recommend you don't parse version strings. In fact I switch the check to use AC_COMPILE precisely for the reason that gcc --version is totally unreliable and vendor specific. For example, what's the regular expression that tells you what the GCC version is:
i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5470) (Aspen 5470.3)

Per the rest of this thread, you can't even be sure that gcc 4.x.y on one linux distribution is compile the same as on another. If there are test cases that you'd like to embed directly into the configure script that will crash the compiler, that's probably worth doing up front. For the "gcc miscompiles llvm" bugs, can we rely on anything other than the testsuite?

Shantonu

I recommend you don't parse version strings. In fact I switch the
check to use AC_COMPILE precisely for the reason that gcc --version is
totally unreliable and vendor specific. For example, what's the
regular expression that tells you what the GCC version is:
i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5470)
(Aspen 5470.3)

Rrright. -v isn't very helpful; I'd have thought it would.

Alternatives would be
  gcc -dumpversion
or __GNUC__, __GNUC_MINOR__, and __GNUC_PATCHLEVEL__ from inside a C
program. (I just checked, __GNUC_PATCHLEVEL is documented to be
available since 3.0, -dumpversion since 3.0.4 or possibly earlier.)

Per the rest of this thread, you can't even be sure that gcc 4.x.y on
one linux distribution is compile the same as on another.

Sure. OTOH one could issue warnings instead of errors in those
situations that are difficult to diagnose exactly. Here's some
pseudocode, take a look at what's happening for 3.3.3 (which assumes
that we can identify cygwin but not SuSE 9.1):

-- snip --
  switch gcc-version
  1.*, 2.*)
    error "gcc before version 3.0 has several problems in the STL
      that effectively prevent it from compiling LLVM. Please upgrade
      to a newer gcc."
  3.2.2, 3.2.3)
    error "gcc 3.2.2 and 3.2.3 fail to compile LLVM with a bogus
      template error. Please upgrade to a newer gcc."
  3.3.3)
    if arch = cygwin then
      error "gcc 3.3.3 on Cygwin does not work. Please upgrade to a
      newer gcc."
    else
      warning "The version of GCC 3.3.3 shipped with SuSE 9.1 (and
        possibly others) does not compile LLVM correctly (it appears
        that exception handling is broken in some cases). Please
        download the FSF 3.3.3 or upgrade to a newer version of GCC."
  3.4.0)
    if arch = x86 then
      error "gcc 3.4.0 for x86 miscompiles portions of the code
        generator, causing an infinite loop in the llvm-gcc build when
        built with optimizations enabled (i.e. a release build). Please
        upgrade to a newer gcc."
  3.4.2)
    if arch = x86 then
      warning "gcc 3.4.2 for x86 miscompiles portions of the code
        generator, causing an infinite loop in the llvm-gcc build when
        built with full optimizations enabled (i.e. a release build).
        The workaround is to use -O2 instead of -O3 as optimization
        level, which has been set."
      activate OPTIMIZE_OPTION=-O2
  3.4.4)
    if arch = arm then
      warning "gcc 3.4.4 for ARM (CodeSourcery ARM 2005q3-2) miscompiles
        LLVM when building with full optimizations enabled.
        The workaround is to use -O1 instead of -O3 as optimization
        level, which has been set."
      activate OPTIMIZE_OPTION=-O1
  4.0.0)
    if arch = ia64 then
      error "gcc 4.0.0 for ia-64 miscompiles LLVM. Please upgrade to a
        newer version of gcc."
  4.1.1)
    error "gcc 4.1.1 fails to build LLVM with template concept check
      errors compiling some files.
      Please update to a newer version of gcc."
  4.1.2)
    warning "gcc 4.1.1 on OpenSuSE segfaults during libstdc++ build.
      Please update to a newer version of gcc if this is OpenSuSE."

  if arch = x86_64 && gcc-version = 3.4.* then
    error "gcc 3.4 for x86_64 miscompiles portions of LLVM. Please
      upgrade to a newer gcc."

  if Xcode 2.3 then
    warning "Xcode 2.3 crashes when compiling LLVM with full
      optimizations enabled.
      The workaround is to use -O1 instead of -O2 as optimization
      level, which has been set."
    activate OPTIMIZE_OPTION=-O2
-- snip --

I'm not sure how to best identify binutils. Assuming their version is in
binutils-version, we could do:

-- snip --
  switch binutils-version
  2.16.*)
    warning "Some 2.16.X versions of the ld linker will produce very
      long warning messages complaining that some ".gnu.linkonce.t.*"
      symbol was defined in a discarded section. You can safely ignore
      these messages as they are erroneous and the linkage is correct."
  2.17.*)
    warning "Binutils 2.17 contains a bug which causes huge link times
      (minutes instead of seconds) when building LLVM.
      Please upgrade to binutils 2.17.50.0.4 or later."
-- snip --

If there are
test cases that you'd like to embed directly into the configure script
that will crash the compiler, that's probably worth doing up front.

Can't say anything for or against that. It's not the problem I was
having.

For the "gcc miscompiles llvm" bugs, can we rely on anything other
than the testsuite?

These things cannot be tested before llvm is compiled, at which point
you're ready to run the test suite anyway.

Regards,
jo

Joachim Durchholz schrieb:

Let me give a shorter version of my previous mail:

> I recommend you don't parse version strings.

I think you mean one shouldn't parse output intended for humans, and I
agree that one should avoid this if possible.

In the case of gcc, the -dumpversion option emits an easily parsable,
bare version string.
For binutils (including ld), this is far more difficult because (a)
there is no bare version number available, and (b) llvm does not assume
GNU tools. Probably it's best to match the output of
  ld -v
for
  *GNU ld*2.16*
  *GNU ld*2.17*
to catch the two versions that are known to cause problems.

> If there are
> test cases that you'd like to embed directly into the configure script
> that will crash the compiler, that's probably worth doing up front.

That might be useful, but this is not what I'm after.
I'd like to see ./configure check the requirements listed in sections
"Software" and "Broken versions of GCC and other tools" on page
file:///home/jo/Desktop/Delta/llvm/docs/GettingStarted.html .

If a version cannot be identified, it's enough to issue a warning.
If downgrading an optimizer option is enough, then this should be made
the default (and issuing a warning would be OK so performance-conscious
people will know they should upgrade).

Regards,
Jo