c++ coverage setup with CMake - c++

I have CMake project that sometimes may use clang, sometimes it may use gcc, sometimes it may use MSVC.
Does CMake provide some generic way to enable coverage generation, or do I need to do if else by myself(compiler flags for gcc and clang differ, and MSVC does not have coverage)?

There is no central cmake option to handle such a situation, but some solutions could be:
Don't do anything. Collect coverage statistics with kcov, which doesn't require special compiler flags.
Add a build configuration alongside the usual Debug, RelWithDebugInfo and so on. Then, select this build configuration only when it makes sense, i.e., when compiling with clang or gcc. Like this:
set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
"Build options: None Debug Release RelWithDebInfo MinSizeRel Coverage." FORCE)
# Use generator expression to enable flags for the Coverage profile
target_compile_options(yourExec
$<$<CONFIG:COVERAGE>:--coverage>)
# Don't forget that the linker needs a flag, too:
target_link_libraries(yourExec
PRIVATE $<$<CONFIG:COVERAGE>:--coverage>)
When you need to dispatch further on the compiler type, you can use generator expressions, too.
$<$<OR:$<CXX_COMPILER_ID:AppleClang>,
$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:-someOtherFlag>
but as far as I know, there are no real differences between clang and gcc with respect to coverage flags.
Don't add another build configuration, just define the above flags for the build configuration you intend to use for coverage reports, probably Debug. Then, it's obviously necessary to exclude MSVC.
target_compile_options(yourExec
$<$<AND:$<CONFIG:DEBUG>,$<NOT:CXX_COMPILER_ID:MSVC>>:--coverage>)
target_link_libraries(yourExec
PRIVATE $<$<AND:$<CONFIG:DEBUG>,$<NOT:CXX_COMPILER_ID:MSVC>>:--coverage>)

Related

CMake Treat Warnings as Errors

How can I configure CMake to treat compiler warnings as errors during the build?
I am aware of the possibility to manually configure command line options for the compiler like -Werror through commands like target_compile_options, but I would prefer a portable solution that does not require fiddling with tool-dependent options.
This can be configured in CMake version 3.24 and higher via the COMPILE_WARNING_AS_ERROR target property.
For example, to enable warnings as errors for the my_app target you could write:
set_property(TARGET my_app PROPERTY COMPILE_WARNING_AS_ERROR ON)
You can also set a global default for all targets in your project via the CMAKE_COMPILE_WARNING_AS_ERROR variable:
set(CMAKE_COMPILE_WARNING_AS_ERROR ON)
add_executable(my_app1 [...])
add_executable(my_app2 [...])
add_executable(my_app3 [...])
If a user finds it annoying that this is set in the CMakeLists.txt file, they can still override it using the --compile-no-warning-as-error configure option.
Treating warnings as errors is a good practice for CI systems with a fixed and predictable toolchain, but it is inappropriate to force on all users. Many are likely using a different toolchain with different sets of warnings and sensitivities for those warnings. Enabling -Werror by default causes broken builds for your consumers and is a bad practice.
Notably, this exact issue was the source of one major debacle in the last year in the Linux kernel: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b339ec9c229aaf399296a120d7be0e34fbc355ca
It is also prohibited by the Gentoo packaging archives (important because it is a source-based distribution): https://devmanual.gentoo.org/ebuild-writing/common-mistakes/index.html
Do a bit more searching and you will hear the shouting from the mountaintops that warnings as errors is good for developers, but not for consumers.
The best way to do this, then, is to set the new (as of CMake 3.24) variable CMAKE_COMPILE_WARNING_AS_ERROR set to ON only when you know it is safe to do so. That is to say, it should not be on by default (but if you insist, then there must be a way to disable it).
There are many good ways to set this up:
You could add it to the cacheVariables section of a preset
You could set it to ON in a toolchain file
You can simply pass it at the command line when you want to toggle it on or off.
Speaking as someone who regularly uses top-of-tree compiler builds, where warnings break frequently, hard-coded warnings-as-errors is a blight. It forces me and countless other package maintainers, devops teams, and so on, to patch your build.

How do I force cmake to use cl.exe without full path?

I am building an open source project (kst, v2.0.8) that uses CMake. I am using CMake v2.8.12.2 and MSVC 2008 as a compiler and am generating NMake makefiles to build it on the command line. I can get it to build successfully with this setup. These versions are mandated so I cannot currently use a later version of CMake or MSVC.
I need to be able to perform a source code analysis of kst using HP's Fortify and to be able to use it from the command line it works in one of two ways:
Touchless mode where it creates it's own "cl.exe", sets the path to it before the path to the real cl.exe and therefore gets launched during build.
Set the compiler in the makefile to the Fortify command line, e.g. sourceanalyzer -b build_id cl instead of cl.
Either way I need to force the compiler that cmake generates into its makefiles to be something that cmake does not automatically detect.
I've tried setting the compiler when running cmake following the same method in this question but cmake still insists on putting the full path to the MSVC cl.exe in the makefiles.
cmake -DCMAKE_C_COMPILER=cl -DCMAKE_C_COMPILER_FORCED=ON -DCMAKE_CXX_COMPILER=cl -DCMAKE_CXX_COMPILER_FORCED=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%CFITSIO_DIR% -G"NMake Makefiles" ..\cfit3250
I also tried setting the compiler to invoke Fortify but when cmake tests the compiler it fails saying that it cannot find the compiler. (I have also tried this without the FORCED=ON arguments and in that case it says the compiler fails.)
cmake -DCMAKE_C_COMPILER="sourceanalyzer -b %BUILDID% cl" -DCMAKE_C_COMPILER_FORCED=ON -DCMAKE_CXX_COMPILER="sourceanalyzer -b %BUILDID% cl" -DCMAKE_CXX_COMPILER_FORCED=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%CFITSIO_DIR% -G"NMake Makefiles" ..\cfit3250
I could probably search and replace all the compiler invocations in the makefiles but I'd have to remember to do that after every cmake, and it would be tedious seeing as there are multiple projects / makefiles / calls to cl (rather than defining a CC variable in the makefile). I'd rather have a way to make cmake use the desired compiler right from the offset.
UPDATED: Testing showed the original suggested approach didn't work as expected on at least some platforms. It seems using a wrapper script is likely the way to go.
If you really want to force a particular compiler and by-pass CMake's compiler checks, the CMakeForceCompiler module may be what you are looking for. That link to the CMake docs contains a trivial toolchain file example which shows how to use a specific compiler invoked as a simple command with no path. Unfortunately, CMake still converts this to an absolute path, so on its own, this won't solve your problem. You could, however, use a toolchain file to point at a wrapper script and use CMakeForceCompiler to bypass the compiler checks. This combination should yield the behaviour you've asked for, but note that CMakeForceCompiler is now deprecated.
Note that when using the CMakeForceCompiler module, you take on a bit more responsibility for telling CMake information, notably the compiler ID of the particular compiler you want to force using, but from the CMake docs it seems pretty clear this will just be MSVC in your case.
To use a toolchain file, invoke CMake with a -DCMAKE_TOOLCHAIN_FILE=path/to/file option pointing at your own custom toolchain file. The CMake docs have a specific section covering the use of toolchains, although it does gloss over some of the important nitty gritty details.
As mentioned in #Tsyvarev's comment, the use of a wrapper script is likely to be your best way of dealing with this. That wrapper script just needs to forward the call to the usual compiler command without specifying a path. You then take responsibility for ensuring the command will be on your PATH when you do a build. Something as simple as the following should suffice as a wrapper batch file on Windows (untested):
cl %*
Now, you can control whether the Visual Studio compiler or Fortify gets invoked purely by the PATH the build sees. Personally, I think this is a bit fragile, but it's what you asked for. ;)
As a more robust alternative, is it possible to use two completely separate builds? If so, then I'd recommend that as a better alternative. Build one with the default Visual Studio compiler as normal and for the other build, use a toolchain file to point at the Fortify compiler to get CMake to bypass its compiler checks. That way you aren't relying on the build environment being set up a particular way.

Enabling RTTI for clang tool?

I'm experimenting with clang's libTooling to build a basic source-to-source transformation tool.
I want to use boost::regex and boost::filesystem, but linking against them requires exceptions and RTTI be enabled. According to the clang mailing list , it should be possible to enable RTTI without breaking anything.
That said, I can't find a setting or variable to instruct the build system to enable RTTI. (i'm using cmake). I can add the -frtti and -fexceptions flags to the compiler commands, but the clang build system is adding its own -fno-rtti, -fno-exceptions flags which seem to have higher priority.
The relevant variables are called LLVM_ENABLE_RTTI and LLVM_ENABLE_EH.
They can can be set either by using a cmake gui like ccmake or cmake-gui, or by passing them directly to the cmake invocation.

Recommended ways to use CMake with icc via configuration options?

I would like to use the Intel compiler icc (or icpc) with a CMake-based project (on Linux for what it's worth). I can of course export the CXX variable when calling cmake, e.g. like
CXX=icpc cmake ../
and this works fine. I would however like to make this choice available via a custom option. For this I parse custom option, e.g.
cmake -DMY_COMPILER_OPTION=Intel ..
as
IF (MY_COMPILER_OPTION STREQUAL "Intel")
MESSAGE(STATUS "** Compiling with Intel settings **")
SET(CMAKE_CXX_COMPILER "icpc")
SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -w")
SET(CMAKE_CXX_FLAGS_DEBUG "-g")
ENDIF ()
and set CMAKE_CXX_COMPILER together with some compiler flags. This also works, however there is an important "but".
I would also like to use the option -ipo (interprocedural optimization) for my code when compiling with icc plus I need to compile a static library within the build process. For this to work, I need to use Intel's xiar (and also xilink I guess).
cmake actually offers a special property for this
set_property(TARGET mytarget PROPERTY INTERPROCEDURAL_OPTIMIZATION 1)
however this only seems to works properly when the compiler has been set via the environment variable (then xiar is used). When setting the compiler via CMAKE_CXX_COMPILERthis property is ignored.
Is there another way to do this?. Some recommended way? Or at least a work-around?
The recommended way is to run cmake with the appropriate CMAKE_<LANG>_COMPILER defined.
Linux users
cmake -DCMAKE_C_COMPILER=icc -DCMAKE_CXX_COMPILER=icpc -DCMAKE_Fortran_COMPILER=ifort ..
Windows users
From an Intel Compiler console:
cmake -G "NMake Makefiles" -DCMAKE_C_COMPILER=icl -DCMAKE_CXX_COMPILER=icl -DCMAKE_Fortran_COMPILER=ifort ..
Ok, since there have been no answers here, I've also turned to the CMake mailing list list for help on this issue. The consent of the experts there seems to be that the way I was trying to do this is a rather bad idea. The reason is that the parsing of my custom flags happens to late in the initialization process. One should therefore rely on setting the compiler via environment variables and let CMake do its magic during the initial configuration run. I will modify my approach..
Basically, avoid trying to change the compiler. See the FAQ: How do I use a different compiler?. CMake Toolchain files provide a way to support some complex cases, like an exotic HPC compiler.

How to tell what optimizations bjam is using to build boost

I'm building the boost libraries with bjam for both the intel compiler and vs2008, and I can't tell what optimizations are being passed to the compiler from bjam. For one of the compiler's gcc, I can see some optimizations in one of the bjam files, but I can't find the optimization flags for the compilers I care about. So, my questions are -
Does anyone know where the default optimization flags are located?
If they're declared within bjam, does anyone know how I can override them?
If you are interested in looking at the entire set of options that are passed to invoke the compiler when building you can run bjam with the -n -a options and the rest of the building options to give you the complete set of commands invoked, and any response files generated (see Boost Jam Options). Also you can look at the Boost Build sources directly and see what the specified features are translated into (see Boost Build Tools Files). For example:
For GCC see gcc.jam
For MSVC see msvc.jam
You can likely figure out the same for other compilers by just looking through the sources as they are fairly self explanatory. And you can just search for "<optimization>" and "<inlining>" in the *.jam sources.
You can override them in the command line by specifying the feature=value option in the command line when building. The options match the <feature>value specifications you see in the toolset files. For example, to override the optimizations feature you would specify in the command line some like "optimization=speed". If you want more fine grained control you would have to delve into Boost Build specifications and likely have to create a variant of your own to define specific options and features to build with.