mirror of
https://github.com/eclipse-paho/paho.mqtt.cpp.git
synced 2025-09-15 12:58:39 +08:00
--------------------------------------------------------------------- Advantages --------------------------------------------------------------------- 1. Automatically find the Paho MQTT C library. Which is required by Paho MQTT C++ library; 2. Detect if the doxygen program is available in order to build (or not) the documentation; 3. Detect if the compiler supports C++11; 4. Choose whether to build static, dynamic or both kinds of libraries; 5. Choose whether or not to build documentation or sample programs; 6. Easier cross compilation; 7. Adds standard make targets, like "install"; 8. Automatic handling of portability issues. For example, library naming differs accross OS; --------------------------------------------------------------------- Build instructions --------------------------------------------------------------------- The first step is to run the bootstrap script: $ ./bootstrap Create the build directory, to build out-of-tree: $ mkdir mybuild && cd mybuild $ export PAHO_CPP_DIR=$PWD Next, in order to build only the static library: $ $PAHO_CPP_DIR/configure --disable-shared --enable-static $ make the commands above build libpaho-mqttpp3.a Or, in order to build only the dynamic library: $ $PAHO_CPP_DIR/configure --enable-shared --disable-static $ make the previous commands build: libpaho-mqttpp3.so.0.2 and its respective link and soname. If the Paho MQTT C is installed on a non-standard directory, you can provide the path to the configure script: $ $PAHO_CPP_DIR/configure --with-paho-mqtt-c=/opt/paho.mqtt.c/ --------------------------------------------------------------------- Remarks --------------------------------------------------------------------- The regular Make version is around 2.5 times faster than the Autotools version. The overall time for Autotools include the time of bootstrap, configure and make. The regular Make time include only the make command. Remove the .dep files from "src/obj/" directory. The "make" sets its current directory to "src/obj/" in order to compile. And "make" does find the libtool script, because its current directory should be "src/". Successfully built on with C++11 restriction: - Ubuntu 10.04 (x86 32-bit) with g++ 4.8.2, GNU libc 2.11.1 and libstdc++ 6.0.13; - Fedora 23.10 (64-bit) with g++ 5.3.1, GNU libc 2.22 and libstdc++ 6.0.21; - FreeBSD 10.3 (64-bit) with clang++ 3.4.1; Signed-off-by: Guilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
563 lines
14 KiB
Plaintext
563 lines
14 KiB
Plaintext
# ===========================================================================
|
|
# http://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>
|
|
#
|
|
# 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 4
|
|
|
|
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], [],
|
|
[$1], [14], [],
|
|
[$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])],
|
|
[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
|
|
AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
|
|
ax_cv_cxx_compile_cxx$1,
|
|
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
|
[ax_cv_cxx_compile_cxx$1=yes],
|
|
[ax_cv_cxx_compile_cxx$1=no])])
|
|
if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
|
|
ac_success=yes
|
|
fi
|
|
|
|
m4_if([$2], [noext], [], [dnl
|
|
if test x$ac_success = xno; then
|
|
for switch in -std=gnu++$1 -std=gnu++0x; 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
|
|
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 switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; 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
|
|
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
|
|
)
|
|
|
|
|
|
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 void f() {}
|
|
};
|
|
|
|
struct Derived : public Base
|
|
{
|
|
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_seperators
|
|
{
|
|
|
|
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
|
|
|
|
]])
|