From 36835df7f02cb5ebad095e6b5b80435caff85951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Lalik?= Date: Thu, 5 May 2022 21:34:32 +0200 Subject: [PATCH] Add hook to create ccov target each time that add_ex.. and add_lib... is called --- README.md | 16 +++++++++ code-coverage.cmake | 42 +++++++++++++++++++++++ example/code-coverage-hook/CMakeLists.txt | 31 +++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 example/code-coverage-hook/CMakeLists.txt diff --git a/README.md b/README.md index a7da1da..319be02 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ This is a collection of quite useful scripts that expand the possibilities for b - [1b - Via target commands](#1b---via-target-commands) - [Example 2: Target instrumented, but with regex pattern of files to be excluded from report](#example-2-target-instrumented-but-with-regex-pattern-of-files-to-be-excluded-from-report) - [Example 3: Target added to the 'ccov' and 'ccov-all' targets](#example-3-target-added-to-the-ccov-and-ccov-all-targets) + - [Example 4: Hook all targets](#example-4-hook-all-targets) - [AFL Fuzzing Instrumentation `afl-fuzzing.cmake`](#afl-fuzzing-instrumentation-afl-fuzzingcmake) - [Usage](#usage-1) - [Compiler Options `compiler-options.cmake`](#compiler-options-compiler-optionscmake) @@ -136,6 +137,7 @@ To enable any code coverage instrumentation/targets, the single CMake option of 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()`, where the target is given and thus only that target is instrumented. This applies to both libraries and executables. +3. Automatically add coverage for each target with `-DCCOV_TARGETS_HOOK=On` and `-DCCOV_TARGETS_HOOK_ARGS=...` for default values, requires `add_code_coverage()` or similar. To add coverage targets, such as calling `make ccov` to generate the actual coverage information for perusal or consumption, call `target_code_coverage()` on an *executable* target. @@ -184,6 +186,20 @@ 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. ``` +#### Example 4: Hook all targets +``` +# this could be as well command line argument +set(CCOV_TARGETS_HOOK ON) # enable 'add_executable' and 'add_library' hooks +set(CCOV_TARGETS_HOOK_ARGS ALL AUTO) # set default arguments for coverage + +add_code_coverage() # Adds instrumentation to all targets + +add_library(theLib lib.cpp) # ccov-theLib target will be add + +add_executable(theExe main.cpp) # ccov-theExe target will be add +target_link_libraries(theExe PRIVATE theLib) +``` + ## AFL Fuzzing Instrumentation [`afl-fuzzing.cmake`](afl-fuzzing.cmake) > American fuzzy lop is a security-oriented fuzzer that employs a novel type of compile-time instrumentation and genetic algorithms to automatically discover clean, interesting test cases that trigger new internal states in the targeted binary. This substantially improves the functional coverage for the fuzzed code. The compact synthesized corpora produced by the tool are also useful for seeding other, more labor- or resource-intensive testing regimes down the road. diff --git a/code-coverage.cmake b/code-coverage.cmake index be8ab06..2b24e0b 100644 --- a/code-coverage.cmake +++ b/code-coverage.cmake @@ -72,6 +72,20 @@ # 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. # ~~~ +# +# Example 4: Hook all targets +# +# ~~~ +# set(CCOV_TARGETS_HOOK ON) # enable 'add_executable' and 'add_library' hooks +# set(CCOV_TARGETS_HOOK_ARGS ALL AUTO) # set default arguments for coverage +# +# add_code_coverage() # Adds instrumentation to all targets +# +# add_library(theLib lib.cpp) # ccov-theLib target will be add +# +# add_executable(theExe main.cpp) # ccov-theExe target will be add +# target_link_libraries(theExe PRIVATE theLib) +# ~~~ # Options option( @@ -79,6 +93,15 @@ option( "Builds targets with code coverage instrumentation. (Requires GCC or Clang)" OFF) +option( + CCOV_TARGETS_HOOK + "Autocapture all new targets." + OFF) + +option( + CCOV_TARGETS_HOOK_ARGS + "Default arguments for all hooked targets.") + # Programs find_program(LLVM_COV_PATH llvm-cov) find_program(LLVM_PROFDATA_PATH llvm-profdata) @@ -181,6 +204,25 @@ if(CODE_COVERAGE AND NOT CODE_COVERAGE_ADDED) else() message(FATAL_ERROR "Code coverage requires Clang or GCC. Aborting.") endif() + + if (CCOV_TARGETS_HOOK) + if (COMMAND _add_executable) + message(FATAL_ERROR "add_executable was already redefined. Only one redefinitions is allowed.") + endif() + macro(add_executable) + _add_executable(${ARGV}) + target_code_coverage(${ARGV0} ${CCOV_TARGETS_HOOK_ARGS}) + endmacro(add_executable) + + if (COMMAND _add_library) + message(FATAL_ERROR "add_library was already redefined. Only one redefinitions is allowed.") + endif() + macro(add_library) + _add_library(${ARGV}) + target_code_coverage(${ARGV0} ${CCOV_TARGETS_HOOK_ARGS}) + endmacro(add_library) + endif (CCOV_TARGETS_HOOK) + endif() # Adds code coverage instrumentation to a library, or instrumentation/targets diff --git a/example/code-coverage-hook/CMakeLists.txt b/example/code-coverage-hook/CMakeLists.txt new file mode 100644 index 0000000..e5972b5 --- /dev/null +++ b/example/code-coverage-hook/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.10) +project(code-coverage-hook C CXX) + +# Set the searching location for cmake 'include' locations +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../..;") +# Include the code coverage module +cmake_policy(SET CMP0077 NEW) + +set(CCOV_TARGETS_HOOK ON) +set(CCOV_TARGETS_HOOK_ARGS "ALL") + +include(code-coverage) + +# Require C++11 +include(c++-standards) +cxx_11() +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + +# This introduces the 'ccov-all' targets Also excludes the main file via a regex +add_code_coverage_all_targets(EXCLUDE coverage.main.cpp) + +# The library +add_library(lib ../src/coverage.cpp) + +# The executable +add_executable(main ../src/coverage.main.cpp) +target_link_libraries(main PUBLIC lib) + +# The second executable +add_executable(main2 ../src/coverage.main.cpp) +target_link_libraries(main2 PUBLIC lib)