sdlcompilers.cmake 7.6 KB

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