CMakeLists.txt 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. cmake_minimum_required(VERSION 3.31)
  2. cmake_policy(SET CMP0184 NEW)
  3. # All runtime checks flags enables single preprocessor definition,
  4. # so override our table of flags to artificially add a definition we can check.
  5. set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/override-C.cmake)
  6. set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/override-CXX.cmake)
  7. set(CMAKE_USER_MAKE_RULES_OVERRIDE_CUDA ${CMAKE_CURRENT_SOURCE_DIR}/override-CUDA.cmake)
  8. set(CMAKE_USER_MAKE_RULES_OVERRIDE_Fortran ${CMAKE_CURRENT_SOURCE_DIR}/override-Fortran.cmake)
  9. project(MSVCRuntimeChecks)
  10. if(CMake_TEST_CUDA STREQUAL "NVIDIA")
  11. enable_language(CUDA)
  12. endif()
  13. if(CMake_TEST_Fortran)
  14. enable_language(Fortran)
  15. endif()
  16. include_directories(${CMAKE_CURRENT_SOURCE_DIR})
  17. set(verify_default VERIFY_RTCsu)
  18. set(verify_def_PossibleDataLoss -DVERIFY_RTCc)
  19. set(verify_def_StackFrameErrorCheck -DVERIFY_RTCs)
  20. set(verify_def_UninitializedVariable -DVERIFY_RTCu)
  21. set(verify_def_RTCsu -DVERIFY_RTCsu)
  22. function(verify_combination format verify_format_defs lang src)
  23. # Test that try_compile builds with this runtime check.
  24. set(CMAKE_MSVC_RUNTIME_CHECKS "${format}")
  25. set(CMAKE_TRY_COMPILE_CONFIGURATION "Debug")
  26. set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
  27. string(REPLACE ";" "_" format_var_name "${format}")
  28. if (NOT format_var_name)
  29. set(format_var_name "Empty")
  30. endif()
  31. if (NOT verify_format_defs)
  32. foreach(format_for_def IN LISTS format)
  33. list(APPEND verify_format_defs ${verify_def_${format_for_def}})
  34. endforeach()
  35. endif()
  36. try_compile(${format_var_name}_COMPILES
  37. ${CMAKE_CURRENT_BINARY_DIR}/try_compile/${format_var_name}
  38. ${CMAKE_CURRENT_SOURCE_DIR}/${src}
  39. COMPILE_DEFINITIONS ${verify_format_defs}
  40. CMAKE_FLAGS -DINCLUDE_DIRECTORIES=${CMAKE_CURRENT_SOURCE_DIR}
  41. OUTPUT_VARIABLE ${format_var_name}_OUTPUT
  42. )
  43. if(${format_var_name}_COMPILES)
  44. message(STATUS "try_compile ${lang} with \"${format}\" worked")
  45. else()
  46. string(REPLACE "\n" "\n " ${format_var_name}_OUTPUT " ${${format_var_name}_OUTPUT}")
  47. message(SEND_ERROR "try_compile ${lang} with \"${format}\" failed:\n${${format_var_name}_OUTPUT}")
  48. endif()
  49. # Test that targets build with this runtime check.
  50. set(CMAKE_MSVC_RUNTIME_CHECKS "$<$<BOOL:$<TARGET_PROPERTY:BOOL_TRUE>>:${format}>$<$<BOOL:$<TARGET_PROPERTY:BOOL_FALSE>>:BadContent>")
  51. add_library(${format_var_name}-${lang} ${src})
  52. set_property(TARGET ${format_var_name}-${lang} PROPERTY BOOL_TRUE TRUE)
  53. target_compile_definitions(${format_var_name}-${lang} PRIVATE ${verify_format_defs})
  54. endfunction()
  55. function(verify lang src)
  56. add_library(default-${lang} ${src})
  57. target_compile_definitions(default-${lang} PRIVATE "$<$<CONFIG:Debug>:${verify_default}>")
  58. # zero checkers
  59. verify_combination("" "" ${lang} ${src})
  60. # single checker
  61. verify_combination(PossibleDataLoss "" ${lang} ${src})
  62. verify_combination(StackFrameErrorCheck "" ${lang} ${src})
  63. verify_combination(UninitializedVariable "" ${lang} ${src})
  64. verify_combination(RTCsu "" ${lang} ${src})
  65. # multiple checkers (without RTCsu merging)
  66. verify_combination("PossibleDataLoss;StackFrameErrorCheck" "" ${lang} ${src})
  67. verify_combination("PossibleDataLoss;UninitializedVariable" "" ${lang} ${src})
  68. # multiple checkers (only RTCsu merging)
  69. set(defs "${verify_def_RTCsu}")
  70. verify_combination("StackFrameErrorCheck;UninitializedVariable" "${defs}" ${lang} ${src})
  71. verify_combination("StackFrameErrorCheck;RTCsu" "${defs}" ${lang} ${src})
  72. verify_combination("UninitializedVariable;RTCsu" "${defs}" ${lang} ${src})
  73. verify_combination("StackFrameErrorCheck;UninitializedVariable;RTCsu" "${defs}" ${lang} ${src})
  74. # multiple checkers (with RTCsu merging)
  75. list(APPEND defs "${verify_def_PossibleDataLoss}")
  76. verify_combination("PossibleDataLoss;StackFrameErrorCheck;UninitializedVariable" "${defs}" ${lang} ${src})
  77. verify_combination("PossibleDataLoss;StackFrameErrorCheck;RTCsu" "${defs}" ${lang} ${src})
  78. verify_combination("PossibleDataLoss;UninitializedVariable;RTCsu" "${defs}" ${lang} ${src})
  79. verify_combination("PossibleDataLoss;StackFrameErrorCheck;UninitializedVariable;RTCsu" "${defs}" ${lang} ${src})
  80. endfunction()
  81. verify(C verify.c)
  82. verify(CXX verify.cxx)
  83. if(CMake_TEST_CUDA STREQUAL "NVIDIA")
  84. verify(CUDA verify.cu)
  85. endif()
  86. if(CMake_TEST_Fortran)
  87. verify(Fortran verify.F90)
  88. endif()