FIX: only use and provide required cmake modules
This commit is contained in:
parent
aba38cb8b6
commit
343e880558
@ -1,7 +1,26 @@
|
|||||||
cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
|
cmake_minimum_required (VERSION 3.1 FATAL_ERROR)
|
||||||
project (libtree++ VERSION 0.1.0 LANGUAGES CXX)
|
project (libtree++ VERSION 0.1.0 LANGUAGES CXX)
|
||||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules)
|
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules)
|
||||||
include(defaultOptions)
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Set the required C++ standard
|
||||||
|
#
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
#
|
||||||
|
# We want to have a compile_commands.json file
|
||||||
|
#
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Module includes for compdb and doxygen
|
||||||
|
#
|
||||||
|
include(compdb)
|
||||||
|
include(doxygen)
|
||||||
|
|
||||||
|
|
||||||
configure_file(${PROJECT_SOURCE_DIR}/src/config.hpp.in ${PROJECT_SOURCE_DIR}/src/config.hpp @ONLY)
|
configure_file(${PROJECT_SOURCE_DIR}/src/config.hpp.in ${PROJECT_SOURCE_DIR}/src/config.hpp @ONLY)
|
||||||
|
|
||||||
@ -23,17 +42,10 @@ target_include_directories(tree PUBLIC
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
IF(CMAKE_BUILD_TYPE MATCHES DEBUG)
|
|
||||||
target_compile_options(tree PUBLIC -Wall -g -O0 )
|
|
||||||
ELSE()
|
|
||||||
target_compile_options(tree PUBLIC -O4)
|
|
||||||
target_compile_options(tree PUBLIC -O4)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Everything TEST related
|
# Everything TEST related
|
||||||
#
|
#
|
||||||
option(TEST_TREE "Turn running of ASMparseRISCV specific tests on/off" ON)
|
option(TEST_TREE "Turn running of tree specific tests on/off" ON)
|
||||||
|
|
||||||
IF(${TEST_TREE})
|
IF(${TEST_TREE})
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
@ -1 +0,0 @@
|
|||||||
get_directory_property(hasParent PARENT_DIRECTORY)
|
|
@ -1,76 +0,0 @@
|
|||||||
# Try to find the GMP library
|
|
||||||
# https://gmplib.org/
|
|
||||||
#
|
|
||||||
# This module supports requiring a minimum version, e.g. you can do
|
|
||||||
# find_package(GMP 6.0.0)
|
|
||||||
# to require version 6.0.0 to newer of GMP.
|
|
||||||
#
|
|
||||||
# Once done this will define
|
|
||||||
#
|
|
||||||
# GMP_FOUND - system has GMP lib with correct version
|
|
||||||
# GMP_INCLUDES - the GMP include directory
|
|
||||||
# GMP_LIBRARIES - the GMP library
|
|
||||||
# GMP_VERSION - GMP version
|
|
||||||
#
|
|
||||||
# Copyright (c) 2016 Jack Poulson, <jack.poulson@gmail.com>
|
|
||||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
|
||||||
|
|
||||||
find_path(GMP_INCLUDES NAMES gmp.h PATHS $ENV{GMPDIR} ${INCLUDE_INSTALL_DIR})
|
|
||||||
|
|
||||||
# Set GMP_FIND_VERSION to 5.1.0 if no minimum version is specified
|
|
||||||
if(NOT GMP_FIND_VERSION)
|
|
||||||
if(NOT GMP_FIND_VERSION_MAJOR)
|
|
||||||
set(GMP_FIND_VERSION_MAJOR 5)
|
|
||||||
endif()
|
|
||||||
if(NOT GMP_FIND_VERSION_MINOR)
|
|
||||||
set(GMP_FIND_VERSION_MINOR 1)
|
|
||||||
endif()
|
|
||||||
if(NOT GMP_FIND_VERSION_PATCH)
|
|
||||||
set(GMP_FIND_VERSION_PATCH 0)
|
|
||||||
endif()
|
|
||||||
set(GMP_FIND_VERSION
|
|
||||||
"${GMP_FIND_VERSION_MAJOR}.${GMP_FIND_VERSION_MINOR}.${GMP_FIND_VERSION_PATCH}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message("GMP_INCLUDES=${GMP_INCLUDES}")
|
|
||||||
if(GMP_INCLUDES)
|
|
||||||
# Since the GMP version macros may be in a file included by gmp.h of the form
|
|
||||||
# gmp-.*[_]?.*.h (e.g., gmp-x86_64.h), we search each of them.
|
|
||||||
file(GLOB GMP_HEADERS "${GMP_INCLUDES}/gmp.h" "${GMP_INCLUDES}/gmp-*.h")
|
|
||||||
foreach(gmp_header_filename ${GMP_HEADERS})
|
|
||||||
file(READ "${gmp_header_filename}" _gmp_version_header)
|
|
||||||
string(REGEX MATCH
|
|
||||||
"define[ \t]+__GNU_MP_VERSION[ \t]+([0-9]+)" _gmp_major_version_match
|
|
||||||
"${_gmp_version_header}")
|
|
||||||
if(_gmp_major_version_match)
|
|
||||||
set(GMP_MAJOR_VERSION "${CMAKE_MATCH_1}")
|
|
||||||
string(REGEX MATCH "define[ \t]+__GNU_MP_VERSION_MINOR[ \t]+([0-9]+)"
|
|
||||||
_gmp_minor_version_match "${_gmp_version_header}")
|
|
||||||
set(GMP_MINOR_VERSION "${CMAKE_MATCH_1}")
|
|
||||||
string(REGEX MATCH "define[ \t]+__GNU_MP_VERSION_PATCHLEVEL[ \t]+([0-9]+)"
|
|
||||||
_gmp_patchlevel_version_match "${_gmp_version_header}")
|
|
||||||
set(GMP_PATCHLEVEL_VERSION "${CMAKE_MATCH_1}")
|
|
||||||
set(GMP_VERSION
|
|
||||||
${GMP_MAJOR_VERSION}.${GMP_MINOR_VERSION}.${GMP_PATCHLEVEL_VERSION})
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# Check whether found version exists and exceeds the minimum requirement
|
|
||||||
if(NOT GMP_VERSION)
|
|
||||||
set(GMP_VERSION_OK FALSE)
|
|
||||||
message(STATUS "GMP version was not detected")
|
|
||||||
elseif(${GMP_VERSION} VERSION_LESS ${GMP_FIND_VERSION})
|
|
||||||
set(GMP_VERSION_OK FALSE)
|
|
||||||
message(STATUS "GMP version ${GMP_VERSION} found in ${GMP_INCLUDES}, "
|
|
||||||
"but at least version ${GMP_FIND_VERSION} is required")
|
|
||||||
else()
|
|
||||||
set(GMP_VERSION_OK TRUE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_library(GMP_LIBRARIES gmp PATHS $ENV{GMPDIR} ${LIB_INSTALL_DIR})
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(GMP DEFAULT_MSG
|
|
||||||
GMP_INCLUDES GMP_LIBRARIES GMP_VERSION_OK)
|
|
||||||
mark_as_advanced(GMP_INCLUDES GMP_LIBRARIES)
|
|
@ -1,25 +0,0 @@
|
|||||||
# Find Valgrind.
|
|
||||||
#
|
|
||||||
# This module defines:
|
|
||||||
# VALGRIND_INCLUDE_DIR, where to find valgrind/memcheck.h, etc.
|
|
||||||
# VALGRIND_PROGRAM, the valgrind executable.
|
|
||||||
# VALGRIND_FOUND, If false, do not try to use valgrind.
|
|
||||||
#
|
|
||||||
# If you have valgrind installed in a non-standard place, you can define
|
|
||||||
# VALGRIND_PREFIX to tell cmake where it is.
|
|
||||||
#
|
|
||||||
# NOTE: Copied from the opencog project, where it is distributed under the
|
|
||||||
# terms of the New BSD License.
|
|
||||||
|
|
||||||
message(STATUS "Valgrind Prefix: ${VALGRIND_PREFIX}")
|
|
||||||
|
|
||||||
find_path(VALGRIND_INCLUDE_DIR valgrind/memcheck.h
|
|
||||||
/usr/include /usr/local/include ${VALGRIND_PREFIX}/include)
|
|
||||||
find_program(VALGRIND_PROGRAM NAMES valgrind PATH
|
|
||||||
/usr/bin /usr/local/bin ${VALGRIND_PREFIX}/bin)
|
|
||||||
|
|
||||||
find_package_handle_standard_args(VALGRIND DEFAULT_MSG
|
|
||||||
VALGRIND_INCLUDE_DIR
|
|
||||||
VALGRIND_PROGRAM)
|
|
||||||
|
|
||||||
mark_as_advanced(VALGRIND_INCLUDE_DIR VALGRIND_PROGRAM)
|
|
@ -1,47 +0,0 @@
|
|||||||
INCLUDE(CheckParent)
|
|
||||||
# search for CCCC binary
|
|
||||||
FIND_PROGRAM(CCCC cccc )
|
|
||||||
|
|
||||||
#
|
|
||||||
# check if the GENERATE_CCCC function has already been defined
|
|
||||||
#
|
|
||||||
get_property(_GENERATE_CCCC GLOBAL PROPERTY _GENERATE_CCCC)
|
|
||||||
IF (NOT _GENERATE_CCCC)
|
|
||||||
|
|
||||||
# set that we have defined GENERATE_CCCC
|
|
||||||
set_property(GLOBAL PROPERTY _GENERATE_CCCC "YES")
|
|
||||||
|
|
||||||
|
|
||||||
FUNCTION(GENERATE_CCCC)
|
|
||||||
IF(CCCC)
|
|
||||||
CMAKE_PARSE_ARGUMENTS(ARG "" "" "TARGETS" ${ARGN})
|
|
||||||
get_property(_ccccfiles GLOBAL PROPERTY _ccccfiles)
|
|
||||||
foreach(_target ${ARG_TARGETS})
|
|
||||||
get_target_property(_sources ${_target} SOURCES)
|
|
||||||
get_target_property(_source_dir ${_target} SOURCE_DIR)
|
|
||||||
|
|
||||||
foreach(_source ${_sources})
|
|
||||||
set(_fullsource "${_source_dir}/${_source}")
|
|
||||||
list(APPEND _ccccfiles "${_fullsource}")
|
|
||||||
endforeach()
|
|
||||||
endforeach()
|
|
||||||
set_property(GLOBAL PROPERTY _ccccfiles ${_ccccfiles})
|
|
||||||
ENDIF()
|
|
||||||
ENDFUNCTION()
|
|
||||||
|
|
||||||
FUNCTION(RESET_CCCC)
|
|
||||||
set_property(GLOBAL PROPERTY _ccccfiles "")
|
|
||||||
ENDFUNCTION()
|
|
||||||
|
|
||||||
FUNCTION(GENERATE_CCCC_TARGET)
|
|
||||||
IF (NOT hasParent AND CCCC)
|
|
||||||
get_property(_targetccccfiles GLOBAL PROPERTY _ccccfiles)
|
|
||||||
|
|
||||||
ADD_CUSTOM_TARGET(cccc
|
|
||||||
COMMAND ${CCCC} --outdir=cccc ${_targetccccfiles}
|
|
||||||
COMMENT "Generating cccc result")
|
|
||||||
ENDIF()
|
|
||||||
ENDFUNCTION()
|
|
||||||
|
|
||||||
|
|
||||||
ENDIF()
|
|
@ -1,74 +0,0 @@
|
|||||||
INCLUDE(CheckParent)
|
|
||||||
find_program(CPPCHECK NAMES cppcheck)
|
|
||||||
|
|
||||||
#
|
|
||||||
# check if the GENERATE_CPPCHECK function has already been defined
|
|
||||||
#
|
|
||||||
get_property(_GENERATE_CPPCHECK GLOBAL PROPERTY _GENERATE_CPPCHECK)
|
|
||||||
IF (NOT _GENERATE_CPPCHECK)
|
|
||||||
|
|
||||||
# set that we have defined GENERATE_CCCC
|
|
||||||
set_property(GLOBAL PROPERTY _GENERATE_CPPCHECK "YES")
|
|
||||||
|
|
||||||
FUNCTION(GENERATE_CPPCHECK)
|
|
||||||
IF(NOT TARGET cppcheck)
|
|
||||||
IF(CPPCHECK)
|
|
||||||
CMAKE_PARSE_ARGUMENTS(ARG "" "" "TARGETS" ${ARGN})
|
|
||||||
get_property(_cppcheckfiles GLOBAL PROPERTY _cppcheckfiles)
|
|
||||||
get_property(_cppcheckincludedirs GLOBAL PROPERTY _cppcheckincludedirs)
|
|
||||||
|
|
||||||
foreach(_target ${ARG_TARGETS})
|
|
||||||
get_target_property(_sources ${_target} SOURCES)
|
|
||||||
get_target_property(_source_dir ${_target} SOURCE_DIR)
|
|
||||||
get_target_property(_include_dir ${_target} INCLUDE_DIRECTORIES)
|
|
||||||
string(REPLACE "$<" ";" _include_dirs ${_include_dir})
|
|
||||||
|
|
||||||
foreach(_dir ${_include_dirs})
|
|
||||||
list(APPEND _cppcheckincludedirs -I${_include_dir})
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
foreach(_source ${_sources})
|
|
||||||
set(_fullsource "${_source_dir}/${_source}")
|
|
||||||
list(APPEND _cppcheckfiles ${_fullsource})
|
|
||||||
endforeach()
|
|
||||||
endforeach()
|
|
||||||
set_property(GLOBAL PROPERTY _cppcheckfiles ${_cppcheckfiles})
|
|
||||||
set_property(GLOBAL PROPERTY _cppcheckincludedirs ${_cppcheckincludedirs})
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
ENDFUNCTION()
|
|
||||||
|
|
||||||
FUNCTION(RESET_CPPCHECK)
|
|
||||||
set_property(GLOBAL PROPERTY _cppcheckfiles "")
|
|
||||||
set_property(GLOBAL PROPERTY _cppcheckincludedirs "")
|
|
||||||
ENDFUNCTION()
|
|
||||||
|
|
||||||
|
|
||||||
FUNCTION(GENERATE_CPPCHECK_TARGET)
|
|
||||||
IF ( NOT hasParent AND CPPCHECK)
|
|
||||||
message("generate cppcheck target")
|
|
||||||
get_property(_targetcppcheckfiles GLOBAL PROPERTY _cppcheckfiles)
|
|
||||||
get_property(_targetcppcheckincludedirs GLOBAL PROPERTY _cppcheckincludedirs)
|
|
||||||
|
|
||||||
add_custom_target(cppcheck
|
|
||||||
COMMAND
|
|
||||||
${CPPCHECK}
|
|
||||||
--xml
|
|
||||||
--xml-version=2
|
|
||||||
--enable=all
|
|
||||||
--inconclusive
|
|
||||||
--force
|
|
||||||
--inline-suppr
|
|
||||||
${_targetcppcheckincludedirs}
|
|
||||||
${_targetcppcheckfiles}
|
|
||||||
2> cppcheck.xml
|
|
||||||
WORKING_DIRECTORY
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
COMMENT
|
|
||||||
"cppcheck: Running cppcheck on target ${_targetname}..."
|
|
||||||
VERBATIM)
|
|
||||||
|
|
||||||
ENDIF()
|
|
||||||
ENDFUNCTION()
|
|
||||||
|
|
||||||
ENDIF()
|
|
@ -1,23 +0,0 @@
|
|||||||
INCLUDE(CheckParent)
|
|
||||||
|
|
||||||
IF(NOT hasParent)
|
|
||||||
find_package(Doxygen)
|
|
||||||
|
|
||||||
|
|
||||||
IF (DOXYGEN_FOUND)
|
|
||||||
# set input and output files
|
|
||||||
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in)
|
|
||||||
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
|
|
||||||
|
|
||||||
# request to configure the file
|
|
||||||
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
|
|
||||||
|
|
||||||
# note the option ALL which allows to build the docs together with the application
|
|
||||||
add_custom_target( doxygen
|
|
||||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
COMMENT "Generating API documentation with Doxygen"
|
|
||||||
VERBATIM )
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
ENDIF()
|
|
@ -1,17 +0,0 @@
|
|||||||
if (GIT_FOUND)
|
|
||||||
execute_process(
|
|
||||||
COMMAND git rev-parse --abbrev-ref HEAD
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
||||||
OUTPUT_VARIABLE GIT_BRANCH
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
|
||||||
|
|
||||||
# Get the latest abbreviated commit hash of the working branch
|
|
||||||
execute_process(
|
|
||||||
COMMAND git log -1 --format=%h
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
||||||
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
|
||||||
|
|
||||||
endif()
|
|
@ -1,22 +0,0 @@
|
|||||||
get_property(_ADD_MY_TEST GLOBAL PROPERTY _ADD_MY_TEST)
|
|
||||||
IF (NOT _ADD_MY_TEST)
|
|
||||||
|
|
||||||
# set that we have defined GENERATE_CCCC
|
|
||||||
set_property(GLOBAL PROPERTY _ADD_MY_TEST "YES")
|
|
||||||
|
|
||||||
|
|
||||||
FUNCTION(ADD_MY_TEST)
|
|
||||||
CMAKE_PARSE_ARGUMENTS(ARG "" "TEST" "SOURCES;LIBS" ${ARGN})
|
|
||||||
get_property(_mytests GLOBAL PROPERTY _mytests)
|
|
||||||
|
|
||||||
list(APPEND _mytests "${ARG_TEST}")
|
|
||||||
|
|
||||||
add_executable(${ARG_TEST} ${ARG_SOURCES})
|
|
||||||
target_link_libraries(${ARG_TEST} ${ARG_LIBS})
|
|
||||||
add_test(${ARG_TEST} ${ARG_TEST})
|
|
||||||
|
|
||||||
set_property(GLOBAL PROPERTY _mytests ${_mytests})
|
|
||||||
ENDFUNCTION()
|
|
||||||
|
|
||||||
|
|
||||||
ENDIF()
|
|
@ -1,66 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2018 by George Cave - gcave@stablecoder.ca
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
||||||
# use this file except in compliance with the License. You may obtain a copy of
|
|
||||||
# the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations under
|
|
||||||
# the License.
|
|
||||||
|
|
||||||
# Set the compiler standard to C++11
|
|
||||||
macro(cxx_11)
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
||||||
|
|
||||||
if(MSVC_VERSION GREATER_EQUAL "1900" AND CMAKE_VERSION LESS 3.10)
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
check_cxx_compiler_flag("/std:c++11" _cpp_latest_flag_supported)
|
|
||||||
if(_cpp_latest_flag_supported)
|
|
||||||
add_compile_options("/std:c++11")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Set the compiler standard to C++14
|
|
||||||
macro(cxx_14)
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
||||||
|
|
||||||
if(MSVC_VERSION GREATER_EQUAL "1900" AND CMAKE_VERSION LESS 3.10)
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
check_cxx_compiler_flag("/std:c++14" _cpp_latest_flag_supported)
|
|
||||||
if(_cpp_latest_flag_supported)
|
|
||||||
add_compile_options("/std:c++14")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Set the compiler standard to C++17
|
|
||||||
macro(cxx_17)
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
||||||
|
|
||||||
if(MSVC_VERSION GREATER_EQUAL "1900" AND CMAKE_VERSION LESS 3.10)
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
check_cxx_compiler_flag("/std:c++17" _cpp_latest_flag_supported)
|
|
||||||
if(_cpp_latest_flag_supported)
|
|
||||||
add_compile_options("/std:c++17")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Set the compiler standard to C++20
|
|
||||||
macro(cxx_20)
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
||||||
endmacro()
|
|
@ -1,588 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2018 by George Cave - gcave@stablecoder.ca
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
||||||
# use this file except in compliance with the License. You may obtain a copy of
|
|
||||||
# the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations under
|
|
||||||
# the License.
|
|
||||||
|
|
||||||
# USAGE: To enable any code coverage instrumentation/targets, the single CMake
|
|
||||||
# option of `CODE_COVERAGE` needs to be set to 'ON', either by GUI, ccmake, or
|
|
||||||
# on the command line.
|
|
||||||
#
|
|
||||||
# From this point, there are two primary methods for adding instrumentation to
|
|
||||||
# targets: 1 - A blanket instrumentation by calling `add_code_coverage()`, where
|
|
||||||
# all targets in that directory and all subdirectories are automatically
|
|
||||||
# instrumented. 2 - Per-target instrumentation by calling
|
|
||||||
# `target_code_coverage(<TARGET_NAME>)`, where the target is given and thus only
|
|
||||||
# that target is instrumented. This applies to both libraries and executables.
|
|
||||||
#
|
|
||||||
# To add coverage targets, such as calling `make ccov` to generate the actual
|
|
||||||
# coverage information for perusal or consumption, call
|
|
||||||
# `target_code_coverage(<TARGET_NAME>)` on an *executable* target.
|
|
||||||
#
|
|
||||||
# Example 1: All targets instrumented
|
|
||||||
#
|
|
||||||
# In this case, the coverage information reported will will be that of the
|
|
||||||
# `theLib` library target and `theExe` executable.
|
|
||||||
#
|
|
||||||
# 1a: Via global command
|
|
||||||
#
|
|
||||||
# ~~~
|
|
||||||
# add_code_coverage() # Adds instrumentation to all targets
|
|
||||||
#
|
|
||||||
# add_library(theLib lib.cpp)
|
|
||||||
#
|
|
||||||
# add_executable(theExe main.cpp)
|
|
||||||
# target_link_libraries(theExe PRIVATE theLib)
|
|
||||||
# target_code_coverage(theExe) # As an executable target, adds the 'ccov-theExe' target (instrumentation already added via global anyways) for generating code coverage reports.
|
|
||||||
# ~~~
|
|
||||||
#
|
|
||||||
# 1b: Via target commands
|
|
||||||
#
|
|
||||||
# ~~~
|
|
||||||
# add_library(theLib lib.cpp)
|
|
||||||
# target_code_coverage(theLib) # As a library target, adds coverage instrumentation but no targets.
|
|
||||||
#
|
|
||||||
# add_executable(theExe main.cpp)
|
|
||||||
# target_link_libraries(theExe PRIVATE theLib)
|
|
||||||
# target_code_coverage(theExe) # As an executable target, adds the 'ccov-theExe' target and instrumentation for generating code coverage reports.
|
|
||||||
# ~~~
|
|
||||||
#
|
|
||||||
# Example 2: Target instrumented, but with regex pattern of files to be excluded
|
|
||||||
# from report
|
|
||||||
#
|
|
||||||
# ~~~
|
|
||||||
# add_executable(theExe main.cpp non_covered.cpp)
|
|
||||||
# target_code_coverage(theExe EXCLUDE non_covered.cpp test/*) # As an executable target, the reports will exclude the non-covered.cpp file, and any files in a test/ folder.
|
|
||||||
# ~~~
|
|
||||||
#
|
|
||||||
# Example 3: Target added to the 'ccov' and 'ccov-all' targets
|
|
||||||
#
|
|
||||||
# ~~~
|
|
||||||
# add_code_coverage_all_targets(EXCLUDE test/*) # Adds the 'ccov-all' target set and sets it to exclude all files in test/ folders.
|
|
||||||
#
|
|
||||||
# add_executable(theExe main.cpp non_covered.cpp)
|
|
||||||
# target_code_coverage(theExe AUTO ALL EXCLUDE non_covered.cpp test/*) # As an executable target, adds to the 'ccov' and ccov-all' targets, and the reports will exclude the non-covered.cpp file, and any files in a test/ folder.
|
|
||||||
# ~~~
|
|
||||||
|
|
||||||
# Options
|
|
||||||
option(
|
|
||||||
CODE_COVERAGE
|
|
||||||
"Builds targets with code coverage instrumentation. (Requires GCC or Clang)"
|
|
||||||
OFF)
|
|
||||||
|
|
||||||
# Programs
|
|
||||||
find_program(LLVM_COV_PATH NAMES llvm-cov llvm-cov-8 llvm-cov-7 llvm-cov-6)
|
|
||||||
find_program(LLVM_PROFDATA_PATH NAMES llvm-profdata llvm-profdata-8 llvm-profdata-7 llvm-profdata-6)
|
|
||||||
find_program(LCOV_PATH lcov)
|
|
||||||
find_program(GENHTML_PATH genhtml)
|
|
||||||
|
|
||||||
# Variables
|
|
||||||
set(CMAKE_COVERAGE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/ccov)
|
|
||||||
|
|
||||||
# Common initialization/checks
|
|
||||||
if(CODE_COVERAGE AND NOT CODE_COVERAGE_ADDED)
|
|
||||||
set(CODE_COVERAGE_ADDED ON)
|
|
||||||
|
|
||||||
# Common Targets
|
|
||||||
add_custom_target(ccov-preprocessing
|
|
||||||
COMMAND ${CMAKE_COMMAND}
|
|
||||||
-E
|
|
||||||
make_directory
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}
|
|
||||||
DEPENDS ccov-clean)
|
|
||||||
|
|
||||||
if("${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang"
|
|
||||||
OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
|
||||||
# Messages
|
|
||||||
message(STATUS "Building with llvm Code Coverage Tools")
|
|
||||||
|
|
||||||
if(NOT LLVM_COV_PATH)
|
|
||||||
message(FATAL_ERROR "llvm-cov not found! Aborting.")
|
|
||||||
else()
|
|
||||||
# Version number checking for 'EXCLUDE' compatability
|
|
||||||
execute_process(COMMAND ${LLVM_COV_PATH} --version
|
|
||||||
OUTPUT_VARIABLE LLVM_COV_VERSION_CALL_OUTPUT)
|
|
||||||
string(REGEX MATCH
|
|
||||||
"[0-9]+\\.[0-9]+\\.[0-9]+"
|
|
||||||
LLVM_COV_VERSION
|
|
||||||
${LLVM_COV_VERSION_CALL_OUTPUT})
|
|
||||||
|
|
||||||
if(LLVM_COV_VERSION VERSION_LESS "7.0.0")
|
|
||||||
message(
|
|
||||||
WARNING
|
|
||||||
"target_code_coverage()/add_code_coverage_all_targets() 'EXCLUDE' option only available on llvm-cov >= 7.0.0"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Targets
|
|
||||||
add_custom_target(ccov-clean
|
|
||||||
COMMAND rm -f
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list
|
|
||||||
COMMAND rm -f
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/profraw.list)
|
|
||||||
|
|
||||||
# Used to get the shared object file list before doing the main all-processing
|
|
||||||
add_custom_target(ccov-libs
|
|
||||||
COMMAND ;
|
|
||||||
COMMENT "libs ready for coverage report.")
|
|
||||||
|
|
||||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
# Messages
|
|
||||||
message(STATUS "Building with lcov Code Coverage Tools")
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE)
|
|
||||||
string(TOUPPER ${CMAKE_BUILD_TYPE} upper_build_type)
|
|
||||||
if(NOT ${upper_build_type} STREQUAL "DEBUG")
|
|
||||||
message(
|
|
||||||
WARNING
|
|
||||||
"Code coverage results with an optimized (non-Debug) build may be misleading"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
message(
|
|
||||||
WARNING
|
|
||||||
"Code coverage results with an optimized (non-Debug) build may be misleading"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(NOT LCOV_PATH)
|
|
||||||
message(FATAL_ERROR "lcov not found! Aborting...")
|
|
||||||
endif()
|
|
||||||
if(NOT GENHTML_PATH)
|
|
||||||
message(FATAL_ERROR "genhtml not found! Aborting...")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Targets
|
|
||||||
add_custom_target(ccov-clean
|
|
||||||
COMMAND ${LCOV_PATH}
|
|
||||||
--directory
|
|
||||||
${CMAKE_BINARY_DIR}
|
|
||||||
--zerocounters)
|
|
||||||
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "Code coverage requires Clang or GCC. Aborting.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Adds code coverage instrumentation to a library, or instrumentation/targets
|
|
||||||
# for an executable target.
|
|
||||||
# ~~~
|
|
||||||
# EXECUTABLE ADDED TARGETS:
|
|
||||||
# GCOV/LCOV:
|
|
||||||
# ccov : Generates HTML code coverage report for every target added with 'AUTO' parameter.
|
|
||||||
# ccov-${TARGET_NAME} : Generates HTML code coverage report for the associated named target.
|
|
||||||
# ccov-all : Generates HTML code coverage report, merging every target added with 'ALL' parameter into a single detailed report.
|
|
||||||
#
|
|
||||||
# LLVM-COV:
|
|
||||||
# ccov : Generates HTML code coverage report for every target added with 'AUTO' parameter.
|
|
||||||
# ccov-report : Generates HTML code coverage report for every target added with 'AUTO' parameter.
|
|
||||||
# ccov-${TARGET_NAME} : Generates HTML code coverage report.
|
|
||||||
# ccov-report-${TARGET_NAME} : Prints to command line summary per-file coverage information.
|
|
||||||
# ccov-show-${TARGET_NAME} : Prints to command line detailed per-line coverage information.
|
|
||||||
# ccov-all : Generates HTML code coverage report, merging every target added with 'ALL' parameter into a single detailed report.
|
|
||||||
# ccov-all-report : Prints summary per-file coverage information for every target added with ALL' parameter to the command line.
|
|
||||||
#
|
|
||||||
# Required:
|
|
||||||
# TARGET_NAME - Name of the target to generate code coverage for.
|
|
||||||
# Optional:
|
|
||||||
# AUTO - Adds the target to the 'ccov' target so that it can be run in a batch with others easily. Effective on executable targets.
|
|
||||||
# ALL - Adds the target to the 'ccov-all' and 'ccov-all-report' targets, which merge several executable targets coverage data to a single report. Effective on executable targets.
|
|
||||||
# EXTERNAL - For GCC's lcov, allows the profiling of 'external' files from the processing directory
|
|
||||||
# EXCLUDE <REGEX_PATTERNS> - Excludes files of the patterns provided from coverage. **These do not copy to the 'all' targets.**
|
|
||||||
# OBJECTS <TARGETS> - For executables ONLY, if the provided targets are shared libraries, adds coverage information to the output
|
|
||||||
# ~~~
|
|
||||||
function(target_code_coverage TARGET_NAME)
|
|
||||||
# Argument parsing
|
|
||||||
set(options AUTO ALL EXTERNAL)
|
|
||||||
set(multi_value_keywords EXCLUDE OBJECTS)
|
|
||||||
cmake_parse_arguments(target_code_coverage
|
|
||||||
"${options}"
|
|
||||||
""
|
|
||||||
"${multi_value_keywords}"
|
|
||||||
${ARGN})
|
|
||||||
|
|
||||||
if(CODE_COVERAGE)
|
|
||||||
|
|
||||||
# Add code coverage instrumentation to the target's linker command
|
|
||||||
if("${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang"
|
|
||||||
OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
|
||||||
target_compile_options(
|
|
||||||
${TARGET_NAME}
|
|
||||||
PRIVATE -fprofile-instr-generate -fcoverage-mapping)
|
|
||||||
set_property(TARGET ${TARGET_NAME}
|
|
||||||
APPEND_STRING
|
|
||||||
PROPERTY LINK_FLAGS "-fprofile-instr-generate ")
|
|
||||||
set_property(TARGET ${TARGET_NAME}
|
|
||||||
APPEND_STRING
|
|
||||||
PROPERTY LINK_FLAGS "-fcoverage-mapping ")
|
|
||||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
target_compile_options(${TARGET_NAME}
|
|
||||||
PRIVATE -fprofile-arcs -ftest-coverage)
|
|
||||||
target_link_libraries(${TARGET_NAME} PRIVATE gcov)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Targets
|
|
||||||
get_target_property(target_type ${TARGET_NAME} TYPE)
|
|
||||||
|
|
||||||
# Add shared library to processing for 'all' targets
|
|
||||||
if(target_type STREQUAL "SHARED_LIBRARY" AND target_code_coverage_ALL)
|
|
||||||
if("${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang"
|
|
||||||
OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
|
||||||
add_custom_target(
|
|
||||||
ccov-run-${TARGET_NAME}
|
|
||||||
COMMAND echo
|
|
||||||
"-object=$<TARGET_FILE:${TARGET_NAME}>"
|
|
||||||
>>
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list
|
|
||||||
DEPENDS ccov-preprocessing ${TARGET_NAME})
|
|
||||||
|
|
||||||
if(NOT TARGET ccov-libs)
|
|
||||||
message(
|
|
||||||
FATAL_ERROR
|
|
||||||
"Calling target_code_coverage with 'ALL' must be after a call to 'add_code_coverage_all_targets'."
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_dependencies(ccov-libs ccov-run-${TARGET_NAME})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# For executables add targets to run and produce output
|
|
||||||
if(target_type STREQUAL "EXECUTABLE")
|
|
||||||
if("${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang"
|
|
||||||
OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
|
||||||
|
|
||||||
# If there are shared objects to also work with, generate the string to add them here
|
|
||||||
foreach(SO_TARGET ${target_code_coverage_OBJECTS})
|
|
||||||
# Check to see if the target is a shared object
|
|
||||||
if(TARGET ${SO_TARGET})
|
|
||||||
get_target_property(SO_TARGET_TYPE ${SO_TARGET} TYPE)
|
|
||||||
if(${SO_TARGET_TYPE} STREQUAL "SHARED_LIBRARY")
|
|
||||||
set(SO_OBJECTS ${SO_OBJECTS} -object=$<TARGET_FILE:${SO_TARGET}>)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# Run the executable, generating raw profile data
|
|
||||||
add_custom_target(
|
|
||||||
ccov-run-${TARGET_NAME}
|
|
||||||
COMMAND LLVM_PROFILE_FILE=${TARGET_NAME}.profraw
|
|
||||||
$<TARGET_FILE:${TARGET_NAME}>
|
|
||||||
COMMAND echo
|
|
||||||
"-object=$<TARGET_FILE:${TARGET_NAME}>"
|
|
||||||
>>
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list
|
|
||||||
COMMAND echo
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.profraw "
|
|
||||||
>>
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/profraw.list
|
|
||||||
DEPENDS ccov-preprocessing ccov-libs ${TARGET_NAME})
|
|
||||||
|
|
||||||
# Merge the generated profile data so llvm-cov can process it
|
|
||||||
add_custom_target(ccov-processing-${TARGET_NAME}
|
|
||||||
COMMAND ${LLVM_PROFDATA_PATH}
|
|
||||||
merge
|
|
||||||
-sparse
|
|
||||||
${TARGET_NAME}.profraw
|
|
||||||
-o
|
|
||||||
${TARGET_NAME}.profdata
|
|
||||||
DEPENDS ccov-run-${TARGET_NAME})
|
|
||||||
|
|
||||||
# Ignore regex only works on LLVM >= 7
|
|
||||||
if(LLVM_COV_VERSION VERSION_GREATER_EQUAL "7.0.0")
|
|
||||||
foreach(EXCLUDE_ITEM ${target_code_coverage_EXCLUDE})
|
|
||||||
set(EXCLUDE_REGEX ${EXCLUDE_REGEX}
|
|
||||||
-ignore-filename-regex='${EXCLUDE_ITEM}')
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Print out details of the coverage information to the command line
|
|
||||||
add_custom_target(ccov-show-${TARGET_NAME}
|
|
||||||
COMMAND ${LLVM_COV_PATH}
|
|
||||||
show
|
|
||||||
$<TARGET_FILE:${TARGET_NAME}>
|
|
||||||
${SO_OBJECTS}
|
|
||||||
-instr-profile=${TARGET_NAME}.profdata
|
|
||||||
-show-line-counts-or-regions
|
|
||||||
${EXCLUDE_REGEX}
|
|
||||||
DEPENDS ccov-processing-${TARGET_NAME})
|
|
||||||
|
|
||||||
# Print out a summary of the coverage information to the command line
|
|
||||||
add_custom_target(ccov-report-${TARGET_NAME}
|
|
||||||
COMMAND ${LLVM_COV_PATH}
|
|
||||||
report
|
|
||||||
$<TARGET_FILE:${TARGET_NAME}>
|
|
||||||
${SO_OBJECTS}
|
|
||||||
-instr-profile=${TARGET_NAME}.profdata
|
|
||||||
${EXCLUDE_REGEX}
|
|
||||||
DEPENDS ccov-processing-${TARGET_NAME})
|
|
||||||
|
|
||||||
# Generates HTML output of the coverage information for perusal
|
|
||||||
add_custom_target(
|
|
||||||
ccov-${TARGET_NAME}
|
|
||||||
COMMAND ${LLVM_COV_PATH}
|
|
||||||
show
|
|
||||||
$<TARGET_FILE:${TARGET_NAME}>
|
|
||||||
${SO_OBJECTS}
|
|
||||||
-instr-profile=${TARGET_NAME}.profdata
|
|
||||||
-show-line-counts-or-regions
|
|
||||||
-output-dir=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/${TARGET_NAME}
|
|
||||||
-format="html"
|
|
||||||
${EXCLUDE_REGEX}
|
|
||||||
DEPENDS ccov-processing-${TARGET_NAME})
|
|
||||||
|
|
||||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
set(COVERAGE_INFO
|
|
||||||
"${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/${TARGET_NAME}.info")
|
|
||||||
|
|
||||||
# Run the executable, generating coverage information
|
|
||||||
add_custom_target(ccov-run-${TARGET_NAME}
|
|
||||||
COMMAND $<TARGET_FILE:${TARGET_NAME}>
|
|
||||||
DEPENDS ccov-preprocessing ${TARGET_NAME})
|
|
||||||
|
|
||||||
# Generate exclusion string for use
|
|
||||||
foreach(EXCLUDE_ITEM ${target_code_coverage_EXCLUDE})
|
|
||||||
set(EXCLUDE_REGEX
|
|
||||||
${EXCLUDE_REGEX}
|
|
||||||
--remove
|
|
||||||
${COVERAGE_INFO}
|
|
||||||
'${EXCLUDE_ITEM}')
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
if(EXCLUDE_REGEX)
|
|
||||||
set(EXCLUDE_COMMAND
|
|
||||||
${LCOV_PATH}
|
|
||||||
${EXCLUDE_REGEX}
|
|
||||||
--output-file
|
|
||||||
${COVERAGE_INFO})
|
|
||||||
else()
|
|
||||||
set(EXCLUDE_COMMAND ;)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT ${target_code_coverage_EXTERNAL})
|
|
||||||
set(EXTERNAL_OPTION --no-external)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Generates HTML output of the coverage information for perusal
|
|
||||||
add_custom_target(
|
|
||||||
ccov-${TARGET_NAME}
|
|
||||||
COMMAND ${CMAKE_COMMAND}
|
|
||||||
-E
|
|
||||||
remove
|
|
||||||
${COVERAGE_INFO}
|
|
||||||
COMMAND ${LCOV_PATH}
|
|
||||||
--directory
|
|
||||||
${CMAKE_BINARY_DIR}
|
|
||||||
--zerocounters
|
|
||||||
COMMAND $<TARGET_FILE:${TARGET_NAME}>
|
|
||||||
COMMAND ${LCOV_PATH}
|
|
||||||
--directory
|
|
||||||
${CMAKE_BINARY_DIR}
|
|
||||||
--base-directory
|
|
||||||
${CMAKE_SOURCE_DIR}
|
|
||||||
--capture
|
|
||||||
${EXTERNAL_OPTION}
|
|
||||||
--output-file
|
|
||||||
${COVERAGE_INFO}
|
|
||||||
COMMAND ${EXCLUDE_COMMAND}
|
|
||||||
COMMAND ${GENHTML_PATH}
|
|
||||||
-o
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/${TARGET_NAME}
|
|
||||||
${COVERAGE_INFO}
|
|
||||||
DEPENDS ccov-preprocessing ${TARGET_NAME})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_custom_command(
|
|
||||||
TARGET ccov-${TARGET_NAME} POST_BUILD
|
|
||||||
COMMAND ;
|
|
||||||
COMMENT
|
|
||||||
"Open ${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/${TARGET_NAME}/index.html in your browser to view the coverage report."
|
|
||||||
)
|
|
||||||
|
|
||||||
# AUTO
|
|
||||||
if(target_code_coverage_AUTO)
|
|
||||||
if(NOT TARGET ccov)
|
|
||||||
add_custom_target(ccov)
|
|
||||||
endif()
|
|
||||||
add_dependencies(ccov ccov-${TARGET_NAME})
|
|
||||||
|
|
||||||
if(NOT CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
if(NOT TARGET ccov-report)
|
|
||||||
add_custom_target(ccov-report)
|
|
||||||
endif()
|
|
||||||
add_dependencies(ccov-report ccov-report-${TARGET_NAME})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# ALL
|
|
||||||
if(target_code_coverage_ALL)
|
|
||||||
if(NOT TARGET ccov-all-processing)
|
|
||||||
message(
|
|
||||||
FATAL_ERROR
|
|
||||||
"Calling target_code_coverage with 'ALL' must be after a call to 'add_code_coverage_all_targets'."
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_dependencies(ccov-all-processing ccov-run-${TARGET_NAME})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Adds code coverage instrumentation to all targets in the current directory and
|
|
||||||
# any subdirectories. To add coverage instrumentation to only specific targets,
|
|
||||||
# use `target_code_coverage`.
|
|
||||||
function(add_code_coverage)
|
|
||||||
if("${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang"
|
|
||||||
OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
|
||||||
add_compile_options(-fprofile-instr-generate -fcoverage-mapping)
|
|
||||||
add_link_options(-fprofile-instr-generate -fcoverage-mapping)
|
|
||||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
add_compile_options(-fprofile-arcs -ftest-coverage)
|
|
||||||
link_libraries(gcov)
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Adds the 'ccov-all' type targets that calls all targets added via
|
|
||||||
# `target_code_coverage` with the `ALL` parameter, but merges all the coverage
|
|
||||||
# data from them into a single large report instead of the numerous smaller
|
|
||||||
# reports.
|
|
||||||
# ~~~
|
|
||||||
# Optional:
|
|
||||||
# EXCLUDE <REGEX_PATTERNS> - Excludes files of the regex patterns provided from coverage.
|
|
||||||
# ~~~
|
|
||||||
function(add_code_coverage_all_targets)
|
|
||||||
# Argument parsing
|
|
||||||
set(multi_value_keywords EXCLUDE)
|
|
||||||
cmake_parse_arguments(add_code_coverage_all_targets
|
|
||||||
""
|
|
||||||
""
|
|
||||||
"${multi_value_keywords}"
|
|
||||||
${ARGN})
|
|
||||||
|
|
||||||
if(CODE_COVERAGE)
|
|
||||||
if("${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang"
|
|
||||||
OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
|
||||||
|
|
||||||
# Merge the profile data for all of the run executables
|
|
||||||
add_custom_target(
|
|
||||||
ccov-all-processing
|
|
||||||
COMMAND ${LLVM_PROFDATA_PATH}
|
|
||||||
merge
|
|
||||||
-o
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.profdata
|
|
||||||
-sparse
|
|
||||||
`cat
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/profraw.list`)
|
|
||||||
|
|
||||||
# Regex exclude only available for LLVM >= 7
|
|
||||||
if(LLVM_COV_VERSION VERSION_GREATER_EQUAL "7.0.0")
|
|
||||||
foreach(EXCLUDE_ITEM ${add_code_coverage_all_targets_EXCLUDE})
|
|
||||||
set(EXCLUDE_REGEX ${EXCLUDE_REGEX}
|
|
||||||
-ignore-filename-regex='${EXCLUDE_ITEM}')
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Print summary of the code coverage information to the command line
|
|
||||||
add_custom_target(
|
|
||||||
ccov-all-report
|
|
||||||
COMMAND
|
|
||||||
${LLVM_COV_PATH}
|
|
||||||
report
|
|
||||||
`cat
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list`
|
|
||||||
-instr-profile=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.profdata
|
|
||||||
${EXCLUDE_REGEX}
|
|
||||||
DEPENDS ccov-all-processing)
|
|
||||||
|
|
||||||
# Export coverage information so continuous integration tools (e.g. Jenkins) can consume it
|
|
||||||
add_custom_target(
|
|
||||||
ccov-all-export
|
|
||||||
COMMAND
|
|
||||||
${LLVM_COV_PATH}
|
|
||||||
export
|
|
||||||
`cat
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list`
|
|
||||||
-instr-profile=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.profdata
|
|
||||||
-format="text"
|
|
||||||
${EXCLUDE_REGEX} > ${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/coverage.json
|
|
||||||
DEPENDS ccov-all-processing)
|
|
||||||
|
|
||||||
# Generate HTML output of all added targets for perusal
|
|
||||||
add_custom_target(
|
|
||||||
ccov-all
|
|
||||||
COMMAND
|
|
||||||
${LLVM_COV_PATH}
|
|
||||||
show
|
|
||||||
`cat
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/binaries.list`
|
|
||||||
-instr-profile=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.profdata
|
|
||||||
-show-line-counts-or-regions
|
|
||||||
-output-dir=${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged
|
|
||||||
-format="html"
|
|
||||||
${EXCLUDE_REGEX}
|
|
||||||
DEPENDS ccov-all-processing)
|
|
||||||
|
|
||||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
set(COVERAGE_INFO "${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged.info")
|
|
||||||
|
|
||||||
# Nothing required for gcov
|
|
||||||
add_custom_target(ccov-all-processing COMMAND ;)
|
|
||||||
|
|
||||||
# Exclusion regex string creation
|
|
||||||
foreach(EXCLUDE_ITEM ${add_code_coverage_all_targets_EXCLUDE})
|
|
||||||
set(EXCLUDE_REGEX
|
|
||||||
${EXCLUDE_REGEX}
|
|
||||||
--remove
|
|
||||||
${COVERAGE_INFO}
|
|
||||||
'${EXCLUDE_ITEM}')
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
if(EXCLUDE_REGEX)
|
|
||||||
set(EXCLUDE_COMMAND
|
|
||||||
${LCOV_PATH}
|
|
||||||
${EXCLUDE_REGEX}
|
|
||||||
--output-file
|
|
||||||
${COVERAGE_INFO})
|
|
||||||
else()
|
|
||||||
set(EXCLUDE_COMMAND ;)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Generates HTML output of all targets for perusal
|
|
||||||
add_custom_target(ccov-all
|
|
||||||
COMMAND ${LCOV_PATH}
|
|
||||||
--directory
|
|
||||||
${CMAKE_BINARY_DIR}
|
|
||||||
--capture
|
|
||||||
--output-file
|
|
||||||
${COVERAGE_INFO}
|
|
||||||
COMMAND ${EXCLUDE_COMMAND}
|
|
||||||
COMMAND ${GENHTML_PATH}
|
|
||||||
-o
|
|
||||||
${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged
|
|
||||||
${COVERAGE_INFO}
|
|
||||||
COMMAND ${CMAKE_COMMAND}
|
|
||||||
-E
|
|
||||||
remove
|
|
||||||
${COVERAGE_INFO}
|
|
||||||
DEPENDS ccov-all-processing)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_custom_command(
|
|
||||||
TARGET ccov-all POST_BUILD
|
|
||||||
COMMAND ;
|
|
||||||
COMMENT
|
|
||||||
"Open ${CMAKE_COVERAGE_OUTPUT_DIRECTORY}/all-merged/index.html in your browser to view the coverage report."
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
@ -1,99 +0,0 @@
|
|||||||
#
|
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
||||||
#
|
|
||||||
option(CODECHECKER "Turns on codecheck processing if it is found." OFF)
|
|
||||||
option(CODECHECKER_STORE "Store results on central codechecker server" OFF)
|
|
||||||
option(CODECHECKER_RUN "Name of the codechecker run" "run-1")
|
|
||||||
option(CODECHECKER_URL "URL and product link to codechecker server" "http://localhost:8001/Default")
|
|
||||||
|
|
||||||
find_program(CODECHECKER_VENV_PATH
|
|
||||||
NAME activate
|
|
||||||
PATHS ~/Apps/codechecker/venv/bin/
|
|
||||||
~/codechecker/venv/bin/
|
|
||||||
/usr/src/codechecker/venv/bin/
|
|
||||||
)
|
|
||||||
|
|
||||||
find_program(CODECHECKER_PATH
|
|
||||||
NAME CodeChecker
|
|
||||||
PATHS ~/Apps/codechecker/build/CodeChecker/bin/
|
|
||||||
~/codechecker/build/CodeChecker/bin/
|
|
||||||
/usr/src/~/codechecker/build/CodeChecker/bin/
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
execute_process(
|
|
||||||
COMMAND git rev-parse --abbrev-ref HEAD
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
||||||
OUTPUT_VARIABLE CODECHECK_GIT_BRANCH
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (CODECHECKER_PATH AND CODECHECKER_VENV_PATH)
|
|
||||||
message(STATUS "CodeChecker found")
|
|
||||||
else()
|
|
||||||
message(STATUS "CodeChecker not found")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# export compile commands to json file to be used by atom c++ ide (clangd)
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
|
||||||
set(CODECHECKER_COMPILE_COMMANDS "${CMAKE_BINARY_DIR}/compile_commands.json")
|
|
||||||
|
|
||||||
# check if a skip file exists
|
|
||||||
if(EXISTS ${CMAKE_SOURCE_DIR}/codecheck.skip)
|
|
||||||
set(CODECHECKER_SKIP "-i${CMAKE_SOURCE_DIR}/codecheck.skip")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# output directory for codecheck analysis
|
|
||||||
set(CODECHECKER_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/codechecker_results)
|
|
||||||
|
|
||||||
# html output directory
|
|
||||||
set(CODECHECKER_HTML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/codechecker_html)
|
|
||||||
|
|
||||||
# Common initialization/checks
|
|
||||||
if(CODECHECKER AND CODECHECKER_PATH AND CODECHECKER_VENV_PATH AND NOT CODECHECKER_ADDED)
|
|
||||||
set(CODECHECKER_ADDED ON)
|
|
||||||
|
|
||||||
add_custom_target(codechecker
|
|
||||||
COMMAND . ${CODECHECKER_VENV_PATH}\;
|
|
||||||
${CODECHECKER_PATH}
|
|
||||||
analyze
|
|
||||||
${CODECHECKER_SKIP}
|
|
||||||
-e sensitive
|
|
||||||
-j 4
|
|
||||||
-o ${CODECHECKER_OUTPUT_DIRECTORY}
|
|
||||||
${CODECHECKER_COMPILE_COMMANDS}
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_target(codechecker-clean
|
|
||||||
COMMAND rm -rf ${CODECHECKER_OUTPUT_DIRECTORY}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
add_custom_target(codechecker-html
|
|
||||||
COMMAND . ${CODECHECKER_VENV_PATH}\;
|
|
||||||
${CODECHECKER_PATH}
|
|
||||||
parse
|
|
||||||
${CODECHECKER_OUTPUT_DIRECTORY}
|
|
||||||
-e html
|
|
||||||
-o ${CODECHECKER_HTML_OUTPUT_DIRECTORY}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (CODECHECKER_STORE)
|
|
||||||
add_custom_target(codechecker-store
|
|
||||||
COMMAND . ${CODECHECKER_VENV_PATH}\;
|
|
||||||
${CODECHECKER_PATH}
|
|
||||||
store
|
|
||||||
--tag ${CODECHECK_GIT_BRANCH}
|
|
||||||
-n ${CODECHECKER_RUN}
|
|
||||||
--url ${CODECHECKER_URL}
|
|
||||||
${CODECHECKER_OUTPUT_DIRECTORY}
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
endif()
|
|
23
cmake/Modules/compdb.cmake
Normal file
23
cmake/Modules/compdb.cmake
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
find_program(COMPDB_PATH
|
||||||
|
NAME compdb
|
||||||
|
PATHS ~/.local/bin/
|
||||||
|
/bin
|
||||||
|
/sbin
|
||||||
|
/usr/bin
|
||||||
|
/usr/sbin
|
||||||
|
/usr/local/bin
|
||||||
|
/usr/local/sbin
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (COMPDB_PATH)
|
||||||
|
IF(NOT TARGET COMPD)
|
||||||
|
add_custom_target(COMPD
|
||||||
|
ALL
|
||||||
|
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
COMMAND ${COMPDB_PATH} -p ${CMAKE_CURRENT_BINARY_DIR} list >compile_commands.json
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
@ -1,46 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2018 by George Cave - gcave@stablecoder.ca
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
||||||
# use this file except in compliance with the License. You may obtain a copy of
|
|
||||||
# the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations under
|
|
||||||
# the License.
|
|
||||||
|
|
||||||
option(ENABLE_ALL_WARNINGS "Compile with all warnings for the major compilers."
|
|
||||||
OFF)
|
|
||||||
option(ENABLE_EFFECTIVE_CXX "Enable Effective C++ warnings." OFF)
|
|
||||||
|
|
||||||
if(ENABLE_ALL_WARNINGS)
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
# GCC
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
|
|
||||||
elseif("${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang"
|
|
||||||
OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
|
||||||
# Clang
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
|
|
||||||
elseif(MSVC)
|
|
||||||
# MSVC
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ENABLE_EFFECTIVE_CXX)
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
|
||||||
# GCC
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weffc++")
|
|
||||||
elseif("${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang"
|
|
||||||
OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
|
||||||
# Clang
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weffc++")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
@ -1,13 +0,0 @@
|
|||||||
include(c++-standards)
|
|
||||||
include(compiler-options)
|
|
||||||
include(sanitizers)
|
|
||||||
include(codecheck)
|
|
||||||
include(code-coverage)
|
|
||||||
include(tools)
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
include(CTest)
|
|
||||||
include(doxygen)
|
|
||||||
include(ProcessGIT)
|
|
||||||
include(CheckParent)
|
|
||||||
include(add_my_test)
|
|
||||||
include(TestBigEndian)
|
|
@ -1,11 +0,0 @@
|
|||||||
include(defaultIncludes)
|
|
||||||
find_package(Git)
|
|
||||||
|
|
||||||
|
|
||||||
enable_testing()
|
|
||||||
cxx_14()
|
|
||||||
build_docs(PROCESS_DOXYFILE DOXYFILE_PATH "docs/Doxyfile.in" )
|
|
||||||
cppcheck("--enable=warning,performance,portability,missingInclude;--template=\"[{severity}][{id}] {message} {callstack} \(On {file}:{line}\)\";--suppress=missingIncludeSystem;--suppress=*:${PROJECT_SOURCE_DIR}/libs/*;--quiet;--verbose;--force")
|
|
||||||
|
|
||||||
add_code_coverage_all_targets(EXCLUDE ${PROJECT_SOURCE_DIR}/libs/* ${PROJECT_SOURCE_DIR}/test/*)
|
|
||||||
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
|
|
@ -71,14 +71,14 @@ function(build_docs)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT build_docs_DOXYFILE_PATH)
|
if(NOT build_docs_DOXYFILE_PATH)
|
||||||
set(DOXYFILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile)
|
set(DOXYFILE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile")
|
||||||
elseif(EXISTS ${build_docs_DOXYFILE_PATH})
|
elseif(EXISTS "${build_docs_DOXYFILE_PATH}")
|
||||||
set(DOXYFILE_PATH ${build_docs_DOXYFILE_PATH})
|
set(DOXYFILE_PATH "${build_docs_DOXYFILE_PATH}")
|
||||||
else()
|
else()
|
||||||
set(DOXYFILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${build_docs_DOXYFILE_PATH})
|
set(DOXYFILE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${build_docs_DOXYFILE_PATH}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT EXISTS ${DOXYFILE_PATH})
|
if(NOT EXISTS "${DOXYFILE_PATH}")
|
||||||
message(
|
message(
|
||||||
SEND_ERROR
|
SEND_ERROR
|
||||||
"Could not find Doxyfile to use for procesing documentation at: ${DOXYFILE_PATH}"
|
"Could not find Doxyfile to use for procesing documentation at: ${DOXYFILE_PATH}"
|
||||||
@ -87,19 +87,19 @@ function(build_docs)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(build_docs_PROCESS_DOXYFILE)
|
if(build_docs_PROCESS_DOXYFILE)
|
||||||
set(DOXYFILE ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
|
set(DOXYFILE "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
|
||||||
configure_file(${DOXYFILE_PATH} ${DOXYFILE} @ONLY)
|
configure_file("${DOXYFILE_PATH}" "${DOXYFILE}" @ONLY)
|
||||||
else()
|
else()
|
||||||
set(DOXYFILE ${DOXYFILE_PATH})
|
set(DOXYFILE "${DOXYFILE_PATH}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(build_docs_OUTPUT_DIR)
|
if(build_docs_OUTPUT_DIR)
|
||||||
set(OUT_DIR ${build_docs_OUTPUT_DIR})
|
set(OUT_DIR "${build_docs_OUTPUT_DIR}")
|
||||||
else()
|
else()
|
||||||
set(OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/doc)
|
set(OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
file(MAKE_DIRECTORY ${OUT_DIR})
|
file(MAKE_DIRECTORY "${OUT_DIR}")
|
||||||
|
|
||||||
if(build_docs_TARGET_NAME)
|
if(build_docs_TARGET_NAME)
|
||||||
set(TARGET_NAME ${build_docs_TARGET_NAME})
|
set(TARGET_NAME ${build_docs_TARGET_NAME})
|
||||||
@ -107,10 +107,12 @@ function(build_docs)
|
|||||||
set(TARGET_NAME doc-${PROJECT_NAME})
|
set(TARGET_NAME doc-${PROJECT_NAME})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
IF(NOT TARGET ${TARGET_NAME})
|
||||||
add_custom_target(${TARGET_NAME}
|
add_custom_target(${TARGET_NAME}
|
||||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE}
|
COMMAND ${DOXYGEN_EXECUTABLE} "${DOXYFILE}"
|
||||||
WORKING_DIRECTORY ${OUT_DIR}
|
WORKING_DIRECTORY "${OUT_DIR}"
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
if(build_docs_ADD_TO_DOC)
|
if(build_docs_ADD_TO_DOC)
|
||||||
if(NOT TARGET doc)
|
if(NOT TARGET doc)
|
||||||
|
@ -1,87 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2018 by George Cave - gcave@stablecoder.ca
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
||||||
# use this file except in compliance with the License. You may obtain a copy of
|
|
||||||
# the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations under
|
|
||||||
# the License.
|
|
||||||
|
|
||||||
set(
|
|
||||||
USE_SANITIZER
|
|
||||||
""
|
|
||||||
CACHE
|
|
||||||
STRING
|
|
||||||
"Compile with a sanitizer. Options are: Address, Memory, MemoryWithOrigins, Undefined, Thread, Leak, 'Address;Undefined'"
|
|
||||||
)
|
|
||||||
|
|
||||||
function(append value)
|
|
||||||
foreach(variable ${ARGN})
|
|
||||||
set(${variable} "${${variable}} ${value}" PARENT_SCOPE)
|
|
||||||
endforeach(variable)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
if(USE_SANITIZER)
|
|
||||||
append("-fno-omit-frame-pointer" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
|
||||||
|
|
||||||
if(UNIX)
|
|
||||||
|
|
||||||
if(uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
|
|
||||||
append("-O1" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(USE_SANITIZER MATCHES "([Aa]ddress);([Uu]ndefined)"
|
|
||||||
OR USE_SANITIZER MATCHES "([Uu]ndefined);([Aa]ddress)")
|
|
||||||
message(STATUS "Building with Address, Undefined sanitizers")
|
|
||||||
append("-fsanitize=address,undefined" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
|
||||||
elseif("${USE_SANITIZER}" MATCHES "([Aa]ddress)")
|
|
||||||
# Optional: -fno-optimize-sibling-calls -fsanitize-address-use-after-scope
|
|
||||||
message(STATUS "Building with Address sanitizer")
|
|
||||||
append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
|
||||||
elseif(USE_SANITIZER MATCHES "([Mm]emory([Ww]ith[Oo]rigins)?)")
|
|
||||||
# Optional: -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2
|
|
||||||
append("-fsanitize=memory" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
|
||||||
if(USE_SANITIZER MATCHES "([Mm]emory[Ww]ith[Oo]rigins)")
|
|
||||||
message(STATUS "Building with MemoryWithOrigins sanitizer")
|
|
||||||
append("-fsanitize-memory-track-origins" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
|
||||||
else()
|
|
||||||
message(STATUS "Building with Memory sanitizer")
|
|
||||||
endif()
|
|
||||||
elseif(USE_SANITIZER MATCHES "([Uu]ndefined)")
|
|
||||||
message(STATUS "Building with Undefined sanitizer")
|
|
||||||
append("-fsanitize=undefined" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
|
||||||
if(EXISTS "${BLACKLIST_FILE}")
|
|
||||||
append("-fsanitize-blacklist=${BLACKLIST_FILE}" CMAKE_C_FLAGS
|
|
||||||
CMAKE_CXX_FLAGS)
|
|
||||||
endif()
|
|
||||||
elseif(USE_SANITIZER MATCHES "([Tt]hread)")
|
|
||||||
message(STATUS "Building with Thread sanitizer")
|
|
||||||
append("-fsanitize=thread" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
|
||||||
elseif(USE_SANITIZER MATCHES "([Ll]eak)")
|
|
||||||
message(STATUS "Building with Leak sanitizer")
|
|
||||||
append("-fsanitize=leak" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
|
||||||
else()
|
|
||||||
message(
|
|
||||||
FATAL_ERROR "Unsupported value of USE_SANITIZER: ${USE_SANITIZER}")
|
|
||||||
endif()
|
|
||||||
elseif(MSVC)
|
|
||||||
if(USE_SANITIZER MATCHES "([Aa]ddress)")
|
|
||||||
message(STATUS "Building with Address sanitizer")
|
|
||||||
append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
|
|
||||||
else()
|
|
||||||
message(
|
|
||||||
FATAL_ERROR
|
|
||||||
"This sanitizer not yet supported in the MSVC environment: ${USE_SANITIZER}"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "USE_SANITIZER is not supported on this platform.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
endif()
|
|
@ -1,94 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2018 by George Cave - gcave@stablecoder.ca
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
||||||
# use this file except in compliance with the License. You may obtain a copy of
|
|
||||||
# the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
# License for the specific language governing permissions and limitations under
|
|
||||||
# the License.
|
|
||||||
|
|
||||||
option(CLANG_TIDY "Turns on clang-tidy processing if it is found." OFF)
|
|
||||||
option(IWYU "Turns on include-what-you-use processing if it is found." OFF)
|
|
||||||
option(CPPCHECK "Turns on cppcheck processing if it is found." OFF)
|
|
||||||
|
|
||||||
# Adds clang-tidy checks to the compilation, with the given arguments being used
|
|
||||||
# as the options set.
|
|
||||||
macro(clang_tidy)
|
|
||||||
if(CLANG_TIDY AND CLANG_TIDY_EXE)
|
|
||||||
set(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY_EXE} ${ARGN})
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Adds include_what_you_use to the compilation, with the given arguments being
|
|
||||||
# used as the options set.
|
|
||||||
macro(include_what_you_use)
|
|
||||||
if(IWYU AND IWYU_EXE)
|
|
||||||
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "${IWYU_EXE};${ARGN}")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
# Adds cppcheck to the compilation, with the given arguments being used as the
|
|
||||||
# options set.
|
|
||||||
macro(cppcheck)
|
|
||||||
if(CPPCHECK AND CPPCHECK_EXE)
|
|
||||||
set(CMAKE_CXX_CPPCHECK "${CPPCHECK_EXE};${ARGN}")
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
find_program(CLANG_TIDY_EXE NAMES clang-tidy clang-tidy-8 clang-tidy-7 clang-tidy-6)
|
|
||||||
if(CLANG_TIDY_EXE)
|
|
||||||
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
|
|
||||||
if(NOT CLANG_TIDY)
|
|
||||||
message(STATUS "clang-tidy NOT ENABLED via 'CLANG_TIDY' variable!")
|
|
||||||
set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) # delete it
|
|
||||||
endif()
|
|
||||||
elseif(CLANG_TIDY)
|
|
||||||
message(SEND_ERROR "Cannot enable clang-tidy, as executable not found!")
|
|
||||||
set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) # delete it
|
|
||||||
else()
|
|
||||||
message(STATUS "clang-tidy not found!")
|
|
||||||
set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) # delete it
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_program(IWYU_EXE NAMES "include-what-you-use")
|
|
||||||
if(IWYU_EXE)
|
|
||||||
message(STATUS "include-what-you-use found: ${IWYU_EXE}")
|
|
||||||
if(NOT IWYU)
|
|
||||||
message(STATUS "include-what-you-use NOT ENABLED via 'IWYU' variable!")
|
|
||||||
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "" CACHE STRING "" FORCE) # delete it
|
|
||||||
endif()
|
|
||||||
elseif(IWYU)
|
|
||||||
message(
|
|
||||||
SEND_ERROR "Cannot enable include-what-you-use, as executable not found!")
|
|
||||||
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "" CACHE STRING "" FORCE) # delete it
|
|
||||||
else()
|
|
||||||
message(STATUS "include-what-you-use not found!")
|
|
||||||
set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "" CACHE STRING "" FORCE) # delete it
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_program(CPPCHECK_EXE NAMES "cppcheck")
|
|
||||||
if(CPPCHECK_EXE)
|
|
||||||
message(STATUS "cppcheck found: ${CPPCHECK_EXE}")
|
|
||||||
if(CPPCHECK)
|
|
||||||
set(
|
|
||||||
CMAKE_CXX_CPPCHECK
|
|
||||||
"${CPPCHECK_EXE};--enable=warning,performance,portability,missingInclude;--template=\"[{severity}][{id}] {message} {callstack} \(On {file}:{line}\)\";--suppress=missingIncludeSystem;--quiet;--verbose;--force"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(NOT CPPCHECK)
|
|
||||||
message(STATUS "cppcheck NOT ENABLED via 'CPPCHECK' variable!")
|
|
||||||
set(CMAKE_CXX_CPPCHECK "" CACHE STRING "" FORCE) # delete it
|
|
||||||
endif()
|
|
||||||
elseif(CPPCHECK)
|
|
||||||
message(SEND_ERROR "Cannot enable cppcheck, as executable not found!")
|
|
||||||
set(CMAKE_CXX_CPPCHECK "" CACHE STRING "" FORCE) # delete it
|
|
||||||
else()
|
|
||||||
message(STATUS "cppcheck not found!")
|
|
||||||
set(CMAKE_CXX_CPPCHECK "" CACHE STRING "" FORCE) # delete it
|
|
||||||
endif()
|
|
Loading…
Reference in New Issue
Block a user