CompilerOptions.cmake 8.3 KB

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