build REFACTOR main cmake list organized into sections
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f98a0fe..68c5e29 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -42,7 +42,7 @@
build-type: "Release",
dep-build-type: "Release",
cc: "gcc",
- options: "-DENABLE_BUILD_TESTS=ON -DENABLE_DNSSEC=ON",
+ options: "-DENABLE_TESTS=ON -DENABLE_DNSSEC=ON",
packages: "",
snaps: "",
make-prepend: "",
@@ -54,7 +54,7 @@
build-type: "Release",
dep-build-type: "Release",
cc: "clang",
- options: "-DENABLE_BUILD_TESTS=ON -DENABLE_DNSSEC=ON",
+ options: "-DENABLE_TESTS=ON -DENABLE_DNSSEC=ON",
packages: "",
snaps: "",
make-prepend: "",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 39fcbcb..d611138 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,6 +13,7 @@
include(ABICheck)
include(SourceFormat)
include(GenDoc)
+include(GenCoverage)
if(POLICY CMP0075)
cmake_policy(SET CMP0075 NEW)
@@ -69,51 +70,25 @@
# libyang SO version required
set(LIBYANG_DEP_SOVERSION_MAJOR 2)
-# build options
-if(("${BUILD_TYPE_UPPER}" STREQUAL "DEBUG") OR ("${BUILD_TYPE_UPPER}" STREQUAL "RELWITHDEBINFO"))
- option(ENABLE_BUILD_TESTS "Build tests" ON)
- option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" ON)
-else()
- option(ENABLE_BUILD_TESTS "Build tests" OFF)
- option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" OFF)
-endif()
-option(ENABLE_COVERAGE "Build code coverage report from tests" OFF)
-
-if(ENABLE_COVERAGE)
- find_program(PATH_GCOV NAMES gcov)
- if(NOT PATH_GCOV)
- message(WARNING "'gcov' executable not found! Disabling building code coverage report.")
- set(ENABLE_COVERAGE OFF)
- endif()
-
- find_program(PATH_LCOV NAMES lcov)
- if(NOT PATH_LCOV)
- message(WARNING "'lcov' executable not found! Disabling building code coverage report.")
- set(ENABLE_COVERAGE OFF)
- endif()
-
- find_program(PATH_GENHTML NAMES genhtml)
- if(NOT PATH_GENHTML)
- message(WARNING "'genhtml' executable not found! Disabling building code coverage report.")
- set(ENABLE_COVERAGE OFF)
- endif()
-
- if(NOT CMAKE_COMPILER_IS_GNUCC)
- message(WARNING "Compiler is not gcc! Coverage may break the tests!")
- endif()
-
- if(ENABLE_COVERAGE)
- set(CMAKE_C_FLAGS_COVERAGE "--coverage -fprofile-arcs -ftest-coverage")
- endif()
-endif()
-
+#
# compilation flags
+#
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_COVERAGE} -Wall -Wextra -fvisibility=hidden -std=gnu99")
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O2")
set(CMAKE_C_FLAGS_DEBUG "-g -O0")
set(CMAKE_C_FLAGS_ABICHECK "-g -Og")
+#
# options
+#
+if(("${BUILD_TYPE_UPPER}" STREQUAL "DEBUG") OR ("${BUILD_TYPE_UPPER}" STREQUAL "RELWITHDEBINFO"))
+ option(ENABLE_TESTS "Build tests" ON)
+ option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" ON)
+else()
+ option(ENABLE_TESTS "Build tests" OFF)
+ option(ENABLE_VALGRIND_TESTS "Build tests with valgrind" OFF)
+endif()
+option(ENABLE_COVERAGE "Build code coverage report from tests" OFF)
option(ENABLE_SSH "Enable NETCONF over SSH support (via libssh)" ON)
option(ENABLE_TLS "Enable NETCONF over TLS support (via OpenSSL)" ON)
option(ENABLE_DNSSEC "Enable support for SSHFP retrieval using DNSSEC for SSH (requires OpenSSL and libval)" OFF)
@@ -123,12 +98,9 @@
set(TIMEOUT_STEP 100 CACHE STRING "Number of microseconds tasks are repeated until timeout elapses")
set(YANG_MODULE_DIR "${CMAKE_INSTALL_PREFIX}/share/yang/modules" CACHE STRING "Directory with common YANG modules")
-if(ENABLE_DNSSEC AND NOT ENABLE_SSH)
- message(WARNING "DNSSEC SSHFP retrieval cannot be used without SSH support.")
- set(ENABLE_DNSSEC OFF)
-endif()
-
-# source files
+#
+# sources
+#
set(libsrc
src/io.c
src/log.c
@@ -185,11 +157,49 @@
tests/*.c
tests/client/*.c)
+#
+# checks
+#
+if(ENABLE_DNSSEC AND NOT ENABLE_SSH)
+ message(WARNING "DNSSEC SSHFP retrieval cannot be used without SSH support.")
+ set(ENABLE_DNSSEC OFF)
+endif()
+
+if(ENABLE_VALGRIND_TESTS)
+ find_program(VALGRIND_FOUND valgrind)
+ if(NOT VALGRIND_FOUND)
+ message(WARNING "valgrind executable not found! Disabling memory leaks tests.")
+ set(ENABLE_VALGRIND_TESTS OFF)
+ else()
+ set(ENABLE_TESTS ON)
+ endif()
+endif()
+
+if(ENABLE_TESTS)
+ find_package(CMocka 1.0.0)
+ if(NOT CMOCKA_FOUND)
+ message(STATUS "Disabling tests because of missing CMocka")
+ set(ENABLE_TESTS OFF)
+ endif()
+endif()
+
+if(ENABLE_COVERAGE)
+ gen_coverage_enable(${ENABLE_TESTS})
+endif()
+
+if ("${BUILD_TYPE_UPPER}" STREQUAL "DEBUG")
+ source_format_enable()
+endif()
+
if("${BUILD_TYPE_UPPER}" STREQUAL "DOCONLY")
gen_doc("${doxy_files}" ${LIBNETCONF2_VERSION} ${LIBNETCONF2_DESCRIPTION} "")
return()
endif()
+#
+# targets
+#
+
# use compat
use_compat()
@@ -300,25 +310,14 @@
endif()
endif()
-if ("${BUILD_TYPE_UPPER}" STREQUAL "DEBUG")
- # enable before adding tests to let them detect that format checking is available - one of the tests is format checking
- source_format_enable()
+# tests
+if(ENABLE_TESTS)
+ enable_testing()
+ add_subdirectory(tests)
endif()
-# source files to be covered by the 'format' target and a test with 'format-check' target
-source_format(${format_sources})
-
-if(ENABLE_VALGRIND_TESTS)
- set(ENABLE_BUILD_TESTS ON)
-endif()
-
-if(ENABLE_BUILD_TESTS)
- find_package(CMocka 1.0.0)
- if(CMOCKA_FOUND)
- enable_testing()
- add_subdirectory(tests)
- endif()
-endif()
+# create coverage target for generating coverage reports
+gen_coverage("test_.*" "test_.*_valgrind")
# generate doxygen documentation for libnetconf2 API
gen_doc("${doxy_files}" ${LIBNETCONF2_VERSION} ${LIBNETCONF2_DESCRIPTION} "")
@@ -328,6 +327,9 @@
lib_abi_check(netconf2 "${headers}" ${LIBNETCONF2_SOVERSION_FULL} e7402149e5b36de7acab2e38970a3a9d6a8165d5)
endif()
+# source files to be covered by the 'format' target and a test with 'format-check' target
+source_format(${format_sources})
+
# clean cmake cache
add_custom_target(cleancache
COMMAND make clean
diff --git a/CMakeModules/GenCoverage.cmake b/CMakeModules/GenCoverage.cmake
new file mode 100644
index 0000000..55be637
--- /dev/null
+++ b/CMakeModules/GenCoverage.cmake
@@ -0,0 +1,118 @@
+# generate test code coverage report
+
+# check that coverage tools are available - always use before GEN_COVERAGE
+macro(GEN_COVERAGE_ENABLE ENABLE_TESTS)
+ # make into normal variable
+ set(TESTS_ENABLED ${ENABLE_TESTS})
+
+ set(GEN_COVERAGE_ENABLED ON)
+ if(NOT TESTS_ENABLED)
+ message(WARNING "You cannot generate coverage when tests are disabled. Enable test by additing parameter -DENABLE_BUILD_TESTS=ON or run cmake with Debug build target.")
+ set(GEN_COVERAGE_ENABLED OFF)
+ endif()
+
+ if(GEN_COVERAGE_ENABLED)
+ find_program(PATH_GCOV NAMES gcov)
+ if(NOT PATH_GCOV)
+ message(WARNING "gcov executable not found! Disabling building code coverage report.")
+ set(GEN_COVERAGE_ENABLED OFF)
+ endif()
+ endif()
+
+ if(GEN_COVERAGE_ENABLED)
+ find_program(PATH_LCOV NAMES lcov)
+ if(NOT PATH_LCOV)
+ message(WARNING "lcov executable not found! Disabling building code coverage report.")
+ set(GEN_COVERAGE_ENABLED OFF)
+ endif()
+ endif()
+
+ if(GEN_COVERAGE_ENABLED)
+ find_program(PATH_GENHTML NAMES genhtml)
+ if(NOT PATH_GENHTML)
+ message(WARNING "genhtml executable not found! Disabling building code coverage report.")
+ set(GEN_COVERAGE_ENABLED OFF)
+ endif()
+ endif()
+
+ if(GEN_COVERAGE_ENABLED)
+ if(NOT CMAKE_COMPILER_IS_GNUCC)
+ message(WARNING "Compiler is not gcc! Coverage may break the tests!")
+ endif()
+
+ execute_process(
+ COMMAND bash "-c" "${CMAKE_C_COMPILER} --version | head -n1 | sed \"s/.* (.*) \\([0-9]\\+.[0-9]\\+.[0-9]\\+ .*\\)/\\1/\""
+ OUTPUT_VARIABLE GCC_VERSION_FULL
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ execute_process(
+ COMMAND bash "-c" "${PATH_GCOV} --version | head -n1 | sed \"s/.* (.*) \\([0-9]\\+.[0-9]\\+.[0-9]\\+ .*\\)/\\1/\""
+ OUTPUT_VARIABLE GCOV_VERSION_FULL
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if(NOT GCC_VERSION_FULL STREQUAL GCOV_VERSION_FULL)
+ message(WARNING "gcc and gcov versions do not match! Generating coverage may fail with errors.")
+ endif()
+
+ # add specific required compile flags
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -fprofile-arcs -ftest-coverage")
+ endif()
+endmacro()
+
+# tests are always expected to be in ${CMAKE_SOURCE_DIR}/tests
+function(GEN_COVERAGE MATCH_TEST_REGEX EXCLUDE_TEST_REGEX)
+ if(NOT GEN_COVERAGE_ENABLED)
+ return()
+ endif()
+
+ # destination
+ set(COVERAGE_DIR "${CMAKE_BINARY_DIR}/code_coverage/")
+ set(COVERAGE_FILE_RAW "${CMAKE_BINARY_DIR}/coverage_raw.info")
+ set(COVERAGE_FILE_CLEAN "${CMAKE_BINARY_DIR}/coverage_clean.info")
+
+ # test match/exclude
+ if(MATCH_TEST_REGEX)
+ set(MATCH_TEST_ARGS -R \"${MATCH_TEST_REGEX}\")
+ endif()
+ if(EXCLUDE_TEST_REGEX)
+ set(EXCLUDE_TEST_ARGS -E \"${EXCLUDE_TEST_REGEX}\")
+ endif()
+
+ # coverage target
+ add_custom_target(coverage
+ COMMENT "Generating code coverage..."
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
+ # Cleanup code counters
+ COMMAND "${PATH_LCOV}" --directory . --zerocounters --quiet
+
+ # Run tests
+ COMMAND "${CMAKE_CTEST_COMMAND}" --quiet ${MATCH_TEST_ARGS} ${EXCLUDE_TEST_ARGS}
+
+ # Capture the counters
+ COMMAND "${PATH_LCOV}"
+ --directory .
+ --rc lcov_branch_coverage=1
+ --rc 'lcov_excl_line=assert'
+ --capture --quiet
+ --output-file "${COVERAGE_FILE_RAW}"
+ # Remove coverage of tests, system headers, etc.
+ COMMAND "${PATH_LCOV}"
+ --remove "${COVERAGE_FILE_RAW}" '${CMAKE_SOURCE_DIR}/tests/*'
+ --rc lcov_branch_coverage=1
+ --quiet --output-file "${COVERAGE_FILE_CLEAN}"
+ # Generate HTML report
+ COMMAND "${PATH_GENHTML}"
+ --branch-coverage --function-coverage --quiet --title "${PROJECT_NAME}"
+ --legend --show-details --output-directory "${COVERAGE_DIR}"
+ "${COVERAGE_FILE_CLEAN}"
+ # Delete the counters
+ COMMAND "${CMAKE_COMMAND}" -E remove
+ ${COVERAGE_FILE_RAW} ${COVERAGE_FILE_CLEAN}
+ )
+
+ add_custom_command(TARGET coverage POST_BUILD
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/tests"
+ COMMENT "To see the code coverage report, open ${COVERAGE_DIR}index.html"
+ COMMAND ;
+ )
+endfunction()
diff --git a/README.md b/README.md
index b4a180b..9faab5f 100644
--- a/README.md
+++ b/README.md
@@ -224,6 +224,7 @@
```
and then the make's `coverage` target should be available to generate statistics:
```
+$ make
$ make coverage
```
@@ -252,7 +253,7 @@
In case of the `Release` mode, the tests are not built by default (it requires
additional dependency), but it can be enabled via cmake option:
```
-$ cmake -DENABLE_BUILD_TESTS=ON ..
+$ cmake -DENABLE_TESTS=ON ..
```
Note that if the necessary [cmocka](https://cmocka.org/) headers are not present
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index a3c5fbd..f9b9f3c 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -63,65 +63,15 @@
endforeach()
if(ENABLE_VALGRIND_TESTS)
- find_program(valgrind_FOUND valgrind)
- if(valgrind_FOUND)
- foreach(test_name IN LISTS tests)
- add_test(${test_name}_valgrind valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1
- --suppressions=${PROJECT_SOURCE_DIR}/tests/ld.supp ${CMAKE_BINARY_DIR}/tests/${test_name})
- endforeach()
+ foreach(test_name IN LISTS tests)
+ add_test(${test_name}_valgrind valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1
+ --suppressions=${PROJECT_SOURCE_DIR}/tests/ld.supp ${CMAKE_BINARY_DIR}/tests/${test_name})
+ endforeach()
- foreach(test_name IN LISTS client_tests)
- add_test(${test_name}_valgrind valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1
- --suppressions=${PROJECT_SOURCE_DIR}/tests/ld.supp ${CMAKE_BINARY_DIR}/tests/${test_name})
- endforeach()
- else()
- message("-- valgrind executable not found! Disabling memory leaks tests")
- endif()
-endif()
-
-if(ENABLE_COVERAGE)
- # Destination
- set(COVERAGE_DIR "${CMAKE_BINARY_DIR}/tests/code_coverage/")
- set(COVERAGE_FILE_RAW "${CMAKE_BINARY_DIR}/tests/coverage_raw.info")
- set(COVERAGE_FILE_CLEAN "${CMAKE_BINARY_DIR}/tests/coverage_clean.info")
-
- # Add coverage target
- add_custom_target(coverage
- COMMENT "Generating code coverage..."
- WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
- # Cleanup code counters
- COMMAND "${PATH_LCOV}" --directory . --zerocounters --quiet
-
- # Run tests
- COMMAND "${CMAKE_CTEST_COMMAND}" --quiet
-
- # Capture the counters
- COMMAND "${PATH_LCOV}"
- --directory .
- --rc lcov_branch_coverage=1
- --rc 'lcov_excl_line=assert'
- --capture --quiet
- --output-file "${COVERAGE_FILE_RAW}"
- # Remove coverage of tests, system headers, etc.
- COMMAND "${PATH_LCOV}"
- --remove "${COVERAGE_FILE_RAW}" '${CMAKE_SOURCE_DIR}/tests/*'
- --rc lcov_branch_coverage=1
- --quiet --output-file "${COVERAGE_FILE_CLEAN}"
- # Generate HTML report
- COMMAND "${PATH_GENHTML}"
- --branch-coverage --function-coverage --quiet --title "libnetconf2"
- --legend --show-details --output-directory "${COVERAGE_DIR}"
- "${COVERAGE_FILE_CLEAN}"
- # Delete the counters
- COMMAND "${CMAKE_COMMAND}" -E remove
- ${COVERAGE_FILE_RAW} ${COVERAGE_FILE_CLEAN}
- )
-
- add_custom_command(TARGET coverage POST_BUILD
- WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/tests"
- COMMENT "To see the code coverage report, open ${COVERAGE_DIR}index.html"
- COMMAND ;
- )
+ foreach(test_name IN LISTS client_tests)
+ add_test(${test_name}_valgrind valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1
+ --suppressions=${PROJECT_SOURCE_DIR}/tests/ld.supp ${CMAKE_BINARY_DIR}/tests/${test_name})
+ endforeach()
endif()
include_directories(${CMAKE_SOURCE_DIR}/src ${PROJECT_BINARY_DIR})