CMakeLists.txt 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. if (${CMAKE_VERSION} VERSION_GREATER 3.0.2 OR
  2. ${CMAKE_VERSION} VERSION_EQUAL 3.0.2)
  3. cmake_policy(SET CMP0028 OLD)
  4. endif()
  5. # Determine if we should print to the output
  6. if (CIVETWEB_ENABLE_THIRD_PARTY_OUTPUT)
  7. set(THIRD_PARTY_LOGGING 0)
  8. else()
  9. set(THIRD_PARTY_LOGGING 1)
  10. endif()
  11. # We use the check unit testing framework for our C unit tests
  12. include(ExternalProject)
  13. ExternalProject_Add(check-unit-test-framework
  14. DEPENDS c-library
  15. URL "https://downloads.sourceforge.net/project/check/check/${CIVETWEB_CHECK_VERSION}/check-${CIVETWEB_CHECK_VERSION}.tar.gz"
  16. URL_MD5 ${CIVETWEB_CHECK_MD5_HASH}
  17. PREFIX "${CIVETWEB_THIRD_PARTY_DIR}"
  18. BUILD_IN_SOURCE 1
  19. PATCH_COMMAND ${CMAKE_COMMAND}
  20. -DSOURCE_DIR=<SOURCE_DIR>
  21. -DBINARY_DIR=<BINARY_DIR>
  22. -DINSTALL_DIR=<INSTALL_DIR>
  23. -DVERSION=${CIVETWEB_CHECK_VERSION}
  24. -P ${CMAKE_SOURCE_DIR}/cmake/check/patch.cmake
  25. CMAKE_ARGS
  26. "-DCMAKE_BUILD_TYPE=Release"
  27. "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
  28. "-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>"
  29. LOG_DOWNLOAD ${THIRD_PARTY_LOGGING}
  30. LOG_UPDATE ${THIRD_PARTY_LOGGING}
  31. LOG_CONFIGURE ${THIRD_PARTY_LOGGING}
  32. LOG_BUILD ${THIRD_PARTY_LOGGING}
  33. LOG_TEST ${THIRD_PARTY_LOGGING}
  34. LOG_INSTALL ${THIRD_PARTY_LOGGING})
  35. ExternalProject_Get_Property(check-unit-test-framework INSTALL_DIR)
  36. set(CHECK_INSTALL_DIR ${INSTALL_DIR})
  37. unset(INSTALL_DIR)
  38. link_directories("${CHECK_INSTALL_DIR}/lib")
  39. include_directories("${CHECK_INSTALL_DIR}/include")
  40. if (WIN32 AND MINGW)
  41. set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/libcheck.a")
  42. set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/libcompat.a")
  43. elseif (WIN32)
  44. set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/check.lib")
  45. set(CHECK_LIBRARIES "${CHECK_LIBRARIES};${CHECK_INSTALL_DIR}/lib/compat.lib")
  46. else()
  47. set(CHECK_LIBRARIES "${CHECK_INSTALL_DIR}/lib/libcheck.a")
  48. endif()
  49. find_package(LibM)
  50. if (LIBM_FOUND)
  51. set(CHECK_LIBRARIES "${CHECK_LIBRARIES};LIBM::LIBM")
  52. endif()
  53. find_package(LibRt)
  54. if (LIBRT_FOUND)
  55. set(CHECK_LIBRARIES "${CHECK_LIBRARIES};LIBRT::LIBRT")
  56. endif()
  57. # Build the C unit tests
  58. add_library(shared-c-unit-tests STATIC shared.c)
  59. target_include_directories(
  60. shared-c-unit-tests PUBLIC
  61. ${PROJECT_SOURCE_DIR}/include)
  62. add_library(public-func-c-unit-tests STATIC public_func.c)
  63. if (BUILD_SHARED_LIBS)
  64. target_compile_definitions(public-func-c-unit-tests PRIVATE CIVETWEB_DLL_IMPORTS)
  65. endif()
  66. target_include_directories(
  67. public-func-c-unit-tests PUBLIC
  68. ${PROJECT_SOURCE_DIR}/include)
  69. target_link_libraries(public-func-c-unit-tests c-library ${CHECK_LIBRARIES})
  70. add_dependencies(public-func-c-unit-tests check-unit-test-framework)
  71. add_library(public-server-c-unit-tests STATIC public_server.c)
  72. if (BUILD_SHARED_LIBS)
  73. target_compile_definitions(public-server-c-unit-tests PRIVATE CIVETWEB_DLL_IMPORTS)
  74. endif()
  75. target_include_directories(
  76. public-server-c-unit-tests PUBLIC
  77. ${PROJECT_SOURCE_DIR}/include)
  78. target_link_libraries(public-server-c-unit-tests c-library ${CHECK_LIBRARIES})
  79. add_dependencies(public-server-c-unit-tests check-unit-test-framework)
  80. add_library(private-c-unit-tests STATIC private.c)
  81. target_include_directories(
  82. private-c-unit-tests PUBLIC
  83. ${PROJECT_SOURCE_DIR}/include)
  84. target_link_libraries(private-c-unit-tests ${CHECK_LIBRARIES})
  85. add_dependencies(private-c-unit-tests check-unit-test-framework)
  86. add_library(exe-c-unit-tests STATIC private_exe.c)
  87. if (BUILD_SHARED_LIBS)
  88. target_compile_definitions(exe-c-unit-tests PRIVATE)
  89. endif()
  90. target_include_directories(
  91. exe-c-unit-tests PUBLIC
  92. ${PROJECT_SOURCE_DIR}/include)
  93. target_link_libraries(exe-c-unit-tests c-library ${CHECK_LIBRARIES})
  94. add_dependencies(exe-c-unit-tests check-unit-test-framework)
  95. add_executable(civetweb-c-unit-test main.c)
  96. target_link_libraries(civetweb-c-unit-test
  97. shared-c-unit-tests
  98. public-func-c-unit-tests
  99. public-server-c-unit-tests
  100. private-c-unit-tests
  101. exe-c-unit-tests
  102. ${CHECK_LIBRARIES})
  103. add_dependencies(civetweb-c-unit-test check-unit-test-framework)
  104. # Add a check command that builds the dependent test program
  105. add_custom_target(check
  106. COMMAND ${CMAKE_CTEST_COMMAND}
  107. DEPENDS civetweb-c-unit-test)
  108. # A macro for adding tests
  109. macro(civetweb_add_test suite test_case)
  110. set(test "test-${suite}-${test_case}")
  111. string(TOLOWER "${test}" test)
  112. string(REGEX REPLACE "[^-A-Za-z0-9]" "-" test "${test}")
  113. add_test(
  114. NAME ${test}
  115. COMMAND civetweb-c-unit-test "--test-dir=${CMAKE_CURRENT_SOURCE_DIR}" "--suite=${suite}" "--test-case=${test_case}")
  116. if (WIN32)
  117. string(REPLACE ";" "\\;" test_path "$ENV{PATH}")
  118. set_tests_properties(${test} PROPERTIES
  119. ENVIRONMENT "PATH=${test_path}\\;$<TARGET_FILE_DIR:c-library>")
  120. endif()
  121. endmacro(civetweb_add_test)
  122. # Tests of private functions
  123. civetweb_add_test(Private "HTTP Message")
  124. civetweb_add_test(Private "URL Parsing")
  125. civetweb_add_test(Private "Internal Parsing")
  126. civetweb_add_test(Private "Encode Decode")
  127. civetweb_add_test(Private "Mask Data")
  128. # Public API function tests
  129. civetweb_add_test(PublicFunc "Version")
  130. civetweb_add_test(PublicFunc "Options")
  131. civetweb_add_test(PublicFunc "MIME types")
  132. civetweb_add_test(PublicFunc "strcasecmp")
  133. civetweb_add_test(PublicFunc "URL encoding decoding")
  134. civetweb_add_test(PublicFunc "Cookies and variables")
  135. civetweb_add_test(PublicFunc "MD5")
  136. # Public API server tests
  137. civetweb_add_test(PublicServer "Check test environment")
  138. civetweb_add_test(PublicServer "Start threads")
  139. civetweb_add_test(PublicServer "Start Stop HTTP Server")
  140. civetweb_add_test(PublicServer "Start Stop HTTPS Server")
  141. civetweb_add_test(PublicServer "TLS Server Client")
  142. civetweb_add_test(PublicServer "Server Requests")
  143. # Tests with main.c
  144. civetweb_add_test(EXE "Helper funcs")
  145. # Add the coverage command(s)
  146. if (${CMAKE_BUILD_TYPE} MATCHES "[Cc]overage")
  147. find_program(GCOV_EXECUTABLE gcov)
  148. find_program(LCOV_EXECUTABLE lcov)
  149. find_program(GENHTML_EXECUTABLE genhtml)
  150. find_program(CTEST_EXECUTABLE ctest)
  151. if (GCOV_EXECUTABLE AND LCOV_EXECUTABLE AND GENHTML_EXECUTABLE AND CTEST_EXECUTABLE AND HAVE_C_FLAG_COVERAGE)
  152. add_custom_command(
  153. OUTPUT ${CMAKE_BINARY_DIR}/lcov/index.html
  154. COMMAND ${LCOV_EXECUTABLE} -q -z -d .
  155. COMMAND ${LCOV_EXECUTABLE} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o before.lcov -i
  156. COMMAND ${CTEST_EXECUTABLE} --force-new-ctest-process
  157. COMMAND ${LCOV_EXECUTABLE} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o after.lcov
  158. COMMAND ${LCOV_EXECUTABLE} -q -a before.lcov -a after.lcov --output-file final.lcov
  159. COMMAND ${LCOV_EXECUTABLE} -q -r final.lcov "'${CMAKE_SOURCE_DIR}/test/*'" -o final.lcov
  160. COMMAND ${GENHTML_EXECUTABLE} final.lcov -o lcov --demangle-cpp --sort -p "${CMAKE_SOURCE_DIR}" -t benchmark
  161. DEPENDS civetweb-c-unit-test
  162. WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
  163. COMMENT "Running LCOV"
  164. )
  165. add_custom_target(coverage
  166. DEPENDS ${CMAKE_BINARY_DIR}/lcov/index.html
  167. COMMENT "LCOV report at lcov/index.html"
  168. )
  169. message(STATUS "Coverage command added")
  170. else()
  171. if (HAVE_C_FLAG_COVERAGE)
  172. set(C_FLAG_COVERAGE_MESSAGE supported)
  173. else()
  174. set(C_FLAG_COVERAGE_MESSAGE unavailable)
  175. endif()
  176. message(WARNING
  177. "Coverage command not available:\n"
  178. " gcov: ${GCOV_EXECUTABLE}\n"
  179. " lcov: ${LCOV_EXECUTABLE}\n"
  180. " genhtml: ${GENHTML_EXECUTABLE}\n"
  181. " ctest: ${CTEST_EXECUTABLE}\n"
  182. " --coverage flag: ${C_FLAG_COVERAGE_MESSAGE}")
  183. endif()
  184. endif()