use_cpp_11.cmake 4.66 KB
Newer Older
1
2
# This script creates a function, enable_cpp11_for_target(), which checks if your
# compiler has C++11 support and enables it if it does.
3
4


5
cmake_minimum_required(VERSION 2.8.12)
6

7
if (POLICY CMP0054)
Davis King's avatar
Davis King committed
8
   cmake_policy(SET CMP0054 NEW)
9
10
endif()

11
12
13
14
15
16

set(_where_is_cmake_utils_dir ${CMAKE_CURRENT_LIST_DIR})

function(enable_cpp11_for_target target_name)


17
18
19
# Set to false unless we find out otherwise in the code below.
set(COMPILER_CAN_DO_CPP_11 0)

20
21


22
23
24
macro(test_compiler_for_cpp11)
   message(STATUS "Building a C++11 test project to see if your compiler supports C++11")
   try_compile(test_for_cpp11_worked ${PROJECT_BINARY_DIR}/cpp11_test_build 
25
26
      ${_where_is_cmake_utils_dir}/test_for_cpp11 cpp11_test
      OUTPUT_VARIABLE cpp11_test_output)
27
28
29
30
31
32
   if (test_for_cpp11_worked)
      message(STATUS "C++11 activated.")
      set(COMPILER_CAN_DO_CPP_11 1)
   else()
      set(COMPILER_CAN_DO_CPP_11 0)
      message(STATUS "********** Your compiler failed to build a C++11 project.  C++11 is required to use all parts of dlib! **********")
33
      message(STATUS "********** Compiler output: ${cpp11_test_output} **********")
34
35
36
   endif()
endmacro()

37
38
39
# Now turn on the appropriate compiler switch to enable C++11 if you have a
# C++11 compiler.  In CMake 3.1 there is a simple flag you can set, but earlier
# verions of CMake are not so convenient.
Davis King's avatar
Davis King committed
40
if (CMAKE_VERSION VERSION_LESS "3.1.2")
41
   if(CMAKE_COMPILER_IS_GNUCXX)
Davis King's avatar
Davis King committed
42
      execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
43
      if (GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
44
         message(STATUS "C++11 activated.")
45
         target_compile_options(${target_name} PUBLIC "-std=gnu++11")
46
47
         set(COMPILER_CAN_DO_CPP_11 1)
      endif()
Davis King's avatar
Davis King committed
48
49
50
   elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
      execute_process( COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE clang_full_version_string )
      string (REGEX REPLACE ".*clang version ([0-9]+\\.[0-9]+).*" "\\1" CLANG_VERSION ${clang_full_version_string})
51
      if (CLANG_VERSION VERSION_GREATER 3.3)
Davis King's avatar
Davis King committed
52
         message(STATUS "C++11 activated.")
53
         target_compile_options(${target_name} PUBLIC "-std=c++11")
Davis King's avatar
Davis King committed
54
55
         set(COMPILER_CAN_DO_CPP_11 1)
      endif()
56
   else()
Davis King's avatar
Davis King committed
57
      # Since we don't know what compiler this is just try to build a c++11 project and see if it compiles.
58
      test_compiler_for_cpp11()
59
   endif()
60
else()  
61

62
   # Set a flag if the compiler you are using is capable of providing C++11 features.
63
64
   get_property(cxx_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
   if (";${cxx_features};" MATCHES ";cxx_rvalue_references;" AND
Davis King's avatar
Davis King committed
65
66
67
68
69
70
71
72
         ";${cxx_features};" MATCHES ";cxx_variadic_templates;" AND
         ";${cxx_features};" MATCHES ";cxx_lambdas;" AND
         ";${cxx_features};" MATCHES ";cxx_defaulted_move_initializers;" AND
         ";${cxx_features};" MATCHES ";cxx_delegating_constructors;" AND
         ";${cxx_features};" MATCHES ";cxx_thread_local;" AND
         ";${cxx_features};" MATCHES ";cxx_constexpr;" AND
         ";${cxx_features};" MATCHES ";cxx_decltype_incomplete_return_types;" AND
         ";${cxx_features};" MATCHES ";cxx_auto_type;")
73

74
      set(COMPILER_CAN_DO_CPP_11 1)
75
76
77
78
79
80
81
82
83
84
      # Tell cmake that we need C++11 for dlib
      target_compile_features(${target_name} 
         PUBLIC 
            cxx_rvalue_references
            cxx_variadic_templates
            cxx_lambdas
            cxx_defaulted_move_initializers
            cxx_delegating_constructors
            cxx_thread_local
            cxx_constexpr
85
            # cxx_decltype_incomplete_return_types  # purposfully commented out because cmake errors out on this when using visual studio and cmake 3.8.0
86
87
88
89
90
91
92
93
94
            cxx_auto_type
         )

      if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
         # Sometimes clang will lie and report that it supports C++11 when
         # really it doesn't support thread_local.  So check for that.
         test_compiler_for_cpp11()
      else()
         message(STATUS "C++11 activated.")
95
96
97
98
      endif()
   endif()
endif()

99
100
# Always enable whatever partial C++11 support we have, even if it isn't full
# support, and just hope for the best.
101
102
103
104
105
106
if (NOT COMPILER_CAN_DO_CPP_11)
   include(CheckCXXCompilerFlag)
   CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
   CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
   if(COMPILER_SUPPORTS_CXX11)
      message(STATUS "C++11 activated (compiler doesn't have full C++11 support).")
107
      target_compile_options(${target_name} PUBLIC "-std=c++11")
108
109
   elseif(COMPILER_SUPPORTS_CXX0X)
      message(STATUS "C++0x activated (compiler doesn't have full C++11 support).")
110
      target_compile_options(${target_name} PUBLIC "-std=c++0x")
111
112
113
   endif()
endif()

114
115
endfunction()