diff options
author | langou <julien.langou@ucdenver.edu> | 2017-02-21 21:51:33 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-21 21:51:33 +0100 |
commit | fa2a0e8763d47e8c5a4e28118ee201d493b98073 (patch) | |
tree | 3ed9cecb656cdcf3df0e86ba32315cfb54f046ee | |
parent | d13744101e9eea94c4eafc8dd2dd7534630cb0f7 (diff) | |
parent | f5e52e264fbe3cf5f6e28286a94db1d0856e38e0 (diff) | |
download | lapack-fa2a0e8763d47e8c5a4e28118ee201d493b98073.tar.gz lapack-fa2a0e8763d47e8c5a4e28118ee201d493b98073.tar.bz2 lapack-fa2a0e8763d47e8c5a4e28118ee201d493b98073.zip |
Merge pull request #129 from Gjacquenot/master
Added Lapack code coverage
-rw-r--r-- | .travis.yml | 33 | ||||
-rw-r--r-- | CMAKE/FindGcov.cmake | 155 | ||||
-rw-r--r-- | CMAKE/Findcodecov.cmake | 202 | ||||
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | SRC/CMakeLists.txt | 5 |
6 files changed, 400 insertions, 5 deletions
diff --git a/.travis.yml b/.travis.yml index 25dcd081..68cfa607 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,25 +13,50 @@ os: - linux - osx +env: + - CMAKE_BUILD_TYPE=Release + - CMAKE_BUILD_TYPE=Coverage + install: - - brew update || echo "ok" - - brew install gcc || echo "ok" + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; + then + for pkg in gcc cmake; do + if brew list -1 | grep -q "^${pkg}\$"; then + brew outdated $pkg || brew upgrade $pkg; + else + brew install $pkg; + fi + done + fi script: - export PR=https://api.github.com/repos/$TRAVIS_REPO_SLUG/pulls/$TRAVIS_PULL_REQUEST - export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo `curl -s $PR | jq -r .head.ref`; fi) - echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH" - export SRC_DIR=$(pwd) - - export BLD_DIR=${SRC_DIR}/../lapack-travis-bld + - export BLD_DIR=${SRC_DIR}/lapack-travis-bld - export INST_DIR=${SRC_DIR}/../lapack-travis-install - mkdir -p ${BLD_DIR} - cd ${BLD_DIR} # See issue #17 on github dashboard. Once resolved, use -DCBLAS=ON # - cmake -DCMAKE_INSTALL_PREFIX=${INST_DIR} -DLAPACKE=ON ${SRC_DIR} - - cmake -DBUILDNAME:STRING="travis-${TRAVIS_OS_NAME}-${BRANCH}" -DCMAKE_INSTALL_PREFIX=${INST_DIR} -DCBLAS:BOOL=ON -DLAPACKE:BOOL=ON -DBUILD_TESTING=ON -DLAPACKE_WITH_TMG:BOOL=ON ${SRC_DIR} + - cmake -DBUILDNAME:STRING="travis-${TRAVIS_OS_NAME}-${BRANCH}" + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_INSTALL_PREFIX=${INST_DIR} + -DCBLAS:BOOL=ON + -DLAPACKE:BOOL=ON + -DBUILD_TESTING=ON + -DLAPACKE_WITH_TMG:BOOL=ON + ${SRC_DIR} - ctest -D ExperimentalStart - ctest -D ExperimentalConfigure - ctest -D ExperimentalBuild -j2 - ctest -D ExperimentalTest --schedule-random -j2 --output-on-failure --timeout 100 - ctest -D ExperimentalSubmit - make install -j2 + - if [[ "$CMAKE_BUILD_TYPE" == "Coverage" ]]; + then + echo "Coverage"; + make coverage; + bash <(curl -s https://codecov.io/bash) -X gcov; + fi diff --git a/CMAKE/FindGcov.cmake b/CMAKE/FindGcov.cmake new file mode 100644 index 00000000..4807f903 --- /dev/null +++ b/CMAKE/FindGcov.cmake @@ -0,0 +1,155 @@ +# This file is part of CMake-codecov. +# +# https://github.com/RWTH-ELP/CMake-codecov +# +# Copyright (c) +# 2015-2016 RWTH Aachen University, Federal Republic of Germany +# +# LICENSE : BSD 3-Clause License +# +# Written by Alexander Haase, alexander.haase@rwth-aachen.de +# Updated by Guillaume Jacquenot, guillaume.jacquenot@gmail.com + +# include required Modules +include(FindPackageHandleStandardArgs) + + +# Search for gcov binary. +set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET}) +set(CMAKE_REQUIRED_QUIET ${codecov_FIND_QUIETLY}) + +get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) +foreach (LANG ${ENABLED_LANGUAGES}) + # Gcov evaluation is dependend on the used compiler. Check gcov support for + # each compiler that is used. If gcov binary was already found for this + # compiler, do not try to find it again. + if(NOT GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN) + get_filename_component(COMPILER_PATH "${CMAKE_${LANG}_COMPILER}" PATH) + + if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "GNU") + # Some distributions like OSX (homebrew) ship gcov with the compiler + # version appended as gcov-x. To find this binary we'll build the + # suggested binary name with the compiler version. + string(REGEX MATCH "^[0-9]+" GCC_VERSION + "${CMAKE_${LANG}_COMPILER_VERSION}") + + find_program(GCOV_BIN NAMES gcov-${GCC_VERSION} gcov + HINTS ${COMPILER_PATH}) + + elseif("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Clang") + # Some distributions like Debian ship llvm-cov with the compiler + # version appended as llvm-cov-x.y. To find this binary we'll build + # the suggested binary name with the compiler version. + string(REGEX MATCH "^[0-9]+.[0-9]+" LLVM_VERSION + "${CMAKE_${LANG}_COMPILER_VERSION}") + + # llvm-cov prior version 3.5 seems to be not working with coverage + # evaluation tools, but these versions are compatible with the gcc + # gcov tool. + if(LLVM_VERSION VERSION_GREATER 3.4) + find_program(LLVM_COV_BIN NAMES "llvm-cov-${LLVM_VERSION}" + "llvm-cov" HINTS ${COMPILER_PATH}) + mark_as_advanced(LLVM_COV_BIN) + + if(LLVM_COV_BIN) + find_program(LLVM_COV_WRAPPER "llvm-cov-wrapper" PATHS + ${CMAKE_MODULE_PATH}) + if(LLVM_COV_WRAPPER) + set(GCOV_BIN "${LLVM_COV_WRAPPER}" CACHE FILEPATH "") + + # set additional parameters + set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV + "LLVM_COV_BIN=${LLVM_COV_BIN}" CACHE STRING + "Environment variables for llvm-cov-wrapper.") + mark_as_advanced(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV) + endif() + endif() + endif() + + if(NOT GCOV_BIN) + # Fall back to gcov binary if llvm-cov was not found or is + # incompatible. This is the default on OSX, but may crash on + # recent Linux versions. + find_program(GCOV_BIN gcov HINTS ${COMPILER_PATH}) + endif() + endif() + + + if(GCOV_BIN) + set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN "${GCOV_BIN}" CACHE STRING + "${LANG} gcov binary.") + + if(NOT CMAKE_REQUIRED_QUIET) + message("-- Found gcov evaluation for " + "${CMAKE_${LANG}_COMPILER_ID}: ${GCOV_BIN}") + endif() + + unset(GCOV_BIN CACHE) + endif() + endif() +endforeach () + + +# Add a new global target for all gcov targets. This target could be used to +# generate the gcov files for the whole project instead of calling <TARGET>-gcov +# for each target. +if(NOT TARGET coverage) + add_custom_target(coverage) +endif() + + +# This function will add gcov evaluation for target <TNAME>. Only sources of +# this target will be evaluated and no dependencies will be added. It will call +# Gcov on any source file of <TNAME> once and store the gcov file in the same +# directory. +function (add_gcov_target TNAME) + set(TDIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TNAME}.dir) + + # We don't have to check, if the target has support for coverage, thus this + # will be checked by add_coverage_target in Findcoverage.cmake. Instead we + # have to determine which gcov binary to use. + get_target_property(TSOURCES ${TNAME} SOURCES) + set(SOURCES "") + set(TCOMPILER "") + foreach (FILE ${TSOURCES}) + codecov_path_of_source(${FILE} FILE) + if(NOT "${FILE}" STREQUAL "") + codecov_lang_of_source(${FILE} LANG) + if(NOT "${LANG}" STREQUAL "") + list(APPEND SOURCES "${FILE}") + set(TCOMPILER ${CMAKE_${LANG}_COMPILER_ID}) + endif() + endif() + endforeach() + + # If no gcov binary was found, coverage data can't be evaluated. + if(NOT GCOV_${TCOMPILER}_BIN) + message(WARNING "No coverage evaluation binary found for ${TCOMPILER}.") + return() + endif() + + set(GCOV_BIN "${GCOV_${TCOMPILER}_BIN}") + set(GCOV_ENV "${GCOV_${TCOMPILER}_ENV}") + + + set(BUFFER "") + foreach(FILE ${SOURCES}) + get_filename_component(FILE_PATH "${TDIR}/${FILE}" PATH) + + # call gcov + add_custom_command(OUTPUT ${TDIR}/${FILE}.gcov + COMMAND ${GCOV_ENV} ${GCOV_BIN} ${TDIR}/${FILE}.gcno > /dev/null + DEPENDS ${TNAME} ${TDIR}/${FILE}.gcno + WORKING_DIRECTORY ${FILE_PATH} + ) + + list(APPEND BUFFER ${TDIR}/${FILE}.gcov) + endforeach() + + + # add target for gcov evaluation of <TNAME> + add_custom_target(${TNAME}-gcov DEPENDS ${BUFFER}) + + # add evaluation target to the global gcov target. + add_dependencies(coverage ${TNAME}-gcov) +endfunction() diff --git a/CMAKE/Findcodecov.cmake b/CMAKE/Findcodecov.cmake new file mode 100644 index 00000000..1f33b2c0 --- /dev/null +++ b/CMAKE/Findcodecov.cmake @@ -0,0 +1,202 @@ +# This file is part of CMake-codecov. +# +# https://github.com/RWTH-ELP/CMake-codecov +# +# Copyright (c) +# 2015-2016 RWTH Aachen University, Federal Republic of Germany +# +# LICENSE : BSD 3-Clause License +# +# Written by Alexander Haase, alexander.haase@rwth-aachen.de +# Updated by Guillaume Jacquenot, guillaume.jacquenot@gmail.com + +set(COVERAGE_FLAG_CANDIDATES + # gcc and clang + "-O0 -g -fprofile-arcs -ftest-coverage" + + # gcc and clang fallback + "-O0 -g --coverage" +) + + +# To avoid error messages about CMP0051, this policy will be set to new. There +# will be no problem, as TARGET_OBJECTS generator expressions will be filtered +# with a regular expression from the sources. +if(POLICY CMP0051) + cmake_policy(SET CMP0051 NEW) +endif() + + +# Add coverage support for target ${TNAME} and register target for coverage +# evaluation. +function(add_coverage TNAME) + foreach (TNAME ${ARGV}) + add_coverage_target(${TNAME}) + endforeach() +endfunction() + + +# Find the reuired flags foreach language. +set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET}) +set(CMAKE_REQUIRED_QUIET ${codecov_FIND_QUIETLY}) + +get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) +foreach (LANG ${ENABLED_LANGUAGES}) + # Coverage flags are not dependend on language, but the used compiler. So + # instead of searching flags foreach language, search flags foreach compiler + # used. + set(COMPILER ${CMAKE_${LANG}_COMPILER_ID}) + if(NOT COVERAGE_${COMPILER}_FLAGS) + foreach (FLAG ${COVERAGE_FLAG_CANDIDATES}) + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Try ${COMPILER} code coverage flag = [${FLAG}]") + endif() + + set(CMAKE_REQUIRED_FLAGS "${FLAG}") + unset(COVERAGE_FLAG_DETECTED CACHE) + + if(${LANG} STREQUAL "C") + include(CheckCCompilerFlag) + check_c_compiler_flag("${FLAG}" COVERAGE_FLAG_DETECTED) + + elseif(${LANG} STREQUAL "CXX") + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag("${FLAG}" COVERAGE_FLAG_DETECTED) + + elseif(${LANG} STREQUAL "Fortran") + # CheckFortranCompilerFlag was introduced in CMake 3.x. To be + # compatible with older Cmake versions, we will check if this + # module is present before we use it. Otherwise we will define + # Fortran coverage support as not available. + include(CheckFortranCompilerFlag OPTIONAL + RESULT_VARIABLE INCLUDED) + if(INCLUDED) + check_fortran_compiler_flag("${FLAG}" + COVERAGE_FLAG_DETECTED) + elseif(NOT CMAKE_REQUIRED_QUIET) + message("-- Performing Test COVERAGE_FLAG_DETECTED") + message("-- Performing Test COVERAGE_FLAG_DETECTED - Failed" + " (Check not supported)") + endif() + endif() + + if(COVERAGE_FLAG_DETECTED) + set(COVERAGE_${COMPILER}_FLAGS "${FLAG}" + CACHE STRING "${COMPILER} flags for code coverage.") + mark_as_advanced(COVERAGE_${COMPILER}_FLAGS) + break() + endif() + endforeach() + endif() +endforeach() + +set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE}) + +# Helper function to get the language of a source file. +function (codecov_lang_of_source FILE RETURN_VAR) + get_filename_component(FILE_EXT "${FILE}" EXT) + string(TOLOWER "${FILE_EXT}" FILE_EXT) + string(SUBSTRING "${FILE_EXT}" 1 -1 FILE_EXT) + + get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + foreach (LANG ${ENABLED_LANGUAGES}) + list(FIND CMAKE_${LANG}_SOURCE_FILE_EXTENSIONS "${FILE_EXT}" TEMP) + if(NOT ${TEMP} EQUAL -1) + set(${RETURN_VAR} "${LANG}" PARENT_SCOPE) + return() + endif() + endforeach() + + set(${RETURN_VAR} "" PARENT_SCOPE) +endfunction() + +# Helper function to get the relative path of the source file destination path. +# This path is needed by FindGcov and FindLcov cmake files to locate the +# captured data. +function (codecov_path_of_source FILE RETURN_VAR) + string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _source ${FILE}) + + # If expression was found, SOURCEFILE is a generator-expression for an + # object library. Currently we found no way to call this function automatic + # for the referenced target, so it must be called in the directoryso of the + # object library definition. + if(NOT "${_source}" STREQUAL "") + set(${RETURN_VAR} "" PARENT_SCOPE) + return() + endif() + + string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}/" "" FILE "${FILE}") + if(IS_ABSOLUTE ${FILE}) + file(RELATIVE_PATH FILE ${CMAKE_CURRENT_SOURCE_DIR} ${FILE}) + endif() + + # get the right path for file + string(REPLACE ".." "__" PATH "${FILE}") + + set(${RETURN_VAR} "${PATH}" PARENT_SCOPE) +endfunction() + +# Add coverage support for target ${TNAME} and register target for coverage +# evaluation. +function(add_coverage_target TNAME) + # Check if all sources for target use the same compiler. If a target uses + # e.g. C and Fortran mixed and uses different compilers (e.g. clang and + # gfortran) this can trigger huge problems, because different compilers may + # use different implementations for code coverage. + get_target_property(TSOURCES ${TNAME} SOURCES) + set(TARGET_COMPILER "") + set(ADDITIONAL_FILES "") + foreach (FILE ${TSOURCES}) + # If expression was found, FILE is a generator-expression for an object + # library. Object libraries will be ignored. + string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _file ${FILE}) + if("${_file}" STREQUAL "") + codecov_lang_of_source(${FILE} LANG) + if(LANG) + list(APPEND TARGET_COMPILER ${CMAKE_${LANG}_COMPILER_ID}) + + list(APPEND ADDITIONAL_FILES "${FILE}.gcno") + list(APPEND ADDITIONAL_FILES "${FILE}.gcda") + endif() + endif() + endforeach () + + list(REMOVE_DUPLICATES TARGET_COMPILER) + list(LENGTH TARGET_COMPILER NUM_COMPILERS) + + if(NUM_COMPILERS GREATER 1) + message(AUTHOR_WARNING "Coverage disabled for target ${TNAME} because " + "it will be compiled by different compilers.") + return() + + elseif((NUM_COMPILERS EQUAL 0) OR + (NOT DEFINED "COVERAGE_${TARGET_COMPILER}_FLAGS")) + message(AUTHOR_WARNING "Coverage disabled for target ${TNAME} " + "because there is no sanitizer available for target sources.") + return() + endif() + + + # enable coverage for target + set_property(TARGET ${TNAME} APPEND_STRING + PROPERTY COMPILE_FLAGS " ${COVERAGE_${TARGET_COMPILER}_FLAGS}") + set_property(TARGET ${TNAME} APPEND_STRING + PROPERTY LINK_FLAGS " ${COVERAGE_${TARGET_COMPILER}_FLAGS}") + + + # Add gcov files generated by compiler to clean target. + set(CLEAN_FILES "") + foreach (FILE ${ADDITIONAL_FILES}) + codecov_path_of_source(${FILE} FILE) + list(APPEND CLEAN_FILES "CMakeFiles/${TNAME}.dir/${FILE}") + endforeach() + + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES + "${CLEAN_FILES}") + + add_gcov_target(${TNAME}) +endfunction() + +# Include modules for parsing the collected data and output it in a readable +# format (like gcov). +find_package(Gcov) diff --git a/CMakeLists.txt b/CMakeLists.txt index c50b5010..eed3796e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to 'Release' as none was specified.") set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo" "Coverage") endif() project(LAPACK Fortran C) @@ -134,6 +134,12 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LAPACK_BINARY_DIR}/lib) include(CheckLAPACKCompilerFlags) CheckLAPACKCompilerFlags() +string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPER) +if(${CMAKE_BUILD_TYPE_UPPER} STREQUAL "COVERAGE") + message(STATUS "Adding coverage") + find_package(codecov) +endif() + # -------------------------------------------------- # Check second function @@ -2,6 +2,8 @@ [![Build Status](https://travis-ci.org/Reference-LAPACK/lapack.svg?branch=master)](https://travis-ci.org/Reference-LAPACK/lapack) [![Appveyor](https://ci.appveyor.com/api/projects/status/bh38iin398msrbtr?svg=true)](https://ci.appveyor.com/project/Gjacquenot/lapack/branch/master) +[![codecov](https://codecov.io/gh/Gjacquenot/lapack/branch/master/graph/badge.svg)](https://codecov.io/gh/Gjacquenot/lapack?branch=master) + * VERSION 1.0 : February 29, 1992 * VERSION 1.0a : June 30, 1992 diff --git a/SRC/CMakeLists.txt b/SRC/CMakeLists.txt index 099c5f48..07008bae 100644 --- a/SRC/CMakeLists.txt +++ b/SRC/CMakeLists.txt @@ -498,4 +498,9 @@ if(USE_XBLAS) endif() target_link_libraries(lapack PRIVATE ${BLAS_LIBRARIES}) +if (${CMAKE_BUILD_TYPE_UPPER} STREQUAL "COVERAGE") + target_link_libraries(lapack PRIVATE gcov) + add_coverage(lapack) +endif() + lapack_install_library(lapack) |