@@ -18,30 +18,108 @@ find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED)
1818include (CheckCXXCompilerFlag)
1919include (CMakeParseArguments)
2020
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
2124if (NOT CMAKE_CXX_STANDARD)
22- if (NOT PYBIND11_CPP_STANDARD AND CMAKE_VERSION VERSION_LESS 3.8)
23- if (NOT MSVC )
24- check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG)
25-
26- if (HAS_CPP14_FLAG)
27- set (PYBIND11_CPP_STANDARD -std=c++14)
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" )
2833 else ()
34+ check_cxx_compiler_flag("-std=c++17" HAS_CPP17_FLAG)
35+ check_cxx_compiler_flag("-std=c++14" HAS_CPP14_FLAG)
2936 check_cxx_compiler_flag("-std=c++11" HAS_CPP11_FLAG)
30- if (HAS_CPP11_FLAG)
31- set (PYBIND11_CPP_STANDARD -std=c++11)
37+
38+ if (HAS_CPP17_FLAG)
39+ set (PYBIND11_CPP_STANDARD "-std=c++17" )
40+ elseif (HAS_CPP14_FLAG)
41+ set (PYBIND11_CPP_STANDARD "-std=c++14" )
42+ elseif (HAS_CPP11_FLAG)
43+ set (PYBIND11_CPP_STANDARD "-std=c++11" )
3244 else ()
3345 message (FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!" )
3446 endif ()
3547 endif ()
36- elseif (MSVC )
37- set (PYBIND11_CPP_STANDARD /std:c++14)
3848 endif ()
39-
40- set (PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING
41- "C++ standard flag, e.g. -std=c++11, -std=c++14, /std:c++14. Defaults to C++14 mode." FORCE)
49+
50+ # Auto add if CMake >= 3.8 and CXX_FEATURES is not set
51+ elseif (NOT PYBIND11_CXX_FEATURES)
52+ # IN_LIST introduced in CMAKE 3.3
53+ # Safe because this will only activate if CMake >= 3.8
54+ cmake_policy (SET CMP0057 NEW)
55+
56+ if (cxx_std_17 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
57+ set (PYBIND11_CXX_FEATURES cxx_std_17)
58+ message (STATUS "pybind11 in C++17 mode, compiler feature" )
59+ elseif (std_std_14 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
60+ message (STATUS "pybind11 in C++14 mode, compiler feature" )
61+ set (PYBIND11_CXX_FEATURES cxx_std_14)
62+ elseif (std_std_11 IN_LIST CMAKE_CXX_COMPILE_FEATURES)
63+ message (STATUS "pybind11 in C++11 mode, compiler feature" )
64+ set (PYBIND11_CXX_FEATURES cxx_std_11)
65+ else ()
66+ message (FATAL_ERROR "Unsupported compiler -- pybind11 requires C++11 support!" )
67+ endif ()
4268 endif ()
4369endif ()
4470
71+ # Allow the user to override by setting the cache value after the auto-discovery
72+ # Empty values get filled on first run (PYBIND11_CPP_STANDARD for CMake < 3.8,
73+ # otherwise PYBIND11_CXX_FEATURES), and then at this point are promoted to the CACHE.
74+
75+ set (PYBIND11_CPP_STANDARD ${PYBIND11_CPP_STANDARD} CACHE STRING
76+ "C++ standard flag, e.g. -std=c++11, -std=c++14, /std:c++14. Defaults to highest supported for CMake 2.8-3.7" )
77+
78+ if (NOT CMAKE_VERSION VERSION_LESS 3.1)
79+ #Only provide the option if CMake >= 3.1
80+ set (PYBIND11_CXX_FEATURES ${PYBIND11_CXX_FEATURES} CACHE STRING
81+ "List of compile features for PyBind, will use highest detected C++ version in CMake 3.8+" )
82+ elseif (PYBIND11_CXX_FEATURES)
83+ message (FATAL_ERROR "PYBIND11_CXX_FEATURES is not supported for CMake < 3.1" )
84+ endif ()
85+
86+ function (_pybind11_target_cxx_std target_name)
87+ message (STATUS "Calling: ${target_name} " )
88+
89+ # Do not do any overriding if global CMAKE_CXX_STANDARD is set
90+ if (NOT CMAKE_CXX_STANDARD)
91+ message (STATUS "Calling: ${target_name} " )
92+ # See if this is an interface or regular target
93+ get_target_property (PYTYPE ${target_name} TYPE )
94+ message (STATUS "With: ${PYTYPE} " )
95+
96+ # Allow manual settings (Needed for older CMakes)
97+ # Will always be set for old CMake
98+ if (PYBIND11_CPP_STANDARD)
99+ if (PYTYPE STREQUAL "INTERFACE_LIBRARY" )
100+ target_compile_options (${target_name} INTERFACE ${PYBIND11_CPP_STANDARD} )
101+ message (STATUS "X Interface: ${target_name} " )
102+ else ()
103+ target_compile_options (${target_name} PUBLIC ${PYBIND11_CPP_STANDARD} )
104+ message (STATUS "X Fixed: ${target_name} " )
105+ endif ()
106+
107+ # A user of CMake 3.1 can override this, or 3.8 will default to using it
108+ elseif (PYBIND11_CXX_FEATURES)
109+ message (STATUS "CXX_FEAT: ${PYBIND11_CXX_FEATURES} " )
110+ if (PYTYPE STREQUAL "INTERFACE_LIBRARY" )
111+ target_compile_features (${target_name} INTERFACE ${PYBIND11_CXX_FEATURES} )
112+ message (STATUS "Interface: ${target_name} " )
113+ else ()
114+ target_compile_features (${target_name} PUBLIC ${PYBIND11_CXX_FEATURES} )
115+ set_target_properties (${target_name} PROPERTIES CXX_EXTENSIONS OFF )
116+ message (STATUS "Fixed: ${target_name} " )
117+ endif ()
118+ endif ()
119+ endif ()
120+ endfunction ()
121+
122+
45123# Checks whether the given CXX/linker flags can compile and link a cxx file. cxxflags and
46124# linkerflags are lists of flags to use. The result variable is a unique variable name for each set
47125# of flags: the compilation result will be cached base on the result variable. If the flags work,
@@ -175,12 +253,8 @@ function(pybind11_add_module target_name)
175253 endif ()
176254
177255 # Make sure C++11/14 are enabled
178- if (PYBIND11_CPP_STANDARD OR ${CMAKE_VERSION} VERSION_LESS 3.8)
179- target_compile_options (${target_name} PUBLIC ${PYBIND11_CPP_STANDARD} )
180- else ()
181- target_compile_features (${target_name} PUBLIC cxx_std_11) # Will be 14 if parent project requests 14
182- set_target_properties (${target_name} PROPERTIES CXX_EXTENSIONS OFF )
183- endif ()
256+ message (STATUS "Adding C++ness" )
257+ _pybind11_target_cxx_std(${target_name} )
184258
185259 if (ARG_NO_EXTRAS)
186260 return ()
0 commit comments