diff options
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | m4/ax_check_compile_flag.m4 | 31 | ||||
| -rw-r--r-- | m4/ax_cxx_compile_stdcxx.m4 | 951 | ||||
| -rw-r--r-- | m4/ax_cxx_compile_stdcxx_11.m4 | 165 | ||||
| -rw-r--r-- | m4/ax_pthread.m4 | 614 | 
5 files changed, 1275 insertions, 488 deletions
| diff --git a/configure.ac b/configure.ac index 5cfc18e..f72e59e 100644 --- a/configure.ac +++ b/configure.ac @@ -14,7 +14,7 @@ AC_PROG_CXX  AC_PROG_LIBTOOL  LT_INIT -AX_CXX_COMPILE_STDCXX_11(noext,mandatory) +AX_CXX_COMPILE_STDCXX(11,noext,mandatory)  # std::thread requires pthread  AX_PTHREAD( [ diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 index dcabb92..bd753b3 100644 --- a/m4/ax_check_compile_flag.m4 +++ b/m4/ax_check_compile_flag.m4 @@ -29,33 +29,12 @@  #   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>  #   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>  # -#   This program is free software: you can redistribute it and/or modify it -#   under the terms of the GNU General Public License as published by the -#   Free Software Foundation, either version 3 of the License, or (at your -#   option) any later version. -# -#   This program is distributed in the hope that it will be useful, but -#   WITHOUT ANY WARRANTY; without even the implied warranty of -#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -#   Public License for more details. -# -#   You should have received a copy of the GNU General Public License along -#   with this program. If not, see <https://www.gnu.org/licenses/>. -# -#   As a special exception, the respective Autoconf Macro's copyright owner -#   gives unlimited permission to copy, distribute and modify the configure -#   scripts that are the output of Autoconf when processing the Macro. You -#   need not follow the terms of the GNU General Public License when using -#   or distributing such scripts, even though portions of the text of the -#   Macro appear in them. The GNU General Public License (GPL) does govern -#   all other use of the material that constitutes the Autoconf Macro. -# -#   This special exception to the GPL applies to versions of the Autoconf -#   Macro released by the Autoconf Archive. When you make and distribute a -#   modified version of the Autoconf Macro, you may extend this special -#   exception to the GPL to apply to your modified version as well. +#   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 5 +#serial 6  AC_DEFUN([AX_CHECK_COMPILE_FLAG],  [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 0000000..43087b2 --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,951 @@ +# =========================================================================== +#  https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +#   AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +#   Check for baseline language coverage in the compiler for the specified +#   version of the C++ standard.  If necessary, add switches to CXX and +#   CXXCPP to enable support.  VERSION may be '11' (for the C++11 standard) +#   or '14' (for the C++14 standard). +# +#   The second 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. +# +#   The third argument, if specified 'mandatory' or if left unspecified, +#   indicates that baseline support for the specified C++ standard is +#   required and that the macro should error out if no mode with that +#   support is found.  If specified 'optional', then configuration proceeds +#   regardless, after defining HAVE_CXX${VERSION} if and only if a +#   supporting mode is found. +# +# LICENSE +# +#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com> +#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com> +#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu> +#   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com> +#   Copyright (c) 2015 Paul Norman <penorman@mac.com> +#   Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu> +#   Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com> +#   Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com> +# +#   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 11 + +dnl  This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl  (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl +  m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], +        [$1], [14], [ax_cxx_compile_alternatives="14 1y"], +        [$1], [17], [ax_cxx_compile_alternatives="17 1z"], +        [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl +  m4_if([$2], [], [], +        [$2], [ext], [], +        [$2], [noext], [], +        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl +  m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], +        [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], +        [$3], [optional], [ax_cxx_compile_cxx$1_required=false], +        [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) +  AC_LANG_PUSH([C++])dnl +  ac_success=no + +  m4_if([$2], [noext], [], [dnl +  if test x$ac_success = xno; then +    for alternative in ${ax_cxx_compile_alternatives}; do +      switch="-std=gnu++${alternative}" +      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) +      AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, +                     $cachevar, +        [ac_save_CXX="$CXX" +         CXX="$CXX $switch" +         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], +          [eval $cachevar=yes], +          [eval $cachevar=no]) +         CXX="$ac_save_CXX"]) +      if eval test x\$$cachevar = xyes; then +        CXX="$CXX $switch" +        if test -n "$CXXCPP" ; then +          CXXCPP="$CXXCPP $switch" +        fi +        ac_success=yes +        break +      fi +    done +  fi]) + +  m4_if([$2], [ext], [], [dnl +  if test x$ac_success = xno; then +    dnl HP's aCC needs +std=c++11 according to: +    dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf +    dnl Cray's crayCC needs "-h std=c++11" +    for alternative in ${ax_cxx_compile_alternatives}; do +      for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do +        cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) +        AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, +                       $cachevar, +          [ac_save_CXX="$CXX" +           CXX="$CXX $switch" +           AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], +            [eval $cachevar=yes], +            [eval $cachevar=no]) +           CXX="$ac_save_CXX"]) +        if eval test x\$$cachevar = xyes; then +          CXX="$CXX $switch" +          if test -n "$CXXCPP" ; then +            CXXCPP="$CXXCPP $switch" +          fi +          ac_success=yes +          break +        fi +      done +      if test x$ac_success = xyes; then +        break +      fi +    done +  fi]) +  AC_LANG_POP([C++]) +  if test x$ax_cxx_compile_cxx$1_required = xtrue; then +    if test x$ac_success = xno; then +      AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) +    fi +  fi +  if test x$ac_success = xno; then +    HAVE_CXX$1=0 +    AC_MSG_NOTICE([No compiler with C++$1 support was found]) +  else +    HAVE_CXX$1=1 +    AC_DEFINE(HAVE_CXX$1,1, +              [define if the compiler supports basic C++$1 syntax]) +  fi +  AC_SUBST(HAVE_CXX$1) +]) + + +dnl  Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], +  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl  Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], +  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], +  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +  _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) + +dnl  Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + +  namespace test_static_assert +  { + +    template <typename T> +    struct check +    { +      static_assert(sizeof(int) <= sizeof(T), "not big enough"); +    }; + +  } + +  namespace test_final_override +  { + +    struct Base +    { +      virtual ~Base() {} +      virtual void f() {} +    }; + +    struct Derived : public Base +    { +      virtual ~Derived() override {} +      virtual void f() override {} +    }; + +  } + +  namespace test_double_right_angle_brackets +  { + +    template < typename T > +    struct check {}; + +    typedef check<void> single_type; +    typedef check<check<void>> double_type; +    typedef check<check<check<void>>> triple_type; +    typedef check<check<check<check<void>>>> quadruple_type; + +  } + +  namespace test_decltype +  { + +    int +    f() +    { +      int a = 1; +      decltype(a) b = 2; +      return a + b; +    } + +  } + +  namespace test_type_deduction +  { + +    template < typename T1, typename T2 > +    struct is_same +    { +      static const bool value = false; +    }; + +    template < typename T > +    struct is_same<T, T> +    { +      static const bool value = true; +    }; + +    template < typename T1, typename T2 > +    auto +    add(T1 a1, T2 a2) -> decltype(a1 + a2) +    { +      return a1 + a2; +    } + +    int +    test(const int c, volatile int v) +    { +      static_assert(is_same<int, decltype(0)>::value == true, ""); +      static_assert(is_same<int, decltype(c)>::value == false, ""); +      static_assert(is_same<int, decltype(v)>::value == false, ""); +      auto ac = c; +      auto av = v; +      auto sumi = ac + av + 'x'; +      auto sumf = ac + av + 1.0; +      static_assert(is_same<int, decltype(ac)>::value == true, ""); +      static_assert(is_same<int, decltype(av)>::value == true, ""); +      static_assert(is_same<int, decltype(sumi)>::value == true, ""); +      static_assert(is_same<int, decltype(sumf)>::value == false, ""); +      static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); +      return (sumf > 0.0) ? sumi : add(c, v); +    } + +  } + +  namespace test_noexcept +  { + +    int f() { return 0; } +    int g() noexcept { return 0; } + +    static_assert(noexcept(f()) == false, ""); +    static_assert(noexcept(g()) == true, ""); + +  } + +  namespace test_constexpr +  { + +    template < typename CharT > +    unsigned long constexpr +    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept +    { +      return *s ? strlen_c_r(s + 1, acc + 1) : acc; +    } + +    template < typename CharT > +    unsigned long constexpr +    strlen_c(const CharT *const s) noexcept +    { +      return strlen_c_r(s, 0UL); +    } + +    static_assert(strlen_c("") == 0UL, ""); +    static_assert(strlen_c("1") == 1UL, ""); +    static_assert(strlen_c("example") == 7UL, ""); +    static_assert(strlen_c("another\0example") == 7UL, ""); + +  } + +  namespace test_rvalue_references +  { + +    template < int N > +    struct answer +    { +      static constexpr int value = N; +    }; + +    answer<1> f(int&)       { return answer<1>(); } +    answer<2> f(const int&) { return answer<2>(); } +    answer<3> f(int&&)      { return answer<3>(); } + +    void +    test() +    { +      int i = 0; +      const int c = 0; +      static_assert(decltype(f(i))::value == 1, ""); +      static_assert(decltype(f(c))::value == 2, ""); +      static_assert(decltype(f(0))::value == 3, ""); +    } + +  } + +  namespace test_uniform_initialization +  { + +    struct test +    { +      static const int zero {}; +      static const int one {1}; +    }; + +    static_assert(test::zero == 0, ""); +    static_assert(test::one == 1, ""); + +  } + +  namespace test_lambdas +  { + +    void +    test1() +    { +      auto lambda1 = [](){}; +      auto lambda2 = lambda1; +      lambda1(); +      lambda2(); +    } + +    int +    test2() +    { +      auto a = [](int i, int j){ return i + j; }(1, 2); +      auto b = []() -> int { return '0'; }(); +      auto c = [=](){ return a + b; }(); +      auto d = [&](){ return c; }(); +      auto e = [a, &b](int x) mutable { +        const auto identity = [](int y){ return y; }; +        for (auto i = 0; i < a; ++i) +          a += b--; +        return x + identity(a + b); +      }(0); +      return a + b + c + d + e; +    } + +    int +    test3() +    { +      const auto nullary = [](){ return 0; }; +      const auto unary = [](int x){ return x; }; +      using nullary_t = decltype(nullary); +      using unary_t = decltype(unary); +      const auto higher1st = [](nullary_t f){ return f(); }; +      const auto higher2nd = [unary](nullary_t f1){ +        return [unary, f1](unary_t f2){ return f2(unary(f1())); }; +      }; +      return higher1st(nullary) + higher2nd(nullary)(unary); +    } + +  } + +  namespace test_variadic_templates +  { + +    template <int...> +    struct sum; + +    template <int N0, int... N1toN> +    struct sum<N0, N1toN...> +    { +      static constexpr auto value = N0 + sum<N1toN...>::value; +    }; + +    template <> +    struct sum<> +    { +      static constexpr auto value = 0; +    }; + +    static_assert(sum<>::value == 0, ""); +    static_assert(sum<1>::value == 1, ""); +    static_assert(sum<23>::value == 23, ""); +    static_assert(sum<1, 2>::value == 3, ""); +    static_assert(sum<5, 5, 11>::value == 21, ""); +    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + +  } + +  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae +  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function +  // because of this. +  namespace test_template_alias_sfinae +  { + +    struct foo {}; + +    template<typename T> +    using member = typename T::member_type; + +    template<typename T> +    void func(...) {} + +    template<typename T> +    void func(member<T>*) {} + +    void test(); + +    void test() { func<foo>(0); } + +  } + +}  // namespace cxx11 + +#endif  // __cplusplus >= 201103L + +]]) + + +dnl  Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + +  namespace test_polymorphic_lambdas +  { + +    int +    test() +    { +      const auto lambda = [](auto&&... args){ +        const auto istiny = [](auto x){ +          return (sizeof(x) == 1UL) ? 1 : 0; +        }; +        const int aretiny[] = { istiny(args)... }; +        return aretiny[0]; +      }; +      return lambda(1, 1L, 1.0f, '1'); +    } + +  } + +  namespace test_binary_literals +  { + +    constexpr auto ivii = 0b0000000000101010; +    static_assert(ivii == 42, "wrong value"); + +  } + +  namespace test_generalized_constexpr +  { + +    template < typename CharT > +    constexpr unsigned long +    strlen_c(const CharT *const s) noexcept +    { +      auto length = 0UL; +      for (auto p = s; *p; ++p) +        ++length; +      return length; +    } + +    static_assert(strlen_c("") == 0UL, ""); +    static_assert(strlen_c("x") == 1UL, ""); +    static_assert(strlen_c("test") == 4UL, ""); +    static_assert(strlen_c("another\0test") == 7UL, ""); + +  } + +  namespace test_lambda_init_capture +  { + +    int +    test() +    { +      auto x = 0; +      const auto lambda1 = [a = x](int b){ return a + b; }; +      const auto lambda2 = [a = lambda1(x)](){ return a; }; +      return lambda2(); +    } + +  } + +  namespace test_digit_separators +  { + +    constexpr auto ten_million = 100'000'000; +    static_assert(ten_million == 100000000, ""); + +  } + +  namespace test_return_type_deduction +  { + +    auto f(int& x) { return x; } +    decltype(auto) g(int& x) { return x; } + +    template < typename T1, typename T2 > +    struct is_same +    { +      static constexpr auto value = false; +    }; + +    template < typename T > +    struct is_same<T, T> +    { +      static constexpr auto value = true; +    }; + +    int +    test() +    { +      auto x = 0; +      static_assert(is_same<int, decltype(f(x))>::value, ""); +      static_assert(is_same<int&, decltype(g(x))>::value, ""); +      return x; +    } + +  } + +}  // namespace cxx14 + +#endif  // __cplusplus >= 201402L + +]]) + + +dnl  Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include <initializer_list> +#include <utility> +#include <type_traits> + +namespace cxx17 +{ + +  namespace test_constexpr_lambdas +  { + +    constexpr int foo = [](){return 42;}(); + +  } + +  namespace test::nested_namespace::definitions +  { + +  } + +  namespace test_fold_expression +  { + +    template<typename... Args> +    int multiply(Args... args) +    { +      return (args * ... * 1); +    } + +    template<typename... Args> +    bool all(Args... args) +    { +      return (args && ...); +    } + +  } + +  namespace test_extended_static_assert +  { + +    static_assert (true); + +  } + +  namespace test_auto_brace_init_list +  { + +    auto foo = {5}; +    auto bar {5}; + +    static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value); +    static_assert(std::is_same<int, decltype(bar)>::value); +  } + +  namespace test_typename_in_template_template_parameter +  { + +    template<template<typename> typename X> struct D; + +  } + +  namespace test_fallthrough_nodiscard_maybe_unused_attributes +  { + +    int f1() +    { +      return 42; +    } + +    [[nodiscard]] int f2() +    { +      [[maybe_unused]] auto unused = f1(); + +      switch (f1()) +      { +      case 17: +        f1(); +        [[fallthrough]]; +      case 42: +        f1(); +      } +      return f1(); +    } + +  } + +  namespace test_extended_aggregate_initialization +  { + +    struct base1 +    { +      int b1, b2 = 42; +    }; + +    struct base2 +    { +      base2() { +        b3 = 42; +      } +      int b3; +    }; + +    struct derived : base1, base2 +    { +        int d; +    }; + +    derived d1 {{1, 2}, {}, 4};  // full initialization +    derived d2 {{}, {}, 4};      // value-initialized bases + +  } + +  namespace test_general_range_based_for_loop +  { + +    struct iter +    { +      int i; + +      int& operator* () +      { +        return i; +      } + +      const int& operator* () const +      { +        return i; +      } + +      iter& operator++() +      { +        ++i; +        return *this; +      } +    }; + +    struct sentinel +    { +      int i; +    }; + +    bool operator== (const iter& i, const sentinel& s) +    { +      return i.i == s.i; +    } + +    bool operator!= (const iter& i, const sentinel& s) +    { +      return !(i == s); +    } + +    struct range +    { +      iter begin() const +      { +        return {0}; +      } + +      sentinel end() const +      { +        return {5}; +      } +    }; + +    void f() +    { +      range r {}; + +      for (auto i : r) +      { +        [[maybe_unused]] auto v = i; +      } +    } + +  } + +  namespace test_lambda_capture_asterisk_this_by_value +  { + +    struct t +    { +      int i; +      int foo() +      { +        return [*this]() +        { +          return i; +        }(); +      } +    }; + +  } + +  namespace test_enum_class_construction +  { + +    enum class byte : unsigned char +    {}; + +    byte foo {42}; + +  } + +  namespace test_constexpr_if +  { + +    template <bool cond> +    int f () +    { +      if constexpr(cond) +      { +        return 13; +      } +      else +      { +        return 42; +      } +    } + +  } + +  namespace test_selection_statement_with_initializer +  { + +    int f() +    { +      return 13; +    } + +    int f2() +    { +      if (auto i = f(); i > 0) +      { +        return 3; +      } + +      switch (auto i = f(); i + 4) +      { +      case 17: +        return 2; + +      default: +        return 1; +      } +    } + +  } + +  namespace test_template_argument_deduction_for_class_templates +  { + +    template <typename T1, typename T2> +    struct pair +    { +      pair (T1 p1, T2 p2) +        : m1 {p1}, +          m2 {p2} +      {} + +      T1 m1; +      T2 m2; +    }; + +    void f() +    { +      [[maybe_unused]] auto p = pair{13, 42u}; +    } + +  } + +  namespace test_non_type_auto_template_parameters +  { + +    template <auto n> +    struct B +    {}; + +    B<5> b1; +    B<'a'> b2; + +  } + +  namespace test_structured_bindings +  { + +    int arr[2] = { 1, 2 }; +    std::pair<int, int> pr = { 1, 2 }; + +    auto f1() -> int(&)[2] +    { +      return arr; +    } + +    auto f2() -> std::pair<int, int>& +    { +      return pr; +    } + +    struct S +    { +      int x1 : 2; +      volatile double y1; +    }; + +    S f3() +    { +      return {}; +    } + +    auto [ x1, y1 ] = f1(); +    auto& [ xr1, yr1 ] = f1(); +    auto [ x2, y2 ] = f2(); +    auto& [ xr2, yr2 ] = f2(); +    const auto [ x3, y3 ] = f3(); + +  } + +  namespace test_exception_spec_type_system +  { + +    struct Good {}; +    struct Bad {}; + +    void g1() noexcept; +    void g2(); + +    template<typename T> +    Bad +    f(T*, T*); + +    template<typename T1, typename T2> +    Good +    f(T1*, T2*); + +    static_assert (std::is_same_v<Good, decltype(f(g1, g2))>); + +  } + +  namespace test_inline_variables +  { + +    template<class T> void f(T) +    {} + +    template<class T> inline T g(T) +    { +      return T{}; +    } + +    template<> inline void f<>(int) +    {} + +    template<> int g<>(int) +    { +      return 5; +    } + +  } + +}  // namespace cxx17 + +#endif  // __cplusplus < 201703L + +]]) diff --git a/m4/ax_cxx_compile_stdcxx_11.m4 b/m4/ax_cxx_compile_stdcxx_11.m4 deleted file mode 100644 index a9a8f58..0000000 --- a/m4/ax_cxx_compile_stdcxx_11.m4 +++ /dev/null @@ -1,165 +0,0 @@ -# ============================================================================ -#  http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html -# ============================================================================ -# -# SYNOPSIS -# -#   AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) -# -# DESCRIPTION -# -#   Check for baseline language coverage in the compiler for the C++11 -#   standard; if necessary, add switches to CXXFLAGS to enable support. -# -#   The first 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. -# -#   The second argument, if specified 'mandatory' or if left unspecified, -#   indicates that baseline C++11 support is required and that the macro -#   should error out if no mode with that support is found.  If specified -#   'optional', then configuration proceeds regardless, after defining -#   HAVE_CXX11 if and only if a supporting mode is found. -# -# LICENSE -# -#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com> -#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com> -#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu> -#   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com> -# -#   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 10 - -m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[ -  template <typename T> -    struct check -    { -      static_assert(sizeof(int) <= sizeof(T), "not big enough"); -    }; - -    struct Base { -    virtual void f() {} -    }; -    struct Child : public Base { -    virtual void f() override {} -    }; - -    typedef check<check<bool>> right_angle_brackets; - -    int a; -    decltype(a) b; - -    typedef check<int> check_type; -    check_type c; -    check_type&& cr = static_cast<check_type&&>(c); - -    auto d = a; -    auto l = [](){}; -    // Prevent Clang error: unused variable 'l' [-Werror,-Wunused-variable] -    struct use_l { use_l() { l(); } }; - -    // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae -    // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function because of this -    namespace test_template_alias_sfinae { -        struct foo {}; - -        template<typename T> -        using member = typename T::member_type; - -        template<typename T> -        void func(...) {} - -        template<typename T> -        void func(member<T>*) {} - -        void test(); - -        void test() { -            func<foo>(0); -        } -    } -]]) - -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 -  m4_if([$2], [], [ax_cxx_compile_cxx11_required=true], -        [$2], [mandatory], [ax_cxx_compile_cxx11_required=true], -        [$2], [optional], [ax_cxx_compile_cxx11_required=false], -        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])]) -  AC_LANG_PUSH([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, -        [ac_save_CXXFLAGS="$CXXFLAGS" -         CXXFLAGS="$CXXFLAGS $switch" -         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], -          [eval $cachevar=yes], -          [eval $cachevar=no]) -         CXXFLAGS="$ac_save_CXXFLAGS"]) -      if eval test x\$$cachevar = xyes; then -        CXXFLAGS="$CXXFLAGS $switch" -        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, -        [ac_save_CXXFLAGS="$CXXFLAGS" -         CXXFLAGS="$CXXFLAGS $switch" -         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], -          [eval $cachevar=yes], -          [eval $cachevar=no]) -         CXXFLAGS="$ac_save_CXXFLAGS"]) -      if eval test x\$$cachevar = xyes; then -        CXXFLAGS="$CXXFLAGS $switch" -        ac_success=yes -        break -      fi -    done -  fi]) -  AC_LANG_POP([C++]) -  if test x$ax_cxx_compile_cxx11_required = xtrue; then -    if test x$ac_success = xno; then -      AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) -    fi -  else -    if test x$ac_success = xno; then -      HAVE_CXX11=0 -      AC_MSG_NOTICE([No compiler with C++11 support was found]) -    else -      HAVE_CXX11=1 -      AC_DEFINE(HAVE_CXX11,1, -                [define if the compiler supports basic C++11 syntax]) -    fi - -    AC_SUBST(HAVE_CXX11) -  fi -]) diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4 index d218d1a..1598d07 100644 --- a/m4/ax_pthread.m4 +++ b/m4/ax_pthread.m4 @@ -1,5 +1,5 @@  # =========================================================================== -#        http://www.gnu.org/software/autoconf-archive/ax_pthread.html +#        https://www.gnu.org/software/autoconf-archive/ax_pthread.html  # ===========================================================================  #  # SYNOPSIS @@ -55,6 +55,7 @@  #  #   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>  #   Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG> +#   Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>  #  #   This program is free software: you can redistribute it and/or modify it  #   under the terms of the GNU General Public License as published by the @@ -67,7 +68,7 @@  #   Public License for more details.  #  #   You should have received a copy of the GNU General Public License along -#   with this program. If not, see <http://www.gnu.org/licenses/>. +#   with this program. If not, see <https://www.gnu.org/licenses/>.  #  #   As a special exception, the respective Autoconf Macro's copyright owner  #   gives unlimited permission to copy, distribute and modify the configure @@ -82,7 +83,7 @@  #   modified version of the Autoconf Macro, you may extend this special  #   exception to the GPL to apply to your modified version as well. -#serial 22 +#serial 27  AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])  AC_DEFUN([AX_PTHREAD], [ @@ -100,22 +101,22 @@ ax_pthread_ok=no  # etcetera environment variables, and if threads linking works using  # them:  if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then -	ax_pthread_save_CC="$CC" -	ax_pthread_save_CFLAGS="$CFLAGS" -	ax_pthread_save_LIBS="$LIBS" -	AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) -	CFLAGS="$CFLAGS $PTHREAD_CFLAGS" -	LIBS="$PTHREAD_LIBS $LIBS" -	AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) -	AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) -	AC_MSG_RESULT([$ax_pthread_ok]) -	if test "x$ax_pthread_ok" = "xno"; then -		PTHREAD_LIBS="" -		PTHREAD_CFLAGS="" -	fi -	CC="$ax_pthread_save_CC" -	CFLAGS="$ax_pthread_save_CFLAGS" -	LIBS="$ax_pthread_save_LIBS" +        ax_pthread_save_CC="$CC" +        ax_pthread_save_CFLAGS="$CFLAGS" +        ax_pthread_save_LIBS="$LIBS" +        AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) +        CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +        LIBS="$PTHREAD_LIBS $LIBS" +        AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) +        AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) +        AC_MSG_RESULT([$ax_pthread_ok]) +        if test "x$ax_pthread_ok" = "xno"; then +                PTHREAD_LIBS="" +                PTHREAD_CFLAGS="" +        fi +        CC="$ax_pthread_save_CC" +        CFLAGS="$ax_pthread_save_CFLAGS" +        LIBS="$ax_pthread_save_LIBS"  fi  # We must check for the threads library under a number of different @@ -123,10 +124,12 @@ fi  # (e.g. DEC) have both -lpthread and -lpthreads, where one of the  # libraries is broken (non-POSIX). -# Create a list of thread flags to try.  Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. +# Create a list of thread flags to try. Items with a "," contain both +# C compiler flags (before ",") and linker flags (after ","). Other items +# starting with a "-" are C compiler flags, and remaining items are +# library names, except for "none" which indicates that we try without +# any flags at all, and "pthread-config" which is a program returning +# the flags for the Pth emulation library.  ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" @@ -152,319 +155,338 @@ ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --  case $host_os in -	freebsd*) +        freebsd*) -	# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -	# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +        # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +        # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) -	ax_pthread_flags="-kthread lthread $ax_pthread_flags" -	;; +        ax_pthread_flags="-kthread lthread $ax_pthread_flags" +        ;; -	hpux*) +        hpux*) -	# From the cc(1) man page: "[-mt] Sets various -D flags to enable -	# multi-threading and also sets -lpthread." +        # From the cc(1) man page: "[-mt] Sets various -D flags to enable +        # multi-threading and also sets -lpthread." -	ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" -	;; +        ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" +        ;; -	openedition*) +        openedition*) -	# IBM z/OS requires a feature-test macro to be defined in order to -	# enable POSIX threads at all, so give the user a hint if this is -	# not set. (We don't define these ourselves, as they can affect -	# other portions of the system API in unpredictable ways.) +        # IBM z/OS requires a feature-test macro to be defined in order to +        # enable POSIX threads at all, so give the user a hint if this is +        # not set. (We don't define these ourselves, as they can affect +        # other portions of the system API in unpredictable ways.) -	AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], -	    [ -#	     if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) -	     AX_PTHREAD_ZOS_MISSING -#	     endif -	    ], -	    [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) -	;; +        AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], +            [ +#            if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) +             AX_PTHREAD_ZOS_MISSING +#            endif +            ], +            [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) +        ;; -	solaris*) +        solaris*) -	# On Solaris (at least, for some versions), libc contains stubbed -	# (non-functional) versions of the pthreads routines, so link-based -	# tests will erroneously succeed. (N.B.: The stubs are missing -	# pthread_cleanup_push, or rather a function called by this macro, -	# so we could check for that, but who knows whether they'll stub -	# that too in a future libc.)  So we'll check first for the -	# standard Solaris way of linking pthreads (-mt -lpthread). +        # On Solaris (at least, for some versions), libc contains stubbed +        # (non-functional) versions of the pthreads routines, so link-based +        # tests will erroneously succeed. (N.B.: The stubs are missing +        # pthread_cleanup_push, or rather a function called by this macro, +        # so we could check for that, but who knows whether they'll stub +        # that too in a future libc.)  So we'll check first for the +        # standard Solaris way of linking pthreads (-mt -lpthread). -	ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" -	;; +        ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" +        ;;  esac +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], +    [ax_cv_PTHREAD_CLANG], +    [ax_cv_PTHREAD_CLANG=no +     # Note that Autoconf sets GCC=yes for Clang as well as GCC +     if test "x$GCC" = "xyes"; then +        AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], +            [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +#            if defined(__clang__) && defined(__llvm__) +             AX_PTHREAD_CC_IS_CLANG +#            endif +            ], +            [ax_cv_PTHREAD_CLANG=yes]) +     fi +    ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + +  # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) +# Note that for GCC and Clang -pthread generally implies -lpthread, +# except when -nostdlib is passed. +# This is problematic using libtool to build C++ shared libraries with pthread: +# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 +# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 +# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 +# To solve this, first try -pthread together with -lpthread for GCC +  AS_IF([test "x$GCC" = "xyes"], -      [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) +      [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) + +# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first + +AS_IF([test "x$ax_pthread_clang" = "xyes"], +      [ax_pthread_flags="-pthread,-lpthread -pthread"]) +  # The presence of a feature test macro requesting re-entrant function  # definitions is, on some systems, a strong hint that pthreads support is  # correctly enabled  case $host_os in -	darwin* | hpux* | linux* | osf* | solaris*) -	ax_pthread_check_macro="_REENTRANT" -	;; +        darwin* | hpux* | linux* | osf* | solaris*) +        ax_pthread_check_macro="_REENTRANT" +        ;; -	aix* | freebsd*) -	ax_pthread_check_macro="_THREAD_SAFE" -	;; +        aix*) +        ax_pthread_check_macro="_THREAD_SAFE" +        ;; -	*) -	ax_pthread_check_macro="--" -	;; +        *) +        ax_pthread_check_macro="--" +        ;;  esac  AS_IF([test "x$ax_pthread_check_macro" = "x--"],        [ax_pthread_check_cond=0],        [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) -# Are we compiling with Clang? -AC_CACHE_CHECK([whether $CC is Clang], -    [ax_cv_PTHREAD_CLANG], -    [ax_cv_PTHREAD_CLANG=no -     # Note that Autoconf sets GCC=yes for Clang as well as GCC -     if test "x$GCC" = "xyes"; then -	AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], -	    [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ -#	     if defined(__clang__) && defined(__llvm__) -	     AX_PTHREAD_CC_IS_CLANG -#	     endif -	    ], -	    [ax_cv_PTHREAD_CLANG=yes]) -     fi -    ]) -ax_pthread_clang="$ax_cv_PTHREAD_CLANG" +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + +        case $ax_pthread_try_flag in +                none) +                AC_MSG_CHECKING([whether pthreads work without any flags]) +                ;; + +                *,*) +                PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` +                PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` +                AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) +                ;; + +                -*) +                AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) +                PTHREAD_CFLAGS="$ax_pthread_try_flag" +                ;; + +                pthread-config) +                AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) +                AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) +                PTHREAD_CFLAGS="`pthread-config --cflags`" +                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" +                ;; + +                *) +                AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) +                PTHREAD_LIBS="-l$ax_pthread_try_flag" +                ;; +        esac + +        ax_pthread_save_CFLAGS="$CFLAGS" +        ax_pthread_save_LIBS="$LIBS" +        CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +        LIBS="$PTHREAD_LIBS $LIBS" + +        # Check for various functions.  We must include pthread.h, +        # since some functions may be macros.  (On the Sequent, we +        # need a special flag -Kthread to make this header compile.) +        # We check for pthread_join because it is in -lpthread on IRIX +        # while pthread_create is in libc.  We check for pthread_attr_init +        # due to DEC craziness with -lpthreads.  We check for +        # pthread_cleanup_push because it is one of the few pthread +        # functions on Solaris that doesn't have a non-functional libc stub. +        # We try pthread_create on general principles. + +        AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h> +#                       if $ax_pthread_check_cond +#                        error "$ax_pthread_check_macro must be defined" +#                       endif +                        static void *some_global = NULL; +                        static void routine(void *a) +                          { +                             /* To avoid any unused-parameter or +                                unused-but-set-parameter warning.  */ +                             some_global = a; +                          } +                        static void *start_routine(void *a) { return a; }], +                       [pthread_t th; pthread_attr_t attr; +                        pthread_create(&th, 0, start_routine, 0); +                        pthread_join(th, 0); +                        pthread_attr_init(&attr); +                        pthread_cleanup_push(routine, 0); +                        pthread_cleanup_pop(0) /* ; */])], +            [ax_pthread_ok=yes], +            []) + +        CFLAGS="$ax_pthread_save_CFLAGS" +        LIBS="$ax_pthread_save_LIBS" + +        AC_MSG_RESULT([$ax_pthread_ok]) +        AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + +        PTHREAD_LIBS="" +        PTHREAD_CFLAGS="" +done +fi -ax_pthread_clang_warning=no  # Clang needs special handling, because older versions handle the -pthread  # option in a rather... idiosyncratic way  if test "x$ax_pthread_clang" = "xyes"; then -	# Clang takes -pthread; it has never supported any other flag - -	# (Note 1: This will need to be revisited if a system that Clang -	# supports has POSIX threads in a separate library.  This tends not -	# to be the way of modern systems, but it's conceivable.) - -	# (Note 2: On some systems, notably Darwin, -pthread is not needed -	# to get POSIX threads support; the API is always present and -	# active.  We could reasonably leave PTHREAD_CFLAGS empty.  But -	# -pthread does define _REENTRANT, and while the Darwin headers -	# ignore this macro, third-party headers might not.) - -	PTHREAD_CFLAGS="-pthread" -	PTHREAD_LIBS= - -	ax_pthread_ok=yes - -	# However, older versions of Clang make a point of warning the user -	# that, in an invocation where only linking and no compilation is -	# taking place, the -pthread option has no effect ("argument unused -	# during compilation").  They expect -pthread to be passed in only -	# when source code is being compiled. -	# -	# Problem is, this is at odds with the way Automake and most other -	# C build frameworks function, which is that the same flags used in -	# compilation (CFLAGS) are also used in linking.  Many systems -	# supported by AX_PTHREAD require exactly this for POSIX threads -	# support, and in fact it is often not straightforward to specify a -	# flag that is used only in the compilation phase and not in -	# linking.  Such a scenario is extremely rare in practice. -	# -	# Even though use of the -pthread flag in linking would only print -	# a warning, this can be a nuisance for well-run software projects -	# that build with -Werror.  So if the active version of Clang has -	# this misfeature, we search for an option to squash it. - -	AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], -	    [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], -	    [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown -	     # Create an alternate version of $ac_link that compiles and -	     # links in two steps (.c -> .o, .o -> exe) instead of one -	     # (.c -> exe), because the warning occurs only in the second -	     # step -	     ax_pthread_save_ac_link="$ac_link" -	     ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' -	     ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` -	     ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" -	     ax_pthread_save_CFLAGS="$CFLAGS" -	     for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do -		AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) -		CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" -		ac_link="$ax_pthread_save_ac_link" -		AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], -		    [ac_link="$ax_pthread_2step_ac_link" -		     AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], -			 [break]) -		    ]) -	     done -	     ac_link="$ax_pthread_save_ac_link" -	     CFLAGS="$ax_pthread_save_CFLAGS" -	     AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) -	     ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" -	    ]) - -	case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in -		no | unknown) ;; -		*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; -	esac +        # Clang takes -pthread; it has never supported any other flag + +        # (Note 1: This will need to be revisited if a system that Clang +        # supports has POSIX threads in a separate library.  This tends not +        # to be the way of modern systems, but it's conceivable.) + +        # (Note 2: On some systems, notably Darwin, -pthread is not needed +        # to get POSIX threads support; the API is always present and +        # active.  We could reasonably leave PTHREAD_CFLAGS empty.  But +        # -pthread does define _REENTRANT, and while the Darwin headers +        # ignore this macro, third-party headers might not.) + +        # However, older versions of Clang make a point of warning the user +        # that, in an invocation where only linking and no compilation is +        # taking place, the -pthread option has no effect ("argument unused +        # during compilation").  They expect -pthread to be passed in only +        # when source code is being compiled. +        # +        # Problem is, this is at odds with the way Automake and most other +        # C build frameworks function, which is that the same flags used in +        # compilation (CFLAGS) are also used in linking.  Many systems +        # supported by AX_PTHREAD require exactly this for POSIX threads +        # support, and in fact it is often not straightforward to specify a +        # flag that is used only in the compilation phase and not in +        # linking.  Such a scenario is extremely rare in practice. +        # +        # Even though use of the -pthread flag in linking would only print +        # a warning, this can be a nuisance for well-run software projects +        # that build with -Werror.  So if the active version of Clang has +        # this misfeature, we search for an option to squash it. + +        AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], +            [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], +            [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown +             # Create an alternate version of $ac_link that compiles and +             # links in two steps (.c -> .o, .o -> exe) instead of one +             # (.c -> exe), because the warning occurs only in the second +             # step +             ax_pthread_save_ac_link="$ac_link" +             ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' +             ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` +             ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" +             ax_pthread_save_CFLAGS="$CFLAGS" +             for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do +                AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) +                CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" +                ac_link="$ax_pthread_save_ac_link" +                AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], +                    [ac_link="$ax_pthread_2step_ac_link" +                     AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], +                         [break]) +                    ]) +             done +             ac_link="$ax_pthread_save_ac_link" +             CFLAGS="$ax_pthread_save_CFLAGS" +             AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) +             ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" +            ]) + +        case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in +                no | unknown) ;; +                *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; +        esac  fi # $ax_pthread_clang = yes -if test "x$ax_pthread_ok" = "xno"; then -for ax_pthread_try_flag in $ax_pthread_flags; do -	case $ax_pthread_try_flag in -		none) -		AC_MSG_CHECKING([whether pthreads work without any flags]) -		;; - -		-mt,pthread) -		AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) -		PTHREAD_CFLAGS="-mt" -		PTHREAD_LIBS="-lpthread" -		;; - -		-*) -		AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) -		PTHREAD_CFLAGS="$ax_pthread_try_flag" -		;; - -		pthread-config) -		AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) -		AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) -		PTHREAD_CFLAGS="`pthread-config --cflags`" -		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" -		;; - -		*) -		AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) -		PTHREAD_LIBS="-l$ax_pthread_try_flag" -		;; -	esac - -	ax_pthread_save_CFLAGS="$CFLAGS" -	ax_pthread_save_LIBS="$LIBS" -	CFLAGS="$CFLAGS $PTHREAD_CFLAGS" -	LIBS="$PTHREAD_LIBS $LIBS" - -	# Check for various functions.  We must include pthread.h, -	# since some functions may be macros.  (On the Sequent, we -	# need a special flag -Kthread to make this header compile.) -	# We check for pthread_join because it is in -lpthread on IRIX -	# while pthread_create is in libc.  We check for pthread_attr_init -	# due to DEC craziness with -lpthreads.  We check for -	# pthread_cleanup_push because it is one of the few pthread -	# functions on Solaris that doesn't have a non-functional libc stub. -	# We try pthread_create on general principles. - -	AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h> -#			if $ax_pthread_check_cond -#			 error "$ax_pthread_check_macro must be defined" -#			endif -			static void routine(void *a) { a = 0; } -			static void *start_routine(void *a) { return a; }], -		       [pthread_t th; pthread_attr_t attr; -			pthread_create(&th, 0, start_routine, 0); -			pthread_join(th, 0); -			pthread_attr_init(&attr); -			pthread_cleanup_push(routine, 0); -			pthread_cleanup_pop(0) /* ; */])], -	    [ax_pthread_ok=yes], -	    []) - -	CFLAGS="$ax_pthread_save_CFLAGS" -	LIBS="$ax_pthread_save_LIBS" - -	AC_MSG_RESULT([$ax_pthread_ok]) -	AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) - -	PTHREAD_LIBS="" -	PTHREAD_CFLAGS="" -done -fi  # Various other checks:  if test "x$ax_pthread_ok" = "xyes"; then -	ax_pthread_save_CFLAGS="$CFLAGS" -	ax_pthread_save_LIBS="$LIBS" -	CFLAGS="$CFLAGS $PTHREAD_CFLAGS" -	LIBS="$PTHREAD_LIBS $LIBS" - -	# Detect AIX lossage: JOINABLE attribute is called UNDETACHED. -	AC_CACHE_CHECK([for joinable pthread attribute], -	    [ax_cv_PTHREAD_JOINABLE_ATTR], -	    [ax_cv_PTHREAD_JOINABLE_ATTR=unknown -	     for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do -		 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>], -						 [int attr = $ax_pthread_attr; return attr /* ; */])], -				[ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], -				[]) -	     done -	    ]) -	AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ -	       test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ -	       test "x$ax_pthread_joinable_attr_defined" != "xyes"], -	      [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], -				  [$ax_cv_PTHREAD_JOINABLE_ATTR], -				  [Define to necessary symbol if this constant -				   uses a non-standard name on your system.]) -	       ax_pthread_joinable_attr_defined=yes -	      ]) - -	AC_CACHE_CHECK([whether more special flags are required for pthreads], -	    [ax_cv_PTHREAD_SPECIAL_FLAGS], -	    [ax_cv_PTHREAD_SPECIAL_FLAGS=no -	     case $host_os in -	     solaris*) -	     ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" -	     ;; -	     esac -	    ]) -	AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ -	       test "x$ax_pthread_special_flags_added" != "xyes"], -	      [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" -	       ax_pthread_special_flags_added=yes]) - -	AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], -	    [ax_cv_PTHREAD_PRIO_INHERIT], -	    [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], -					     [[int i = PTHREAD_PRIO_INHERIT;]])], -			    [ax_cv_PTHREAD_PRIO_INHERIT=yes], -			    [ax_cv_PTHREAD_PRIO_INHERIT=no]) -	    ]) -	AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ -	       test "x$ax_pthread_prio_inherit_defined" != "xyes"], -	      [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) -	       ax_pthread_prio_inherit_defined=yes -	      ]) - -	CFLAGS="$ax_pthread_save_CFLAGS" -	LIBS="$ax_pthread_save_LIBS" - -	# More AIX lossage: compile with *_r variant -	if test "x$GCC" != "xyes"; then -	    case $host_os in -		aix*) -		AS_CASE(["x/$CC"], -		    [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], -		    [#handle absolute path differently from PATH based program lookup -		     AS_CASE(["x$CC"], -			 [x/*], -			 [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], -			 [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) -		;; -	    esac -	fi +        ax_pthread_save_CFLAGS="$CFLAGS" +        ax_pthread_save_LIBS="$LIBS" +        CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +        LIBS="$PTHREAD_LIBS $LIBS" + +        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. +        AC_CACHE_CHECK([for joinable pthread attribute], +            [ax_cv_PTHREAD_JOINABLE_ATTR], +            [ax_cv_PTHREAD_JOINABLE_ATTR=unknown +             for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do +                 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>], +                                                 [int attr = $ax_pthread_attr; return attr /* ; */])], +                                [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], +                                []) +             done +            ]) +        AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ +               test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ +               test "x$ax_pthread_joinable_attr_defined" != "xyes"], +              [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], +                                  [$ax_cv_PTHREAD_JOINABLE_ATTR], +                                  [Define to necessary symbol if this constant +                                   uses a non-standard name on your system.]) +               ax_pthread_joinable_attr_defined=yes +              ]) + +        AC_CACHE_CHECK([whether more special flags are required for pthreads], +            [ax_cv_PTHREAD_SPECIAL_FLAGS], +            [ax_cv_PTHREAD_SPECIAL_FLAGS=no +             case $host_os in +             solaris*) +             ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" +             ;; +             esac +            ]) +        AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ +               test "x$ax_pthread_special_flags_added" != "xyes"], +              [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" +               ax_pthread_special_flags_added=yes]) + +        AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], +            [ax_cv_PTHREAD_PRIO_INHERIT], +            [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], +                                             [[int i = PTHREAD_PRIO_INHERIT; +                                               return i;]])], +                            [ax_cv_PTHREAD_PRIO_INHERIT=yes], +                            [ax_cv_PTHREAD_PRIO_INHERIT=no]) +            ]) +        AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ +               test "x$ax_pthread_prio_inherit_defined" != "xyes"], +              [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) +               ax_pthread_prio_inherit_defined=yes +              ]) + +        CFLAGS="$ax_pthread_save_CFLAGS" +        LIBS="$ax_pthread_save_LIBS" + +        # More AIX lossage: compile with *_r variant +        if test "x$GCC" != "xyes"; then +            case $host_os in +                aix*) +                AS_CASE(["x/$CC"], +                    [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], +                    [#handle absolute path differently from PATH based program lookup +                     AS_CASE(["x$CC"], +                         [x/*], +                         [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], +                         [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) +                ;; +            esac +        fi  fi  test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" @@ -475,11 +497,11 @@ AC_SUBST([PTHREAD_CC])  # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:  if test "x$ax_pthread_ok" = "xyes"; then -	ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) -	: +        ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) +        :  else -	ax_pthread_ok=no -	$2 +        ax_pthread_ok=no +        $2  fi  AC_LANG_POP  ])dnl AX_PTHREAD | 
