Skip to content

Commit 6a8dee9

Browse files
Remove redundant feature checks on re-run of CMake config step (#2084)
- On a config re-run, CMake will not check features again as it will read previously defined cache variables. - Logic was difficult to follow, so refactored `cxx_feature_check` for simplicity Fixes #2078.
1 parent 2279f2a commit 6a8dee9

File tree

2 files changed

+76
-51
lines changed

2 files changed

+76
-51
lines changed

CMakeLists.txt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,17 @@ if (BENCHMARK_USE_LIBCXX)
309309
endif(BENCHMARK_USE_LIBCXX)
310310

311311
# C++ feature checks
312-
# Determine the correct regular expression engine to use
312+
# Determine the correct regular expression engine to use. First compatible engine found is used.
313313
cxx_feature_check(STD_REGEX)
314-
cxx_feature_check(GNU_POSIX_REGEX)
315-
cxx_feature_check(POSIX_REGEX)
314+
315+
if(NOT HAVE_STD_REGEX)
316+
cxx_feature_check(GNU_POSIX_REGEX)
317+
endif()
318+
319+
if(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX)
320+
cxx_feature_check(POSIX_REGEX)
321+
endif()
322+
316323
if(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)
317324
message(FATAL_ERROR "Failed to determine the source files for the regular expression backend")
318325
endif()

cmake/CXXFeatureCheck.cmake

Lines changed: 66 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,35 @@
1010
#
1111
# include(CXXFeatureCheck)
1212
# cxx_feature_check(STD_REGEX)
13-
# Requires CMake 2.8.12+
13+
# Requires CMake 3.13+
1414

1515
if(__cxx_feature_check)
1616
return()
1717
endif()
1818
set(__cxx_feature_check INCLUDED)
1919

20-
option(CXXFEATURECHECK_DEBUG OFF)
20+
option(CXXFEATURECHECK_DEBUG OFF "Enable debug messages for CXX feature checks")
2121

22-
function(cxx_feature_check FILE)
23-
string(TOLOWER ${FILE} FILE)
24-
string(TOUPPER ${FILE} VAR)
25-
string(TOUPPER "HAVE_${VAR}" FEATURE)
26-
if (DEFINED HAVE_${VAR})
27-
set(HAVE_${VAR} 1 PARENT_SCOPE)
28-
add_definitions(-DHAVE_${VAR})
22+
function(cxx_feature_check_print log)
23+
if(CXXFEATURECHECK_DEBUG)
24+
message(STATUS "${log}")
25+
endif()
26+
endfunction()
27+
28+
function(cxx_feature_check FEATURE)
29+
string(TOLOWER ${FEATURE} FILE)
30+
string(TOUPPER HAVE_${FEATURE} VAR)
31+
32+
# Check if the variable is already defined to a true or false for a quick return.
33+
# This allows users to predefine the variable to skip the check.
34+
# Or, if the variable is already defined by a previous check, we skip the costly check.
35+
if (DEFINED ${VAR})
36+
if (${VAR})
37+
cxx_feature_check_print("Feature ${FEATURE} already enabled.")
38+
add_compile_definitions(${VAR})
39+
else()
40+
cxx_feature_check_print("Feature ${FEATURE} already disabled.")
41+
endif()
2942
return()
3043
endif()
3144

@@ -35,48 +48,53 @@ function(cxx_feature_check FILE)
3548
list(APPEND FEATURE_CHECK_CMAKE_FLAGS ${ARGV1})
3649
endif()
3750

38-
if (NOT DEFINED COMPILE_${FEATURE})
39-
if(CMAKE_CROSSCOMPILING)
40-
message(STATUS "Cross-compiling to test ${FEATURE}")
41-
try_compile(COMPILE_${FEATURE}
42-
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
43-
CXX_STANDARD 17
44-
CXX_STANDARD_REQUIRED ON
45-
CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}
46-
LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}
47-
OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)
48-
if(COMPILE_${FEATURE})
49-
message(WARNING
50-
"If you see build failures due to cross compilation, try setting HAVE_${VAR} to 0")
51-
set(RUN_${FEATURE} 0 CACHE INTERNAL "")
52-
else()
53-
set(RUN_${FEATURE} 1 CACHE INTERNAL "")
54-
endif()
55-
else()
56-
message(STATUS "Compiling and running to test ${FEATURE}")
57-
try_run(RUN_${FEATURE} COMPILE_${FEATURE}
58-
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
59-
CXX_STANDARD 17
60-
CXX_STANDARD_REQUIRED ON
61-
CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}
62-
LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}
63-
COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)
51+
if(CMAKE_CROSSCOMPILING)
52+
cxx_feature_check_print("Cross-compiling to test ${FEATURE}")
53+
try_compile(
54+
COMPILE_STATUS
55+
${CMAKE_BINARY_DIR}
56+
${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
57+
CXX_STANDARD 17
58+
CXX_STANDARD_REQUIRED ON
59+
CMAKE_FLAGS "${FEATURE_CHECK_CMAKE_FLAGS}"
60+
LINK_LIBRARIES "${BENCHMARK_CXX_LIBRARIES}"
61+
OUTPUT_VARIABLE COMPILE_OUTPUT_VAR
62+
)
63+
if(COMPILE_STATUS)
64+
set(RUN_STATUS 0)
65+
message(WARNING
66+
"If you see build failures due to cross compilation, try setting ${VAR} to 0")
6467
endif()
68+
else()
69+
cxx_feature_check_print("Compiling and running to test ${FEATURE}")
70+
try_run(
71+
RUN_STATUS
72+
COMPILE_STATUS
73+
${CMAKE_BINARY_DIR}
74+
${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
75+
CXX_STANDARD 17
76+
CXX_STANDARD_REQUIRED ON
77+
CMAKE_FLAGS "${FEATURE_CHECK_CMAKE_FLAGS}"
78+
LINK_LIBRARIES "${BENCHMARK_CXX_LIBRARIES}"
79+
COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
80+
RUN_OUTPUT_VARIABLE RUN_OUTPUT
81+
)
6582
endif()
6683

67-
if(COMPILE_${FEATURE})
68-
if(DEFINED RUN_${FEATURE} AND RUN_${FEATURE} EQUAL 0)
69-
message(STATUS "Performing Test ${FEATURE} -- success")
70-
set(HAVE_${VAR} 1 PARENT_SCOPE)
71-
add_definitions(-DHAVE_${VAR})
72-
else()
73-
message(STATUS "Performing Test ${FEATURE} -- compiled but failed to run")
74-
endif()
84+
if(COMPILE_STATUS AND RUN_STATUS EQUAL 0)
85+
message(STATUS "Performing Test ${FEATURE} -- success")
86+
set(${VAR} TRUE CACHE BOOL "" FORCE)
87+
add_compile_definitions(${VAR})
88+
return()
89+
endif()
90+
91+
set(${VAR} FALSE CACHE BOOL "" FORCE)
92+
message(STATUS "Performing Test ${FEATURE} -- failed")
93+
94+
if(NOT COMPILE_STATUS)
95+
cxx_feature_check_print("Compile Output: ${COMPILE_OUTPUT}")
7596
else()
76-
if(CXXFEATURECHECK_DEBUG)
77-
message(STATUS "Performing Test ${FEATURE} -- failed to compile: ${COMPILE_OUTPUT_VAR}")
78-
else()
79-
message(STATUS "Performing Test ${FEATURE} -- failed to compile")
80-
endif()
97+
cxx_feature_check_print("Run Output: ${RUN_OUTPUT}")
8198
endif()
99+
82100
endfunction()

0 commit comments

Comments
 (0)