[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