I need to switch a cmake based project from g++ to clang for some reasons. I've made the switch to llvm-11 on Ubuntu 20.04. I got the project itself compile, unit tests work as well. Though, getting coverage reporting working again seems tough.
I need to create a cobertura xml file in order to integrate it into the existing CI/CD infrastructure (Jenkins and Gitlab). I've been using an older version of [1] for cmake cobertura reporting.
I thought 'llvm-cov gcov' should do the trick for me already to do the switch, but I just end up with an empty xml file with no error reported.
Next to the empty xml there is a new default.profraw file generated by llvm-cov that ends up in the build directory. I got so far as to figure out that the .profdata file format which llvm-profdata can convert to seems to be more promising as intermediate format for conversion than the raw data format. So I've generated a .profdata file for testing from that using:
llvm-profdata-11 merge -sparse default.profraw -o default.profdata
And I can generate an HTML file from this as well which actually contains expected coverage:
llvm-cov show my-unit-tests -instr-profile=default.profdata ../src/*.cpp -path-equivalence -use-color --format html > coverage.html
Here is also the related snippet from the CMake file:
append_coverage_compiler_flags()
setup_target_for_coverage_gcovr_xml(
NAME coveragereports
EXECUTABLE my-unit-tests
DEPENDENCIES my-unit-tests my-app-lib-testing
#BASE_DIRECTORY "coverage"
#BASE_DIRECTORY "../"
EXCLUDE "${CMAKE_SOURCE_DIR}/libraries/*" "${CMAKE_SOURCE_DIR}/test/*" "/Library/*"
)
What tools / options do I have to convert the coverage data generated by clang(11) to cobertura xml?
[1] https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake
Related
Our project uses CMake to configure our code. We use Ninja along with a distributed build system. A number of people on our team use Eclipse CDT. We run CMake with the "Eclipse CDT4 - Ninja" generator and the result is generally pretty good.
The issues is that any time a CMake file is changed and you ask Eclipse to build the code it regenerate the eclipse project file overwriting any manual changes you've made to the project.
For example the default build command that it provides the eclipse project is /usr/bin/ninja when in fact I want to take advantage of our distributed build system and set the build command to /usr/bin/ninja -j16. It would be nice if I could have the project file that CMake generates automatically include this setting change.
The other setting I am most interested in preserving is the C/C++ Project Paths->Source. As a general rule we place our CMake build directory as a sibling to the main project directory i.e. ./project ./build. We want to include some files in the build directory in the Eclipse index to make code completion and other tools work better. The default project doesn't include the build directory in source path and thus it does not get indexed.
Is there some way to remedy these issues?
I found a solution to build command issue.
When you run cmake to generate the eclipse project include the additional argument:-DCMAKE_ECLIPSE_NINJA_ARGUMENTS=-j100. I haven't confirmed but I believe a similar command is required for eclipse make projects -DCMAKE_ECLIPSE_MAKE_ARGUMENTS=-j100.
Unfortunately this feature is poorly documented and I have not found a solution to my other issue.
I am creating a Mapnik plugin (https://github.com/rbuch703/coords-mapnik-plugin), and am currently working on packaging it for Debian/Ubuntu. The binary package consists of only a single shared library that is built from C++ code. But being a Mapnik plugin, this library follows conventions quite different from the usual POSIX library conventions:
the file name has to be <name>.input instead of lib<name>.so
the file is installed in the Mapnik plugin directory (usually /usr/lib/mapnik/input)
the file is not supposed to be found by ldconfig, but rather Mapnik tries to find the plugin by itself at runtime
Now the plugin's build system is cmake, which makes most parts of Debian packaging straight-forward: the debian/rules file contains only the basic lines:
#!/usr/bin/make -f
%:
dh $#
However, I am running into problems with the substitution variable {shlibs:Depends}: it is simply not set (in particular, there is no corresponding line in the debian/<package name>.substvars file), and Lintian rightly complains about that fact (Lintian's actual complaint is missing-dependency-on-libc. But when I manually add a libc dependency, Lintian explains package-depends-on-hardcoded-libc, which means "The given package declares a dependency on libc directly instead of using ${shlibs:Depends} in its debian/control stanza."). I would like to satisfy Lintian in than respect, but are unable to do so.
Now I found that I could add the line
dpkg-shlibdeps debian/<packagename>/usr/lib/mapnik/input/coords.input
to my rules file. That will create the correct ${shlibs:Depends} line, but it will create it in the wrong file (debian/substvars instead of debian/<package name>.substvars), where the build system simply ignores it and Lintian keeps complaining about missing dependencies.
I am guessing that the root of my problem is that my Mapnik plugin does not conform to the POSIX library naming conventions (and as a Mapnik plugin cannot do so), and thus the packaging system does not handle it correctly. But I am at a loss as to how to fix this problem.
Additional notes:
the packages are built using debuild. Apart from the Lintian error messages, the build process work fine and correctly creates the .deb package.
my practical goal is for the package to build cleanly on Launchpad, so that I can add it to my Ubuntu PPA.
you can provide an output file for dpkg-shlibdeps with the -T flag.
something like:
override_dh_shlibdeps:
dh_shlibdeps
dpkg-shlibdeps \
-Tdebian/<packagename>.substvars \
debian/<packagename>/usr/lib/mapnik/input/coords.input
if there are multiple *.input files, you could also do something like:
override_dh_shlibdeps:
dh_shlibdeps
find debian/<packagename>/ -name "*.input" -exec \
dpkg-shlibdeps -Tdebian/<packagename>.substvars {} +
I'm using the idea plugin on a Gradle multiproject configuration to generate the Intellij configuration files. At the moment the build is working fine in Gradle, but it gives me errors on the IDE due to the missing JPA Metamodel source files.
My question is, how can I place the generated .java files in a different folder and set them as a source folder for the modules in Intellij?
Currently I'm trying to send the parameter -s to javac but I keep getting the error invalid flag: -s...
Depending on how you want the generated source files to be compiled, the solution may be as simple as adding the source files to the main source set:
sourceSets.main.java.srcDir "build/generated-files" // adapt as necessary
Additionally, compileJava will need to depend on the task that generates the sources.
I want to set up my Jenkins with Cobertura to track code coverage.
Unfortunately I can not generate a valid xml.
I'm using:
gcovr 2.5-prerelease (r2774)
Xcode 4.6.1 Build version 4H512
My project is generating code coverage files correctly, but the report created with gcovr is not useful.
The command I use to generate the report is:
gcovr -r /Users/Shared/Jenkins/Home/jobs/CodeCoverage/workspace
--object-directory /Users/Shared/Jenkins/Home/Library/Developer/Xcode/DerivedData/myProject-aooceqwwovrizceerghqvhflcfty//Build/Intermediates/myProject.build/Development/myProject.build/Objects-normal/x86_64
--exclude '.*Developer.*'
--exclude '.*Tests.*'
--xml
This will create me this output:
<?xml version="1.0" ?>
<!DOCTYPE coverage SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-03.dtd'>
<coverage branch-rate="0.0" line-rate="0.0" timestamp="1364322914" version="gcovr 2.5-prerelease (r2774)">
<sources>
<source>
/Users/Shared/Jenkins/Home/jobs/CodeCoverage/workspace/Project/myProject/
</source>
</sources>
<packages/>
</coverage>
Additional Informations:
If I remove --object-directory and -r and then I execute the command from the derived data directory a valid report is generated. This report can be read from cobertura but can not show any detailed information about the source files.
When working with XCode, I've found that using $WORKSPACE/build as the build directory helps with this problem. This keeps the Derived Data directory out of it, and also neatly keeps my object files in the build directory. It also prevents two builds from interfering with each other.
If using the Xcode build tool, set SYMROOT to $WORKSPACE/build in the Tool's build configuration. If you're building from the command line, set it manually on the command line or in the environment.
Then a gcovr script such as:
/your/path/to/gcovr -r . --object-directory build/YourApp.build/Coverage-iphonesimulator/YourApp.build/Objects-normal/i386 --xml > build/coverage.xml
(your path may vary slightly depending on what you call your build style, etc.)
And finally in the Cobertura config, point at build/coverage.xml, and you should get annotated source when you use the tool within Jenkins.
Should do the trick. I've been really happy with that configuration on our small farm of Mac Minis.
gcovr should be executed from the folder where the .gcda and .gcno files exist. And the root path is the folder where the source files(.c or .cpp) exist.
With this, the command looks like something as shown below.
rr-mac:gcdaFolder$ gcovr -r /path_to_C_sourceFiles/ .
For output html file below command works
rr-mac:gcdaFolder$ gcovr --html -o Filename_rp.html -r /path_to_C_sourceFiles/ .
Note: The dot(.) at the end is mandatory
The gcovr python script does not appear to supports out of source tree builds.
I raised a bug report about this here https://github.com/gcovr/gcovr/issues/61
After compiling with CMake with flags --coverage, and running my boost unit test programs, files with extension .cpp.gcda and .cpp.gcno are created. If I then run gcovr it claims it cannot find the .gcno files (error message ".gcno:cannot open graph file"). I could possibly move all output files but that would be really awkward/silly.
Related problems of other people could be solved by using CTest but as I am using Jenkins I'd like to stick to gcovr and use the cobertura xml output.
Ps. Maybe I should simply ask: how should I combine CMake with gcovr?
This is the solution we are using for the same setup inside jenkins: http://www.semipol.de/archives/320. You can simply grab the CMake macro from the linked RSC library for your own purposes.
Apart from that read something about a slightly changed format of the coverage files in recent gcc versions and it seems gcovr didn't keep up with that. But I cannot remember where I read this.