Skip to content

Commit ae430cf

Browse files
committed
cmake: Add TryAppendCXXFlags module
1 parent 7903bd5 commit ae430cf

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

cmake/module/TryAppendCXXFlags.cmake

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Copyright (c) 2023-present The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or https://opensource.org/license/mit/.
4+
5+
include_guard(GLOBAL)
6+
include(CheckCXXSourceCompiles)
7+
8+
#[=[
9+
Usage examples:
10+
11+
try_append_cxx_flags(warn_cxx_flags "-Wformat -Wformat-security")
12+
13+
14+
try_append_cxx_flags(warn_cxx_flags "-Wsuggest-override"
15+
SOURCE "struct A { virtual void f(); }; struct B : A { void f() final; };"
16+
)
17+
18+
19+
try_append_cxx_flags(sanitizers_cxx_flags "-fsanitize=${SANITIZERS}" RESULT_VAR cxx_supports_sanitizers)
20+
if(NOT cxx_supports_sanitizers)
21+
message(FATAL_ERROR "Compiler did not accept requested flags.")
22+
endif()
23+
24+
25+
try_append_cxx_flags(warn_cxx_flags "-Wunused-parameter" IF_CHECK_PASSED "-Wno-unused-parameter")
26+
27+
28+
try_append_cxx_flags(error_cxx_flags "-Werror=return-type"
29+
IF_CHECK_FAILED "-Wno-error=return-type"
30+
SOURCE "#include <cassert>\nint f(){ assert(false); }"
31+
)
32+
33+
34+
In configuration output, this function prints a string by the following pattern:
35+
36+
-- Performing Test CXX_SUPPORTS_[flags]
37+
-- Performing Test CXX_SUPPORTS_[flags] - Success
38+
39+
]=]
40+
function(try_append_cxx_flags flags_var flags)
41+
cmake_parse_arguments(PARSE_ARGV 2
42+
TACXXF # prefix
43+
"" # options
44+
"SOURCE;RESULT_VAR" # one_value_keywords
45+
"IF_CHECK_PASSED;IF_CHECK_FAILED" # multi_value_keywords
46+
)
47+
48+
string(MAKE_C_IDENTIFIER "${flags}" result)
49+
string(TOUPPER "${result}" result)
50+
set(result "CXX_SUPPORTS_${result}")
51+
52+
# Every subsequent check_cxx_source_compiles((<code> <resultVar>) run will re-use
53+
# the cached result rather than performing the check again, even if the <code> changes.
54+
# Removing the cached result in order to force the check to be re-evaluated.
55+
unset(${result} CACHE)
56+
57+
if(NOT DEFINED TACXXF_SOURCE)
58+
set(TACXXF_SOURCE "int main() { return 0; }")
59+
endif()
60+
61+
# This avoids running a linker.
62+
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
63+
set(CMAKE_REQUIRED_FLAGS "${flags} ${working_compiler_werror_flag}")
64+
check_cxx_source_compiles("${TACXXF_SOURCE}" ${result})
65+
66+
if(${result})
67+
if(DEFINED TACXXF_IF_CHECK_PASSED)
68+
string(STRIP "${${flags_var}} ${TACXXF_IF_CHECK_PASSED}" ${flags_var})
69+
else()
70+
string(STRIP "${${flags_var}} ${flags}" ${flags_var})
71+
endif()
72+
elseif(DEFINED TACXXF_IF_CHECK_FAILED)
73+
string(STRIP "${${flags_var}} ${TACXXF_IF_CHECK_FAILED}" ${flags_var})
74+
endif()
75+
set(${flags_var} "${${flags_var}}" PARENT_SCOPE)
76+
set(${TACXXF_RESULT_VAR} "${${result}}" PARENT_SCOPE)
77+
endfunction()
78+
79+
if(MSVC)
80+
set(warning_as_error_flag /WX)
81+
else()
82+
set(warning_as_error_flag -Werror)
83+
endif()
84+
try_append_cxx_flags(working_compiler_werror_flag ${warning_as_error_flag})
85+
unset(warning_as_error_flag)

0 commit comments

Comments
 (0)