﻿# How to use PVS\-Studio with CMake projects

Besides the [compile\_commands\.json](https://pvs-studio.com/en/docs/manual/6557/) mode, you can work with PVS\-Studio in CMake via an official integration or a special CMake module\. This allows you to integrate the analyzer into a CMake\-based project in a deeper way\. For example, you can set specific goals for the analysis\. Thus, you can check only those parts that you need, not the whole project\.


> \*\*Note:\*\* The minimum version of CMake required to use the CMake module is 3\\\.15 \\\(April 2019\\\)\\\.

## Before you start

Make sure you entered the license key \(Linux/macOS section\)\. Otherwise, the analysis will not run\. You can read more about entering the license [here](https://pvs-studio.com/en/docs/manual/0046/)\. 

## How to use the official integration

Starting from version 4\.3\.0, CMake provides a way to use the analyzer without `compile_commands.json`\. In this mode, PVS\-Studio warnings appear directly during project compilation\.

To enable analysis via the official integration, add the following rule to `CMakeLists.txt`:

```cpp
set(CMAKE_<LANG>_PVS_STUDIO <EXECUTABLE> analyze -a "GA\;OP")
```

* `LANG` can be either `C` or `CXX`;
* `EXECUTABLE` is the path to the `pvs-studio-analyzer` \(GNU/Linux\) or `CompilerCommandsAnalyzer.exe` \(Windows\)\. CMake will extract its location from `PATH` if no absolute path is specified before it\.

All [parameters](https://pvs-studio.com/en/docs/manual/6615/#flags) specified after `EXECUTABLE` will be passed to the C\+\+ analyzer executable `pvs-studio-analyzer`/`CompilerCommandsAnalyzer.exe`\.


> This integration imposes limitations on the output format\\\. In particular, you cannot convert the report using \`plog\-converter\`, since the analysis is performed per file and no resulted PVS\\\-Studio report is generated\\\.

Since PVS\-Studio warnings become part of the build log, you can use CTest to submit the results to a [CDash](https://cmake.org/cmake/help/book/mastering-cmake/chapter/CDash.html) dashboard\.

If you want to avoid running the analysis with every build, wrap the configuration in a conditional statement:

```cpp
if(ENABLE_PVS_STUDIO_CHECKS)
  set(CMAKE_<LANG>_PVS_STUDIO <EXECUTABLE> analyze -a "GA\;OP")
endif()
```

Cross\-platform projects can also use the automatic naming feature for PVS\-Studio executable files in C and C\+\+ projects:

```cpp
find_program(PVS_STUDIO_COMMAND NAMES
             pvs-studio-analyzer CompilerCommandsAnalyzer)
set(CMAKE_CXX_PVS_STUDIO ${PVS_STUDIO_COMMAND} analyze -a "GA\;OP")
```

You can also set the `-DCMAKE_<LANG>_PVS_STUDIO` command\-line parameter to avoid changing `CMakeLists.txt`\. Note that in this case, PVS\-Studio's command\-line parameters use the `;` character as a separator; so, to specify multiple diagnostic rule groups in the `-a` parameter, escaping is required:

```cpp
cmake -B build -DCMAKE_C_PVS_STUDIO="<EXECUTABLE>;analyze;-a;GA\;OP"
```

## How to add the CMake module to the project

An alternative way to integrate PVS\-Studio analysis into a project is to use the dedicated CMake module\. To automatically download it, use [`FetchContent`](https://cmake.org/cmake/help/latest/module/FetchContent.html)\. For example:

```cpp
include(FetchContent)
FetchContent_Declare(
    PVS_CMakeModule
    GIT_REPOSITORY "https://github.com/viva64/pvs-studio-cmake-module.git"
    GIT_TAG        "master" 
)
FetchContent_MakeAvailable(PVS_CMakeModule)
include("${pvs_cmakemodule_SOURCE_DIR}/PVS-Studio.cmake")
```

Such code downloads the Git repository with the module into the generated cache folder and allows users to integrate the analyzer into the project\. 

**Note**\. `master` is the latest version\. If issues arise, try to roll back to the latest release tag of the current analyzer's version\.

You can [upload](https://raw.githubusercontent.com/viva64/pvs-studio-cmake-module/master/PVS-Studio.cmake) the file with the `PVS-Studio.cmake` module if you do not want to have unnecessary dependencies on `FetchContent`\.

Do not forget to update the module with the release of a new analyzer's version to avoid problems in its work\. In the `GIT_TAG` parameter, you can specify the master branch to always use the latest version of the module\.

## How to configure the CMake module

To run the analyzer, CMake module adds a separate target for the build\. When you run the build of this target, the analysis will run with the parameters that you specified when adding this target\. To add the analysis target, use the `pvs_studio_add_target` command\. For example:

```cpp
cmake_minimum_required(VERSION 3.5)
project(pvs-studio-cmake-example CXX)

add_executable(example main.cpp)

# Optional:
# include(FetchContent)
# FetchContent_Declare(....)
# FetchContent_MakeAvailable(....)
include(PVS-Studio.cmake)
pvs_studio_add_target(TARGET example.analyze ALL
                      OUTPUT FORMAT json
                      ANALYZE example
                      MODE GA:1,2
                      LOG target.err
                      ARGS -e /path/to/exclude-path)
```

This CMake file contains one target to build the executable file and one target to run the analysis\. Look at the parameters of the `pvs_studio_add_target` command:

### Target options

* `ALL` automatically starts the analysis when the `all` target is built and works with each project build;
* `TARGET` creates the target name created for the analysis\. To run the analysis, build this target;
* `ANALYZE` sets targets to analyze\. They must be unique when building multiple targets in parallel with the CMake module\. To analyze the dependencies of these targets, add the `RECURSIVE` flag;
* `RECURSIVE` recursively analyze targets dependencies;
* `COMPILE_COMMANDS` uses `compile_commands.json` instead of specifying targets in the `ANALYZE` option\. It works with `CMAKE_EXPORT_COMPILE_COMMANDS` and available only when you use `Makefile` or `Ninja` generators\.

### Output options

* `OUTPUT` shows the analyzer output into the build log;
* `LOG` shows the report file\. If it is unspecified, the `PVS-Studio.log` file will be used in the directory with the CMake cache;
* `FORMAT` shows the report format\. In this case, `.json` is an error format with support for multi\-file navigation\. A list of available formats is [here](https://pvs-studio.com/en/docs/manual/0036/#IDE0C6002A8D)\. Multiple formats can be used \(for example: `FORMAT "gitlab,tasklist-verbose"`\);
* `MODE` enables diagnostic rule groups and their levels\.

### Analysis options

* `PLATFORM`: a platform name\. Available options: `win32`, `x64/win64`, `linux32`, `linux64`, `macos`, `arm` \(IAR Embedded Workbench\), `pic8` \(MPLAB XC8\), `tms` \(Texas Instruments C6000\);
* `PREPROCESSOR`: a preprocessed file format \(`clang`/`visualcpp`/`gcc`\);
* `LICENSE`: a path to the `.lic` file;
* `CONFIG`: a path to the `.cfg` file;
* `CFG_TEXT`: contents of the `.cfg` file;
* `SUPPRESS_BASE`: a path to the [suppress file](https://pvs-studio.com/en/docs/manual/0032/) in the `.suppress.json` format;
* `KEEP_COMBINED_PLOG`: forbids to delete the combined `.pvs.raw` file for subsequent processing by the `plog-converter` utility\.

### Other options

* `DEPENDS`: additional dependencies for the target;
* `SOURCES`: a list of source files for analysis;
* `BIN`: a path to pvs\-studio\-analyzer \(macOS/Linux\) or CompilerCommandsAnalyzer\.exe \(Windows\);
* `CONVERTER`: a path to plog\-converter \(macOS/Linux\) or HtmlGenerator\.exe \(Windows\);
* `C_FLAGS`: additional flags for the C compiler;
* `CXX_FLAGS`: additional flags for the C\+\+ compiler;
* `ARGS`: [additional arguments](https://pvs-studio.com/en/docs/manual/6615/#flags) for pvs\-studio\-analyzer/CompilerCommandsAnalyzer\.exe;
* `CONVERTER_ARGS`: [additional arguments](https://pvs-studio.com/en/docs/manual/0038/#plog-converter_flags) for plog\-converter/HtmlGenerator\.exe \.

### How to exclude files from analysis

To exclude files from analysis, use the ARGS option by passing the paths through the `-e` \(`--exclude-path`\) flag, as shown in the example above\. You can specify absolute, relative paths, or a search mask \(`glob`\)\. 

**Note**\. Relative paths will be expanded in relation to the build directory\. This approach allows you exclude third\-party libraries from the analysis\.

## How to start the analysis

To start the analysis, build the target added to `pvs_studio_add_target`\. For example, this is how the analysis run looks like for the example above:

```cpp
cmake --build <path-to-cache-dir> --target example.analyze
```

Before the run, all the targets specified for analysis in the `ANALYZE` parameter are built\.

[Here](https://github.com/viva64/pvs-studio-cmake-examples) you can find examples of the PVS\-Studio integration in CMake\.