[cmake-developers] CheckSymbolExists is unreliable

Brad King brad.king at kitware.com
Tue Jan 3 09:59:39 EST 2012


On 1/2/2012 5:24 PM, Rolf Eike Beer wrote:
> It looks like gcc simply optimizes out any reference to the tested symbol.
> Given the fact that we don't really ever use that symbol anywhere it is even
> correct to do so. Just that this is not what we want.

Yuck.  Clearly a less-optimizable approach is needed.

> I pushed a topic test-symbol-exists to stage that verifies that this is indeed
> a problem in Check{,CXX}SymbolExists, it iterates through all build
> configurations (were this problem does _not_ happen) and later explicitely
> adds a -O3 test if it is gcc/g++ which then _does_ fail.
>
> So, there are 3 points that I need advise:
>
> -what should happen with this topic? Should I merge it to next? Then we will
> get a ton of failures on at least everything that is using GNU compilers.

Certainly we should add tests for these modules.  They are critical to
many projects.  However, let's not add a test when we know it will break
immediately.  Please also rebase the topic so it does not depend on your
FindDoxygen topic.  Add a commit prior to the test to fix the behavior
as discussed below.

> -which other compilers can be tested this way, I mean using -O3? From what I
> know Clang does understand this and even -O4, what is about the Intel one?

Let's start with the GNU case and add more later.  I suspect that if we can
convince GCC -O3 to keep the symbol (see below) then no other compiler will
be able to optimize it out.

> -how  to fix this thing at the end? I was thinking about just doing
>
> #include<stdio.h>
> printf("%s is at %p\n", ${SYMBOL},&${SYMBOL}));
>
> Is anyone aware of some place where this wouldn't work? Or should I just put
> this in and try out?

We don't want the test to depend on any symbols other than the one tested,
even runtime library symbols.  Some cross-compilers may not provide everything
by default.  We just need to make the return value depend on the symbol.  I
worked this out in "Modules/CMakeCCompilerId.c.in".  Note that the return
value should also depend on a runtime argument (argc) so the optimizer cannot
make any assumptions.

I think this will work:

  int main(int argc, char* argv[])
  {
    (void)argv;
    return ((int*)(&SYMBOL))[argc];
  }

-Brad



More information about the cmake-developers mailing list