TryAppendLinkerFlag.cmake raw
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 example:
10
11 try_append_linker_flag("-Wl,--major-subsystem-version,6" TARGET core_interface)
12
13
14 In configuration output, this function prints a string by the following pattern:
15
16 -- Performing Test LINKER_SUPPORTS_[flag]
17 -- Performing Test LINKER_SUPPORTS_[flag] - Success
18
19 ]=]
20 function(try_append_linker_flag flag)
21 cmake_parse_arguments(PARSE_ARGV 1
22 TALF # prefix
23 "NO_CACHE_IF_FAILED" # options
24 "TARGET;VAR;SOURCE;RESULT_VAR" # one_value_keywords
25 "IF_CHECK_PASSED" # multi_value_keywords
26 )
27
28 string(MAKE_C_IDENTIFIER "${flag}" result)
29 string(TOUPPER "${result}" result)
30 string(PREPEND result LINKER_SUPPORTS_)
31
32 set(source "int main() { return 0; }")
33 if(DEFINED TALF_SOURCE AND NOT TALF_SOURCE STREQUAL source)
34 set(source "${TALF_SOURCE}")
35 string(SHA256 source_hash "${source}")
36 string(SUBSTRING ${source_hash} 0 4 source_hash_head)
37 string(APPEND result _${source_hash_head})
38 endif()
39
40 # This forces running a linker.
41 set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
42 set(CMAKE_REQUIRED_LINK_OPTIONS ${flag} ${working_linker_werror_flag})
43 check_cxx_source_compiles("${source}" ${result})
44
45 if(${result})
46 if(DEFINED TALF_IF_CHECK_PASSED)
47 if(DEFINED TALF_TARGET)
48 target_link_options(${TALF_TARGET} INTERFACE ${TALF_IF_CHECK_PASSED})
49 endif()
50 if(DEFINED TALF_VAR)
51 list(JOIN TALF_IF_CHECK_PASSED " " flags_if_check_passed_as_string)
52 string(STRIP "${${TALF_VAR}} ${flags_if_check_passed_as_string}" ${TALF_VAR})
53 endif()
54 else()
55 if(DEFINED TALF_TARGET)
56 target_link_options(${TALF_TARGET} INTERFACE ${flag})
57 endif()
58 if(DEFINED TALF_VAR)
59 string(STRIP "${${TALF_VAR}} ${flag}" ${TALF_VAR})
60 endif()
61 endif()
62 endif()
63
64 if(DEFINED TALF_VAR)
65 set(${TALF_VAR} "${${TALF_VAR}}" PARENT_SCOPE)
66 endif()
67
68 if(DEFINED TALF_RESULT_VAR)
69 set(${TALF_RESULT_VAR} "${${result}}" PARENT_SCOPE)
70 endif()
71
72 if(NOT ${result} AND TALF_NO_CACHE_IF_FAILED)
73 unset(${result} CACHE)
74 endif()
75 endfunction()
76
77 if(MSVC)
78 try_append_linker_flag("/WX" VAR working_linker_werror_flag)
79 elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
80 try_append_linker_flag("-Wl,-fatal_warnings" VAR working_linker_werror_flag)
81 else()
82 try_append_linker_flag("-Wl,--fatal-warnings" VAR working_linker_werror_flag)
83 endif()
84