Welcome to XTDMake’s documentation!

Introduction

XTDMake is a set of CMake packages that provides easy-to-use targets that generate code quality measurements reports.

  • Documentation (using Doxygen)
  • Documentation coverage (using Doxygen and Lcov)
  • Count lines of code (using Cloc)
  • C++ static code analysis (using CppCheck)
  • Unit tests (using CMake’s test facility)
  • Code coverage (using Lcov)
  • Memory leak of unit tests (using Valgrind)
  • Code duplication analysis (using Pmd)
  • C++ include sanitizing (using Iwyu)

Each target generates both a locally readable and machine processable reports. Local report targets the developer while the machine-processable reports can be used in your Continuous Integration (CI) process.

Locally runnable

Key Point Indicators (KPIs) measurement tools are often built in the CI work flow and therefore cannot be run on the developer’s local environment. This usually lead to discovering regressions (failed tests, a lower coverage or what-so-ever) only after pushing code to distant repository. Developer’s being responsible for the KPIs, they should be able to run the measurement tools before pushing new code.

Per module

Because code of industrial applications is usually divided in different modules, each with a different purpose and levels of criticity, XTDMake’s KPIs reports are generated per module, allowing a finer interpretation of the indicators.

Incremental execution

C++ compilation is already slow enough. XTDMake’s targets are designed to be fully incremental with a fine dependency tracking.

Installation

From PPA Package

Project homepage : https://launchpad.net/~psycofdj/+archive/ubuntu/xtdmake

  1. Add PPA repository to apt

    sudo add-apt-repository ppa:psycofdj/xtdmake
    
  2. Update apt

    sudo apt-get update
    
  3. Install XTDMake

    sudo apt-get install --install-suggests xtdmake
    

From source

Project homepage : https://github.com/psycofdj/xtdmake

Note

Each packages requires a set of programs. You’re not forced to install everything if you don’t need all XTDMake’s modules.

  1. Install suggested dependencies
# Doxygen (Generate documentation from source code)
sudo apt-get install doxygen
# Dot (Generate pictures from graphs)
sudo apt-get install graphviz
# xsltproc (Transform XML files from XSLT style-sheets)
sudo apt-get install xsltproc
# lcov (Generate HTML results from code-coverage information)
sudo apt-get install lcov
# coverxygen (Generate documentation-coverage information from doxygen documentation)
sudo pip install coverxygen
# cloc (Count line of codes)
sudo apt-get install cloc
# cppcheck (C++ static code analysis tool)
sudo apt-get install cppcheck
# valgrind instrumentation framework for dynamic analysis
sudo apt-get install valgrind
# jq, awk for json
sudo apt-get install jq
# java 8
sudo apt-get install openjdk-8-jre
# PMD
wget https://github.com/pmd/pmd/releases/download/pmd_releases%2F5.7.0/pmd-bin-5.7.0.zip
sudo unzip -d /usr/share pmd-bin-5.7.0.zip
# Include what you use
sudo apt-get install iwyu
  1. Download latest release
# fetch latest release version
tag=$(curl -s https://api.github.com/repos/psycofdj/xtdmake/tags | \
  jq -r '[ .[] | .["name"] ] | sort | last')

# download archive
wget https://github.com/psycofdj/xtdmake/archive/${tag}.tar.gz -O xtdmake-${tag}.tar.gz

# uncompress archive
tar xvzf xtdmake-${tag}.tar.gz
  1. Install XTDMake
cd xtdmake-${tag}.tar.gz
mkdir .build
cd .build
cmake ..
sudo make install

Quick Start

In your root CMakeLists.txt

# ----------
# cmake init
# ----------

cmake_minimum_required(VERSION 2.6)
project(<project_name>)

# enabled_testing() must be called at top-level for module CheckRule to work
# properly
enable_testing()

# project's versions must be set for module StaicShared to work properly
set(PROJECT_VERSION_MAJOR 0)
set(PROJECT_VERSION_MINOR 1)
set(PROJECT_VERSION_PATCH 1)

# ------------
# load XTDmake
# ------------

# All XTDMake global default parameters must be set before calling init function.
# Ex:
#   -> list(APPEND CheckRule_DEFAULT_LINKS "${Boost_LIBRARIES}")

# this function load desisred XTDMake module, each one may or may not be REQUIRED
xtdmake_init(
  StaticShared    REQUIRED
  DocRule         REQUIRED
  DocCoverageRule REQUIRED
  CppcheckRule    REQUIRED
  CheckRule       REQUIRED
  ClocRule        REQUIRED
  Tracking        REQUIRED
  Cppunit         REQUIRED
  CovRule         REQUIRED
  MemcheckRule    REQUIRED
  CodeDupRule     REQUIRED
  Reports         REQUIRED)

# make XTDMake aware of current cmake project
xtdmake_init_project(<project_name> ${PROJECT_BINARY_DIR})

# (optional) configure XTDMake to injects dependency tracking informations in binaries and libraries
enable_tracking()

# ---------------------------
# rest of your CMakeLists.txt
# ---------------------------

Load code quality targets

In your module CMakelists.txt, example core/CMakeLists.txt :

include_directories(
  ${Boost_INCLUDE_DIRS}
  ${core_INCLUDE_DIRS}
  )

# Create both statis and shared libraries using a single call
add_shared_static_library(core
  src/types.cc
  src/log/Appender.cc
  src/log/ColoredFormatter.cc
  src/log/ConfLoader.cc
  src/log/Formatter.cc
  src/log/helpers.cc
  src/log/Logger.cc
  src/log/MemoryAppender.cc
  src/log/StreamAppender.cc
  src/log/Stream.cc
  src/log/SyslogAppender.cc
  src/log/FormatModifiers.cc
  src/tty.cc
  src/text.cc
  src/Application.cc
  src/config/Parser.cc
  src/config/Grammar.cc
  )

# enable doxygen documentation
add_doc(core)

# enable documentation coverage report
add_doc_coverage(core)

# enable count lines of code report
add_cloc(core)

# enable cppcheck report
add_cppcheck(core)

# enable unittests report
# link all test to static version on library libcore
add_check(core
  INCLUDES ./src}
  LINKS    core_s)

# enable test coverage report
add_cov(core)

# enable test memory check report
add_memcheck(core)

# enable code duplication report
add_codedup(core)

# enable code duplication report
add_iwyu(core)

Adds some unittests

in core/unit/TestMyClass.cc

Run targets

$ cd path-to-build-dir
$ make reports
...
...
...
[100%] Built target

$ make reports-show
(browser opens on report interface)

Binaries RSC keywords

_images/reports-1.png

Code quality modules

DocRule

This module generates a report from result of cppcheck static analysis.

Prerequisites

doxygen
Code documentation generator for C/C++. Available from ubuntu packages or from source at http://www.doxygen.org/
graphviz
Graph drawing tools, Available from ubuntu packages or from source at http://www.graphviz.org/
Plantuml
UML diagrams drawing tool. Available from ubuntu packages (>= xenial) or from source at http://plantuml.com/

Functions

add_doc(module,
  [INPUT              <dir>     [ <dir>     ... ]]
  [FILE_PATTERNS      <pattern> [ <pattern> ... ]]
  [EXCLUDE            <file>    [ <file>    ... ]]
  [EXCLUDE_PATTERNS   <pattern> [ <pattern> ... ]]
  [PREDEFINED         <name>    [ <name>    ... ]]
  [EXPAND_AS_DEFINED  <name>    [ <name>    ... ]]
  [EXAMPLE            <dir>  ]
  [PLANTUML]          <jar>  ]
  [IMAGE]             <dir>  ]
  [CONFIGURE_TEMPLATE <file> ]
  [WERROR             { YES | NO } ]
  [CALL_GRAPHS        { YES | NO } ]
)

This function generates cmake targets that produce doxygen documentation for a given module. Generated targets are added as dependency of the global doc and doc-clean targets.

Parameters

module
Name of the module. It determines the name of the generated cmake targets and the directory where targets generate the report.
INPUT

List of directories where target should search source files to process. Ultimatly this paramter will be given to doxygen INPUT configuration (see https://www.stack.nl/~dimitri/doxygen/manual/config.html#cfg_input).

Default value is given by DocRule_DEFAULT_INPUT

FILE_PATTERNS

List of wildcards search files in given input directories. Ultimatly this paramter will be given to doxygen FILE_PATTERNS configuration. (see https://www.stack.nl/~dimitri/doxygen/manual/config.html#cfg_input). Together with INPUT, this paramter will determine the files dependency of generated target.

Default value is given by DocRule_DEFAULT_FILE_PATTERNS

EXCLUDE

List of files to exclude from doxygen generation. Ultimatly this paramter will be given to doxygen EXCLUDE configuration. (see https://www.stack.nl/~dimitri/doxygen/manual/config.html#cfg_exclude).

Default value is given by DocRule_DEFAULT_EXCLUDE

EXCLUDE

List of patterns to exclude from doxygen generation. Ultimatly this paramter will be given to doxygen EXCLUDE_PATTERNS configuration. (see https://www.stack.nl/~dimitri/doxygen/manual/config.html#cfg_exclude_patterns).

Default value is given by DocRule_DEFAULT_EXCLUDE_PATTERNS

EXCLUDE

List of predefined macro given to doxygen in PREDEFINED configuration (see https://www.stack.nl/~dimitri/doxygen/manual/config.html#cfg_predefined).

Default value is given by DocRule_DEFAULT_PREDEFINED

EXPAND_AS_DEFINED

List of predefined macro given to doxygen in EXPAND_AS_DEFINED configuration (see https://www.stack.nl/~dimitri/doxygen/manual/config.html#cfg_expand_as_defined).

Default value is given by DocRule_DEFAULT_EXPAND_AS_DEFINED

EXAMPLE

Directory containing examples files given to doxygen as EXAMPLE_PATH configuration (see https://www.stack.nl/~dimitri/doxygen/manual/config.html#cfg_example_path).

Default value is given by DocRule_DEFAULT_EXAMPLE

IMAGE

Directory containing images files given to doxygen as IMAGE_PATH configuration (see https://www.stack.nl/~dimitri/doxygen/manual/config.html#cfg_image_path).

Default value is given by DocRule_DEFAULT_IMAGE

PLANTUML

Path to plantuml jar file given to doxygen as PLANTUML_JAR_PATH configuration (see https://www.stack.nl/~dimitri/doxygen/manual/config.html#cfg_plantuml_jar_path).

Default value is given by DocRule_DEFAULT_PLANTUML

Warning

Plantml integration is not supported in doxygen version prior to 1.8.11. In that case this parameter has no effect.

WERROR

If YES, doxygen warning are threated as errors (see https://www.stack.nl/~dimitri/doxygen/manual/config.html#cfg_warn_as_error).

Default value is given by DocRule_DEFAULT_WERROR

CALL_GRAPHS

If YES, doxygen will generate call graph and caller graph. This option requires grahviz to be installed.

Default value is given by DocRule_DEFAULT_CALL_GRAPHS

CONFIGURE_TEMPLATE

Path to doxygen configuration template to use. If empty, the function chooses one if its own default templates based on currently installed doxygen version.

Default value is given by DocRule_DEFAULT_CONFIG

Warning

For XTDMake to work correclty with your manually defined configure template, you must insure that :

  • GENERATE_XML is YES (required by DocCoverageRule module)
  • OUTPUT_DIRECTORY is @DocRule_OUTPUT@.

Tip

The following variables are given to the configure template :

  • @CMAKE_PROJECT_NAME@
  • @DocRule_MODULE@
  • @DocRule_OUTPUT@
  • @DocRule_WERROR@
  • @DocRule_INPUT@
  • @DocRule_FILE_PATTERNS@
  • @DocRule_EXCLUDE@
  • @DocRule_EXAMPLE@
  • @DocRule_IMAGE@
  • @DocRule_PREDEFINED@
  • @DocRule_EXPAND_AS_DEFINED@
  • @DocRule_CALL_GRAPHS@
  • @DocRule_PLANTUML@

Global variables

DocRule_DEFAULT_EXCLUDE
""
DocRule_DEFAULT_EXCLUDE_PATTERNS
""
DocRule_DEFAULT_FILE_PATTERNS
"*.cc;*.hh;*.hpp"
DocRule_DEFAULT_PREDEFINED
""
DocRule_DEFAULT_EXPAND_AS_DEFINED
""
DocRule_DEFAULT_EXAMPLE
"${CMAKE_CURRENT_SOURCE_DIR}/doc/example"
DocRule_DEFAULT_IMAGE
"${CMAKE_CURRENT_SOURCE_DIR}/doc/image"
DocRule_DEFAULT_PLANTUML
"/usr/share/plantuml/plantuml.jar"
DocRule_DEFAULT_INPUT
"${CMAKE_CURRENT_SOURCE_DIR}/src;${CMAKE_CURRENT_SOURCE_DIR}/doc"
DocRule_DEFAULT_WERROR
"YES"
DocRule_DEFAULT_CALL_GRAPHS
"YES"
DocRule_DEFAULT_CONFIG
""

Generated targets

doc
generate doc reports for all modules
doc-clean
removes doc reports for all modules
<module>-doc
generate doc report for module <module>
<module>-doc-clean
removes doc report for module <module>

Dependencies

digraph G {
  rankdir="LR";
  node [shape=box, style=filled, fillcolor="#ffff99", fontsize=12];
  "cmake" -> "dir_list(INPUT)"
  "cmake" -> "doc"
  "cmake" -> "doc-clean"
  "doc" -> "<module>-doc"
  "<module>-doc" -> "file_list(INPUT, FILE_PATTERNS)"
  "doc-clean" -> "<module>-doc-clean"
}

Warning

The dependency of cmake build system to the modification time of INPUT directories doesn’t work with cmake versions prior to 3.0. This mean you must re-run cmake after adding new sources files in order to properly update the target files dependencies

Generated reports

XML : reports/doc/xml/<module>/index.xml

HTML : reports/doc/html/<module>/index.html

Bellow an example of generated html report :

_images/doc.png

DocCoverageRule

This modules generate a report about documentation’s coverage.

Prerequisites

lcov
Generates html report from coverage statistics. Available from ubuntu packages or from http://ltp.sourceforge.net/coverage/lcov.php
coverxygen

Generate coverage statictics from doxygen xml output. Available from :

DocRule
This module must be enabled in order to load DocCoverageRule.

Functions

add_doc_coverage(<module>
  [ KIND  <kind>  [<kind>  ...]]
  [ SCOPE <scope> [<scope> ...]]
  [ MIN_PERCENT   <value> ]
  [ PREFIX        <path>  ]
)

This function generates cmake targets that produce reports that show your documentation’s coverage. Generated targets are added as dependency of the global doc-coverage and doc-coverage-clean targets.

Parameters

module
Name of the module. It determines the name of the generated cmake targets and the directory where targets generate the report.
KIND

List of symbols to consider for coverage measurements. Available values are described by the --kind parameter of the coverxygen tools at https://github.com/psycofdj/coverxygen.

Default value is given by DocCoverageRule_DEFAULT_KIND.

SCOPE

List of scope of symbol to consider for coverage measurements. Available values are described by the --scope parameter of the coverxygen tools at https://github.com/psycofdj/coverxygen.

Default value is given by DocCoverageRule_DEFAULT_SCOPE.

MIN_PERCENT

Minimal percent of line coverage to consider target as successful. The target itself won’t fail but generated JSON status will be tagged as failure.

Default value is given by DocCoverageRule_DEFAULT_MIN_PERCENT.

PREFIX

Path prefix to remove from files in coverage interface.

Default value is given by DocCoverageRule_DEFAULT_PREFIX.

Global variables

DocCoverageRule_DEFAULT_KIND
"enum;typedef;variable;function;class;struct;define"
DocCoverageRule_DEFAULT_SCOPE
"public;protected"
DocCoverageRule_DEFAULT_MIN_PERCENT
"30"
DocCoverageRule_DEFAULT_PREFIX
"${CMAKE_CURRENT_SOURCE_DIR}/src"

Generated targets

doc-coverage
generate documentation coverage reports for all modules
doc-coverage-clean
removes documentation coverage reports for all modules
<module>-doc-coverage
generate documentation coverage report for module <module>
<module>-doc-coverage-clean
removes documentation coverage report for module <module>

Generated reports

HTML : reports/doc-coverage/<module>/index.html

Bellow an example of generated html report :

_images/doc-coverage-summary.png _images/doc-coverage-details.png

JSON : reports/doc-coverage/<module>/data.json

[
  {
    "<path_to_file1>": [
      {
        "line": 53,
        "documented": true,
        "file": "/home/psyco/dev/xtdcpp/core/src/log/Appender.hh",
        "symbol": "xtd::log::Appender::Appender"
      },
      "..."
    ]
  },
  {
    "<path_to_file2>": [
       "..."
    ]
  }
]

JSON : reports/doc-coverage/<module>/status.json

{
  "status": "success",
  "graphs": [
    {
      "data": {
        "labels": [],
        "datasets": [
          {
            "borderColor": "rgba(51, 204, 51, 0.5)",
            "pointBorderColor": "rgba(31, 122, 31, 1)",
            "yAxisID": "absolute",
            "label": "documented lines",
            "backgroundColor": "rgba(51, 204, 51, 0)",
            "pointBackgroundColor": "rgba(31, 122, 31, 1)",
            "data": "%(documented)d"
          },
          {
            "borderColor": "rgba(179, 0, 0, 0.5)",
            "pointBorderColor": "rgba(102, 0, 0, 1)",
            "yAxisID": "absolute",
            "label": "total lines",
            "backgroundColor": "rgba(179, 0, 0, 0)",
            "pointBackgroundColor": "rgba(102, 0, 0, 1)",
            "data": "%(total)d"
          },
          {
            "borderColor": "rgba(102, 153, 255, 0.5)",
            "pointBorderColor": "rgba(0, 60, 179, 1)",
            "yAxisID": "percent",
            "label": "% covered lines",
            "backgroundColor": "rgba(102, 153, 255, 0)",
            "pointBackgroundColor": "rgba(0, 60, 179, 1)",
            "data": "int((float(%(documented)d) / float(%(total)d)) * 100)"
          }
        ]
      },
      "type": "line",
      "options": {
        "scales": {
          "xAxes": [
            {
              "ticks": {
                "fontSize": 12,
                "minRotation": 80
              }
            }
          ],
          "yAxes": [
            {
              "position": "left",
              "ticks": {
                "fontSize": 24,
                "beginAtZero": true
              },
              "type": "linear",
              "id": "absolute",
              "display": true
            },
            {
              "position": "right",
              "ticks": {
                "max": 100,
                "fontSize": 24,
                "beginAtZero": true
              },
              "type": "linear",
              "id": "percent"
            }
          ]
        },
        "title": {
          "text": "%(module)s : doc-coverage",
          "display": true
        }
      }
    }
  ],
  "data": {
    "documented": 335,
    "total": 347
  },
  "label": "96 %"
}

ClocRule

This module generates a report counting the number of code, blank and comments lines of your module.

Prerequisites

cloc
Count line of code tool. Available from ubuntu packages (>= trusty) or from source at http://cloc.sourceforge.net/
xsltproc
XSL Template rendering tool. Available from ubuntu packages or from source at http://xmlsoft.org/

Functions

add_cloc(module,
  [ INTPUT        <dir>     [ <dir>     ... ]],
  [ FILE_PATTERNS <pattern> [ <pattern> ... ]],
  [ MIN_PERCENT   <value> ]
)

This function generates cmake targets that produce cloc reports for a given module. Generated targets are added as dependency of the global cloc and cloc-clean targets.

Parameters

module
Name of the module. It determines the name of the generated cmake targets and the directory where targets generate the report.
INPUT
List of directories where target should search source files process. Default value is given by ClocRule_DEFAULT_INPUT
FILE_PATTERNS
List of wildcards search files in given input directories. Default value is given by ClocRule_DEFAULT_FILE_PATTERNS
MIN_PERCENT

Minimal percent of comment lines to consider target as successful. The target itself won’t fail but generated JSON status will be tagged as failure.

Default value is given by ClocRule_DEFAULT_MIN_PERCENT.

Global variables

ClocRule_DEFAULT_INPUT
"${CMAKE_CURRENT_SOURCE_DIR}/src"
ClocRule_DEFAULT_FILE_PATTERNS
"*.cc;*.hh;*.hxx"
ClocRule_DEFAULT_MIN_PERCENT
"30"

Generated target

cloc generate
cloc reports for all modules
cloc-clean
removes cloc reports for all modules
<module>-cloc
generate cloc report for module <module>
<module>-cloc-clean
removes cloc report for module <module>

Dependencies

digraph G {
  rankdir="LR";
  node [shape=box, style=filled, fillcolor="#ffff99", fontsize=12];
  "cmake" -> "dir_list(INPUT)"
  "cmake" -> "cloc"
  "cmake" -> "cloc-clean"
  "cloc" -> "<module>-cloc"
  "<module>-cloc" -> "file_list(INPUT, FILE_PATTERNS)"
  "cloc-clean" -> "<module>-cloc-clean"
}

Warning

The dependency of cmake build system to the modification time of INPUT directories doesn’t work with cmake versions prior to 3.0. This mean you must re-run cmake after adding new sources files in order to properly update the rule files dependencies

Generated reports

XML : reports/cloc/<module>/cloc.xml

<?xml version="1.0"?>
<results>
<header>
  <cloc_url>http://cloc.sourceforge.net</cloc_url>
  <cloc_version>1.60</cloc_version>
  <elapsed_seconds>0.14513897895813</elapsed_seconds>
  <n_files>43</n_files>
  <n_lines>6476</n_lines>
  <files_per_second>296.267758728031</files_per_second>
  <lines_per_second>44619.302454017</lines_per_second>
  <report_file>/home/psyco/dev/xtdcpp/.release/reports/core/cloc/cloc.xml</report_file>
</header>
<files>
  <file name="/home/psyco/dev/xtdcpp/core/src/Application.cc" blank="73" comment="19"  code="349" language="C++" />
  <!-- <file ...> -->
  <total blank="927" comment="2283" code="3266" />
</files>
<languages>
  <language name="C++" files_count="17" blank="410" comment="50" code="1981" />
  <language name="C/C++ Header" files_count="26" blank="517" comment="2233" code="1285" />
  <total sum_files="43" blank="927" comment="2283" code="3266" />
</languages>
</results>

HTML : reports/cloc/<module>/index.html

Bellow an example of generated html report :

_images/cloc.png

JSON : reports/cloc/<module>/status.json

{
  "status": "success",
  "graphs": [
    {
      "data": {
        "labels": [],
        "datasets": [
          {
            "borderColor": "rgba(51, 204, 51, 0.5)",
            "pointBorderColor": "rgba(31, 122, 31, 1)",
            "yAxisID": "absolute",
            "label": "comment lines",
            "backgroundColor": "rgba(51, 204, 51, 0)",
            "pointBackgroundColor": "rgba(31, 122, 31, 1)",
            "data": "%(comment)d"
          },
          {
            "borderColor": "rgba(179, 0, 0, 0.5)",
            "pointBorderColor": "rgba(102, 0, 0, 1)",
            "yAxisID": "absolute",
            "label": "code lines",
            "backgroundColor": "rgba(179, 0, 0, 0)",
            "pointBackgroundColor": "rgba(102, 0, 0, 1)",
            "data": "%(code)d"
          },
          {
            "borderColor": "rgba(102, 153, 255, 0.5)",
            "pointBorderColor": "rgba(0, 60, 179, 1)",
            "yAxisID": "percent",
            "label": "% comment lines",
            "backgroundColor": "rgba(102, 153, 255, 0)",
            "pointBackgroundColor": "rgba(0, 60, 179, 1)",
            "data": "int(float(%(comment)d) / (float(%(comment)d) + float(%(code)d)) * 100)"
          }
        ]
      },
      "type": "line",
      "options": {
        "scales": {
          "xAxes": [
            {
              "ticks": {
                "fontSize": 12,
                "minRotation": 80
              }
            }
          ],
          "yAxes": [
            {
              "position": "left",
              "ticks": {
                "fontSize": 24,
                "beginAtZero": true
              },
              "type": "linear",
              "id": "absolute",
              "display": true
            },
            {
              "position": "right",
              "ticks": {
                "max": 100,
                "fontSize": 24,
                "beginAtZero": true
              },
              "type": "linear",
              "id": "percent"
            }
          ]
        },
        "title": {
          "text": "%(module)s : cloc",
          "display": true
        }
      }
    }
  ],
  "data": {
    "comment": 2283,
    "code": 3266
  },
  "label": "41 %"
}

CppcheckRule

This module generates a report from result of cppcheck static analysis.

Prerequisites

cppcheck
Static C++ code analyzer tool. Available from ubuntu packages or from source at http://cppcheck.sourceforge.net/
xsltproc
XSL Template rendering tool. Available from ubuntu packages or from source at http://xmlsoft.org/

Functions

add_cppcheck(module,
  [INTPUT        <dir>     [ <dir>     ... ]],
  [FILE_PATTERNS <pattern> [ <pattern> ... ]]
)

This function generates cmake targets that produce cppcheck reports for a given module. Generated targets are added as dependency of the global cppcheck and cppcheck-clean targets.

Parameters

module
Name of the module. It determines the name of the generated cmake targets and the directory where targets generate the report.
INPUT
List of directories where target should search source files process. Default value is given by CppcheckRule_DEFAULT_INPUT
FILE_PATTERNS
List of wildcards search files in given input directories. Default value is given by CppcheckRule_DEFAULT_FILE_PATTERNS

Global variables

CppcheckRule_DEFAULT_INPUT
"${CMAKE_CURRENT_SOURCE_DIR}/src"
CppcheckRule_DEFAULT_FILE_PATTERNS
"*.cc;*.hh;*.hxx"

Generated targets

cppcheck
generate cppcheck reports for all modules
cppcheck-clean
removes cppcheck reports for all modules
<module>-cppcheck
generate cppcheck report for module <module>
<module>-cppcheck-clean
removes cppcheck report for module <module>

Dependencies

digraph G {
  rankdir="LR";
  node [shape=box, style=filled, fillcolor="#ffff99", fontsize=12];
  "cmake" -> "dir_list(INPUT)"
  "cmake" -> "cppcheck"
  "cmake" -> "cppcheck-clean"
  "cppcheck" -> "<module>-cppcheck"
  "<module>-cppcheck" -> "file_list(INPUT, FILE_PATTERNS)"
  "cppcheck-clean" -> "<module>-cppcheck-clean"
}

Warning

The dependency of cmake build system to the modification time of INPUT directories doesn’t work with cmake versions prior to 3.0. This mean you must re-run cmake after adding new sources files in order to properly update the rule files dependencies

Generated reports

HTML : reports/cppcheck/<module>/index.html

Bellow an example of generated html report :

_images/cppcheck.png

XML : reports/cppcheck/<module>/cppcheck.xml

<?xml version="1.0" encoding="UTF-8"?>
<results version="2">
  <cppcheck version="1.72"/>
  <errors>
    <error id="duplicateExpression" severity="style" msg="Same expression on both sides of '<='." verbose="Finding the same expression on both sides of an operator is suspicious and might indicate a cut and paste or logic error. Please examine this code carefully to determine if it is correct.">
      <location file="functions.hh" line="12"/>
      <location file="functions.hh" line="12"/>
    </error>
    <error id="bitwiseOnBoolean" severity="style" msg="Boolean variable 'test1' is used in bitwise operation. Did you mean '&&'?" verbose="Boolean variable 'test1' is used in bitwise operation. Did you mean '&&'?" inconclusive="true">
      <location file="functions.hh" line="22"/>
    </error>
  </errors>
</results>

JSON : reports/cppcheck/<module>/status.json

{
  "status": "success",
  "graphs": [
    {
      "data": {
        "labels": [],
        "datasets": [
          {
            "borderColor": "rgba(179, 0, 0, 0.5)",
            "pointBorderColor": "rgba(102, 0, 0, 1)",
            "yAxisID": "absolute",
            "label": "cppcheck error count",
            "backgroundColor": "rgba(179, 0, 0, 0.5)",
            "pointBackgroundColor": "rgba(102, 0, 0, 1)",
            "data": "%(total)d"
          }
        ]
      },
      "type": "line",
      "options": {
        "scales": {
          "xAxes": [
            {
              "ticks": {
                "fontSize": 12,
                "minRotation": 80
              }
            }
          ],
          "yAxes": [
            {
              "position": "left",
              "ticks": {
                "fontSize": 24,
                "beginAtZero": true
              },
              "type": "linear",
              "id": "absolute",
              "display": true
            }
          ]
        },
        "title": {
          "text": "%(module)s : cppcheck",
          "display": true
        }
      }
    }
  ],
  "data": {
    "total": 0
  },
  "label": "0"
}

CheckRule

This module create targets that runs and generate reports about unit-tests.

Prerequisites

enable_testing()
This module requires that enable_testing() is called at top level CMakeLists.txt.
xsltproc
XSL Template rendering tool. Available from ubuntu packages or from source at http://xmlsoft.org/

Functions

add_check(<module>
  [ PATTERNS  <pattern>     [<pattern>   ...]]
  [ INCLUDES  <dir>         [<dir>       ...]]
  [ LINKS     <lib>         [<lib>       ...]]
  [ ENV       <key>=<value> [<key=value> ...]]
  [ ARGS      <arg>         [<arg>       ...]]
  [ DIRECTORY      <dir>  ]
  [ PREFIX         <str>  ]
  [ JOBS           <int>  ]
  [ CMAKEVARS_NAME <name> ]
  [ NO_DEFAULT_ENV        ]
  [ NO_DEFAULT_ARGS       ]
  [ NO_DEFAULT_INCLUDES   ]
  [ NO_DEFAULT_LINKS      ]
)

This function automatically detects tests source files, creates binary targets and generate test report.

Parameters

module
Name of the module. It determines the name of the generated cmake targets and the directory where targets generate the report.
PATTERNS

List of file extensions to match while searching for tests. See details about how tests are automatically detected by this module.

Default value is given by CheckRule_DEFAULT_PATTERNS

Warning

Items given in PATTERNS list are not wildcards but only file extensions (ie: no asterix)

INCLUDES

List of include directories to add when compiling test sources. Each item will be added through cmake target_include_directories directive.

Warning

When using cmake version prior to 2.8.12, test include directories are added through cmake include_directories. Therefore, they will also be added to your CMakeLists.txt targets.

Default value is given by CheckRule_DEFAULT_INCLUDES unless NO_DEFAULT_INCLUDES option is given.

LINKS

List of libraries to add when linking test binaries. Each item will be added through cmake target_link_directories directive.

Default value is given by CheckRule_DEFAULT_LINKS unless NO_DEFAULT_LINKS option is given.

ENV

List of environment variable to defined before running each test.

Default value is given by CheckRule_DEFAULT_ENV unless NO_DEFAULT_ENV option is given.

ARGS

List of command-line options to pass when running test binaries.

Default value is given by CheckRule_DEFAULT_ARGS unless NO_DEFAULT_ARGS option is given.

Tip

This option is a convenient way to give your tests some informations about source and build directory tree.

Default value is given CheckRule_DEFAULT_ARGS

DBG_ARGS

List of command-line options to pass when running test through debugger. It Usually sets arguments to command line to prevent your test framework to protect run with forks, allowing to get a usable frame-stack to investigate crashes.

Default value is given by CheckRule_DEFAULT_DBG_ARGS unless NO_DEFAULT_ARGS option is given.

Default value is given CheckRule_DEFAULT_DBG_ARGS

DIRECTORY

Directory to search tests source files. See details about how tests are automatically detected by this module.

Default value is given CheckRule_DEFAULT_DIRECTORY

PREFIX

Filename prefix of test source files. See details about how tests are automatically detected by this module.

Default value is given CheckRule_DEFAULT_PREFIX

JOBS

Number of simultaneous test to run when target is called.

Default value is given CheckRule_DEFAULT_JOBS

CMAKEVARS_NAME

Path to header file generated by check rule. See details about how getting information about source/build tree in your test code.

Default value is given CheckRule_DEFAULT_CMAKEVARS_NAME

NO_DEFAULT_ENV
If option is given, don’t use CheckRule_DEFAULT_ENV
NO_DEFAULT_ARGS
If option is given, don’t use CheckRule_DEFAULT_ARGS
NO_DEFAULT_INCLUDES
If option is given, don’t use CheckRule_DEFAULT_INCLUDES
NO_DEFAULT_LINKS
If option is given, don’t use CheckRule_DEFAULT_LINKS

Global variables

CheckRule_DEFAULT_PATTERNS
".c;.cc;.cpp"
CheckRule_DEFAULT_INCLUDES
""
""
CheckRule_DEFAULT_ENV
""
CheckRule_DEFAULT_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}/unit"
CheckRule_DEFAULT_PREFIX
"Test"
CheckRule_DEFAULT_JOBS
"1"
CheckRule_DEFAULT_ARGS
""
CheckRule_DEFAULT_DBG_ARGS
""
CheckRule_DEFAULT_CMAKEVARS_NAME
"${CMAKE_CURRENT_BINARY_DIR}/cmakevars.h"
CheckRule_DEFAULT_TIMEOUT
"120"

Getting path informations in tests

Tests often need to read sample files located in either source or build directory. Because source and build trees are not relative to each others, only CMake knows where both root directories are located.

XTDMake’s CheckRule provides two ways to forward this informations to your tests :

  1. Using ARGS and/or CheckRule_DEFAULT_ARGS to add command line parameters built with CMake variables such as :

    • CMAKE_SOURCE_DIR : top source directory
    • CMAKE_BINARY_DIR : top build directory
    • CMAKE_CURRENT_SOURCE_DIR : current module’s source directory
    • CMAKE_CURRENT_BINARY_DIR : current module’s build directory

    One possible value for CheckRule_DEFAULT_ARGS could be:

    --topsrc-dir=\${CMAKE_PROJECT_SOURCE_DIR} \
    --topbuild-dir=\${CMAKE_PROJECT_BINARY_DIR} \
    --src-dir=\${CMAKE_SOURCE_DIR} \
    --build-dir=\${CMAKE_BINARY_DIR}
    
  2. Using generated header file. CheckRule automatically creates for each module an header file named CheckRule_DEFAULT_CMAKEVARS or CMAKEVARS arguments. This file is generated from the given template :

    #define   TOP_SRCDIR       "@CMAKE_SOURCE_DIR@"
    #define       SRCDIR       "@CMAKE_CURRENT_SOURCE_DIR@"
    #define TOP_BUILDDIR       "@PROJECT_BINARY_DIR@"
    #define     BUILDDIR       "@CMAKE_CURRENT_BINARY_DIR@"
    #define PROJECT_SOURCE_DIR "@PROJECT_SOURCE_DIR@"
    #define PROJECT_BINARY_DIR "@PROJECT_BINARY_DIR@"
    

    Your test code can simply include the generated header and use defined variables to build path to your assets files located in source or build tree.

Finding the test sources

This module scans given DIRECTORY for source files prefixed by PREFIX and matches one of file extensions given by PATTERNS. Each matched file is considered as a standalone executable test.

Deducing the target name

This function deduces the name of the test from its source file by stripping DIRECTORY, PREFIX and match extension. Example :

file:./unit/TestApplication.cc
DIRECTORY:./unit
PATTERNS:.cc;.cpp.c
Deduced name:Application

Generated targets

check
generate doc reports for all modules
check-clean
removes doc reports for all modules
<module>-check
generate unittests report for module <module>
<module>-check-build
build all test binaries for module <module>
<module>-check-run
run tests for module <module> that are not up-to-date
<module>-check-run-verbose
run tests for module <module> that are not up-to-date with ctest verbose output
<module>-check-run-forced
run all tests for module <module>
<module>-check-clean
clean test targets for module <module>

For each test <name>, the function also produces :

t<name>
build individual test binary target <name>
<module>-check-ut-<name>
run individual test <name>
<module>-check-ut-<name>-dbg
run individual test <name> wrapped in debugger
<module>-check-ut-<name>-cmd
prints individual test command <name>

Adding test manually

To integrate manually defined tests with CheckRule module, you must use the following function.

Warning

This function must be called before add_check

add_check_test(module name
  COMMAND <command> [ <arg> ... ]
  [ ENVIRONMENT <var>=<value> [ <var>=<value> ... ]
)
module
name of targeted module
name
name of the test target
COMMAND
command line to run for this test
ENVIRONMENT
environment variable to define before running the test

About debugger

By default, CheckRule debugger target wraps test execution in GNU gdb. If USE_CLANG variable is defined, debugger is switched to lldb.

Target Dependencies

digraph G {
  node [shape=box, style=filled, fillcolor="#ffff99", fontsize=12];
  "cmake"                        -> "dir(DIRECTORY)"
  "cmake"                        -> "check"
  "cmake"                        -> "check-clean"
  "check"                        -> "<module>-check"
  "check-clean"                  -> "<module>-check-clean"
  "<module>-check"               -> "t<name>"
  "<module>-check"               -> "file_list(DIRECTORY, PREFIX, PATTERNS)"
  "t<name>"                      -> "sources(<name>, INCLUDES, LINKS)"
  "<module>-check-ut-<name>"     -> "t<name>"
  "<module>-check-ut-<name>-gdb" -> "t<name>"
  "<module>-check-ut-<name>-cmd" -> ""
  "<module>-check-build"         -> "t<name>"
  "<module>-check-run-forced"    -> ""
  "<module>-check-run-verbose"   -> "<module>-check-build"
  "<module>-check-run"           -> "<module>-check-build"
  "<module>-check-run"           -> "<module>-check-run-forced"
}

Warning

The dependency of cmake build system to the modification time of DIRECTORY doesn’t work with cmake versions prior to 3.0. This mean you must re-run cmake after adding new sources files in order to properly update the rule files dependencies.

Generated reports

HTML : reports/check/<module>/index.html

Bellow an example of generated html report :

_images/check.png

XML : reports/check/<module>/index.xml

<?xml version="1.0" encoding="UTF-8"?>
<Site BuildName="(empty)"
      BuildStamp="20161231-1237-Experimental"
      Name="(empty)"
      Generator="ctest-3.5.1"
      CompilerName=""
      CompilerVersion=""
      OSName="Linux"
      Hostname="PSYCO-INTEL"
      OSRelease="4.4.0-57-generic"
      OSVersion="#78-Ubuntu SMP Fri Dec 9 23:50:32 UTC 2016"
      OSPlatform="x86_64"
      Is64Bits="1"
      VendorString="GenuineIntel"
      VendorID="Intel Corporation"
      FamilyID="6"
      ModelID="79"
      ProcessorCacheSize="20480"
      NumberOfLogicalCPU="16"
      NumberOfPhysicalCPU="1"
      TotalVirtualMemory="93"
      TotalPhysicalMemory="64340"
      LogicalProcessorsPerPhysical="16"
      ProcessorClockFrequency="1898.75"
      >
      <Testing>
              <StartDateTime>Dec 31 13:37 CET</StartDateTime>
              <StartTestTime>1483187874</StartTestTime>
              <TestList>
                      <Test>./tApplication</Test>
              </TestList>
              <Test Status="passed">
                      <Name>tConfigParser</Name>
                      <Path>.</Path>
                      <FullName>./tConfigParser</FullName>
                      <FullCommandLine>/home/psyco/dev/xtdcpp/.release/core/tConfigParser "--srcdir=/home/psyco/dev/xtdcpp/core" "--top-srcdir=/home/psyco/dev/xtdcpp" "--top-builddir=/home/psyco/dev/xtdcpp/.release" "--testdir=/home/psyco/dev/xtdcpp/core/unit" "--outputter=compiler" "-p" "-e" "7"</FullCommandLine>
                      <Results>
                              <NamedMeasurement type="numeric/double" name="Execution Time">
                                      <Value>0.0134299</Value>
                              </NamedMeasurement>
                              <NamedMeasurement type="text/string" name="Completion Status">
                                      <Value>Completed</Value>
                              </NamedMeasurement>
                              <NamedMeasurement type="text/string" name="Command Line">
                                      <Value>/home/psyco/dev/xtdcpp/.release/core/tConfigParser "--srcdir=/home/psyco/dev/xtdcpp/core" "--top-srcdir=/home/psyco/dev/xtdcpp" "--top-builddir=/home/psyco/dev/xtdcpp/.release" "--testdir=/home/psyco/dev/xtdcpp/core/unit" "--outputter=compiler" "-p" "-e" "7"</Value>
                              </NamedMeasurement>
                              <Measurement>
                                      <Value>
            TestConfParser::Constructor : start
            TestConfParser::Constructor : end Ok
            TestConfParser::parse : start
            TestConfParser::parse : end Ok
            TestConfParser::get : start
            TestConfParser::get : end Ok
            TestConfParser::search : start
            TestConfParser::search : end Ok
            TestConfParser::setParams : start
            TestConfParser::setParams : end Ok
            TestConfParser::parseFile : start
            TestConfParser::parseFile : end Ok
            OK (6)
          </Value>
                              </Measurement>
                      </Results>
              </Test>
              <EndDateTime>Dec 31 13:37 CET</EndDateTime>
              <EndTestTime>1483187875</EndTestTime>
              <ElapsedMinutes>0</ElapsedMinutes>
      </Testing>
</Site>

JSON : reports/check/<module>/status.json

{
  "status": "success",
  "graphs": [
    {
      "data": {
        "labels": [],
        "datasets": [
          {
            "borderColor": "rgba(51, 204, 51, 0.5)",
            "pointBorderColor": "rgba(31, 122, 31, 1)",
            "yAxisID": "absolute",
            "label": "success tests",
            "backgroundColor": "rgba(51, 204, 51, 0)",
            "pointBackgroundColor": "rgba(31, 122, 31, 1)",
            "data": "%(success)d"
          },
          {
            "borderColor": "rgba(179, 0, 0, 0.5)",
            "pointBorderColor": "rgba(102, 0, 0, 1)",
            "yAxisID": "absolute",
            "label": "failure tests",
            "backgroundColor": "rgba(179, 0, 0, 0)",
            "pointBackgroundColor": "rgba(102, 0, 0, 1)",
            "data": "%(failures)d"
          }
        ]
      },
      "type": "line",
      "options": {
        "scales": {
          "xAxes": [
            {
              "ticks": {
                "fontSize": 12,
                "minRotation": 80
              }
            }
          ],
          "yAxes": [
            {
              "position": "left",
              "ticks": {
                "fontSize": 24,
                "beginAtZero": true
              },
              "type": "linear",
              "id": "absolute",
              "display": true
            }
          ]
        },
        "title": {
          "text": "%(module)s : unittests",
          "display": true
        }
      }
    }
  ],
  "data": {
    "failures": 0,
    "success": 14
  },
  "label": "14 / 14"
}

CovRule

This module generates a report from result of cppcheck static analysis.

Prerequisites

lcov
Generates html report from coverage statistics. Available from ubuntu packages or from http://ltp.sourceforge.net/coverage/lcov.php
CheckRule
This module must be enabled in order to load CovRule.

Functions

add_cov(<module>
  [ EXCLUDE_PATTERNS <pattern> [ <pattern> .. ]]
  [ MIN_PERCENT      <value> ]
)

This function generates cmake targets that produce reports that show your code coverage. Generated targets are added as dependency of the global cov and doc-clean targets.

Parameters

module
Name of the module. It determines the name of the generated cmake targets and the directory where targets generate the report.
EXCLUDE_PATTERNS

List of files patterns to exclude from for coverage measurements.

Default value is given by CovRule_DEFAULT_EXCLUDE_PATTERNS.

MIN_PERCENT

Minimal percent of line coverage to consider target as successful. The target itself won’t fail but generated JSON status will be tagged as failure.

Default value is given by CovRule_DEFAULT_MIN_PERCENT.

Global variables

CovRule_DEFAULT_EXCLUDE_PATTERNS
"Test*.*"
CovRule_DEFAULT_MIN_PERCENT
"30"

Generated targets

cov
generate coverage reports for all modules
cov-clean
removes coverage reports for all modules
<module>-cov
generate coverage report for module <module>
<module>-cov-clean
removes coverage report for module <module>

Generated reports

HTML : reports/coverage/<module>/index.html

Bellow an example of generated html report :

_images/coverage-summary.png _images/coverage-details.png

XML : reports/coverage/<module>/coverage.xml

<?xml version="1.0" ?>
<!DOCTYPE coverage
  SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-04.dtd'>
<coverage branch-rate="0.0" branches-covered="0" branches-valid="0" complexity="0" line-rate="0.939089692102" lines-covered="1403" lines-valid="1494" timestamp="1483189103" version="2.0.3">
      <sources>
              <source>.</source>
      </sources>
      <packages>
              <package branch-rate="0.0" complexity="0" line-rate="1.0" name="......core.src.config">
                      <classes>
                              <class branch-rate="0.0" complexity="0" filename="../../core/src/config/Grammar.hxx" line-rate="1.0" name="......core.src.config.Grammar.hxx">
                                      <methods>
                                              <method branch-rate="0.0" line-rate="0.0" name="xtd::config::impl::Grammar&lt;std::istream_iterator&lt;char, char, std::char_traits&lt;char&gt;, long&gt; &gt;::handleError(boost::spirit::line_pos_iterator&lt;std::istream_iterator&lt;char, char, std::char_traits&lt;char&gt;, long&gt; &gt;, boost::spirit::line_pos_iterator&lt;std::istream_iterator&lt;char, char, std::char_traits&lt;char&gt;, long&gt; &gt;, boost::spirit::line_pos_iterator&lt;std::istream_iterator&lt;char, char, std::char_traits&lt;char&gt;, long&gt; &gt;, boost::spirit::info const&amp;)" signature="">
                                                      <lines>
                                                              <line branch="false" hits="0" number="124"/>
                                                      </lines>
                                              </method>
                                              <method branch-rate="1.0" line-rate="1.0" name="xtd::config::impl::Grammar&lt;__gnu_cxx::__normal_iterator&lt;char*, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt;::Grammar()" signature="">
                                                      <lines>
                                                              <line branch="false" hits="20" number="10"/>
                                                      </lines>
                                              </method>
                                      </methods>
                                      <lines>
                                              <line branch="false" hits="23" number="10"/>
                                              <line branch="false" hits="23" number="11"/>
                                              <line branch="false" hits="46" number="26"/>
                                              <line branch="false" hits="46" number="27"/>
                                              <line branch="false" hits="23" number="28"/>
                                      </lines>
                              </class>
                      </classes>
              </package>
      </packages>
</coverage>

JSON : reports/coverage/<module>/status.json

{
  "status": "success",
  "graphs": [
    {
      "data": {
        "labels": [],
        "datasets": [
          {
            "borderColor": "rgba(51, 204, 51, 0.5)",
            "pointBorderColor": "rgba(31, 122, 31, 1)",
            "yAxisID": "absolute",
            "label": "covered lines",
            "backgroundColor": "rgba(51, 204, 51, 0)",
            "pointBackgroundColor": "rgba(31, 122, 31, 1)",
            "data": "%(covered)d"
          },
          {
            "borderColor": "rgba(179, 0, 0, 0.5)",
            "pointBorderColor": "rgba(102, 0, 0, 1)",
            "yAxisID": "absolute",
            "label": "total lines",
            "backgroundColor": "rgba(179, 0, 0, 0)",
            "pointBackgroundColor": "rgba(102, 0, 0, 1)",
            "data": "%(total)d"
          },
          {
            "borderColor": "rgba(102, 153, 255, 0.5)",
            "pointBorderColor": "rgba(0, 60, 179, 1)",
            "yAxisID": "percent",
            "label": "% covered lines",
            "backgroundColor": "rgba(102, 153, 255, 0)",
            "pointBackgroundColor": "rgba(0, 60, 179, 1)",
            "data": "int((float(%(covered)d) / float(%(total)d)) * 100)"
          }
        ]
      },
      "type": "line",
      "options": {
        "scales": {
          "xAxes": [
            {
              "ticks": {
                "fontSize": 12,
                "minRotation": 80
              }
            }
          ],
          "yAxes": [
            {
              "position": "left",
              "ticks": {
                "fontSize": 24,
                "beginAtZero": true
              },
              "type": "linear",
              "id": "absolute",
              "display": true
            },
            {
              "position": "right",
              "ticks": {
                "max": 100,
                "fontSize": 24,
                "beginAtZero": true
              },
              "type": "linear",
              "id": "percent"
            }
          ]
        },
        "title": {
          "text": "%(module)s : coverage",
          "display": true
        }
      }
    }
  ],
  "data": {
    "covered": 1403,
    "total": 1494,
    "percent": "int((float(%(covered)d) / float(%(total)d)) * 100)"
  },
  "label": "93 %"
}

MemcheckRule

This module generates a report that shows memory defects detected by valgrind for available unit tests.

Prerequisites

valgrind
Instrumentation framework for building dynamic analysis tools. Available from ubuntu packages or from source at http://valgrind.org/
CheckRule
This module must be enabled in order to load MemcheckRule.

Functions

add_memcheck(<module>
[SUPPRESSIONS <file> [<file> ... ]]
[EXTRA_ARGS   <args>]
)

This function generates cmake targets that produce reports that show memory flaws detected by valgrind on module’s test suite. Generated targets are added as dependency of the global memcheck and memcheck-clean targets.

Parameters

module
Name of the module. It determines the name of the generated cmake targets and the directory where targets generate the report.
SUPPRESSIONS
List of existing files to add as valgrind supression stacks. See http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress
EXTRA_ARGS
List of additional arguments to pass to valgrind. Use with caution, parameters must be compatible with --tool=memcheck.

Generated targets

memcheck
generate memory reports for all modules
memcheck-clean
removes memory reports for all modules
<module>-memcheck
generate memory report for module <module>
<module>-memcheck-clean
removes memory report for module <module>

Generated reports

HTML : reports/memcheck/<module>/index.html

Bellow an example of generated html report :

_images/memcheck.png

JSON : reports/memcheck/<module>/memcheck.json

{
   "tests" : [
      {
         "args" : {
            "args" : [
               "--srcdir=/home/psyco/dev/xtdcpp/core",
               "--top-srcdir=/home/psyco/dev/xtdcpp",
               "--top-builddir=/home/psyco/dev/xtdcpp/.release",
               "--testdir=/home/psyco/dev/xtdcpp/core/unit",
               "--outputter=compiler",
               "-p",
               "-e",
               "7"
            ],
            "bin" : "./tApplication"
         },
         "errors" : [
            {
               "descr" : "100 bytes in 1 blocks are definitely lost in loss record 1 of 2",
               "kind" : "Leak_DefinitelyLost",
               "stack" : [
                  {
                     "line" : "",
                     "ip" : "0x4C2E80F",
                     "fn" : "operator new[](unsigned long)",
                     "obj" : "/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so",
                     "file" : "",
                     "dir" : ""
                  },
                  {
                     "dir" : "/home/psyco/dev/xtdcpp/core/unit",
                     "obj" : "/home/psyco/dev/xtdcpp/.release/core/tApplication",
                     "file" : "TestApplication.cc",
                     "line" : "62",
                     "ip" : "0x5085D9",
                     "fn" : "MyApp::MyApp(bool)"
                  },
                  {
                     "obj" : "/home/psyco/dev/xtdcpp/.release/core/tApplication",
                     "file" : "TestApplication.cc",
                     "line" : "93",
                     "ip" : "0x4ABDEF",
                     "fn" : "TestApplication::handleSignal()",
                     "dir" : "/home/psyco/dev/xtdcpp/core/unit"
                  }
               ]
            }
         ]
      }
   ],
   "stats" : {
      "Leak_DefinitelyLost" : 1
   }
}

JSON : reports/memcheck/<module>/status.json

{
  "status": "failure",
  "graphs": [
    {
      "data": {
        "labels": [],
        "datasets": [
          {
            "borderColor": "rgba(179, 0, 0, 0.5)",
            "pointBorderColor": "rgba(102, 0, 0, 1)",
            "yAxisID": "absolute",
            "label": "memcheck error count",
            "backgroundColor": "rgba(179, 0, 0, 0.5)",
            "pointBackgroundColor": "rgba(102, 0, 0, 1)",
            "data": "%(total)d"
          }
        ]
      },
      "type": "line",
      "options": {
        "scales": {
          "xAxes": [
            {
              "ticks": {
                "fontSize": 12,
                "minRotation": 80
              }
            }
          ],
          "yAxes": [
            {
              "position": "left",
              "ticks": {
                "fontSize": 24,
                "beginAtZero": true
              },
              "type": "linear",
              "id": "absolute",
              "display": true
            }
          ]
        },
        "title": {
          "text": "%(module)s : memcheck",
          "display": true
        }
      }
    }
  ],
  "data": {
    "total": 1
  },
  "label": "1"
}

CodeDupRule

This module generates a report that shows detected code duplication blocks.

Prerequisites

Java

Java runtime environment. Available from ubuntu packages or from source at http://cppcheck.sourceforge.net/

Warning

module requires Java 8 minimum version.

Pmd
PMD is a source code analyzer. Available from source or binaries at http://pmd.sourceforge.net/
xsltproc
XSL Template rendering tool. Available from ubuntu packages or from source at http://xmlsoft.org/

Functions

add_codedup(module,
  [INTPUT           <dir>     [ <dir>     ... ]],
  [FILE_PATTERNS    <pattern> [ <pattern> ... ]],
  [EXCLUDE_PATTERNS <regexp>  [ <regexp>  ... ]],
  [SUPPRESSIONS     <file>]
  [MIN_TOKENS       <int>]
  [ARGS             <int>]
)

This function generates cmake targets that produce codedup report for a given module. Generated targets are added as dependency of the global codedup and codedup-clean targets.

Parameters

module
Name of the module. It determines the name of the generated cmake targets and the directory where targets generate the report.
INPUT
List of directories where target should search source files process. Default value is given by CodeDupRule_DEFAULT_INPUT
FILE_PATTERNS
List of wildcards search files in given input directories. Default value is given by CodeDupRule_DEFAULT_FILE_PATTERNS
EXCLUDE_PATTERNS
List of regular expressions to exclude matched input files. Default value is given by CodeDupRule_DEFAULT_EXCLUDE_PATTERNS
SUPPRESSIONS
Path to suppression list. Default value is given by CodeDupRule_DEFAULT_SUPPRESSION

Global variables

CodeDupRule_DEFAULT_PMD_VERSION
"5.7.0"

CodeDupRule PDM installed version.

CodeDupRule_DEFAULT_PMD_HOME
"/usr/share/pmd-bin-${CodeDupRule_PMD_VERSION}"

CodeDupRule location of PDM installation.

CodeDupRule_DEFAULT_INPUT
"${CMAKE_CURRENT_SOURCE_DIR}/src"

CodeDupRule default list of input source directories

CodeDupRule_DEFAULT_FILE_PATTERNS
"*.cc;*.hh;*.hxx"

CodeDupRule default list of wildcard patterns to search in INPUT directories

CodeDupRule_DEFAULT_EXCLUDE_PATTERNS
"${CMAKE_CURRENT_SOURCE_DIR}/unit/.*"

CodeDupRule default list of regexp to exclude from analysis

CodeDupRule_DEFAULT_MIN_TOKENS
"100"

CodeDupRule default minimum token length which should be reported as a duplicate

CodeDupRule_DEFAULT_ARGS
"--skip-lexical-errors"

CodeDupRule default additional arguments to give to PMD

CodeDupRule_DEFAULT_SUPPRESSION
"${CMAKE_CURRENT_SOURCE_DIR}/src/codedup.suppr"

CodeDupRule default path to suppression file

Suppression file

You may want to squelch some of the duplicated blocks detected by PMD. To do so can provide a json file with the following format:

[
  <suppression_1>,
  <suppression_2>,
  ...
]

where each <suppression> structure gives instruction to squelch one bloc with the following format:

[
  {
    "file" : "<path-to-file>",
    "from" : <start_line>,
    "to"   : <end_line>
  },
  {
    "file" : "<path-to-file>",
    "from" : <start_line>,
    "to"   : <end_line>
  },
  ...
]

Duplicated code block detected by PMD is compared to each <suppression>. When bloc if found is all given files between from and to lines, the duplication is squelched.

Generated targets

codedup
generate codedup reports for all modules
codedup-clean
removes codedup reports for all modules
<module>-codedup
generate codedup report for module <module>
<module>-codedup-clean
removes codedup report for module <module>

Dependencies

digraph G {
  rankdir="LR";
  node [shape=box, style=filled, fillcolor="#ffff99", fontsize=12];
  "cmake" -> "dir_list(INPUT)"
  "cmake" -> "codedup"
  "cmake" -> "codedup-clean"
  "codedup" -> "<module>-codedup"
  "<module>-codedup" -> "file_list(INPUT, FILE_PATTERNS) - EXCLUDE_PATTERNS"
  "codedup-clean" -> "<module>-codedup-clean"
}

Warning

The dependency of cmake build system to the modification time of INPUT directories doesn’t work with cmake versions prior to 3.0. This mean you must re-run cmake after adding new sources files in order to properly update the rule files dependencies

Generated reports

HTML : reports/codedup/<module>/index.html

Bellow an example of generated html report :

_images/codedup.png

XML : reports/codedup/<module>/codedup.xml

<?xml version="1.0" encoding="UTF-8"?>
<pmd-cpd>
   <duplication lines="18" tokens="121">
      <file line="16" path="/home/psyco/dev/xtdcpp/core/src/log/ColoredFormatter.cc"/>
      <file line="34" path="/home/psyco/dev/xtdcpp/core/src/log/ColoredFormatter.cc"/>
      <codefragment><![CDATA[  Formatter()
{
  using namespace tty;

  setStyles({
      { "name",     style(color::green)               },
      { "threadid", style(color::yellow)              },
      { "message",  style(color::white)               },
      { "module",   style(color::lyellow)             },
      { "time",     style(color::cyan)                },
      { "slevel",   style(color::lred, attrs::bold)   },
      { "location", style(color::lblack)              },
      { "pid",      style(color::lblue)               },
      { "ppid",     style(color::lblue, attrs::bold)  }
    });
}

ColoredFormatter::ColoredFormatter(const Formatter& p_base) :]]></codefragment>
   </duplication>
</pmd-cpd>

JSON : reports/codedup/<module>/status.json

{
  "status": "failure",
  "index": "index.html",
  "module": "core",
  "label": "1",
  "graphs": [
    {
      "data": {
        "labels": [],
        "datasets": [
          {
            "borderColor": "rgba(179, 0, 0, 0.5)",
            "pointBorderColor": "rgba(102, 0, 0, 1)",
            "yAxisID": "absolute",
            "label": "codedup: # error count",
            "backgroundColor": "rgba(179, 0, 0, 0.5)",
            "pointBackgroundColor": "rgba(102, 0, 0, 1)",
            "data": "%(total)d"
          }
        ]
      },
      "type": "line",
      "options": {
        "scales": {
          "xAxes": [
            {
              "ticks": {
                "fontSize": 12,
                "minRotation": 80
              }
            }
          ],
          "yAxes": [
            {
              "position": "left",
              "ticks": {
                "fontSize": 24,
                "beginAtZero": true
              },
              "type": "linear",
              "id": "absolute",
              "display": true
            }
          ]
        },
        "title": {
          "text": "%(module)s : codedup",
          "display": true
        }
      }
    }
  ],
  "kpi": "codedup",
  "data": {
    "total": 1
  }
}

IwyuRule

This module generates a report that shows detected code duplication blocks.

Prerequisites

include-what-you-use
LLVM-based include analyzer. Available from ubuntu packages or from source at https://include-what-you-use.org/
Mako
Python template renderer. Available from ubuntu packages or from source at http://www.makotemplates.org/

Functions

add_iwyu(module,
  DEPENDS target1 [target2 ... ],
  [EXCLUDE_PATTERN  <glob>],
  [JOBS             <int>],
  [MAPPING          <file>],
  [VERBOSE]
)

This function generates cmake targets that produce a report about includes dependencies for a given module. Generated targets are added as dependency of the global iwyu and iwyu-clean targets.

Parameters

module
Name of the module. It determines the name of the generated cmake targets and the directory where targets generate the report.
INPUT
List of directories where target should search source files process. Default value is given by IwyuRule_DEFAULT_INPUT
FILE_PATTERNS
List of wildcards search files in given input directories. Default value is given by IwyuRule_DEFAULT_FILE_PATTERNS
EXCLUDE_PATTERNS
List of regular expressions to exclude matched input files. Default value is given by IwyuRule_DEFAULT_EXCLUDE_PATTERNS
SUPPRESSIONS
Path to suppression list. Default value is given by IwyuRule_DEFAULT_SUPPRESSION

Global variables

IwyuRule_DEFAULT_PMD_VERSION
"5.7.0"

IwyuRule PDM installed version.

IwyuRule_DEFAULT_PMD_HOME
"/usr/share/pmd-bin-${IwyuRule_PMD_VERSION}"

IwyuRule location of PDM installation.

IwyuRule_DEFAULT_INPUT
"${CMAKE_CURRENT_SOURCE_DIR}/src"

IwyuRule default list of input source directories

IwyuRule_DEFAULT_FILE_PATTERNS
"*.cc;*.hh;*.hxx"

IwyuRule default list of wildcard patterns to search in INPUT directories

IwyuRule_DEFAULT_EXCLUDE_PATTERNS
"${CMAKE_CURRENT_SOURCE_DIR}/unit/.*"

IwyuRule default list of regexp to exclude from analysis

IwyuRule_DEFAULT_MIN_TOKENS
"100"

IwyuRule default minimum token length which should be reported as a duplicate

IwyuRule_DEFAULT_ARGS
"--skip-lexical-errors"

IwyuRule default additional arguments to give to PMD

IwyuRule_DEFAULT_SUPPRESSION
"${CMAKE_CURRENT_SOURCE_DIR}/src/codedup.suppr"

IwyuRule default path to suppression file

Suppression file

You may want to squelch some of the duplicated blocks detected by PMD. To do so can provide a json file with the following format:

[
  <suppression_1>,
  <suppression_2>,
  ...
]

where each <suppression> structure gives instruction to squelch one bloc with the following format:

[
  {
    "file" : "<path-to-file>",
    "from" : <start_line>,
    "to"   : <end_line>
  },
  {
    "file" : "<path-to-file>",
    "from" : <start_line>,
    "to"   : <end_line>
  },
  ...
]

Duplicated code block detected by PMD is compared to each <suppression>. When bloc if found is all given files between from and to lines, the duplication is squelched.

Generated targets

codedup
generate codedup reports for all modules
codedup-clean
removes codedup reports for all modules
<module>-codedup
generate codedup report for module <module>
<module>-codedup-clean
removes codedup report for module <module>

Dependencies

digraph G {
  rankdir="LR";
  node [shape=box, style=filled, fillcolor="#ffff99", fontsize=12];
  "cmake" -> "dir_list(INPUT)"
  "cmake" -> "codedup"
  "cmake" -> "codedup-clean"
  "codedup" -> "<module>-codedup"
  "<module>-codedup" -> "file_list(INPUT, FILE_PATTERNS) - EXCLUDE_PATTERNS"
  "codedup-clean" -> "<module>-codedup-clean"
}

Warning

The dependency of cmake build system to the modification time of INPUT directories doesn’t work with cmake versions prior to 3.0. This mean you must re-run cmake after adding new sources files in order to properly update the rule files dependencies

Generated reports

HTML : reports/codedup/<module>/index.html

Bellow an example of generated html report :

_images/codedup.png

XML : reports/codedup/<module>/codedup.xml

<?xml version="1.0" encoding="UTF-8"?>
<pmd-cpd>
   <duplication lines="18" tokens="121">
      <file line="16" path="/home/psyco/dev/xtdcpp/core/src/log/ColoredFormatter.cc"/>
      <file line="34" path="/home/psyco/dev/xtdcpp/core/src/log/ColoredFormatter.cc"/>
      <codefragment><![CDATA[  Formatter()
{
  using namespace tty;

  setStyles({
      { "name",     style(color::green)               },
      { "threadid", style(color::yellow)              },
      { "message",  style(color::white)               },
      { "module",   style(color::lyellow)             },
      { "time",     style(color::cyan)                },
      { "slevel",   style(color::lred, attrs::bold)   },
      { "location", style(color::lblack)              },
      { "pid",      style(color::lblue)               },
      { "ppid",     style(color::lblue, attrs::bold)  }
    });
}

ColoredFormatter::ColoredFormatter(const Formatter& p_base) :]]></codefragment>
   </duplication>
</pmd-cpd>

JSON : reports/codedup/<module>/status.json

{
  "status": "failure",
  "index": "index.html",
  "module": "core",
  "label": "1",
  "graphs": [
    {
      "data": {
        "labels": [],
        "datasets": [
          {
            "borderColor": "rgba(179, 0, 0, 0.5)",
            "pointBorderColor": "rgba(102, 0, 0, 1)",
            "yAxisID": "absolute",
            "label": "codedup: # error count",
            "backgroundColor": "rgba(179, 0, 0, 0.5)",
            "pointBackgroundColor": "rgba(102, 0, 0, 1)",
            "data": "%(total)d"
          }
        ]
      },
      "type": "line",
      "options": {
        "scales": {
          "xAxes": [
            {
              "ticks": {
                "fontSize": 12,
                "minRotation": 80
              }
            }
          ],
          "yAxes": [
            {
              "position": "left",
              "ticks": {
                "fontSize": 24,
                "beginAtZero": true
              },
              "type": "linear",
              "id": "absolute",
              "display": true
            }
          ]
        },
        "title": {
          "text": "%(module)s : codedup",
          "display": true
        }
      }
    }
  ],
  "kpi": "codedup",
  "data": {
    "total": 1
  }
}

Reports

This module will gather HTML reports generated by other XTDMake modules in a fancy HTML interface. This interface allows to navigates from report to report for all declared modules.

The generated html code is fully static, allowing user to view it directly in a web browser without any web server installed.

Prerequisites

Although there is no actual prerequisites to use this module, it’s designed to work with other XTDMake’s module that generates HTML reports. If none of them then are loaded, Report module will work but won’t display any valuable information.

Generated Targets

reports
run all code quality targets for all modules
reports-clean
clean all generated code quality reports
reports-update
(internal use) update report static interface with available generated code quality targets
reports-show
opens report interface in default web-browser (ie: sensible-browser)

Generated interface

HTML : reports/interface/index.html

Try live example: https://psycofdj.github.io/xtdcpp/master/

Bellow few screnn shots :

_images/reports-1.png _images/reports-2.png _images/reports-3.png

Graph history

Report module also provides a graph generator tools that allow to keep track of the code quality measurements in time.

usage: graph [-h] --report-dir REPORT_DIR --history-dir HISTORY_DIR --output-dir OUTPUT_DIR --build-label BUILD_LABEL [--max-items MAX_ITEMS] [--random]

optional arguments:
  -h, --help                show this help message and exit
  --report-dir REPORT_DIR   path to xtdmake reports
  --history-dir HISTORY_DIR path to history output
  --output-dir OUTPUT_DIR   path to javascript output
  --build-label BUILD_LABEL name of current build
  --max-items MAX_ITEMS     maximum number of build to keep in graph
  --random                  internal use

Note

This tool not run automatically by XTDMake since it has no way to know when to pin a new “release”. It’s designed to be run in your continuous integration process.

Example of generated graph :

_images/reports-graphs.png

Utility modules

StaticShared

This module provides an equivalent of cmake’s add_library function that builds both static and shared libraries from the same set of object file which improves compilation time.

Warning

Objects are created with -fPIC flag which may lead to a loss of runtime performance when linking to static library.

Prerequisites

name and version

The following variables must be defined :

  • PROJECT_NAME
  • PROJECT_VERSION_MAJOR
  • PROJECT_VERSION_MINOR
  • PROJECT_VERSION_PATH
cmake
This module doesn’t work properly with cmake version prior to 3.0. However this module is still compatible with such versions but will create two separate sets of objects for static and shared libraries.

Functions

add_shared_static_library(<libname>
  <source> [ <source> ... ]
  [ INSTALL_HEADERS_PATTERNS  <pattern>  [<pattern>  ...]]
  [ INSTALL_HEADERS_DESTINATION <path> ]
  [ INSTALL_LIBS_DESTINATION    <path> ]
  [ INSTALL_HEADERS_DIRECTORY   <dir>  ]
  [ VERSION <version>   ]
  [ SOVERSION <version> ]
  [ NOINSTALL ]
)

Parameters

libname
Internal name of target libraries. At install time, files will be respectively named lib${PROJECT_NAME}<name>.so and lib${PROJECT_NAME}<name>.a.
source
List of source file to build in libraries.
INSTALL_HEADERS_PATTERNS

List of glob pattern to match headers file to install with target libraries.

Default value is given by StaticShared_DEFAULT_INSTALL_HEADERS_PATTERNS.

INSTALL_HEADERS_DIRECTORY

Directory containing headers to install with target libraries.

Default value is given by StaticShared_DEFAULT_INSTALL_HEADERS_DIRECTORY.

INSTALL_HEADERS_DESTINATION

Headers target install directory.

Default value is given by StaticShared_DEFAULT_INSTALL_HEADERS_DESTINATION.

INSTALL_LIBS_DESTINATION

Libraries target install directory

Default value is given by StaticShared_DEFAULT_INSTALL_LIBS_DESTINATION.

VERSION
Shared library version given to cmake VERSION property
SOVERSION
Shared library version given to cmake SOVERSION property.
NOINSTALL
Disables installation configuration for current libraries

Global variables

StaticShared_DEFAULT_INSTALL_LIBS_DESTINATION
"lib"
StaticShared_DEFAULT_INSTALL_HEADERS_DESTINATION
"include/${PROJECT_NAME}/${name}"
StaticShared_DEFAULT_INSTALL_HEADERS_PATTERNS
"*.h;*.hxx;*.hh;*.hpp"
StaticShared_DEFAULT_DIRECTORY
"src/"
StaticShared_DEFAULT_DEFAULT_VERSION
"${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
StaticShared_DEFAULT_DEFAULT_SOVERSION
"${PROJECT_VERSION_MAJOR}"

Generated targets

<libname>
Target shared library
<libname>_s
Target static library

Tracking

This module module wraps C and CXX linkers to embed RSC keywords string in your binaries and libraries. RSC keywords ran be later read using the ident command from rcs Ubuntu package.

Information included for libraries :

$date
compile date of binary
$time
compile time of binary
$revno
current git or bzr revision if any

Information included for binaries :

$date
compile date of binary
$time
compile time of binary
$name
target name of binary
$user
shell user used for compilation
$pwd
compile build directory
$revno
current git or bzr revision if any
$archive
[lib_name] (data) compile date of lib_name [lib_name] (time) compile time of lib_name [lib_name] (revno) git or bzr revno of lib_name if any

Functions

enable_tracking()

You must call this function on top level CMakeLists.txt after loading the Tracking module to enable tracking on your libraries and binaries.

Example

Given a binary tAppender compiled with static libraries libxtdcore_s and libxtdtests_s :

$ ident tAppender

$date: 01-01-2017 $
$time: 15:18:03 $
$name: tAppender $
$user: psyco $
$host: psyco-laptop-tux $
$pwd: /home/psyco/dev/xtdcpp/.release/core $
$revno: 9422c4460c24c7e0289f1d4ff0525e14ccabaedb $
$archive: [libxtdcore_s] (time) 15:17:33 $
$archive: [libxtdcore_s] (date) 01-01-2017 $
$archive: [libxtdcore_s] (revno) 9422c4460c24c7e0289f1d4ff0525e14ccabaedb $
$archive: [libxtdtests_s] (time) 15:14:06 $
$archive: [libxtdtests_s] (date) 01-01-2017 $
$archive: [libxtdtests_s] (revno) 9422c4460c24c7e0289f1d4ff0525e14ccabaedb $

How is works

Tracking module wraps C and C++ default linker and archive commands with link_wrapper and ar_wrapper scripts.

ar_wrapper silently adds a .version file when creating archives. Archives are sort of tars of object files, adding a file to the archive is not harmful.

link_wrapper does 3 things. First it searches for .version files on linked static archives and adds their content to the list. After gathering all possible information, it silently adds a source file to default link command. This source file declares char rscid[] = __RCSID__. Finally, the wrapper adds a -D__RCSID__= to linker command that defines the value of rcs keyword.

Other functions

xtdmake_eval

xtdmake_eval(var expr)

Evaluates cmake expression expr and store it in var.

expr
cmake expression to evaluate. Example: “${CMAKE_CURRENT_SOURCE_DIR}/toto”
var
output variable

xtdmake_get_directory

xtdmake_get_directory(out in)

This function extract directory of path given as in and stores it in out variable. This function is compatible with both cmake (< 3.0) and cmake (>= 3.x).

in
input file path
out
destination variable

xtdmake_stringify

xtdmake_stringify(var)

Transform cmake list is a space-separated string

var
input list

xtdmake_find_program

xtdmake_find_program(ns
  NAMES <name> [<name> ...]
  DOC   <string>
  URL   <string>
  REQUIRED <bool>
  [ VERSION_OPT <options> ]
  [ VERSION_POS <int>     ]
  [ MIN_VERSION <version> ]
)

Search program matching one of given NAMES, try to extract its version using VERSION_OPT and VERSION_POS, prints a message with STATUS or SEND_ERROR flag depending on REQUIRED option value.

Searching results are stores in variables prefixed by namespace ns :
  • <ns>_EXECUTABLE
    name of executable file found among given names
  • <ns>_FOUND
    1 if program was found, 0 otherwise
  • <ns>_VERSION
    version of found program, unknown if couldn’t find any
ns
namespace to store result variables
NAMES
possible names of searched program
DOC
brief description of searched program, displayed in status message when program is not found
URL
url where searched program can be downloaded, displayed in status message when program is not found
REQUIRED
when true and program is not found, status message is replace by an error
VERSION_OPT
parameter string to pass to program to get its version on stdout, usually --version
VERSION_POS
position of the version number in the space-delimited string outputted by program with VERSION_OPT
MIN_VERSION
minimum allowed version of searched program

Example

xtdmake_find_program(cloc
  NAMES cloc
  DOC "cloc code line counting tool"
  URL "http://cloc.sourceforge.net/"
  VERSION_OPT "--version"
  VERSION_POS "0"
  MIN_VERSION 1.2
  REQUIRED 0)

if (cloc_FOUND)
  message("cloc executable is ${cloc_EXECUTABLE}")
  message("cloc version ${cloc_VERSION}")
else()
  message("cloc is not available")
endif()

xtdmake_find_python_module

xtdmake_find_python_module(ns
 INTERPRETERS <pythonX> [ <pythonX> ... ]
 NAME <name>
 DOC  <string>
 URL  <string>
 REQUIRED <bool>
 VERSION_MEMBER <string>
 VERSION_POS    <string>
)

Search python module NAME trying given INTERPRETERS, try to extract its version using VERSION_MEMBER and VERSION_POS, prints a message with STATUS or SEND_ERROR flag depending on REQUIRED option value.

Searching results are stores in variables prefixed by namespace ns :
  • <ns>_FOUND
    1 if program was found, 0 otherwise
  • <ns>_INTERPRETER
    python interpreter where module was found
  • <ns>_VERSION
    version of found program, unknown if couldn’t find any
  • <ns>_NAME
    name of python module
ns
namespace to store result variables
INTERPRETERS
list of python interpreters to try to find module
NAMES
name of python module to load
DOC
brief description of searched module, displayed in status message when program is not found
URL
url where searched module can be downloaded, displayed in status message when program is not found
REQUIRED
when true and program is not found, status message is replace by an error
VERSION_MEMBER
module member where version can be parsed, usually __version__
VERSION_POS
position of the version number in the space-delimited string parsed in version member with VERSION_MEMBER

Example

xtdmake_find_python_module(coverxygen
  NAME coverxygen
  INTERPRETERS python3 python
  DOC "Tool to generate coverage report from Doxygen documentation"
  URL "https://github.com/psycofdj/coverxygen"
  REQUIRED DocCoverageRule_FIND_REQUIRED
  VERSION_MEMBER "__version__"
  VERSION_POS 0)


 if (coverxygen_FOUND)
   message("coverxygen was found using interpreter ${coverxygen_INTERPRETER}")
   message("coverxygen version is ${coverxygen_VERSION}")
   message("coverxygen can be run by the following command : ${coverxygen_INTERPRETER} -m ${coverxygen_MODULE} <args>")
 else()
   message("coverxygen module was not found")
 endif()

Indices and tables