CMakeLists.txt 6.1 KB

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