sdlcompilers.cmake 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. macro(SDL_DetectCompiler)
  2. set(USE_CLANG FALSE)
  3. set(USE_GCC FALSE)
  4. set(USE_INTELCC FALSE)
  5. set(USE_QCC FALSE)
  6. set(USE_TCC FALSE)
  7. if(CMAKE_C_COMPILER_ID MATCHES "Clang|IntelLLVM")
  8. set(USE_CLANG TRUE)
  9. # Visual Studio 2019 v16.2 added support for Clang/LLVM.
  10. # Check if a Visual Studio project is being generated with the Clang toolset.
  11. if(MSVC)
  12. set(MSVC_CLANG TRUE)
  13. endif()
  14. elseif(CMAKE_COMPILER_IS_GNUCC)
  15. set(USE_GCC TRUE)
  16. elseif(CMAKE_C_COMPILER_ID MATCHES "^Intel$")
  17. set(USE_INTELCC TRUE)
  18. elseif(CMAKE_C_COMPILER_ID MATCHES "QCC")
  19. set(USE_QCC TRUE)
  20. elseif(CMAKE_C_COMPILER_ID MATCHES "TinyCC")
  21. set(USE_TCC TRUE)
  22. endif()
  23. endmacro()
  24. function(sdl_target_compile_option_all_languages TARGET OPTION)
  25. target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:${OPTION}>")
  26. if(CMAKE_OBJC_COMPILER)
  27. target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:OBJC>:${OPTION}>")
  28. endif()
  29. endfunction()
  30. macro(cached_check_c_compiler_flag _arg _var)
  31. if(NOT DEFINED "${_var}")
  32. check_c_compiler_flag("${_arg}" "${_var}" ${ARGN})
  33. endif()
  34. endmacro()
  35. function(SDL_AddCommonCompilerFlags TARGET)
  36. option(SDL_WERROR "Enable -Werror" OFF)
  37. get_property(TARGET_TYPE TARGET "${TARGET}" PROPERTY TYPE)
  38. if(MSVC)
  39. cmake_push_check_state()
  40. cached_check_c_compiler_flag("/W3" COMPILER_SUPPORTS_W3)
  41. if(COMPILER_SUPPORTS_W3)
  42. target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:/W3>")
  43. endif()
  44. cmake_pop_check_state()
  45. endif()
  46. if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC OR USE_TCC)
  47. if(MINGW)
  48. # See if GCC's -gdwarf-4 is supported
  49. # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101377 for why this is needed on Windows
  50. cmake_push_check_state()
  51. cached_check_c_compiler_flag("-gdwarf-4" HAVE_GDWARF_4)
  52. if(HAVE_GDWARF_4)
  53. target_compile_options(${TARGET} PRIVATE "$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:-gdwarf-4>")
  54. endif()
  55. cmake_pop_check_state()
  56. endif()
  57. # Check for -Wall first, so later things can override pieces of it.
  58. # Note: clang-cl treats -Wall as -Weverything (which is very loud),
  59. # /W3 as -Wall, and /W4 as -Wall -Wextra. So: /W3 is enough.
  60. cached_check_c_compiler_flag(-Wall HAVE_GCC_WALL)
  61. if(MSVC_CLANG)
  62. target_compile_options(${TARGET} PRIVATE "/W3")
  63. elseif(HAVE_GCC_WALL)
  64. sdl_target_compile_option_all_languages(${TARGET} "-Wall")
  65. if(HAIKU)
  66. sdl_target_compile_option_all_languages(${TARGET} "-Wno-multichar")
  67. endif()
  68. endif()
  69. cached_check_c_compiler_flag(-Wundef HAVE_GCC_WUNDEF)
  70. if(HAVE_GCC_WUNDEF)
  71. sdl_target_compile_option_all_languages(${TARGET} "-Wundef")
  72. endif()
  73. cached_check_c_compiler_flag(-Wfloat-conversion HAVE_GCC_WFLOAT_CONVERSION)
  74. if(HAVE_GCC_WFLOAT_CONVERSION)
  75. sdl_target_compile_option_all_languages(${TARGET} "-Wfloat-conversion")
  76. endif()
  77. cached_check_c_compiler_flag(-fno-strict-aliasing HAVE_GCC_NO_STRICT_ALIASING)
  78. if(HAVE_GCC_NO_STRICT_ALIASING)
  79. sdl_target_compile_option_all_languages(${TARGET} "-fno-strict-aliasing")
  80. endif()
  81. cached_check_c_compiler_flag(-Wdocumentation HAVE_GCC_WDOCUMENTATION)
  82. if(HAVE_GCC_WDOCUMENTATION)
  83. if(SDL_WERROR)
  84. cached_check_c_compiler_flag(-Werror=documentation HAVE_GCC_WERROR_DOCUMENTATION)
  85. if(HAVE_GCC_WERROR_DOCUMENTATION)
  86. sdl_target_compile_option_all_languages(${TARGET} "-Werror=documentation")
  87. endif()
  88. endif()
  89. sdl_target_compile_option_all_languages(${TARGET} "-Wdocumentation")
  90. endif()
  91. cached_check_c_compiler_flag(-Wdocumentation-unknown-command HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND)
  92. if(HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND)
  93. if(SDL_WERROR)
  94. cached_check_c_compiler_flag(-Werror=documentation-unknown-command HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND)
  95. if(HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND)
  96. sdl_target_compile_option_all_languages(${TARGET} "-Werror=documentation-unknown-command")
  97. endif()
  98. endif()
  99. sdl_target_compile_option_all_languages(${TARGET} "-Wdocumentation-unknown-command")
  100. endif()
  101. cached_check_c_compiler_flag(-fcomment-block-commands=threadsafety HAVE_GCC_COMMENT_BLOCK_COMMANDS)
  102. if(HAVE_GCC_COMMENT_BLOCK_COMMANDS)
  103. sdl_target_compile_option_all_languages(${TARGET} "-fcomment-block-commands=threadsafety")
  104. else()
  105. cached_check_c_compiler_flag(/clang:-fcomment-block-commands=threadsafety HAVE_CLANG_COMMENT_BLOCK_COMMANDS)
  106. if(HAVE_CLANG_COMMENT_BLOCK_COMMANDS)
  107. sdl_target_compile_option_all_languages(${TARGET} "/clang:-fcomment-block-commands=threadsafety")
  108. endif()
  109. endif()
  110. cached_check_c_compiler_flag(-Wshadow HAVE_GCC_WSHADOW)
  111. if(HAVE_GCC_WSHADOW)
  112. sdl_target_compile_option_all_languages(${TARGET} "-Wshadow")
  113. endif()
  114. cached_check_c_compiler_flag(-Wunused-local-typedefs HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS)
  115. if(HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS)
  116. sdl_target_compile_option_all_languages(${TARGET} "-Wno-unused-local-typedefs")
  117. endif()
  118. cached_check_c_compiler_flag(-Wimplicit-fallthrough HAVE_GCC_WIMPLICIT_FALLTHROUGH)
  119. if(HAVE_GCC_WIMPLICIT_FALLTHROUGH)
  120. sdl_target_compile_option_all_languages(${TARGET} "-Wimplicit-fallthrough")
  121. endif()
  122. endif()
  123. if(SDL_WERROR)
  124. if(MSVC)
  125. cached_check_c_compiler_flag(/WX HAVE_WX)
  126. if(HAVE_WX)
  127. target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:/WX>")
  128. endif()
  129. elseif(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QNX)
  130. cached_check_c_compiler_flag(-Werror HAVE_WERROR)
  131. if(HAVE_WERROR)
  132. sdl_target_compile_option_all_languages(${TARGET} "-Werror")
  133. endif()
  134. if(TARGET_TYPE STREQUAL "SHARED_LIBRARY")
  135. check_linker_flag(C "-Wl,--no-undefined-version" LINKER_SUPPORTS_NO_UNDEFINED_VERSION)
  136. if(LINKER_SUPPORTS_NO_UNDEFINED_VERSION)
  137. target_link_options(${TARGET} PRIVATE "-Wl,--no-undefined-version")
  138. endif()
  139. endif()
  140. endif()
  141. if(NOT (APPLE OR MSVC))
  142. if(SDL_WERROR)
  143. get_property(target_type TARGET ${TARGET} PROPERTY TYPE)
  144. if(target_type MATCHES "SHARED_LIBRARY|MODULE_LIBRARY")
  145. check_linker_flag(C "-Wl,-fatal-warnings" LINKER_SUPPORTS_WL_FATAL_WARNINGS)
  146. if(LINKER_SUPPORTS_WL_FATAL_WARNINGS)
  147. target_link_options(${TARGET} PRIVATE "-Wl,-fatal-warnings")
  148. endif()
  149. endif()
  150. endif()
  151. endif()
  152. endif()
  153. if(USE_CLANG)
  154. cached_check_c_compiler_flag("-fcolor-diagnostics" COMPILER_SUPPORTS_FCOLOR_DIAGNOSTICS)
  155. if(COMPILER_SUPPORTS_FCOLOR_DIAGNOSTICS)
  156. sdl_target_compile_option_all_languages(${TARGET} "-fcolor-diagnostics")
  157. endif()
  158. else()
  159. cached_check_c_compiler_flag("-fdiagnostics-color=always" COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS)
  160. if(COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS)
  161. sdl_target_compile_option_all_languages(${TARGET} "-fdiagnostics-color=always")
  162. endif()
  163. endif()
  164. if(USE_TCC)
  165. sdl_target_compile_option_all_languages(${TARGET} "-DSTBI_NO_SIMD")
  166. endif()
  167. endfunction()
  168. function(check_x86_source_compiles BODY VAR)
  169. if(ARGN)
  170. message(FATAL_ERROR "Unknown arguments: ${ARGN}")
  171. endif()
  172. if(APPLE_MULTIARCH AND (SDL_CPU_X86 OR SDL_CPU_X64))
  173. set(test_conditional 1)
  174. else()
  175. set(test_conditional 0)
  176. endif()
  177. check_c_source_compiles("
  178. #if ${test_conditional}
  179. # if defined(__i386__) || defined(__x86_64__)
  180. # define test_enabled 1
  181. # else
  182. # define test_enabled 0 /* feign success in Apple multi-arch configs */
  183. # endif
  184. #else /* test normally */
  185. # define test_enabled 1
  186. #endif
  187. #if test_enabled
  188. ${BODY}
  189. #else
  190. int main(int argc, char *argv[]) {
  191. (void)argc;
  192. (void)argv;
  193. return 0;
  194. }
  195. #endif" ${VAR})
  196. endfunction()
  197. function(check_arm_source_compiles BODY VAR)
  198. if(ARGN)
  199. message(FATAL_ERROR "Unknown arguments: ${ARGN}")
  200. endif()
  201. if(APPLE_MULTIARCH AND (SDL_CPU_ARM32 OR SDL_CPU_ARM64))
  202. set(test_conditional 1)
  203. else()
  204. set(test_conditional 0)
  205. endif()
  206. check_c_source_compiles("
  207. #if ${test_conditional}
  208. # if defined(__arm__) || defined(__aarch64__)
  209. # define test_enabled 1
  210. # else
  211. # define test_enabled 0 /* feign success in Apple multi-arch configs */
  212. # endif
  213. #else /* test normally */
  214. # define test_enabled 1
  215. #endif
  216. #if test_enabled
  217. ${BODY}
  218. #else
  219. int main(int argc, char *argv[]) {
  220. (void)argc;
  221. (void)argv;
  222. return 0;
  223. }
  224. #endif" ${VAR})
  225. endfunction()