@@ -18,27 +18,116 @@ find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED)
1818include (CheckCXXCompilerFlag)
1919include (CMakeParseArguments)
2020
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 ()
2453
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)
2771 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 ()
31123 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 )
33126 endif ()
34127 endif ()
35- elseif (MSVC )
36- set (PYBIND11_CPP_STANDARD /std:c++14)
37128 endif ()
129+ endfunction ()
38130
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 ()
42131
43132# Checks whether the given CXX/linker flags can compile and link a cxx file. cxxflags and
44133# 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)
185274 endif ()
186275
187276 # Make sure C++11/14 are enabled
188- target_compile_options (${target_name} PUBLIC ${PYBIND11_CPP_STANDARD } )
277+ _pybind11_target_cxx_std (${target_name} )
189278
190279 if (ARG_NO_EXTRAS)
191280 return ()
0 commit comments