aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Schupp <w.schupp@a1.net>2016-07-19 12:10:38 +0200
committerGitHub <noreply@github.com>2016-07-19 12:10:38 +0200
commit82e30af27000e47abff3fb687135d70d6b90ad2e (patch)
tree11efd0934fcbcaa91aa85b2a1764abd1d9ef99c7
parent2cac3e385eda993bc3557b10f37fcc8673336aa5 (diff)
parentd510c7d4b64cfa184b923d3cd0aa9218a3f5881a (diff)
Merge pull request #10095 from fetzerch/cmake_codecoverage
[cmake/linux] Code coverage
-rw-r--r--project/cmake/CMakeLists.txt9
-rw-r--r--project/cmake/README.md6
-rw-r--r--project/cmake/scripts/linux/ArchSetup.cmake8
-rw-r--r--project/cmake/scripts/linux/CodeCoverage.cmake97
-rw-r--r--project/cmake/scripts/linux/Macros.cmake8
-rwxr-xr-xtools/buildsteps/linux64/run-tests6
-rw-r--r--tools/depends/target/cmakebuildsys/Makefile2
-rw-r--r--xbmc/network/cddb.cpp4
8 files changed, 135 insertions, 5 deletions
diff --git a/project/cmake/CMakeLists.txt b/project/cmake/CMakeLists.txt
index e209ed9791..7017a9bf21 100644
--- a/project/cmake/CMakeLists.txt
+++ b/project/cmake/CMakeLists.txt
@@ -358,6 +358,15 @@ if(NOT CMAKE_CROSSCOMPILING)
-DCMAKE_BINARY_DIR=${CMAKE_BINARY_DIR})
endif()
+# code coverage
+if(CMAKE_BUILD_TYPE STREQUAL Coverage)
+ if(EXISTS ${PROJECT_SOURCE_DIR}/scripts/${CORE_SYSTEM_NAME}/CodeCoverage.cmake)
+ include(${PROJECT_SOURCE_DIR}/scripts/${CORE_SYSTEM_NAME}/CodeCoverage.cmake)
+ else()
+ message(FATAL_ERROR "Code coverage not (yet) implemented for platform ${CORE_SYSTEM_NAME}")
+ endif()
+endif()
+
# link wrapper
if(FFMPEG_LINK_EXECUTABLE)
set(CMAKE_CXX_LINK_EXECUTABLE "${FFMPEG_LINK_EXECUTABLE}")
diff --git a/project/cmake/README.md b/project/cmake/README.md
index fafd07885a..2ac01f1689 100644
--- a/project/cmake/README.md
+++ b/project/cmake/README.md
@@ -152,6 +152,12 @@ When using the makefile builds a few extra targets are defined:
- `make check` builds and executes the test suite.
+Code coverage (with Gcov, LCOV and Gcovr) can be built on Linux:
+
+- CMake has to be executed with `-DCMAKE_BUILD_TYPE=Coverage`
+- `make coverage` generates an HTML code coverage report.
+- `make coverage_xml` generates an XML code coverage report.
+
## Sanitizers
Clang and GCC support different kinds of Sanitizers. To enable a Sanitizer call CMake with the
diff --git a/project/cmake/scripts/linux/ArchSetup.cmake b/project/cmake/scripts/linux/ArchSetup.cmake
index e2adf5bb3b..09675f19b2 100644
--- a/project/cmake/scripts/linux/ArchSetup.cmake
+++ b/project/cmake/scripts/linux/ArchSetup.cmake
@@ -22,3 +22,11 @@ if(ENABLE_LIRC)
set(LIRC_DEVICE "\"/dev/lircd\"" CACHE STRING "LIRC device to use")
set(DEP_DEFINES -DLIRC_DEVICE=${LIRC_DEVICE} -DHAVE_LIRC=1)
endif()
+
+# Code Coverage
+if(CMAKE_BUILD_TYPE STREQUAL Coverage)
+ set(COVERAGE_TEST_BINARY ${APP_NAME_LC}-test)
+ set(COVERAGE_SOURCE_DIR ${CORE_SOURCE_DIR})
+ set(COVERAGE_DEPENDS "\${APP_NAME_LC}" "\${APP_NAME_LC}-test")
+ set(COVERAGE_EXCLUDES */test/* lib/* */lib/*)
+endif()
diff --git a/project/cmake/scripts/linux/CodeCoverage.cmake b/project/cmake/scripts/linux/CodeCoverage.cmake
new file mode 100644
index 0000000000..efc2208b07
--- /dev/null
+++ b/project/cmake/scripts/linux/CodeCoverage.cmake
@@ -0,0 +1,97 @@
+# - CodeCoverage
+# Generate code coverage reports with LCOV and GCovr.
+#
+# Configuration:
+# COVERAGE_SOURCE_DIR - Source root directory (default ${CMAKE_SOURCE_DIR}).
+# COVERAGE_BINARY_DIR - Directory where the coverage reports (and intermediate files)
+# are generated to.
+# COVERAGE_EXCLUDES - List of exclude patterns (for example '*/tests/*').
+#
+# The following targets will be generated:
+# coverage - Builds an html report. Requires LCOV.
+# coverage_xml - Builds an xml report (in Cobertura format for Jenkins).
+# Requires Gcovr.
+#
+# Inspired by https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake
+
+# Comiler and linker setup
+set(CMAKE_C_FLAGS_COVERAGE "-g -O0 --coverage" CACHE STRING
+ "Flags used by the C compiler during coverage builds." FORCE)
+set(CMAKE_CXX_FLAGS_COVERAGE "-g -O0 --coverage" CACHE STRING
+ "Flags used by the C++ compiler during coverage builds." FORCE)
+set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "--coverage" CACHE STRING
+ "Flags used for linking binaries during coverage builds." FORCE)
+set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "--coverage" CACHE STRING
+ "Flags used by the shared libraries linker during coverage builds." FORCE)
+mark_as_advanced(
+ CMAKE_C_FLAGS_COVERAGE CMAKE_CXX_FLAGS_COVERAGE CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ CMAKE_SHARED_LINKER_FLAGS_COVERAGE CMAKE_STATIC_LINKER_FLAGS_COVERAGE
+)
+
+find_program(LCOV_EXECUTABLE lcov)
+find_program(GENINFO_EXECUTABLE geninfo)
+find_program(GENHTML_EXECUTABLE genhtml)
+find_program(GCOVR_EXECUTABLE gcovr)
+mark_as_advanced(LCOV_EXECUTABLE GENINFO_EXECUTABLE GENHTML_EXECUTABLE GCOVR_EXECUTABLE)
+
+# Default options
+if(NOT COVERAGE_SOURCE_DIR)
+ set(COVERAGE_SOURCE_DIR ${CMAKE_SOURCE_DIR})
+endif()
+if(NOT COVERAGE_BINARY_DIR)
+ set(COVERAGE_BINARY_DIR ${CMAKE_BINARY_DIR}/coverage)
+endif()
+if(NOT COVERAGE_EXCLUDES)
+ set(COVERAGE_EXCLUDES)
+endif()
+
+# Allow variables in COVERAGE_DEPENDS that are not evaluated before this file is included.
+string(CONFIGURE "${COVERAGE_DEPENDS}" COVERAGE_DEPENDS)
+
+# Add coverage target that generates an HTML report using LCOV
+if(LCOV_EXECUTABLE AND GENINFO_EXECUTABLE AND GENHTML_EXECUTABLE)
+ file(MAKE_DIRECTORY ${COVERAGE_BINARY_DIR})
+ add_custom_target(coverage
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${COVERAGE_BINARY_DIR}
+ COMMAND ${LCOV_EXECUTABLE} -z -q -d ${CMAKE_BINARY_DIR}
+ COMMAND ${LCOV_EXECUTABLE} -c -q -i -d ${CMAKE_BINARY_DIR} -b ${COVERAGE_SOURCE_DIR}
+ -o ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage_base.info
+ COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test || true
+ COMMAND ${LCOV_EXECUTABLE} -c -q -d ${CMAKE_BINARY_DIR} -b ${COVERAGE_SOURCE_DIR}
+ -o ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage_test.info
+ COMMAND ${LCOV_EXECUTABLE} -a ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage_base.info
+ -a ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage_test.info
+ -o ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage.info -q
+ COMMAND ${LCOV_EXECUTABLE} -q -r ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage.info
+ /usr/include/* ${CMAKE_BINARY_DIR}/* ${COVERAGE_EXCLUDES}
+ -o ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage.info
+ COMMAND ${GENHTML_EXECUTABLE} ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage.info
+ -o ${COVERAGE_BINARY_DIR}/html -s --legend --highlight --demangle-cpp
+ COMMAND ${CMAKE_COMMAND} -E echo "Coverage report: file://${COVERAGE_BINARY_DIR}/html/index.html"
+ WORKING_DIRECTORY ${COVERAGE_BINARY_DIR}
+ VERBATIM
+ DEPENDS ${COVERAGE_DEPENDS}
+ COMMENT "Generate code coverage html report"
+ )
+else()
+ message(WARNING "Target coverage not available (lcov, geninfo and genhtml needed).")
+endif()
+
+# Add coverage target that generates an XML report using Gcovr
+if(GCOVR_EXECUTABLE)
+ file(MAKE_DIRECTORY ${COVERAGE_BINARY_DIR})
+ string(REGEX REPLACE "([^;]+)" "--exclude=\"\\1\"" _gcovr_excludes "${COVERAGE_EXCLUDES}")
+ string(REPLACE "*" ".*" _gcovr_excludes "${_gcovr_excludes}")
+ add_custom_target(coverage_xml
+ COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test || true
+ COMMAND ${GCOVR_EXECUTABLE} -x -r ${COVERAGE_SOURCE_DIR} -o ${COVERAGE_BINARY_DIR}/coverage.xml
+ --object-directory ${CMAKE_BINARY_DIR} ${_gcovr_excludes} ${CMAKE_BINARY_DIR}
+ COMMAND ${CMAKE_COMMAND} -E echo "Coverage report: file://${COVERAGE_BINARY_DIR}/coverage.xml"
+ WORKING_DIRECTORY ${COVERAGE_BINARY_DIR}
+ DEPENDS ${COVERAGE_DEPENDS}
+ COMMENT "Generate code coverage xml report"
+ )
+ unset(_gcovr_excludes)
+else()
+ message(WARNING "Target coverage_xml not available (gcovr needed).")
+endif()
diff --git a/project/cmake/scripts/linux/Macros.cmake b/project/cmake/scripts/linux/Macros.cmake
index 7453a1c03d..9d8c00a984 100644
--- a/project/cmake/scripts/linux/Macros.cmake
+++ b/project/cmake/scripts/linux/Macros.cmake
@@ -14,8 +14,14 @@ function(core_link_library lib wraplib)
set(check_arg ${ARGV3})
set(data_arg ${ARGV4})
endif()
+
+ # wrapper has to be adapted in order to support coverage.
+ if(CMAKE_BUILD_TYPE STREQUAL Coverage)
+ set(export "")
+ endif()
+
if(check_arg STREQUAL export)
- set(export ${export}
+ set(export ${export}
-Wl,--version-script=${ARGV3})
elseif(check_arg STREQUAL nowrap)
set(export ${data_arg})
diff --git a/tools/buildsteps/linux64/run-tests b/tools/buildsteps/linux64/run-tests
index 265ff01985..abcaea49fa 100755
--- a/tools/buildsteps/linux64/run-tests
+++ b/tools/buildsteps/linux64/run-tests
@@ -4,7 +4,11 @@ XBMC_PLATFORM_DIR=linux64
if [ "$CMAKE_BUILD" = true ]; then
cd $WORKSPACE/build;make -j$BUILDTHREADS kodi-test
- cd $WORKSPACE;build/kodi-test --gtest_output=xml:gtestresults.xml
+ if [ "$Configuration" != "Coverage" ]; then
+ cd $WORKSPACE;build/kodi-test --gtest_output=xml:gtestresults.xml
+ else
+ cd $WORKSPACE/build;GTEST_OUTPUT="xml:$WORKSPACE/gtestresults.xml" make coverage
+ fi
else
cd $WORKSPACE;make -j$BUILDTHREADS testsuite
cd $WORKSPACE;./kodi-test --gtest_output=xml:gtestresults.xml
diff --git a/tools/depends/target/cmakebuildsys/Makefile b/tools/depends/target/cmakebuildsys/Makefile
index 60a88e153d..1b3207eafa 100644
--- a/tools/depends/target/cmakebuildsys/Makefile
+++ b/tools/depends/target/cmakebuildsys/Makefile
@@ -5,7 +5,7 @@ APP_NAME=$(shell awk '/APP_NAME/ {print tolower($$2)}' $(VERSION.TXT))
all:
mkdir -p $(XBMCROOT)/build
- cd $(XBMCROOT)/build; $(CMAKE) $(XBMCROOT)/project/cmake
+ cd $(XBMCROOT)/build; $(CMAKE) -DCMAKE_BUILD_TYPE=$(Configuration) $(XBMCROOT)/project/cmake
clean:
cd $(XBMCROOT)/build; $(MAKE) clean
diff --git a/xbmc/network/cddb.cpp b/xbmc/network/cddb.cpp
index 3878bfcef5..4267697bfc 100644
--- a/xbmc/network/cddb.cpp
+++ b/xbmc/network/cddb.cpp
@@ -219,8 +219,8 @@ bool Xcddb::queryCDinfo(CCdInfo* pInfo, int inexact_list_select)
//##########################################################
// Read the data from cddb
- Recv(false); //erstmal den Müll abholen
- if ( !Send(read_buffer.c_str()) )
+ Recv(false); // Clear pending data on our connection
+ if (!Send(read_buffer.c_str()))
{
CLog::Log(LOGERROR, "Xcddb::queryCDinfo_inexaxt_list_select Error sending \"%s\"", read_buffer.c_str());
CLog::Log(LOGERROR, "Xcddb::queryCDinfo_inexaxt_list_select pInfo == NULL");