From b76d67fca0a6cc3b003606734f3595a118650ef6 Mon Sep 17 00:00:00 2001 From: maier Date: Wed, 12 Sep 2012 10:19:27 +0000 Subject: [PATCH] Add checks for C++0X Support git-svn-id: https://svn.dealii.org/branches/branch_cmake@26301 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/CMakeLists.txt | 2 +- deal.II/aclocal.m4 | 214 ------------------ .../check/check_for_compiler_features.cmake | 19 ++ .../cmake/check/check_for_cxx_features.cmake | 199 +++++++++++++++- 4 files changed, 207 insertions(+), 227 deletions(-) diff --git a/deal.II/CMakeLists.txt b/deal.II/CMakeLists.txt index b4a32ea812..6718a281e8 100644 --- a/deal.II/CMakeLists.txt +++ b/deal.II/CMakeLists.txt @@ -81,7 +81,7 @@ SET(DEAL_II_PATH ${CMAKE_INSTALL_PREFIX}) #TODO: -SET(CMAKE_CXX_FLAGS "-std=c++0x -Wfatal-errors -D_REENTRANT -fPIC -O2 -march=native") +SET(CMAKE_CXX_FLAGS "-Wfatal-errors -D_REENTRANT -fPIC -O2 -march=native") SET(CMAKE_C_FLAGS "-Wfatal-errors -D_REENTRANT -fPIC -O2 -march=native") diff --git a/deal.II/aclocal.m4 b/deal.II/aclocal.m4 index 97e5b93c7c..c3ff58128b 100644 --- a/deal.II/aclocal.m4 +++ b/deal.II/aclocal.m4 @@ -1147,220 +1147,6 @@ AC_DEFUN(DEAL_II_SET_CXX_DEBUG_FLAG, dnl -dnl ------------------------------------------------------------- -dnl See if there is a compiler flag to enable C++1x features -dnl -dnl Usage: DEAL_II_CHECK_CXX1X -dnl -dnl ------------------------------------------------------------- -AC_DEFUN(DEAL_II_CHECK_CXX1X, dnl -[ - AC_MSG_CHECKING(whether compiler has a flag to support C++2011) - - dnl See if -std=c++0x exists - OLD_CXXFLAGS="$CXXFLAGS" - CXXFLAGS=-std=c++0x - AC_TRY_COMPILE([], [;], - [ - AC_MSG_RESULT(yes) - test_cxx1x=yes - ], - [ - AC_MSG_RESULT(no) - test_cxx1x=no - ]) - CXXFLAGS="${OLD_CXXFLAGS}" - - dnl If the flag above works, then see if the compiler is complete - dnl enough in this area - if test "x$test_cxx1x" = "xyes" ; then - DEAL_II_CHECK_CXX1X_COMPONENTS("-std=c++0x") - fi -]) - - -dnl ------------------------------------------------------------- -dnl Given the command line flag specified as argument to this macro, -dnl test whether all components that we need from the C++1X -dnl standard are actually available. If so, add the flag to -dnl CXXFLAGSG and CXXFLAGSO, and set a flag in config.h -dnl -dnl Usage: DEAL_II_CHECK_CXX1X_COMPONENTS(cxxflag) -dnl -dnl ------------------------------------------------------------- -AC_DEFUN(DEAL_II_CHECK_CXX1X_COMPONENTS, dnl -[ - OLD_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$1" - - all_cxx1x_classes_available=yes - - AC_MSG_CHECKING(for std::array) - AC_TRY_COMPILE( - [#include ], - [ std::array p; p[0];], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ] - ) - - AC_MSG_CHECKING(for std::condition_variable) - AC_TRY_COMPILE( - [#include ], - [ std::condition_variable c; c.notify_all()], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ] - ) - - AC_MSG_CHECKING(for std::function and std::bind) - AC_TRY_COMPILE( - [#include - void f(int, double); ], - [ std::function - g = std::bind (f, std::placeholders::_1, 1.1) ;], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ] - ) - - dnl Make sure we don't run into GCC bug 35569 - AC_MSG_CHECKING(for std::bind works with rvalues) - AC_TRY_COMPILE( - [#include - void f(int); ], - [ using namespace std; - using namespace std::placeholders; - bind(multiplies(),4,_1)(5); ;], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ] - ) - - AC_MSG_CHECKING(for std::shared_ptr) - AC_TRY_COMPILE( - [#include ], - [ std::shared_ptr p(new int(3))], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ] - ) - - AC_MSG_CHECKING(for std::thread) - AC_TRY_COMPILE( - [#include - void f(int); ], - [ std::thread t(f,1); t.join();], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ] - ) - - dnl On some systems with gcc 4.5.0, we can compile the code - dnl above but it will throw an exception when run. So test - dnl that as well. The test will only be successful if we have - dnl libpthread available, so link it in for this test. If - dnl multithreading is requested, it will be added to CXXFLAGS - dnl later on so there is no need to do this here. - CXXFLAGS="$1 -lpthread" - AC_MSG_CHECKING(whether std::thread actually works) - AC_TRY_RUN( - [#include - void f(int) {} - int main() { std::thread t(f,1); t.join(); } ], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ] - ) - CXXFLAGS="$1" - - AC_MSG_CHECKING(for std::mutex) - AC_TRY_COMPILE( - [#include ], - [ std::mutex m; m.lock();], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ] - ) - - AC_MSG_CHECKING(for std::tuple) - AC_TRY_COMPILE( - [#include ], - [ std::tuple p(1,1.1,'a')], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ] - ) - - AC_MSG_CHECKING(for std::type_traits) - AC_TRY_COMPILE( - [#include ], - [ const bool m0 = std::is_trivial::value; - const bool m1 = std::is_standard_layout::value; - const bool m2 = std::is_pod::value; ], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ] - ) - - CXXFLAGS="${OLD_CXXFLAGS}" - - dnl If the above classes and operations are all defined then we can - dnl use the corresponding flag in CXXFLAGS* to switch on support and - dnl correspondingly use the C++ classes instead of the BOOST classes - AC_MSG_CHECKING(whether C++1x support is complete enough) - if test "x$all_cxx1x_classes_available" = "xyes" ; then - AC_MSG_RESULT(yes) - - CXXFLAGSG="$CXXFLAGSG $1" - CXXFLAGSO="$CXXFLAGSO $1" - - AC_DEFINE(DEAL_II_CAN_USE_CXX1X, 1, - [Defined if the compiler we use supports the C++2011 standard - well enough to allow using the standard library classes instead - of the corresponding BOOST classes.]) - - - dnl Also test for a couple C++1x things that we don't use in the library - dnl but that users may want to use in their applications and that we - dnl might want to test in the testsuite - OLD_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGSG" - - extra_cxx1x_features_available=yes - - AC_MSG_CHECKING(for auto typed variables) - AC_TRY_COMPILE( - [#include ], - [ - std::vector v; - auto i = v.begin(); - *i; - ], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no); extra_cxx1x_features_available=no ] - ) - - AC_MSG_CHECKING(for range-based for) - AC_TRY_COMPILE( - [#include ], - [ - std::vector v; - for (std::vector::iterator i : v) - *i; - ], - [ AC_MSG_RESULT(yes) ], - [ AC_MSG_RESULT(no); extra_cxx1x_features_available=no ] - ) - - CXXFLAGS="${OLD_CXXFLAGS}" - - dnl Right now, do nothing with this information since we don't - dnl have any compiler that gets all this right (gcc 4.5 included) - dnl and that we could use to test these features. - else - AC_MSG_RESULT(no) - - dnl Intel icc 12.1 has this crazy behavior where it needs -std=c++0x - dnl to compile BOOST, but it fails every single one of the header - dnl file tests above. So we end up here. Work around this by using - dnl the flag even though we can't use a single piece of functionality. - if test "x$GXX_VERSION" = "xintel_icc12" ; then - CXXFLAGSG="$CXXFLAGSG $1" - CXXFLAGSO="$CXXFLAGSO $1" - fi - fi -]) diff --git a/deal.II/contrib/cmake/check/check_for_compiler_features.cmake b/deal.II/contrib/cmake/check/check_for_compiler_features.cmake index 5ddfed80bc..75334b5393 100644 --- a/deal.II/contrib/cmake/check/check_for_compiler_features.cmake +++ b/deal.II/contrib/cmake/check/check_for_compiler_features.cmake @@ -5,3 +5,22 @@ INCLUDE(CheckIncludeFiles) # # Check for various compiler features. # + + + +# +# Check whether the std::vector::iterator is just a plain pointer +# +CHECK_CXX_SOURCE_COMPILES( + " + #include + template void f(T) {} + template void f(int *); + template void f(std::vector::iterator); + int main(){return 0;} + " + DEAL_II_VECTOR_ITERATOR_IS_NOT_POINTER) + +IF(NOT DEAL_II_VECTOR_ITERATOR_IS_NOT_POINTER) + SET(DEAL_II_VECTOR_ITERATOR_IS_POINTER TRUE) +ENDIF() diff --git a/deal.II/contrib/cmake/check/check_for_cxx_features.cmake b/deal.II/contrib/cmake/check/check_for_cxx_features.cmake index 32d1c42ba4..1b7afbac78 100644 --- a/deal.II/contrib/cmake/check/check_for_cxx_features.cmake +++ b/deal.II/contrib/cmake/check/check_for_cxx_features.cmake @@ -1,36 +1,211 @@ INCLUDE(CheckCXXSourceCompiles) +INCLUDE(CheckCXXSourceRuns) INCLUDE(CheckIncludeFiles) # -# Check for various CXX features. +# Check for various C++ language features # +CHECK_CXX_SOURCE_COMPILES( # TODO: Phase out + " + #include + int main(){return 0;} + " + HAVE_STD_OSTREAM_HEADER) + +CHECK_CXX_SOURCE_COMPILES( + " + #include + int main(){return 0;} + " + HAVE_STD_IOSFWD_HEADER) + + + # -# Check whether the std::vector::iterator is just a plain pointer +# C++0x Support: # + + +# See if there is a compiler flag to enable C++0x features +# (Only test for -std=c++0x for the moment.) + +# Set CMAKE_REQUIRED_FLAGS for the unit tests +LIST(APPEND CMAKE_REQUIRED_FLAGS "-std=c++0x") + CHECK_CXX_SOURCE_COMPILES( " - #include - template void f(T) {} - template void f(int *); - template void f(std::vector::iterator); - int main(){return 0;} + int main(){ return 0; } " - DEAL_II_VECTOR_ITERATOR_IS_NOT_POINTER) + DEAL_II_HAVE_CXX0X_FLAG) + + + +IF(DEAL_II_HAVE_CXX0X_FLAG) + + CHECK_CXX_SOURCE_COMPILES( + " + #include + std::array p; + int main(){ p[0]; return 0; } + " + DEAL_II_HAVE_CXX0X_ARRAY) + + CHECK_CXX_SOURCE_COMPILES( + " + #include + std::condition_variable c; + int main(){ c.notify_all(); return 0; } + " + DEAL_II_HAVE_CXX0X_CONDITION_VARIABLE) + + CHECK_CXX_SOURCE_COMPILES( + " + #include + void f(int, double){} + std::function g = std::bind (f, std::placeholders::_1,1.1); + int main(){ return 0; } + " + DEAL_II_HAVE_CXX0X_FUNCTIONAL) + + # Make sure we don't run into GCC bug 35569 + CHECK_CXX_SOURCE_COMPILES( + " + #include + void f(int){} + using namespace std; + using namespace std::placeholders; + int main(){ bind(multiplies(),4,_1)(5); return 0; } + " + DEAL_II_HAVE_CXX0X_FUNCTIONAL_GCCBUG35569_OK) + + CHECK_CXX_SOURCE_COMPILES( + " + #include + std::shared_ptr p(new int(3)); + int main(){ return 0; } + " + DEAL_II_HAVE_CXX0X_SHARED_PTR) + + LIST(APPEND CMAKE_REQUIRED_FLAGS "-lpthreads") + + CHECK_CXX_SOURCE_COMPILES( + " + #include + void f(int){} + int main(){ std::thread t(f,1); t.join(); return 0; } + " + DEAL_II_HAVE_CXX0X_THREAD) + + #On some systems with gcc 4.5.0, we can compile the code + #above but it will throw an exception when run. So test + #that as well. The test will only be successful if we have + #libpthread available, so link it in for this test. If + #multithreading is requested, it will be added to CXXFLAGS + #later on so there is no need to do this here. + CHECK_CXX_SOURCE_RUNS( + " + #include + void f(int){} + int main(){ std::thread t(f,1); t.join(); return 0; } + " + DEAL_II_HAVE_CXX0X_THREAD_RUN_OK) + + LIST(REMOVE_ITEM CMAKE_REQUIRED_FLAGS "-lpthreads") + + CHECK_CXX_SOURCE_COMPILES( + " + #include + std::mutex m; + int main(){ m.lock(); return 0; } + " + DEAL_II_HAVE_CXX0X_MUTEX) + + CHECK_CXX_SOURCE_COMPILES( + " + #include ], + std::tuple p(1,1.1,'a'); + int main(){ return 0; } + " + DEAL_II_HAVE_CXX0X_TUPLE) + + CHECK_CXX_SOURCE_COMPILES( + " + #include + const bool m0 = std::is_trivial::value; + const bool m1 = std::is_standard_layout::value; + const bool m2 = std::is_pod::value; + int main(){ return 0; } + " + DEAL_II_HAVE_CXX0X_TYPE_TRAITS) + + IF( DEAL_II_HAVE_CXX0X_ARRAY AND + DEAL_II_HAVE_CXX0X_CONDITION_VARIABLE AND + DEAL_II_HAVE_CXX0X_FUNCTIONAL AND + DEAL_II_HAVE_CXX0X_FUNCTIONAL_GCCBUG35569_OK AND + DEAL_II_HAVE_CXX0X_SHARED_PTR AND + DEAL_II_HAVE_CXX0X_THREAD AND + DEAL_II_HAVE_CXX0X_THREAD_RUN_OK AND + DEAL_II_HAVE_CXX0X_MUTEX AND + DEAL_II_HAVE_CXX0X_TUPLE AND + DEAL_II_HAVE_CXX0X_TYPE_TRAITS ) + + MESSAGE(STATUS "Sufficient C++0x support. Enabling -std=c++0x.") + + SET(DEAL_II_CAN_USE_CXX1X TRUE) + + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") # TODO + + ELSE() + + MESSAGE(STATUS "Insufficient C++0x support. Disabling -std=c++0x.") + ENDIF() + + IF(DEAL_II_CAN_USE_CXX1X) + # + # Also test for a couple C++0x things that we don't use in the library + # but that users may want to use in their applications and that we + # might want to test in the testsuite + # + + CHECK_CXX_SOURCE_COMPILES( + " + #include + std::vector v; + int main(){ auto i = v.begin(); *i; return 0;} + " + DEAL_II_HAVE_CXX0X_AUTO_TYPE) + + CHECK_CXX_SOURCE_COMPILES( + " + #include ], + std::vector v; + int main(){ for (std::vector::iterator i : v) *i; return 0;} + " + DEAL_II_HAVE_CXX0X_RANGE_BASED_FOR) + + IF( DEAL_II_HAVE_CXX0X_AUTO_TYPE AND + DEAL_II_HAVE_CXX0X_RANGE_BASED_FOR ) + + MESSAGE(STATUS "Additional C++0x support available.") + + SET(DEAL_II_CAN_USE_ADDITIONAL_CXX1X_FEATURES) + + ENDIF() + ENDIF() -IF(NOT DEAL_II_VECTOR_ITERATOR_IS_NOT_POINTER) - SET(DEAL_II_VECTOR_ITERATOR_IS_POINTER 1) ENDIF() +LIST(REMOVE_ITEM CMAKE_REQUIRED_FLAGS "-std=c++0x") + + # # Checks for various header files: # -CHECK_INCLUDE_FILES("ostream" HAVE_STD_OSTREAM_HEADER) # TODO: remove this... -CHECK_INCLUDE_FILES("iosfwd" HAVE_STD_IOSFWD_HEADER) CHECK_INCLUDE_FILES("stdint.h" HAVE_STDINT_H) CHECK_INCLUDE_FILES("stdlib.h" HAVE_STDLIB_H) CHECK_INCLUDE_FILES("strings.h" HAVE_STRINGS_H) -- 2.39.5