CompilerOptions.cmake 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. include_guard(DIRECTORY)
  2. #[[
  3. Disable all possible warnings from the compiler.
  4. qm_compiler_no_warnings()
  5. ]] #
  6. macro(qm_compiler_no_warnings)
  7. if(NOT "x${CMAKE_C_FLAGS}" STREQUAL "x")
  8. if(MSVC)
  9. string(REGEX REPLACE "[/|-]W[0|1|2|3|4]" " " CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
  10. else()
  11. string(REGEX REPLACE "-W[all|extra]" " " CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
  12. string(REGEX REPLACE "-[W]?pedantic" " " CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
  13. endif()
  14. endif()
  15. if(NOT "x${CMAKE_CXX_FLAGS}" STREQUAL "x")
  16. if(MSVC)
  17. string(REGEX REPLACE "[/|-]W[0|1|2|3|4]" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
  18. else()
  19. string(REGEX REPLACE "-W[all|extra]" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
  20. string(REGEX REPLACE "-[W]?pedantic" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
  21. endif()
  22. endif()
  23. string(APPEND CMAKE_C_FLAGS " -w ")
  24. string(APPEND CMAKE_CXX_FLAGS " -w ")
  25. if(MSVC)
  26. add_compile_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS)
  27. add_compile_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE)
  28. add_compile_definitions(-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
  29. add_compile_definitions(-D_SCL_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_DEPRECATE)
  30. else()
  31. string(APPEND CMAKE_C_FLAGS " -fpermissive ")
  32. string(APPEND CMAKE_CXX_FLAGS " -fpermissive ")
  33. endif()
  34. endmacro()
  35. #[[
  36. Enable all possible warnings from the compiler.
  37. qm_compiler_max_warnings()
  38. ]] #
  39. function(qm_compiler_max_warnings)
  40. if(MSVC)
  41. add_compile_options(-W4)
  42. elseif("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang")
  43. add_compile_options(-Weverything)
  44. else()
  45. add_compile_options(-Wall -Wextra -Wpedantic)
  46. endif()
  47. endfunction()
  48. #[[
  49. Treat all warnings as errors.
  50. qm_compiler_warnings_are_errors()
  51. ]] #
  52. function(qm_compiler_warnings_are_errors)
  53. if(MSVC)
  54. add_compile_options(-WX)
  55. else()
  56. add_compile_options(-Werror)
  57. endif()
  58. endfunction()
  59. #[[
  60. Prevent the compiler from receiving unknown parameters.
  61. qm_compiler_no_unknown_options()
  62. ]] #
  63. function(qm_compiler_no_unknown_options)
  64. if(MSVC)
  65. if(MSVC_VERSION GREATER_EQUAL 1930) # Visual Studio 2022 version 17.0
  66. add_compile_options(-options:strict)
  67. endif()
  68. add_link_options(-WX)
  69. endif()
  70. endfunction()
  71. #[[
  72. Remove all unused code from the final binary.
  73. qm_compiler_eliminate_dead_code()
  74. ]] #
  75. function(qm_compiler_eliminate_dead_code)
  76. if(MSVC)
  77. add_compile_options(-Gw -Gy -Zc:inline)
  78. add_link_options(-OPT:REF -OPT:ICF -OPT:LBR)
  79. else()
  80. add_compile_options(-ffunction-sections -fdata-sections)
  81. if(APPLE)
  82. add_link_options(-Wl,-dead_strip)
  83. else()
  84. add_link_options(-Wl,--as-needed -Wl,--strip-all -Wl,--gc-sections)
  85. endif()
  86. if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang")
  87. add_link_options(-Wl,--icf=all)
  88. endif()
  89. endif()
  90. endfunction()
  91. #[[
  92. Only export symbols which are marked to be exported, just like MSVC.
  93. qm_compiler_dont_export_by_default()
  94. ]] #
  95. macro(qm_compiler_dont_export_by_default)
  96. set(CMAKE_C_VISIBILITY_PRESET "hidden")
  97. set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
  98. set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
  99. endmacro()
  100. #[[
  101. Enable all possible security issue mitigations from your compiler.
  102. qm_compiler_enable_secure_code()
  103. ]] #
  104. macro(qm_compiler_enable_secure_code)
  105. if(MSVC)
  106. add_compile_options(-GS -sdl -guard:cf)
  107. add_link_options(-DYNAMICBASE -FIXED:NO -NXCOMPAT -GUARD:CF)
  108. if(CMAKE_SIZEOF_VOID_P EQUAL 4)
  109. add_link_options(-SAFESEH)
  110. endif()
  111. if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  112. add_link_options(-HIGHENTROPYVA)
  113. endif()
  114. if(MSVC_VERSION GREATER_EQUAL 1920) # Visual Studio 2019 version 16.0
  115. add_link_options(-CETCOMPAT)
  116. endif()
  117. if(MSVC_VERSION GREATER_EQUAL 1925) # Visual Studio 2019 version 16.5
  118. add_compile_options(-Qspectre-load)
  119. elseif(MSVC_VERSION GREATER_EQUAL 1912) # Visual Studio 2017 version 15.5
  120. add_compile_options(-Qspectre)
  121. endif()
  122. if(MSVC_VERSION GREATER_EQUAL 1927) # Visual Studio 2019 version 16.7
  123. if(CMAKE_SIZEOF_VOID_P EQUAL 8)
  124. add_compile_options(-guard:ehcont)
  125. add_link_options(-guard:ehcont)
  126. endif()
  127. endif()
  128. elseif(MINGW)
  129. if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang")
  130. add_compile_options(-mguard=cf)
  131. add_link_options(-mguard=cf)
  132. else()
  133. endif()
  134. else()
  135. add_compile_options(-mshstk)
  136. if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang")
  137. add_compile_options(-mretpoline -mspeculative-load-hardening)
  138. if(NOT APPLE)
  139. add_compile_options(-fsanitize=cfi -fsanitize-cfi-cross-dso)
  140. endif()
  141. endif()
  142. endif()
  143. endmacro()
  144. #[[
  145. Enable all possible Qt coding style policies.
  146. qm_compiler_enable_strict_qt(
  147. TARGETS <target1> <target2> ... <targetN>
  148. [NO_DEPRECATED_API]
  149. [ALLOW_KEYWORD]
  150. [ALLOW_UNSAFE_FLAGS]
  151. )
  152. NO_DEPRECATED_API: Disable the use of any deprecated Qt APIs. Only has effect since Qt6.
  153. ALLOW_KEYWORD: Allow the use of the traditional Qt keywords such as "signal" "slot" "emit".
  154. ALLOW_UNSAFE_FLAGS: Allow the use of the unsafe QFlags (unsafe: can be implicitly cast to and from "int").
  155. ]] #
  156. function(qm_compiler_enable_strict_qt)
  157. cmake_parse_arguments(arg "NO_DEPRECATED_API;ALLOW_KEYWORD;ALLOW_UNSAFE_FLAGS" "" "TARGETS" ${ARGN})
  158. if(NOT arg_TARGETS)
  159. message(AUTHOR_WARNING "qm_compiler_enable_strict_qt: you need to specify at least one target!")
  160. return()
  161. endif()
  162. if(arg_UNPARSED_ARGUMENTS)
  163. message(AUTHOR_WARNING "qm_compiler_enable_strict_qt: Unrecognized arguments: ${arg_UNPARSED_ARGUMENTS}")
  164. endif()
  165. foreach(_target IN LISTS arg_TARGETS)
  166. if(NOT TARGET ${_target})
  167. message(AUTHOR_WARNING "qm_compiler_enable_strict_qt: ${_target} is not a valid CMake target!")
  168. continue()
  169. endif()
  170. target_compile_definitions(${_target} PRIVATE
  171. QT_NO_CAST_TO_ASCII
  172. QT_NO_CAST_FROM_ASCII
  173. QT_NO_CAST_FROM_BYTEARRAY
  174. QT_NO_URL_CAST_FROM_STRING
  175. QT_NO_NARROWING_CONVERSIONS_IN_CONNECT
  176. QT_NO_FOREACH
  177. QT_NO_JAVA_STYLE_ITERATORS
  178. QT_NO_AS_CONST
  179. QT_NO_QEXCHANGE
  180. QT_NO_USING_NAMESPACE
  181. QT_NO_CONTEXTLESS_CONNECT
  182. QT_EXPLICIT_QFILE_CONSTRUCTION_FROM_PATH
  183. QT_USE_QSTRINGBUILDER
  184. QT_USE_FAST_OPERATOR_PLUS
  185. QT_DEPRECATED_WARNINGS # Have no effect since 5.13
  186. QT_DEPRECATED_WARNINGS_SINCE=0x070000 # Deprecated since 6.5
  187. QT_WARN_DEPRECATED_UP_TO=0x070000 # Available since 6.5
  188. )
  189. if(arg_NO_DEPRECATED_API)
  190. target_compile_definitions(${_target} PRIVATE
  191. QT_DISABLE_DEPRECATED_BEFORE=0x070000 # Deprecated since 6.5
  192. QT_DISABLE_DEPRECATED_UP_TO=0x070000 # Available since 6.5
  193. )
  194. endif()
  195. # On Windows enabling this flag requires us re-compile Qt with this flag enabled,
  196. # so only enable it on non-Windows platforms.
  197. if(NOT WIN32)
  198. target_compile_definitions(${_target} PRIVATE
  199. QT_STRICT_ITERATORS
  200. )
  201. endif()
  202. # We handle this flag specially because some Qt headers may still use the
  203. # traditional keywords (especially some private headers).
  204. if(NOT arg_ALLOW_KEYWORD)
  205. target_compile_definitions(${_target} PRIVATE
  206. QT_NO_KEYWORDS
  207. )
  208. endif()
  209. # We handle this flag specially because some Qt headers may still use the
  210. # unsafe flags (especially some QtQuick headers).
  211. if(NOT arg_ALLOW_UNSAFE_FLAGS)
  212. target_compile_definitions(${_target} PRIVATE
  213. QT_TYPESAFE_FLAGS
  214. )
  215. endif()
  216. endforeach()
  217. endfunction()