Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions man/manual-premium.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,17 @@ To ignore certain folders you can use `-i`. This will skip analysis of source fi

cppcheck --project=compile_commands.json -ifoo

### `-isystem`, `-I`, `--sysroot`

We have a [script](https://github.com/cppcheck-opensource/cppcheck/blob/main/tools/tweak-compile-commands.py) that tweaks compile_commands.json.

You can use it to:
* use `--sysroot` flags in Cppcheck analysis
* use `-isystem` paths in Cppcheck analysis
* remove `-I` paths from the compile_commands.json

See [script documentation](https://github.com/cppcheck-opensource/cppcheck/blob/main/tools/tweak-compile-commands.md).

## Visual Studio

You can run Cppcheck on individual project files (`*.vcxproj`) or on a whole solution (`*.sln`) or (`*.slnx`).
Expand Down Expand Up @@ -1166,6 +1177,7 @@ To use a `.cfg` file shipped with Cppcheck, pass the `--library=<lib>` option. T
| `lua.cfg` | | |
| `mfc.cfg` | [MFC](https://learn.microsoft.com/en-us/cpp/mfc/mfc-desktop-applications) | |
| `microsoft_atl.cfg` | [ATL](https://learn.microsoft.com/en-us/cpp/atl/active-template-library-atl-concepts) | |
| `microsoft_gsl.cfg` | [Microsoft.GSL](https://github.com/microsoft/gsl) | |
| `microsoft_sal.cfg` | [SAL annotations](https://learn.microsoft.com/en-us/cpp/c-runtime-library/sal-annotations) | |
| `microsoft_unittest.cfg` | [CppUnitTest](https://learn.microsoft.com/en-us/visualstudio/test/microsoft-visualstudio-testtools-cppunittestframework-api-reference) | |
| `motif.cfg` | | |
Expand Down
11 changes: 11 additions & 0 deletions man/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,17 @@ To ignore certain folders you can use `-i`. This will skip analysis of source fi

cppcheck --project=compile_commands.json -ifoo

### `-isystem`, `-I`, `--sysroot`

We have a [script](https://github.com/cppcheck-opensource/cppcheck/blob/main/tools/tweak-compile-commands.py) that tweaks compile_commands.json.

You can use it to:
* use `--sysroot` flags in Cppcheck analysis
* use `-isystem` paths in Cppcheck analysis
* remove `-I` paths from the compile_commands.json

See [script documentation](https://github.com/cppcheck-opensource/cppcheck/blob/main/tools/tweak-compile-commands.md).

## Visual Studio

You can run Cppcheck on individual project files (`*.vcxproj`) or on a whole solution (`*.sln`) or (`*.slnx`).
Expand Down
2 changes: 1 addition & 1 deletion releasenotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Changed interface:
-

Infrastructure & dependencies:
-
- compile_commands.json - flexible handling of -isystem, --sysroot and -I flags through the script tweak-compile_commands.py.

Other:
- Added configuration file for Microsoft.GSL (Guideline Support Library).
6 changes: 6 additions & 0 deletions tools/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,9 @@ message.

Script to compare the error IDs in the expected `testrunner` output (without executing it) with the `--errorlist` output.
It will report missing test coverage for an ID and missing IDs in the `--errorlist` output.

### * tools/tweak-compile-commands.py

Script to tweak `-isystem`/`--sysroot`/`-I` options in a `compile_commands.json` file, for example to make
implicit `--sysroot`-relative `-isystem` paths explicit, convert `-isystem` to `-I`, or remove unwanted include
paths. See `tools/tweak-compile-commands.md` for details.
167 changes: 167 additions & 0 deletions tools/tweak-compile-commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# tweak-compile-commands.py

## NAME

tweak-compile-commands.py - tweak `-isystem`/`--sysroot`/`-I` options in a `compile_commands.json` file

## SYNOPSIS

```
tools/tweak-compile-commands.py COMPILE_COMMANDS [-o OUTPUT | -i]
[--isystem-to-i] [--exclude-folder FOLDER ...]
[--remove-include-path PATH ...]
```

## DESCRIPTION

In many cases the system headers should not be included in Cppcheck
analysis, it is preferable to use `--library` instead. The headers
do not provide the knowledge needed for static analysis, i.e. they
can say what types the arguments to a function has but the header
do not provide the semantics of the functions.

However sometimes you do want to include system headers in Cppcheck
analysis. And you need to have handling of `--sysroot` and
`-isystem`. This script will tweak the compile_commands.json file.

### SYSROOT

Example build command such as:

```
gcc --sysroot /a/b -isystem /opt/x -c foo.c
```

gcc searches both `/opt/x` *and* `/a/b/opt/x` for headers.

`tweak-compile-commands.py` rewrites each build command in a
`compile_commands.json` file so this implicit behaviour is spelled out
explicitly: for every command that has a `--sysroot` argument, every
existing `-isystem PATH` argument gets a matching, explicit
`-isystem SYSROOT/PATH` argument added right after it, and the `--sysroot`
argument is then removed (it is no longer needed since the sysroot-relative
paths are now spelled out explicitly). Commands without a `--sysroot`
argument are left unchanged.

### ISYSTEM

The script has an option `--isystem-to-i`, this tells the script to
convert `-isystem` arguments to `-I`.

The option `--exclude-folder` can be used to skip certain folders. Use
that for a folder if Cppcheck option `--library` can be used instead.

### REMOVE -I

The script also has `--remove-include-path`, the script will remove
any `-I PATH` argument whose path contains a given string. This is
useful for stripping include paths that Cppcheck should not see at all.

## ARGUMENTS

`COMPILE_COMMANDS`
: Path to the `compile_commands.json` file to read.

## OPTIONS

`-o OUTPUT`, `--output OUTPUT`
: Write the result to `OUTPUT` instead of stdout. Cannot be combined with
`-i`.

`-i`, `--in-place`
: Overwrite `COMPILE_COMMANDS` with the result. Cannot be combined with
`-o`.

`--isystem-to-i`
: Also convert `-isystem PATH` arguments to `-I PATH`, except for paths
excluded with `--exclude-folder`. Has no effect on its own if not given
(the sysroot tweak still applies).

`--exclude-folder FOLDER`
: When used with `--isystem-to-i`, keep any `-isystem` argument as
`-isystem` (instead of converting it to `-I`) if `FOLDER` is one of the
path's folder components (an exact match of a path segment, not a
substring). May be given multiple times. Ignored if `--isystem-to-i` is
not given.

`--remove-include-path PATH`
: Remove any `-I` argument whose path contains `PATH` as a substring. May be
given multiple times; a path is removed if it matches any of them.
Independent of `--isystem-to-i`/`--exclude-folder`, and applies after them,
so a path converted from `-isystem` to `-I` can also be removed by this
option.

With neither `-o` nor `-i`, the resulting JSON is written to stdout, and
the input file is left untouched. A summary (`tweaked N of M entries`) is
always printed to stderr.

## EXAMPLES

Preview the sysroot tweak without touching any file:

```
$ tools/tweak-compile-commands.py compile_commands.json
```

Apply the sysroot tweak in place:

```
$ tools/tweak-compile-commands.py -i compile_commands.json
```

Apply the sysroot tweak and convert `-isystem` to `-I`, keeping any path
that goes through a `lib1` or `lib2` folder as `-isystem`:

```
$ tools/tweak-compile-commands.py -i compile_commands.json \
--isystem-to-i --exclude-folder lib1 --exclude-folder lib2
```

Given this input entry:

```json
{
"command": "gcc --sysroot /a/b -isystem /opt/x -isystem /path/lib1/include -c foo.c -o foo.o"
}
```

the last command above produces:

```json
{
"command": "gcc -I /opt/x -I /a/b/opt/x -isystem /path/lib1/include -isystem /a/b/path/lib1/include -c foo.c -o foo.o"
}
```

Note that `/path/lib1/include` is kept as `-isystem` (matching
`--exclude-folder lib1`), and so is its sysroot-relative duplicate
`/a/b/path/lib1/include`, since it also contains a `lib1` folder component.

Remove all `-I` include paths that go through `/path/lib1`:

```
$ tools/tweak-compile-commands.py -i compile_commands.json \
--remove-include-path /path/lib1
```

Given this input entry:

```json
{
"command": "gcc -I /opt/x -I /path/lib1/include -c foo.c -o foo.o"
}
```

the command above produces:

```json
{
"command": "gcc -I /opt/x -c foo.c -o foo.o"
}
```

## EXIT STATUS

Exits with a non-zero status and a traceback if `COMPILE_COMMANDS` cannot
be read or does not contain valid JSON. Otherwise exits 0, even if no
entries needed changes.
Loading
Loading