Direct integration of the analyzer into build automation systems (in the absence of .vcproj/.vcxproj project files)

29.01.2013

Abstract

We recommend utilizing PVS-Studio analyzer through the Microsoft Visual Studio development environments, into which the tool is perfectly integrated. But sometimes you can face situations when command line launch is required, for instance in case of the cross-platform build system based on makefiles.

In case you possess project (.vcproj/.vcxproj) and solution (.sln) files, and command line execution is required for the sake of daily code checks, for instance, we advise you to examine the article "Checking code with PVS-Studio from the command line (with a Visual Studio solution file present)".

PVS-Studio analyzer independent mode

So, how does a code analyzer work (be it PVS-Studio or any other tool)?

When the analyzer user gives a command to check some file (for example, file.cpp), the analyzer performs preprocessing of this file at first. As a result, all the macros are defined and #include-files are arranged.

The preprocessed i-file can now be parsed by the code analyzer. Pay attention that the analyzer cannot parse a file which has not been preprocessed, for it won't have information about the types, functions and classes being used. Operation of any code analyzer includes at least two steps: preprocessing and analysis itself.

It is possible that C++ sources do not have project files associated with them, for example it is possible in case of multiplatform software or old projects which are built using command line batch utilities. Various Make systems are often employed to control building process in such cases, Microsoft NMake or GNU Make for instance.

To analyze such projects it is necessary to embed the direct call for the analyzer (the 'programfiles%\PVS-Studio\x64\PVS-Studio.exe' file) into building process and to pass all arguments required for preprocessing to it. In fact the analyzer should be called for the same files for which the compiler (cl.exe in case of Visual C++) is being called.

The PVS-Studio analyzer should be called in batch mode for each C/C++ file or for a whole group of files (files with c/cpp/cxx etc. extensions, the analyzer shouldn't be called for header h files) with the following arguments:

PVS-Studio.exe --cl-params  %ClArgs%
--source-file %cppFile% --cfg %cfgPath%  --output-file %ExtFilePath%

%ClArgs% — arguments which are passed to cl.exe compiler during regular compilation, including the path to source file (or files).

%cppFile% — path to analyzed C/C++ file or paths to a collection of C/C++ files (the filenames should be separated by spaces)

%ClArgs% and %cppFile% parameters should be passed to PVS-Studio analyzer in the same way in which they are passed to the compiler, i.e. the full path to the source file should be passed twice, in each param.

%cfgPath% — path to PVS-Studio.cfg configuration file. This file is shared between all C/C++ files and can be created manually (the example will be presented below)

%ExtFilePath% — optional argument, a path to the external file in which the results of analyzer's work will be stored. In case this argument is missing, the analyzer will output the error messages into stdout. The results generated here can be viewed in Visual Studio's 'PVS-Studio' toolwindow using 'PVS-Studio/Load Analysis Report' menu command (selecting 'Unparsed output' as a file type). Please note, that starting from PVS-Studio version 4.52, the analyzer supports multi-process (PVS-Studio.exe) output into a single file (specified through --output-file) in command line independent mode. This allows several analyzer processes to be launched simultaneously during the compilation performed by a makefile based system. The output file will not be rewritten and lost, as file blocking mechanism had been utilized.

Consider this example for starting the analyzer in independent mode for a single file, utilizing the Visual C++ preprocessor (cl.exe):

PVS-Studio.exe --cl-params "C:\Test\test.cpp" /D"WIN32" /I"C:/Test/" 
--source-file "C:\Test\test.cpp" --cfg "C:\Test\PVS-Studio.cfg" 
--output-file "C:\Test\test.log"

The PVS-Studio.cfg (the --cfg parameter) configuration file should include the following lines:

exclude-path = C:\Program Files (x86)\Microsoft Visual Studio 10.0
vcinstalldir = C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\ 
platform = Win32
preprocessor = visualcpp
language = C++11

Let's review these parameters:

  • The exclude-path parameter contains the directories for which the analysis will not be performed. If the Visual Studio directory is not included here, the analyzer will generate error messages for its' header .h-files. But you of course cannot modify them. Therefore we recommend you to always add this path to the exclusions. It is also possible to set multiple exclude-path parameters.
  • The vcinstalldir parameter indicates the directory in which the utilized preprocessor is located. The supported preprocessors are: Microsoft Visual C++ (cl.exe), Clang(clang.exe) and MinGW (gcc.exe).
  • The platform parameter points to the correct version of the compiler — Win32, x64, Itanium or ARMV4. It is usually Win32 or x64.
  • The preprocessor parameter indicates which preprocessor should be located at vcinstalldir. Supported values are: visualcpp, clang, gcc. Generally, one should select the preprocessor according to the compiler being used by the build automation system in question.
  • The 'language' parameter determines the version of C/C++ language within the code of the file being verified (--source-file) which is expected by the analyzer during its' parsing process. Possible values are: C, C++03, C++11. As each of the supported language variants does contain specific key words, the incorrect assignment of this parameter could potentially lead to the V001 parsing error messages.

You can filter diagnostics messages generated by analyzer using analyzer-errors and analysis-mode parameters (set them in cfg file of pass through command line). These parameters are optional.

  • The analyzers-errors parameter allows you to set the codes for errors in which you are interested. For example: analyzer-errors=V112 V111. We do not recommend setting this parameter.
  • The analysis-mode parameter allows you to control the analyzers being used. Values: 0 - full analysis (by default), 1 - only 64 bit analysis, 4 - only general-purpose analysis, 8 - only optimization analysis. The recommended value is 4.

The full list of command line switches will be displayed with this argument:

PVS-Studio.exe --help

An example of using the analyzer independent mode with Makefile project

For example let's take the Makefile project which is build using VisualC++ compiler and it is declared in the project's makefile like this:

$(CC) $(CFLAGS) $<

The $(CC) macro calls cl.exe, the compilation parameters $(CFLAGS) are passed to it and finally all C/C++ files on which the current build target is dependent are inserted using the $< macro. Thereby the cl.exe compiler will be called with required compilation parameters for all source files.

Let's modify this script in such a way that every file is analyzed with PVS-Studio before the compiler is called:

$(PVS) --source-file $< --cl-params $(CFLAGS)  $<
--cfg "C:\CPP\PVS-Studio.cfg"
$(CC) $(CFLAGS) $<

$(PVS) - path to analyzer's executable (%programfiles%\PVS-Studio\x64\PVS-Studio.exe). Take into account that the Visual C++ compiler is being called after the analyzer on the next line with the same arguments as before. This is done to allow for all targets to be built correctly so the build would not stop because of the lack of .obj-files.

Specifics of using PVS-Studio while launching from command line

PVS-Studio tool has been developed to work within the framework of Visual Studio environment. And launching it from the command line is the function that is additional to the main working mode. However, all of analyzer's diagnostic capabilities are available.

Also, when launching from the command line, the mechanisms of error-warning filtration are not available (see: diagnosable errors and suppression of separate warnings).

However the error messages generated in this mode could be easily redirected into the external file with the help of --output-file command line switch. This file will contain the unprocessed and unfiltered analyzer output.

Such a file could be viewed in PVS-Studio IDE toolwindow using 'Load Analysis Report' menu command (selecting 'Unparsed output' as a file type) and afterwards it could be saved in a standard PVS-Studio log file (plog) format. This allows you to avoid the duplication of error messages and also to use all of the standard filtering mechanisms for them.

Incremental analysis in independent command line mode

The users who are familiar with PVS-Studio incremental analysis mode within the IDE naturally will miss this feature in the command line mode. But fortunately, almost any build system could provide an incremental analysis just "out of the box", because by invoking "make" we recompile only file which were modified. So the incremental analysis will be automatically provided by using the independent command line version.

Using Microsoft IntelliSense with analyzer in independent mode.

Although it is possible to open the unfiltered text file containing analyzer diagnostic messages from within the IDE into PVS-Studio Output window (which itself will allow you to use file navigation and filtering mechanisms), you will only be able to use the code text editor inside the Visual Studio itself, as the additional IntelliSense functionality will be unavailable (that is, autocompletion, type declarations and function navigation, etc.). And all this is quite inconvenient, especially while you are handling the analysis results, even more so with the large projects, forcing you to search class and method declarations manually. As a result the time for handling a single diagnostic message will be greatly increased.

To solve this issue, you need to create an empty Visual C++ project (Makefile based one for instance) in the same directory with C++ files being verified by the analyzer (vcproj/vcxproj file should be created in the root folder which is above every file verified). After creating an empty project you should enable the 'Show All Files' mode for it (the button is in the upper part of the Solution Explorer window), which will display all the underlying files in the Solution Explorer tree view. Then you will be able to use the 'Include in Project' context menu command to add all the necessary c, cpp and h files into your project (You will also probably have to add include directory paths for some files, for instance the ones containing third-party library includes). If including only a fraction of the files verified, you also should remember that IntelliSense possibly will not recognize some of the types from within these files, as these types could be defined right in the missing files which were not included by you.

Figure 1 — including files into the project

Figure 1 — including files into the project

The project file we created could not be used to build or verify the sources with PVS-Studio, but still it will substantially simplify handling of the analysis results. Such a project could also be saved and then used later with the next iteration of analyzer diagnostics results in independent mode.

Differences in behavior of PVS-Studio.exe console version while processing one file or several files at once.

The cl.exe compiler is able to process source files as either one at a time or as a whole group of files at once. In the first case the compiler is called several times for each file:

cl.exe ... file1.cpp
cl.exe ... file2.cpp
cl.exe ... file2.cpp

In the second case it is called just once:

cl.exe ... file1.cpp file2.cpp file3.cpp

Both of these modes are supported by the PVS-Studio.exe console version as demonstrated above in the examples.

It could be helpful for a user to understand the analyzer's logics behind theses two modes. If launched individually, PVS-Studio.exe will firstly invoke the preprocessor for each file and the preprocessed file will be analyzed after it. But when processing several files at once, PVS-Studio.exe will firstly preprocess all these files and then separate instances of PVS-Studio.exe will be invoked individually for each one of the resulting preprocessed files.

Conclusion

Although the abilities included into PVS-Studio are enough to use the tool from the command line, of course it can be greatly improved. We are ready to improve the mechanism of launching PVS-Studio from the command line to the level allowing making it convenient for you to use the tool in your particular project. Please refer to our customer support.