@@ -18,27 +18,116 @@ find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED)
18
18
include (CheckCXXCompilerFlag)
19
19
include (CMakeParseArguments)
20
20
21
- if (NOT PYBIND11_CPP_STANDARD AND NOT CMAKE_CXX_STANDARD)
22
- if (NOT MSVC )
23
- check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG)
21
+ # The following options start out empty and cached; if empty they support "auto" behavior
22
+
23
+ ## Don't do anything if CMAKE_CXX_STANDARD is set
24
+ if (NOT CMAKE_CXX_STANDARD)
25
+ # While complile features were introduced in 3.1, only 3.8+ have meta-features
26
+ # (And C++17 seems to be mostly supported through the meta-feature)
27
+
28
+ if (CMAKE_VERSION VERSION_LESS 3.8 AND NOT PYBIND11_CXX_FEATURES)
29
+ if (NOT PYBIND_CPP_STANDARD)
30
+ # Only try to get the standard manually if CMake doesn't support compiler features
31
+ if (MSVC )
32
+ set (PYBIND11_CPP_STANDARD "/std:c++14" )
33
+ message (STATUS "pybind11 selected C++14 flag, MSVC" )
34
+ else ()
35
+ check_cxx_compiler_flag("-std=c++17" HAS_CPP17_FLAG)
36
+ check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG)
37
+ check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG)
38
+
39
+ if (HAS_CPP17_FLAG)
40
+ set (PYBIND11_CPP_STANDARD "-std=c++17" )
41
+ message (STATUS "pybind11 selected C++17 flag" )
42
+ elseif (HAS_CPP14_FLAG)
43
+ set (PYBIND11_CPP_STANDARD "-std=c++14" )
44
+ message (STATUS "pybind11 selected C++14 flag" )
45
+ elseif (HAS_CPP11_FLAG)
46
+ set (PYBIND11_CPP_STANDARD "-std=c++11" )
47
+ message (STATUS "pybind11 selected C++11 flag" )
48
+ else ()
49
+ message (FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!" )
50
+ endif ()
51
+ endif ()
52
+ endif ()
24
53
25
- if (HAS_CPP14_FLAG)
26
- set (PYBIND11_CPP_STANDARD -std=c++14)
54
+ # Auto add if CMake >= 3.8 and CXX_FEATURES is not set
55
+ elseif (NOT PYBIND11_CXX_FEATURES)
56
+ # IN_LIST introduced in CMAKE 3.3
57
+ # Safe because this will only activate if CMake >= 3.8
58
+ cmake_policy (SET CMP0057 NEW)
59
+
60
+ # The following only print if running the first time,
61
+ # and no C++ mode selected
62
+ if (cxx_std_17 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
63
+ set (PYBIND11_CXX_FEATURES cxx_std_17)
64
+ message (STATUS "pybind11 selected C++17 mode, compiler feature" )
65
+ elseif (cxx_std_14 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
66
+ message (STATUS "pybind11 selected C++14 mode, compiler feature" )
67
+ set (PYBIND11_CXX_FEATURES cxx_std_14)
68
+ elseif (cxx_std_11 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
69
+ message (STATUS "pybind11 selected C++11 mode, compiler feature" )
70
+ set (PYBIND11_CXX_FEATURES cxx_std_11)
27
71
else ()
28
- check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG)
29
- if (HAS_CPP11_FLAG)
30
- set (PYBIND11_CPP_STANDARD -std=c++11)
72
+ message (FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!" )
73
+ endif ()
74
+ endif ()
75
+ endif ()
76
+
77
+ # Allow the user to override by setting the cache value after the auto-discovery
78
+ # Empty values get filled on first run (PYBIND11_CPP_STANDARD for CMake < 3.8,
79
+ # otherwise PYBIND11_CXX_FEATURES), and then at this point are promoted to the CACHE.
80
+
81
+ set (PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING
82
+ "C++ standard flag, e.g. -std=c++11, -std=c++14, /std:c++14. Defaults to highest supported for CMake 2.8-3.7" )
83
+
84
+ if (NOT CMAKE_VERSION VERSION_LESS 3.1)
85
+ #Only provide the option if CMake >= 3.1
86
+ set (PYBIND11_CXX_FEATURES ${PYBIND11_CXX_FEATURES} CACHE STRING
87
+ "List of compile features for PyBind, will use highest detected C++ version in CMake 3.8+" )
88
+ elseif (PYBIND11_CXX_FEATURES)
89
+ message (FATAL_ERROR "PYBIND11_CXX_FEATURES is not supported for CMake < 3.1" )
90
+ endif ()
91
+
92
+ function (_pybind11_target_cxx_std target_name)
93
+
94
+ # Do not do any overriding if global CMAKE_CXX_STANDARD is set
95
+ if (NOT CMAKE_CXX_STANDARD)
96
+ # See if this is an interface or regular target
97
+ get_target_property (PYTYPE ${target_name} TYPE )
98
+ get_target_property (PYIMPORTED ${target_name} IMPORTED )
99
+
100
+ # Allow manual settings (Needed for older CMakes)
101
+ # Will always be set for old CMake
102
+ if (PYBIND11_CPP_STANDARD)
103
+ if (PYTYPE STREQUAL "INTERFACE_LIBRARY" )
104
+ if (PYIMPORTED)
105
+ set_property (TARGET ${target_name} APPEND PROPERTY
106
+ INTERFACE_COMPILE_OPTIONS ${PYBIND11_CPP_STANDARD} )
107
+ else ()
108
+ target_compile_options (${target_name} INTERFACE ${PYBIND11_CPP_STANDARD} )
109
+ endif ()
110
+ else ()
111
+ target_compile_options (${target_name} PUBLIC ${PYBIND11_CPP_STANDARD} )
112
+ endif ()
113
+
114
+ # A user of CMake 3.1 can override this, or 3.8 will default to using it
115
+ elseif (PYBIND11_CXX_FEATURES)
116
+ if (PYTYPE STREQUAL "INTERFACE_LIBRARY" )
117
+ if (PYIMPORTED)
118
+ set_property (TARGET ${target_name} APPEND PROPERTY
119
+ INTERFACE_COMPILE_FEATURES ${PYBIND11_CXX_FEATURES} )
120
+ else ()
121
+ target_compile_features (${target_name} INTERFACE ${PYBIND11_CXX_FEATURES} )
122
+ endif ()
31
123
else ()
32
- message (FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!" )
124
+ target_compile_features (${target_name} PUBLIC ${PYBIND11_CXX_FEATURES} )
125
+ set_target_properties (${target_name} PROPERTIES CXX_EXTENSIONS OFF )
33
126
endif ()
34
127
endif ()
35
- elseif (MSVC )
36
- set (PYBIND11_CPP_STANDARD /std:c++14)
37
128
endif ()
129
+ endfunction ()
38
130
39
- set (PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING
40
- "C++ standard flag, e.g. -std=c++11, -std=c++14, /std:c++14. Defaults to C++14 mode." FORCE)
41
- endif ()
42
131
43
132
# Checks whether the given CXX/linker flags can compile and link a cxx file. cxxflags and
44
133
# linkerflags are lists of flags to use. The result variable is a unique variable name for each set
@@ -185,7 +274,7 @@ function(pybind11_add_module target_name)
185
274
endif ()
186
275
187
276
# Make sure C++11/14 are enabled
188
- target_compile_options (${target_name} PUBLIC ${PYBIND11_CPP_STANDARD } )
277
+ _pybind11_target_cxx_std (${target_name} )
189
278
190
279
if (ARG_NO_EXTRAS)
191
280
return ()
0 commit comments