ax_cxx_compile_stdcxx_14.m4 6.89 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
#  Further modified for C++14 by Kenton Varda.
Kenton Varda's avatar
Kenton Varda committed
5 6 7 8
# ============================================================================
#
# SYNOPSIS
#
Kenton Varda's avatar
Kenton Varda committed
9
#   AX_CXX_COMPILE_STDCXX_14([ext|noext])
Kenton Varda's avatar
Kenton Varda committed
10 11 12
#
# DESCRIPTION
#
Kenton Varda's avatar
Kenton Varda committed
13
#   Check for baseline language coverage in the compiler for the C++14
Kenton Varda's avatar
Kenton Varda committed
14
#   standard; if necessary, add switches to CXXFLAGS to enable support.
Kenton Varda's avatar
Kenton Varda committed
15
#   Errors out if no mode that supports C++14 baseline syntax can be found.
Kenton Varda's avatar
Kenton Varda committed
16
#   The argument, if specified, indicates whether you insist on an extended
Kenton Varda's avatar
Kenton Varda committed
17
#   mode (e.g. -std=gnu++14) or a strict conformance mode (e.g. -std=c++14).
Kenton Varda's avatar
Kenton Varda committed
18 19 20
#   If neither is specified, you get whatever works, with preference for an
#   extended mode.
#
21 22 23 24 25
#   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++.
#
26 27 28 29 30 31 32
#   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
33 34 35 36
# LICENSE
#
#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
37
#   Copyright (c) 2013 Kenton Varda <temporal@gmail.com>
Kenton Varda's avatar
Kenton Varda committed
38 39 40 41 42 43 44 45
#
#   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

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

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

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

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
  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
82 83 84 85 86 87 88 89 90 91 92 93

  // C++14 stuff
  auto deduceReturnType(int i) { return i; }

  auto genericLambda = [](auto x, auto y) { return x + y; };
  auto captureExpressions = [x = 123]() { return x; };

  // Avoid unused variable warnings.
  int foo() {
    return genericLambda(1, 2) + captureExpressions();
  }
]])
Kenton Varda's avatar
Kenton Varda committed
94

95 96 97 98 99 100 101
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
102
AC_DEFUN([AX_CXX_COMPILE_STDCXX_14], [dnl
Kenton Varda's avatar
Kenton Varda committed
103 104 105
  m4_if([$1], [], [],
        [$1], [ext], [],
        [$1], [noext], [],
Kenton Varda's avatar
Kenton Varda committed
106
        [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_14])])dnl
Kenton Varda's avatar
Kenton Varda committed
107 108
  AC_LANG_ASSERT([C++])dnl
  ac_success=no
Kenton Varda's avatar
Kenton Varda committed
109 110 111 112 113 114
  AC_CACHE_CHECK(whether $CXX supports C++14 features by default,
  ax_cv_cxx_compile_cxx14,
  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_14_testbody])],
    [ax_cv_cxx_compile_cxx14=yes],
    [ax_cv_cxx_compile_cxx14=no])])
  if test x$ax_cv_cxx_compile_cxx14 = xyes; then
Kenton Varda's avatar
Kenton Varda committed
115 116 117 118 119
    ac_success=yes
  fi

  m4_if([$1], [noext], [], [dnl
  if test x$ac_success = xno; then
Kenton Varda's avatar
Kenton Varda committed
120 121 122
    for switch in -std=gnu++14 -std=gnu++1y; do
      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx14_$switch])
      AC_CACHE_CHECK(whether $CXX supports C++14 features with $switch,
Kenton Varda's avatar
Kenton Varda committed
123
                     $cachevar,
124 125
        [ac_save_CXX="$CXX"
         CXX="$CXX $switch"
Kenton Varda's avatar
Kenton Varda committed
126
         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_14_testbody])],
Kenton Varda's avatar
Kenton Varda committed
127 128
          [eval $cachevar=yes],
          [eval $cachevar=no])
129
         CXX="$ac_save_CXX"])
Kenton Varda's avatar
Kenton Varda committed
130
      if eval test x\$$cachevar = xyes; then
131
        CXX="$CXX $switch"
Kenton Varda's avatar
Kenton Varda committed
132 133 134 135 136 137 138 139
        ac_success=yes
        break
      fi
    done
  fi])

  m4_if([$1], [ext], [], [dnl
  if test x$ac_success = xno; then
Kenton Varda's avatar
Kenton Varda committed
140 141 142
    for switch in -std=c++14 -std=c++1y; do
      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx14_$switch])
      AC_CACHE_CHECK(whether $CXX supports C++14 features with $switch,
Kenton Varda's avatar
Kenton Varda committed
143
                     $cachevar,
144 145
        [ac_save_CXX="$CXX"
         CXX="$CXX $switch"
Kenton Varda's avatar
Kenton Varda committed
146
         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_14_testbody])],
Kenton Varda's avatar
Kenton Varda committed
147 148
          [eval $cachevar=yes],
          [eval $cachevar=no])
149
         CXX="$ac_save_CXX"])
Kenton Varda's avatar
Kenton Varda committed
150
      if eval test x\$$cachevar = xyes; then
151
        CXX="$CXX $switch"
Kenton Varda's avatar
Kenton Varda committed
152 153 154 155 156 157 158
        ac_success=yes
        break
      fi
    done
  fi])

  if test x$ac_success = xno; then
Kenton Varda's avatar
Kenton Varda committed
159
    AC_MSG_ERROR([*** A compiler with support for C++14 language features is required.])
160 161 162 163 164 165 166 167 168 169 170 171 172 173
  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,
174 175
        [ac_save_CXX="$CXX"
         CXX="$CXX -stdlib=libc++"
176 177 178
         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])
179
         CXX="$ac_save_CXX"])
180
      if eval test x$ax_cv_cxx_compile_cxx11_lib_libcxx = xyes; then
181
        CXX="$CXX -stdlib=libc++"
182 183 184 185 186 187
        ac_success=yes
        break
      fi
    fi

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