common.cmake 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. include(CMakeParseArguments)
  2. # cache this for use inside of the function
  3. set(CURRENT_LIST_DIR_CACHED ${CMAKE_CURRENT_LIST_DIR})
  4. set_property(GLOBAL PROPERTY USE_FOLDERS ON)
  5. enable_testing()
  6. find_package(Threads)
  7. set(DOCTEST_TEST_MODE "COMPARE" CACHE STRING "Test mode - normal/run through valgrind/collect output/compare with output")
  8. set_property(CACHE DOCTEST_TEST_MODE PROPERTY STRINGS "NORMAL;VALGRIND;COLLECT;COMPARE")
  9. function(doctest_add_test_impl)
  10. cmake_parse_arguments(ARG "NO_VALGRIND;NO_OUTPUT;XML_OUTPUT;JUNIT_OUTPUT" "NAME" "COMMAND" ${ARGN})
  11. if(NOT "${ARG_UNPARSED_ARGUMENTS}" STREQUAL "" OR "${ARG_NAME}" STREQUAL "" OR "${ARG_COMMAND}" STREQUAL "")
  12. message(FATAL_ERROR "doctest_add_test() called with wrong options!")
  13. endif()
  14. set(the_test_mode NORMAL)
  15. # construct the command that will be called by the exec_test.cmake script
  16. set(the_command "")
  17. if(${DOCTEST_TEST_MODE} STREQUAL "VALGRIND" AND NOT ARG_NO_VALGRIND)
  18. set(the_test_mode VALGRIND)
  19. set(the_command "valgrind -v --leak-check=full --track-origins=yes --error-exitcode=1")
  20. endif()
  21. foreach(cur ${ARG_COMMAND})
  22. set(the_command "${the_command} ${cur}")
  23. endforeach()
  24. if(ARG_XML_OUTPUT)
  25. set(the_command "${the_command} --reporters=xml")
  26. set(ARG_NAME ${ARG_NAME}_xml)
  27. endif()
  28. if(ARG_JUNIT_OUTPUT)
  29. set(the_command "${the_command} --reporters=junit")
  30. set(ARG_NAME ${ARG_NAME}_junit)
  31. endif()
  32. # append the argument for removing paths from filenames in the output so tests give the same output everywhere
  33. set(the_command "${the_command} --dt-no-path-filenames=1")
  34. # append the argument for substituting source line numbers with 0 in the output so tests give the same output when lines change a bit
  35. set(the_command "${the_command} --dt-no-line-numbers=1")
  36. # append the argument for ignoring the exit code of the test programs because some are intended to have failing tests
  37. set(the_command "${the_command} --dt-no-exitcode=1")
  38. # append the argument for using the same line format in the output - so gcc/non-gcc builds have the same output
  39. set(the_command "${the_command} --dt-gnu-file-line=0")
  40. # append the argument for skipping any time-related output so that the reference output from reporters is stable on CI
  41. set(the_command "${the_command} --dt-no-time-in-output=1")
  42. string(STRIP ${the_command} the_command)
  43. if(${DOCTEST_TEST_MODE} STREQUAL "COLLECT" OR ${DOCTEST_TEST_MODE} STREQUAL "COMPARE")
  44. if(NOT ARG_NO_OUTPUT)
  45. file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test_output/)
  46. set(the_test_mode ${DOCTEST_TEST_MODE})
  47. list(APPEND ADDITIONAL_FLAGS -DTEST_OUTPUT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/test_output/${ARG_NAME}.txt)
  48. list(APPEND ADDITIONAL_FLAGS -DTEST_TEMP_FILE=${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/temp_test_output_${ARG_NAME}.txt)
  49. endif()
  50. endif()
  51. list(APPEND ADDITIONAL_FLAGS -DTEST_MODE=${the_test_mode})
  52. add_test(NAME ${ARG_NAME} COMMAND ${CMAKE_COMMAND} -DCOMMAND=${the_command} ${ADDITIONAL_FLAGS} -P ${CURRENT_LIST_DIR_CACHED}/exec_test.cmake)
  53. endfunction()
  54. # a custom version of add_test() to suite my needs
  55. function(doctest_add_test)
  56. doctest_add_test_impl(${ARGN})
  57. doctest_add_test_impl(${ARGN} XML_OUTPUT)
  58. doctest_add_test_impl(${ARGN} JUNIT_OUTPUT)
  59. endfunction()
  60. macro(add_compiler_flags)
  61. foreach(flag ${ARGV})
  62. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
  63. endforeach()
  64. endmacro()
  65. if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
  66. add_compiler_flags(-Werror)
  67. add_compiler_flags(-fstrict-aliasing)
  68. # The following options are not valid when clang-cl is used.
  69. if(NOT MSVC)
  70. add_compiler_flags(-pedantic)
  71. add_compiler_flags(-pedantic-errors)
  72. add_compiler_flags(-fvisibility=hidden)
  73. endif()
  74. endif()
  75. if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  76. #add_compiler_flags(-Wno-unknown-pragmas)
  77. add_compiler_flags(-Wall)
  78. add_compiler_flags(-Wextra)
  79. add_compiler_flags(-fdiagnostics-show-option)
  80. add_compiler_flags(-Wconversion)
  81. add_compiler_flags(-Wold-style-cast)
  82. add_compiler_flags(-Wfloat-equal)
  83. add_compiler_flags(-Wlogical-op)
  84. add_compiler_flags(-Wundef)
  85. add_compiler_flags(-Wredundant-decls)
  86. add_compiler_flags(-Wshadow)
  87. add_compiler_flags(-Wstrict-overflow=5)
  88. add_compiler_flags(-Wwrite-strings)
  89. add_compiler_flags(-Wpointer-arith)
  90. add_compiler_flags(-Wcast-qual)
  91. add_compiler_flags(-Wformat=2)
  92. add_compiler_flags(-Wswitch-default)
  93. add_compiler_flags(-Wmissing-include-dirs)
  94. add_compiler_flags(-Wcast-align)
  95. add_compiler_flags(-Wswitch-enum)
  96. add_compiler_flags(-Wnon-virtual-dtor)
  97. add_compiler_flags(-Wctor-dtor-privacy)
  98. add_compiler_flags(-Wsign-conversion)
  99. add_compiler_flags(-Wdisabled-optimization)
  100. add_compiler_flags(-Weffc++)
  101. add_compiler_flags(-Winvalid-pch)
  102. add_compiler_flags(-Wmissing-declarations)
  103. add_compiler_flags(-Woverloaded-virtual)
  104. add_compiler_flags(-Wunused-but-set-variable)
  105. add_compiler_flags(-Wunused-result)
  106. # add_compiler_flags(-Wsuggest-override)
  107. # add_compiler_flags(-Wmultiple-inheritance)
  108. # add_compiler_flags(-Wcatch-value)
  109. # add_compiler_flags(-Wsuggest-attribute=cold)
  110. # add_compiler_flags(-Wsuggest-attribute=const)
  111. # add_compiler_flags(-Wsuggest-attribute=format)
  112. # add_compiler_flags(-Wsuggest-attribute=malloc)
  113. # add_compiler_flags(-Wsuggest-attribute=noreturn)
  114. # add_compiler_flags(-Wsuggest-attribute=pure)
  115. # add_compiler_flags(-Wsuggest-final-methods)
  116. # add_compiler_flags(-Wsuggest-final-types)
  117. if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6)
  118. add_compiler_flags(-Wnoexcept)
  119. endif()
  120. if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
  121. add_compiler_flags(-Wno-missing-field-initializers)
  122. endif()
  123. # no way to silence it in the expression decomposition macros: _Pragma() in macros doesn't work for the c++ front-end of g++
  124. # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578
  125. # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69543
  126. # Also the warning is completely worthless nowadays - https://stackoverflow.com/questions/14016993
  127. #add_compiler_flags(-Waggregate-return)
  128. if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
  129. add_compiler_flags(-Wdouble-promotion)
  130. add_compiler_flags(-Wtrampolines)
  131. add_compiler_flags(-Wzero-as-null-pointer-constant)
  132. add_compiler_flags(-Wuseless-cast)
  133. add_compiler_flags(-Wvector-operation-performance)
  134. endif()
  135. if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)
  136. add_compiler_flags(-Wshift-overflow=2)
  137. add_compiler_flags(-Wnull-dereference)
  138. add_compiler_flags(-Wduplicated-cond)
  139. endif()
  140. if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)
  141. add_compiler_flags(-Walloc-zero)
  142. add_compiler_flags(-Walloca)
  143. add_compiler_flags(-Wduplicated-branches)
  144. endif()
  145. if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.0)
  146. add_compiler_flags(-Wcast-align=strict)
  147. endif()
  148. endif()
  149. # necessary for some older compilers which don't default to C++11
  150. set(CMAKE_CXX_STANDARD 11)
  151. set(CMAKE_CXX_STANDARD_REQUIRED ON)
  152. if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  153. add_compiler_flags(-Weverything)
  154. add_compiler_flags(-Wno-c++98-compat)
  155. add_compiler_flags(-Wno-c++98-compat-pedantic)
  156. add_compiler_flags(-Wno-c++98-compat-bind-to-temporary-copy)
  157. add_compiler_flags(-Wno-c++98-compat-local-type-template-args)
  158. add_compiler_flags(-Qunused-arguments -fcolor-diagnostics) # needed for ccache integration
  159. endif()
  160. if(MSVC)
  161. add_compiler_flags(/std:c++latest) # for post c++14 updates in MSVC
  162. add_compiler_flags(/permissive-) # force standard conformance - this is the better flag than /Za
  163. add_compiler_flags(/WX)
  164. add_compiler_flags(/Wall) # turns on warnings from levels 1 through 4 which are off by default - https://msdn.microsoft.com/en-us/library/23k5d385.aspx
  165. add_compiler_flags(
  166. /wd4514 # unreferenced inline function has been removed
  167. /wd4571 # SEH related
  168. /wd5264 # const variable is not used
  169. /wd4710 # function not inlined
  170. /wd4711 # function 'x' selected for automatic inline expansion
  171. /wd4616 # invalid compiler warnings - https://msdn.microsoft.com/en-us/library/t7ab6xtd.aspx
  172. /wd4619 # invalid compiler warnings - https://msdn.microsoft.com/en-us/library/tacee08d.aspx
  173. #/wd4820 # padding in structs
  174. #/wd4625 # copy constructor was implicitly defined as deleted
  175. #/wd4626 # assignment operator was implicitly defined as deleted
  176. #/wd5027 # move assignment operator was implicitly defined as deleted
  177. #/wd5026 # move constructor was implicitly defined as deleted
  178. #/wd4623 # default constructor was implicitly defined as deleted
  179. )
  180. endif()