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