1INCLUDE(CheckCXXSourceCompiles)
2
3# This checks two things.  First, it checks whether
4# __attribute__((weak)) compiles in C++, when dealing with an extern
5# void() function in a namespace.  Second, it checks whether it is
6# legit syntax to test the resulting function pointer and call it if
7# it's not NULL.
8#
9# The first thing should work with GCC and compilers that claim GCC
10# compatibility (Clang, Intel, recent PGI).  The second doesn't work
11# on Mac, but does work on Linux.  That's OK, because we only need to
12# use this technique with static libraries (see Bug 6392), and Macs
13# don't like static libraries.
14#
15# #pragma weak $FUNCTION (see CheckCXXPragmaWeakCompiles.cmake in this
16# #directory) seems to be implemented by more compilers.  GCC claims
17# #to implement it "[f]or compatibility with SVR4":
18#
19# https://gcc.gnu.org/onlinedocs/gcc/Weak-Pragmas.html
20#
21# Other compilers implement this as well, probably for the same
22# reason.  For example (all links tested 20 Aug 2015):
23#
24#   - Intel's C++ compiler:
25#     https://software.intel.com/en-us/node/524560
26#   - Sun Studio 12: C++ User's Guide:
27#     http://docs.oracle.com/cd/E19205-01/819-5267/bkbkr/index.html
28#   - PGI: I can't find anything in the User's Guide or Reference, but
29#     the following bug fix report suggests that #pragma weak works
30#     (otherwise, how did PGI 2014 fix a problem with it?):
31#     https://www.pgroup.com/support/release_tprs_2014.htm
32#   - "IBM XL C/C++ for Linux, V11.1 Compiler Reference, Version 11.1":
33#     the compiler does support #pragma weak, BUT unfortunately requires
34#     the mangled C++ name:
35#     http://www-01.ibm.com/support/docview.wss?uid=swg27018970&aid=1
36#     That means it won't pass this test, though.  However, IBM XL
37#     C/C++ for AIX 13.1.2 supports __attribute__((weak)):
38#     http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.2/com.ibm.xlcpp131.aix.doc/language_ref/fn_attrib_weak.html
39FUNCTION(CHECK_CXX_ATTRIBUTE_WEAK_COMPILES VARNAME)
40  SET(SOURCE
41  "
42#include <iostream>
43
44namespace A {
45// theFunction never gets defined, because we
46// don't link with a library that defines it.
47// That's OK, because it's weak linkage.
48extern void __attribute__((weak)) theFunction ();
49}
50
51int main() {
52  std::cout << \"Hi!  I am main.\" << std::endl;
53  if (A::theFunction != NULL) {
54    // Should never be called, since we don't link
55    // with a library that defines A::theFunction.
56    A::theFunction ();
57  }
58  return 0;
59}
60  "
61  )
62
63  # This is a local variable name.  ${VARNAME} is the output variable.
64  CHECK_CXX_SOURCE_COMPILES("${SOURCE}" HAVE_CXX_ATTRIBUTE_WEAK)
65
66  IF(HAVE_CXX_ATTRIBUTE_WEAK)
67    GLOBAL_SET(${VARNAME} TRUE)
68    MESSAGE(STATUS "C++ compiler supports __attribute__((weak)) syntax and testing weak functions")
69  ELSE()
70    GLOBAL_SET(${VARNAME} FALSE)
71    MESSAGE(STATUS "C++ compiler does NOT support __attribute__((weak)) syntax and testing weak functions")
72  ENDIF()
73ENDFUNCTION()
74