ax_cxx_compile_stdcxx_11.m4 6.56 KB
Newer Older
Kenton Varda's avatar
Kenton Varda committed
1 2
# ============================================================================
#  http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
3
#  Additionally modified to detect -stdlib by Kenton Varda.
Kenton Varda's avatar
Kenton Varda committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# ============================================================================
#
# SYNOPSIS
#
#   AX_CXX_COMPILE_STDCXX_11([ext|noext])
#
# DESCRIPTION
#
#   Check for baseline language coverage in the compiler for the C++11
#   standard; if necessary, add switches to CXXFLAGS to enable support.
#   Errors out if no mode that supports C++11 baseline syntax can be found.
#   The argument, if specified, indicates whether you insist on an extended
#   mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. -std=c++11).
#   If neither is specified, you get whatever works, with preference for an
#   extended mode.
#
20 21 22 23 24
#   Additionally, check if the standard library supports C++11.  If not,
#   try adding -stdlib=libc++ to see if that fixes it.  This is needed e.g.
#   on Mac OSX 10.8, which ships with a very old libstdc++ but a relatively
#   new libc++.
#
25 26 27 28 29 30 31
#   Both flags are actually added to CXX rather than CXXFLAGS to work around
#   a bug in libtool: -stdlib is stripped from CXXFLAGS when linking dynamic
#   libraries because it is not recognized.  A patch was committed to mainline
#   libtool in February 2012 but as of June 2013 there has not yet been a
#   release containing this patch.
#      http://git.savannah.gnu.org/gitweb/?p=libtool.git;a=commit;h=c0c49f289f22ae670066657c60905986da3b555f
#
Kenton Varda's avatar
Kenton Varda committed
32 33 34 35
# LICENSE
#
#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
36
#   Copyright (c) 2013 Kenton Varda <temporal@gmail.com>
Kenton Varda's avatar
Kenton Varda committed
37 38 39 40 41 42 43 44 45 46
#
#   Copying and distribution of this file, with or without modification, are
#   permitted in any medium without royalty provided the copyright notice
#   and this notice are preserved. This file is offered as-is, without any
#   warranty.

#serial 1

m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
  template <typename T>
47 48 49 50
  struct check
  {
    static_assert(sizeof(int) <= sizeof(T), "not big enough");
  };
Kenton Varda's avatar
Kenton Varda committed
51

52
  typedef check<check<bool>> right_angle_brackets;
Kenton Varda's avatar
Kenton Varda committed
53

54 55
  int a;
  decltype(a) b;
Kenton Varda's avatar
Kenton Varda committed
56

57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
  typedef check<int> check_type;
  check_type c;
  check_type&& cr = static_cast<check_type&&>(c);

  // GCC 4.7 introduced __float128 and makes reference to it in type_traits.
  // Clang doesn't implement it, so produces an error.  Using -std=c++11
  // instead of -std=gnu++11 works around the problem.  But on some
  // platforms we need -std=gnu++11.  So we want to make sure the test of
  // -std=gnu++11 fails only where this problem is present, and we hope that
  // -std=c++11 is always an acceptable fallback in these cases.  Complicating
  // matters, though, is that we don't want to fail here if the platform is
  // completely missing a C++11 standard library, because we want to probe that
  // in a later test.  It happens, though, that Clang allows us to check
  // whether a header exists at all before we include it.
  //
  // So, if we detect that __has_include is available (which it is on Clang),
  // and we use it to detect that <type_traits> (a C++11 header) exists, then
  // we go ahead and #include it to see if it breaks.  In all other cases, we
  // don't #include it at all.
  #ifdef __has_include
  #if __has_include(<type_traits>)
  #include <type_traits>
  #endif
  #endif
Kenton Varda's avatar
Kenton Varda committed
81 82
])

83 84 85 86 87 88 89
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody_lib], [
  #include <initializer_list>
  #include <unordered_map>
  #include <atomic>
  #include <thread>
])

Kenton Varda's avatar
Kenton Varda committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
  m4_if([$1], [], [],
        [$1], [ext], [],
        [$1], [noext], [],
        [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
  AC_LANG_ASSERT([C++])dnl
  ac_success=no
  AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
  ax_cv_cxx_compile_cxx11,
  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
    [ax_cv_cxx_compile_cxx11=yes],
    [ax_cv_cxx_compile_cxx11=no])])
  if test x$ax_cv_cxx_compile_cxx11 = xyes; then
    ac_success=yes
  fi

  m4_if([$1], [noext], [], [dnl
  if test x$ac_success = xno; then
    for switch in -std=gnu++11 -std=gnu++0x; do
      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
      AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
                     $cachevar,
112 113
        [ac_save_CXX="$CXX"
         CXX="$CXX $switch"
Kenton Varda's avatar
Kenton Varda committed
114 115 116
         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
          [eval $cachevar=yes],
          [eval $cachevar=no])
117
         CXX="$ac_save_CXX"])
Kenton Varda's avatar
Kenton Varda committed
118
      if eval test x\$$cachevar = xyes; then
119
        CXX="$CXX $switch"
Kenton Varda's avatar
Kenton Varda committed
120 121 122 123 124 125 126 127 128 129 130 131
        ac_success=yes
        break
      fi
    done
  fi])

  m4_if([$1], [ext], [], [dnl
  if test x$ac_success = xno; then
    for switch in -std=c++11 -std=c++0x; do
      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
      AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
                     $cachevar,
132 133
        [ac_save_CXX="$CXX"
         CXX="$CXX $switch"
Kenton Varda's avatar
Kenton Varda committed
134 135 136
         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
          [eval $cachevar=yes],
          [eval $cachevar=no])
137
         CXX="$ac_save_CXX"])
Kenton Varda's avatar
Kenton Varda committed
138
      if eval test x\$$cachevar = xyes; then
139
        CXX="$CXX $switch"
Kenton Varda's avatar
Kenton Varda committed
140 141 142 143 144 145 146 147
        ac_success=yes
        break
      fi
    done
  fi])

  if test x$ac_success = xno; then
    AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
148 149 150 151 152 153 154 155 156 157 158 159 160 161
  else
    ac_success=no
    AC_CACHE_CHECK(whether $CXX supports C++11 library features by default,
                   ax_cv_cxx_compile_cxx11_lib,
      [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody_lib])],
         [ax_cv_cxx_compile_cxx11_lib=yes],
         [ax_cv_cxx_compile_cxx11_lib=no])
      ])
    if test x$ax_cv_cxx_compile_cxx11_lib = xyes; then
      ac_success=yes
    else
      # Try with -stdlib=libc++
      AC_CACHE_CHECK(whether $CXX supports C++11 library features with -stdlib=libc++,
                     ax_cv_cxx_compile_cxx11_lib_libcxx,
162 163
        [ac_save_CXX="$CXX"
         CXX="$CXX -stdlib=libc++"
164 165 166
         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody_lib])],
          [eval ax_cv_cxx_compile_cxx11_lib_libcxx=yes],
          [eval ax_cv_cxx_compile_cxx11_lib_libcxx=no])
167
         CXX="$ac_save_CXX"])
168
      if eval test x$ax_cv_cxx_compile_cxx11_lib_libcxx = xyes; then
169
        CXX="$CXX -stdlib=libc++"
170 171 172 173 174 175
        ac_success=yes
        break
      fi
    fi

    if test x$ac_success = xno; then
Kenton Varda's avatar
Kenton Varda committed
176
      AC_MSG_ERROR([*** A C++ library with support for C++11 features is required.])
177
    fi
Kenton Varda's avatar
Kenton Varda committed
178 179
  fi
])