Am Samstag, 5. März 2011, 14:20:44 schrieb Rolf Eike Beer: > Hi, > > I would like to have CMake tests for a bunch of C++ features (especially > C++0x ones). Before I start investing time in this I ask here if anyone > already has done this or parts thereof so I don't reinvent the wheel? > > Bill, David, would you be interested in adding such thing as a module to > CMake 2.8.5?
Ok, I have done some basic things (for the features that are currently interesting to me). I would like to get some feedback on this. Very appreciated would be the results of the test on different compilers. If you compare the results to http://wiki.apache.org/stdcxx/C++0xCompilerSupport please be aware that g++ requires CXXFLAGS=--std=c++0x to enable most of the new features. Eike
>From d8480a2afe16d4592488aa59fc30bbb8a362254f Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer <[email protected]> Date: Thu, 24 Mar 2011 19:53:16 +0100 Subject: [PATCH] add a module to check C++0x features With this module one can get a set of CMake variables indicating which features of the upcoming C++0x standard are supported by the compiler. --- Modules/CheckCXX0xFeatures.cmake | 68 ++++++++++++++++++++ Modules/c++0x-test-__func__-N2340.cpp | 8 ++ Modules/c++0x-test-constexpr-N2235.cpp | 13 ++++ Modules/c++0x-test-cstdint.cpp | 6 ++ Modules/c++0x-test-long_long-N1811.cpp | 6 ++ Modules/c++0x-test-nullptr-N2431.cpp | 6 ++ Modules/c++0x-test-nullptr-N2431_fail_compile.cpp | 6 ++ Modules/c++0x-test-rvalue-references-N2118.cpp | 57 ++++++++++++++++ Modules/c++0x-test-sizeof_member-N2253.cpp | 9 +++ Modules/c++0x-test-sizeof_member-N2253_fail.cpp | 9 +++ Modules/c++0x-test-static_assert-N1720.cpp | 5 ++ ...c++0x-test-static_assert-N1720_fail_compile.cpp | 5 ++ Tests/CMakeLists.txt | 1 + Tests/Module/CXX0xFeatures/CMakeLists.txt | 21 ++++++ Tests/Module/CXX0xFeatures/cxx0xfeatures.cxx | 57 ++++++++++++++++ 15 files changed, 277 insertions(+), 0 deletions(-) create mode 100644 Modules/CheckCXX0xFeatures.cmake create mode 100644 Modules/c++0x-test-__func__-N2340.cpp create mode 100644 Modules/c++0x-test-constexpr-N2235.cpp create mode 100644 Modules/c++0x-test-cstdint.cpp create mode 100644 Modules/c++0x-test-long_long-N1811.cpp create mode 100644 Modules/c++0x-test-nullptr-N2431.cpp create mode 100644 Modules/c++0x-test-nullptr-N2431_fail_compile.cpp create mode 100644 Modules/c++0x-test-rvalue-references-N2118.cpp create mode 100644 Modules/c++0x-test-sizeof_member-N2253.cpp create mode 100644 Modules/c++0x-test-sizeof_member-N2253_fail.cpp create mode 100644 Modules/c++0x-test-static_assert-N1720.cpp create mode 100644 Modules/c++0x-test-static_assert-N1720_fail_compile.cpp create mode 100644 Tests/Module/CXX0xFeatures/CMakeLists.txt create mode 100644 Tests/Module/CXX0xFeatures/cxx0xfeatures.cxx diff --git a/Modules/CheckCXX0xFeatures.cmake b/Modules/CheckCXX0xFeatures.cmake new file mode 100644 index 0000000..3e77a66 --- /dev/null +++ b/Modules/CheckCXX0xFeatures.cmake @@ -0,0 +1,68 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3) + +MACRO(CXX0X_CHECK_FEATURE FEATURE_NAME FEATURE_NUMBER RESULT_VAR) + IF (NOT DEFINED ${RESULT_VAR}) + set(_bindir "${CMAKE_CURRENT_BINARY_DIR}/cxx0x_${FEATURE_NAME}") + + IF (${FEATURE_NUMBER}) + SET(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/c++0x-test-${FEATURE_NAME}-N${FEATURE_NUMBER}) + SET(_LOG_NAME "\"${FEATURE_NAME}\" (N${FEATURE_NUMBER})") + ELSE (${FEATURE_NUMBER}) + SET(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/c++0x-test-${FEATURE_NAME}) + SET(_LOG_NAME "\"${FEATURE_NAME}\"") + ENDIF (${FEATURE_NUMBER}) + MESSAGE(STATUS "Checking C++0x support for ${_LOG_NAME}") + + SET(_SRCFILE "${_SRCFILE_BASE}.cpp") + SET(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp") + SET(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cpp") + + IF (CROSS_COMPILING) + try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}") + IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) + try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}") + ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) + ELSE (CROSS_COMPILING) + try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR + "${_bindir}" "${_SRCFILE}") + IF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR) + SET(${RESULT_VAR} TRUE) + ELSE (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR) + SET(${RESULT_VAR} FALSE) + ENDIF (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR) + IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) + try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR + "${_bindir}_fail" "${_SRCFILE_FAIL}") + IF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR) + SET(${RESULT_VAR} TRUE) + ELSE (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR) + SET(${RESULT_VAR} FALSE) + ENDIF (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR) + ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL}) + ENDIF (CROSS_COMPILING) + IF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE}) + try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}") + IF (_TMP_RESULT) + SET(RESULT_VAR FALSE) + ELSE (_TMP_RESULT) + SET(RESULT_VAR TRUE) + ENDIF (_TMP_RESULT) + ENDIF (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE}) + + IF (${RESULT_VAR}) + MESSAGE(STATUS "Checking C++0x support for ${_LOG_NAME}: works") + ELSE (${RESULT_VAR}) + MESSAGE(STATUS "Checking C++0x support for ${_LOG_NAME}: not supported") + ENDIF (${RESULT_VAR}) + SET(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++0x support for ${_LOG_NAME}") + ENDIF (NOT DEFINED ${RESULT_VAR}) +ENDMACRO(CXX0X_CHECK_FEATURE) + +CXX0X_CHECK_FEATURE("static_assert" 1720 HAS_CXX0X_STATIC_ASSERT) +CXX0X_CHECK_FEATURE("long_long" 1811 HAS_CXX0X_LONG_LONG) +CXX0X_CHECK_FEATURE("rvalue-references" 2118 HAS_CXX0X_RVALUE_REFERENCES) +CXX0X_CHECK_FEATURE("constexpr" 2235 HAS_CXX0X_CONSTEXPR) +CXX0X_CHECK_FEATURE("sizeof_member" 2253 HAS_CXX0X_SIZEOF_MEMBER) +CXX0X_CHECK_FEATURE("__func__" 2340 HAS_CXX0X_FUNC) +CXX0X_CHECK_FEATURE("nullptr" 2431 HAS_CXX0X_NULLPTR) +CXX0X_CHECK_FEATURE("cstdint" "" HAS_CXX0X_CSTDINT_H) diff --git a/Modules/c++0x-test-__func__-N2340.cpp b/Modules/c++0x-test-__func__-N2340.cpp new file mode 100644 index 0000000..bbd0be9 --- /dev/null +++ b/Modules/c++0x-test-__func__-N2340.cpp @@ -0,0 +1,8 @@ +int main(void) +{ + if (!__func__) + return 1; + if (!(*__func__)) + return 1; + return 0; +} \ No newline at end of file diff --git a/Modules/c++0x-test-constexpr-N2235.cpp b/Modules/c++0x-test-constexpr-N2235.cpp new file mode 100644 index 0000000..37ee124 --- /dev/null +++ b/Modules/c++0x-test-constexpr-N2235.cpp @@ -0,0 +1,13 @@ +#include <sys/types.h> + +constexpr size_t intsize() +{ + return sizeof(int); +} + +int main(void) +{ + unsigned char size_like_int[intsize()]; + + return sizeof(size_like_int) >= sizeof(int) ? 0 : 1; +} diff --git a/Modules/c++0x-test-cstdint.cpp b/Modules/c++0x-test-cstdint.cpp new file mode 100644 index 0000000..5d1aed8 --- /dev/null +++ b/Modules/c++0x-test-cstdint.cpp @@ -0,0 +1,6 @@ +#include <cstdint> + +int main(void) +{ + return (sizeof(uint64_t) == 8) ? 0 : 1; +} \ No newline at end of file diff --git a/Modules/c++0x-test-long_long-N1811.cpp b/Modules/c++0x-test-long_long-N1811.cpp new file mode 100644 index 0000000..9a7f137 --- /dev/null +++ b/Modules/c++0x-test-long_long-N1811.cpp @@ -0,0 +1,6 @@ +int main(void) +{ + long long l; + + return sizeof(l == 8) ? 0 : 1; +} diff --git a/Modules/c++0x-test-nullptr-N2431.cpp b/Modules/c++0x-test-nullptr-N2431.cpp new file mode 100644 index 0000000..9f41071 --- /dev/null +++ b/Modules/c++0x-test-nullptr-N2431.cpp @@ -0,0 +1,6 @@ +int main(void) +{ + void *v = nullptr; + + return v ? 1 : 0; +} diff --git a/Modules/c++0x-test-nullptr-N2431_fail_compile.cpp b/Modules/c++0x-test-nullptr-N2431_fail_compile.cpp new file mode 100644 index 0000000..6a002bc --- /dev/null +++ b/Modules/c++0x-test-nullptr-N2431_fail_compile.cpp @@ -0,0 +1,6 @@ +int main(void) +{ + int i = nullptr; + + return 1; +} diff --git a/Modules/c++0x-test-rvalue-references-N2118.cpp b/Modules/c++0x-test-rvalue-references-N2118.cpp new file mode 100644 index 0000000..e261add --- /dev/null +++ b/Modules/c++0x-test-rvalue-references-N2118.cpp @@ -0,0 +1,57 @@ +#include <cassert> + +class rvmove { +public: + void *ptr; + char *array; + + rvmove() + : ptr(0), + array(new char[10]) + { + ptr = this; + } + + rvmove(rvmove &&other) + : ptr(other.ptr), + array(other.array) + { + other.array = 0; + other.ptr = 0; + } + + ~rvmove() + { + assert(((ptr != 0) && (array != 0)) || ((ptr == 0) && (array == 0))); + delete[] array; + } + + rvmove &operator=(rvmove &&other) + { + delete[] array; + ptr = other.ptr; + array = other.array; + other.array = 0; + other.ptr = 0; + return *this; + } + + static rvmove create() + { + return rvmove(); + } +private: + rvmove(const rvmove &); + rvmove &operator=(const rvmove &); +}; + +int main() +{ + rvmove mine; + if (mine.ptr != &mine) + return 1; + mine = rvmove::create(); + if (mine.ptr == &mine) + return 1; + return 0; +} \ No newline at end of file diff --git a/Modules/c++0x-test-sizeof_member-N2253.cpp b/Modules/c++0x-test-sizeof_member-N2253.cpp new file mode 100644 index 0000000..27ed4e8 --- /dev/null +++ b/Modules/c++0x-test-sizeof_member-N2253.cpp @@ -0,0 +1,9 @@ +struct foo { + short bar; + int baz; +}; + +int main(void) +{ + return (sizeof(foo::baz) == 4) ? 0 : 1; +} \ No newline at end of file diff --git a/Modules/c++0x-test-sizeof_member-N2253_fail.cpp b/Modules/c++0x-test-sizeof_member-N2253_fail.cpp new file mode 100644 index 0000000..579a31d --- /dev/null +++ b/Modules/c++0x-test-sizeof_member-N2253_fail.cpp @@ -0,0 +1,9 @@ +struct foo { + int baz; + double bar; +}; + +int main(void) +{ + return (sizeof(foo::bar) == 4) ? 0 : 1; +} \ No newline at end of file diff --git a/Modules/c++0x-test-static_assert-N1720.cpp b/Modules/c++0x-test-static_assert-N1720.cpp new file mode 100644 index 0000000..1406b86 --- /dev/null +++ b/Modules/c++0x-test-static_assert-N1720.cpp @@ -0,0 +1,5 @@ +int main(void) +{ + static_assert(0 < 1, "your ordering of integers is screwed"); + return 0; +} \ No newline at end of file diff --git a/Modules/c++0x-test-static_assert-N1720_fail_compile.cpp b/Modules/c++0x-test-static_assert-N1720_fail_compile.cpp new file mode 100644 index 0000000..56e0979 --- /dev/null +++ b/Modules/c++0x-test-static_assert-N1720_fail_compile.cpp @@ -0,0 +1,5 @@ +int main(void) +{ + static_assert(1 < 0, "your ordering of integers is screwed"); + return 0; +} \ No newline at end of file diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 77c5752..64d0293 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -197,6 +197,7 @@ IF(BUILD_TESTING) LIST(APPEND TEST_BUILD_DIRS ${CMAKE_BUILD_TEST_BINARY_DIR}) ADD_TEST_MACRO(Module.CheckTypeSize CheckTypeSize) + ADD_TEST_MACRO(Module.CXX0xFeatures CXX0xFeatures) ADD_TEST(LinkFlags-prepare ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} diff --git a/Tests/Module/CXX0xFeatures/CMakeLists.txt b/Tests/Module/CXX0xFeatures/CMakeLists.txt new file mode 100644 index 0000000..24ca26f --- /dev/null +++ b/Tests/Module/CXX0xFeatures/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR) +project(Cxx0xFeatures C CXX) + +include(CheckCXX0xFeatures) + +foreach (flag + HAS_CXX0X_STATIC_ASSERT + HAS_CXX0X_LONG_LONG + HAS_CXX0X_RVALUE_REFERENCES + HAS_CXX0X_CONSTEXPR + HAS_CXX0X_SIZEOF_MEMBER + HAS_CXX0X_FUNC + HAS_CXX0X_NULLPTR + HAS_CXX0X_CSTDINT_H) + if (${flag}) + add_definitions("-D${flag}") + message(STATUS "Compiler C++0x support flag ${flag} set") + endif () +endforeach (flag) + +add_executable(CXX0xFeatures cxx0xfeatures.cxx) diff --git a/Tests/Module/CXX0xFeatures/cxx0xfeatures.cxx b/Tests/Module/CXX0xFeatures/cxx0xfeatures.cxx new file mode 100644 index 0000000..63a370f --- /dev/null +++ b/Tests/Module/CXX0xFeatures/cxx0xfeatures.cxx @@ -0,0 +1,57 @@ +#if defined(HAS_CXX0X_CSTDINT_H) +#include <cstdint> +#endif + +#include <sys/types.h> + +struct thing { + unsigned char one; +#if defined(HAS_CXX0X_CSTDINT_H) + uint32_t four; +#endif +#if defined(HAS_CXX0X_LONG_LONG) + long long eight; +#endif +}; + +#include <stdio.h> + +int main() +{ +#if defined (HAS_CXX0X_NULLPTR) + void *nix = nullptr; +#else /* HAS_CXX0X_NULLPTR */ + void *nix = 0; +#endif /* HAS_CXX0X_NULLPTR */ + +#if defined(HAS_CXX0X_STATIC_ASSERT) + static_assert(1 < 42, "Your C++ compiler is b0rked"); +#endif /* HAS_CXX0X_STATIC_ASSERT */ + +#if defined(HAS_CXX0X_FUNC) + const char *funcname = __func__; + printf("the name of main() function is: %s\n", funcname); +#endif /* HAS_CXX0X_FUNC */ + +#if defined(HAS_CXX0X_SIZEOF_MEMBER) + size_t onesize = sizeof(thing::one); +#if defined(HAS_CXX0X_STATIC_ASSERT) + static_assert(sizeof(thing::one) == 1, "Your char is not one byte long"); +#endif /* HAS_CXX0X_STATIC_ASSERT */ + +#if defined(HAS_CXX0X_CSTDINT_H) + size_t foursize = sizeof(thing::four); +#if defined(HAS_CXX0X_STATIC_ASSERT) + static_assert(sizeof(thing::four) == 4, "Your uint32_t is not 32 bit long"); +#endif /* HAS_CXX0X_STATIC_ASSERT */ +#endif /* HAS_CXX0X_CSTDINT_H */ +#if defined(HAS_CXX0X_LONG_LONG) + size_t eightsize = sizeof(thing::eight); +#if defined(HAS_CXX0X_STATIC_ASSERT) + static_assert(sizeof(thing::eight) == 8, "Your uint32_t is not 64 bit long"); +#endif /* HAS_CXX0X_STATIC_ASSERT */ +#endif /* HAS_CXX0X_LONG_LONG */ +#endif /* HAS_CXX0X_SIZEOF_MEMBER */ + + return 0; +} -- 1.7.3.2
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Follow this link to subscribe/unsubscribe: http://www.cmake.org/mailman/listinfo/cmake
