NetdataCompilerFlags.cmake 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. # SPDX-License-Identifier: GPL-3.0-or-later
  2. # Functions to simplify handling of extra compiler flags.
  3. include(CheckCCompilerFlag)
  4. include(CheckCXXCompilerFlag)
  5. # Construct a pre-processor safe name
  6. #
  7. # This takes a specified value, and assigns the generated name to the
  8. # specified target.
  9. function(make_cpp_safe_name value target)
  10. string(REPLACE "-" "_" tmp "${value}")
  11. string(REPLACE "=" "_" tmp "${tmp}")
  12. set(${target} "${tmp}" PARENT_SCOPE)
  13. endfunction()
  14. # Conditionally add an extra compiler flag to C and C++ flags.
  15. #
  16. # If the language flags already match the `match` argument, skip this flag.
  17. # Otherwise, check for support for `flag` and if support is found, add it to
  18. # the compiler flags for the run.
  19. function(add_simple_extra_compiler_flag match flag)
  20. set(CMAKE_REQUIRED_FLAGS "-Werror")
  21. make_cpp_safe_name("${flag}" flag_name)
  22. if(NOT ${CMAKE_C_FLAGS} MATCHES ${match})
  23. check_c_compiler_flag("${flag}" HAVE_C_${flag_name})
  24. endif()
  25. if(NOT ${CMAKE_CXX_FLAGS} MATCHES ${match})
  26. check_cxx_compiler_flag("${flag}" HAVE_CXX_${flag_name})
  27. endif()
  28. if(HAVE_C_${flag_name} AND HAVE_CXX_${flag_name})
  29. add_compile_options("${flag}")
  30. add_link_options("${flag}")
  31. endif()
  32. endfunction()
  33. # Same as add_simple_extra_compiler_flag, but check for a second flag if the
  34. # first one is unsupported.
  35. function(add_double_extra_compiler_flag match flag1 flag2)
  36. set(CMAKE_REQUIRED_FLAGS "-Werror")
  37. make_cpp_safe_name("${flag1}" flag1_name)
  38. make_cpp_safe_name("${flag2}" flag2_name)
  39. if(NOT ${CMAKE_C_FLAGS} MATCHES ${match})
  40. check_c_compiler_flag("${flag1}" HAVE_C_${flag1_name})
  41. if(NOT HAVE_C_${flag1_name})
  42. check_c_compiler_flag("${flag2}" HAVE_C_${flag2_name})
  43. endif()
  44. endif()
  45. if(NOT ${CMAKE_CXX_FLAGS} MATCHES ${match})
  46. check_cxx_compiler_flag("${flag1}" HAVE_CXX_${flag1_name})
  47. if(NOT HAVE_CXX_${flag1_name})
  48. check_cxx_compiler_flag("${flag2}" HAVE_CXX_${flag2_name})
  49. endif()
  50. endif()
  51. if(HAVE_C_${flag1_name} AND HAVE_CXX_${flag1_name})
  52. add_compile_options("${flag1}")
  53. add_link_options("${flag1}")
  54. elseif(HAVE_C_${flag2_name} AND HAVE_CXX${flag2_name})
  55. add_compile_options("${flag2}")
  56. add_link_options("${flag2}")
  57. endif()
  58. endfunction()
  59. # Add a required extra compiler flag to C and C++ flags.
  60. #
  61. # Similar logic as add_simple_extra_compiler_flag, but ignores existing
  62. # instances and throws an error if the flag is not supported.
  63. function(add_required_compiler_flag flag)
  64. set(CMAKE_REQUIRED_FLAGS "-Werror")
  65. make_cpp_safe_name("${flag}" flag_name)
  66. check_c_compiler_flag("${flag}" HAVE_C_${flag_name})
  67. check_cxx_compiler_flag("${flag}" HAVE_CXX_${flag_name})
  68. if(HAVE_C_${flag_name} AND HAVE_CXX_${flag_name})
  69. add_compile_options("${flag}")
  70. add_link_options("${flag}")
  71. else()
  72. message(FATAL_ERROR "${flag} support is required to build Netdata")
  73. endif()
  74. endfunction()
  75. if(CMAKE_BUILD_TYPE STREQUAL "Debug")
  76. option(DISABLE_HARDENING "Disable adding extra compiler flags for hardening" TRUE)
  77. option(USE_LTO "Attempt to use of LTO when building. Defaults to being enabled if supported for release builds." FALSE)
  78. else()
  79. option(DISABLE_HARDENING "Disable adding extra compiler flags for hardening" FALSE)
  80. option(USE_LTO "Attempt to use of LTO when building. Defaults to being enabled if supported for release builds." TRUE)
  81. endif()
  82. option(ENABLE_ADDRESS_SANITIZER "Build with address sanitizer enabled" False)
  83. mark_as_advanced(ENABLE_ADDRESS_SANITIZER)
  84. if(ENABLE_ADDRESS_SANITIZER)
  85. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
  86. endif()
  87. if(USE_LTO)
  88. if(OS_WINDOWS)
  89. message(WARNING "LTO not supported on Windows, not checking for it")
  90. else()
  91. include(CheckIPOSupported)
  92. message(CHECK_START "Checking for LTO support")
  93. check_ipo_supported(RESULT HAVE_LTO)
  94. if(HAVE_LTO)
  95. message(CHECK_PASS "supported")
  96. set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
  97. else()
  98. message(CHECK_FAIL "not supported")
  99. endif()
  100. endif()
  101. else()
  102. message(STATUS "Not checking for LTO support as it has been explicitly disabled")
  103. endif()
  104. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}")
  105. add_required_compiler_flag("-fexceptions")
  106. if(NOT ${DISABLE_HARDENING})
  107. add_double_extra_compiler_flag("stack-protector" "-fstack-protector-strong" "-fstack-protector")
  108. add_double_extra_compiler_flag("_FORTIFY_SOURCE" "-D_FORTIFY_SOURCE=3" "-D_FORTIFY_SOURCE=2")
  109. add_simple_extra_compiler_flag("stack-clash-protection" "-fstack-clash-protection")
  110. add_simple_extra_compiler_flag("-fcf-protection" "-fcf-protection=full")
  111. add_simple_extra_compiler_flag("branch-protection" "-mbranch-protection=standard")
  112. endif()
  113. foreach(FLAG function-sections data-sections)
  114. add_simple_extra_compiler_flag("${FLAG}" "-f${FLAG}")
  115. endforeach()
  116. add_simple_extra_compiler_flag("-Wbuiltin-macro-redefined" "-Wno-builtin-macro-redefined")
  117. add_simple_extra_compiler_flag("-fexecptions" "-fexceptions")