I've looking to get an HTML code coverage report working with an XCode 6.1 based project. My solution 'partially works', but I'm getting a lot of skipped files when running lcov:
geninfo: file found unrecognized record format - skipping
Some more detail on my setup:
Created an XCode 'Coverage' configuration via these instructions (Steps 1+2):
https://developer.apple.com/library/ios/qa/qa1514/_index.html
Build and run my standalone testrunner using this configuration via xcodebuild.
This successfully appears to generate GCNO files and GCDA files for each of my source files. So far so good.
Run lcov (v1.11) to generate an HTML report. The command I'm using looks like the following:
lcov --capture --derive-func-data --directory ./build/Coverage/MyCppRunner.build --output-file lcov-testrun.info --ignore-errors graph
This also succeeds, due to the ignore-errors argument. However, I'm getting a lot of skipped gcno files with the following error:
geninfo: WARNING: /Users/myname/build/Coverage/MyCppRunner.build/Objects-normal/x86_64/MyFile.gcno: found unrecognized record format - skipping
When I generate my HTML report via genhtml, these files don't show any coverage.
Is there any way around this issue? A different set of clang flags perhaps, or an alternative to lcov? I briefly tried gcovr, but I couldn't get it working.
Related
I am unable to generate the code coverage data when the the workspace is built with custom XCODE_CONFIGURATION_BUILD_DIR.
We run the xcodebuild commands to build the workspace with a XCODE_CONFIGURATION_BUILD_DIR, so that multiple jenkins CI jobs won't overwrite the build output of other jobs which are also running concurrently.
When we run the tests for a build generated this way and try to get the code coverage report, the command fails with the below error.
jenkins$ xcrun xccov view *.xccovreport
Errors:
Error Domain=IDEFoundationErrorDomain Code=14 "Failed to merge raw profiles in directory /Users/jenkins/Library/Developer/Xcode/DerivedData/XXXXXX-buggtqumttnpjvejnbfhulhqcvno/Build/ProfileData/bff950eda0f75b2dbadb3ce08510474b4667ac82 to destination /Users/jenkins/Library/Developer/Xcode/DerivedData/XXXXXX-buggtqumttnpjvejnbfhulhqcvno/Build/ProfileData/bff950eda0f75b2dbadb3ce08510474b4667ac82/Coverage.profdata: No profile data files were written to '/Users/jenkins/Library/Developer/Xcode/DerivedData/XXXXXX-buggtqumttnpjvejnbfhulhqcvno/Build/ProfileData/bff950eda0f75b2dbadb3ce08510474b4667ac82'" UserInfo={NSLocalizedDescription=Failed to merge raw profiles in directory /Users/jenkins/Library/Developer/Xcode/DerivedData/XXXXXX-buggtqumttnpjvejnbfhulhqcvno/Build/ProfileData/bff950eda0f75b2dbadb3ce08510474b4667ac82 to destination /Users/jenkins/Library/Developer/Xcode/DerivedData/XXXXXX-buggtqumttnpjvejnbfhulhqcvno/Build/ProfileData/bff950eda0f75b2dbadb3ce08510474b4667ac82/Coverage.profdata: No profile data files were written to '/Users/jenkins/Library/Developer/Xcode/DerivedData/XXXXXX-buggtqumttnpjvejnbfhulhqcvno/Build/ProfileData/bff950eda0f75b2dbadb3ce08510474b4667ac82'}
Version/Build:
Version 10.1 (10B61)
Found this thread on Github
The issue was: generating coverage for a Static Library fails, but not for a Dynamic Library.
So check if it works, changing on pbxproj:
- MACH_O_TYPE = staticlib;
+ MACH_O_TYPE = mh_dylib;
And it really generated coverage successfully on my sample framework.
The solution which worked for me was, I have changed the Mach-O-Type from Executable to Static Library.
With the option Dynamic Library also, the coverage report was generating but the build was failing.
Another option was to set the test target as Static Library and Main Target as Executable. Build Succeeded and able to see the coverage for multiple targets.
Xcode Version : 13.4
I my trying to do code coverage of gcc source code for a set of 2000 programs.
I built compiler with --enable-coverage compiler option so it generates the coverage files upon compilation of a sample program.
Running the following command :
path/to/bin/lcov -c -d path/to/*.gcda/files/ -o info.info
I am getting error as:
Capturing coverage data from .
Found gcov version: 6.3.0
Scanning . for .gcda files ...
Found 460 data files in .
Processing i386.gcda
geninfo: ERROR: build/gcc/i386.gcno: could not open file
I am unable to find anything on google for such problem?
Make sure your .gcda and .gcno files are in the same directory as gcov searches for .gcno files in the same location where .gcda files are.
After updating to Xcode 10 there are some issues with initial project configurations. The steps look like this:
Generating some files using Sourcery
Linting with SwiftLint
Build
And configuration works like this:
And this was working fine in Xcode 9, but apparently, it's not working under Xcode 10 build system. The issue is if I download repository (.generated files are not a part of the repository). And hit build it will show me results like:
...
Using configuration file at '.sourcery.yml'
Scanning sources...
Found 239 types.
Loading templates...
Loaded 9 templates.
Generating code...
Finished.
Processing time 0.491948962211609 seconds
...
So sourcery works ok, then linting:
Linting 'FromResponse.generated.swift' (1/186)
Works fine as well as a process, but in the end, build will fail with:
error: Build input files cannot be found:
'/path/Generated/FromResponse.generated.swift',
...
So it's strange since a files are physically there and according to build settings file should be compiled later than generating them. How should I approach sourcery in build process then?
We are able to "fix" this in a similar way as this Github issue:
https://github.com/mac-cain13/R.swift/issues/438#issuecomment-416982928
We have to add each of the generated files by Sourcery to the output folder and it will get picked up by the Xcode correctly.
This relates to changes in the New Xcode Build System that has been enabled by default in Xcode 10. If a build phase creates files which are needed as an input to a later build phase then it needs to specify them explicitly in the Output Files or Output File List.
In your example the Sourcery build phase is generating Swift source file(s) which are needed as input to the Compile Sources phase.
However, the issue at this point is that after you specify the output files for Sourcery, the build phase doesn't re-run every time as it sees the output file is already there. So far I haven't worked out a useable solution to this part, beyond running tools like Sourcery and SwiftGen manually or keeping the generated files in Git so that they are always present.
I was having a similar problem with a buildphase calling mogenerator to build my data model classes. The approach given by #Yuchen should work.
#Andrew: To force always (re-)running this build phase, I add the line
touch .alwaysRun
as the last line in the shell command to run and mark the build phase "Input Files" to have $(SRCROOT)/.alwaysRun. That seems to do the trick.
I'm trying to use lcov to generate coverage reports for my unit test suite, but I cannot even capture a tracefile. The error messages indicate that the source files cannot be found. The code is compiled by a Jenkins job on a build machine and the unit test are executed as a downstream job on a target machine. The source code and gcno files are transfered to the downstream job, which then executes the call to lcov. Here follows all the details, a cup of coffee might be needed.
On the build machine, make is executed in
/var/lib/jenkins/workspace/App-Coverage/BUILD/app/
The source code which I want coverage for is in subdirectories in
/var/lib/jenkins/workspace/App-Coverage/BUILD/app/packages/
The object files and gcno files are generated in an subdirectory o relative to the corresponding cpp file. So for example
/var/lib/jenkins/workspace/App-Coverage/BUILD/app/packages/subdir/Myclass.cpp
/var/lib/jenkins/workspace/App-Coverage/BUILD/app/packages/subdir/o/Myclass.o
/var/lib/jenkins/workspace/App-Coverage/BUILD/app/packages/subdir/o/Myclass.gcno
The source files and gcno files are copied to the unit test machine keeping the same folder structure and ends up in
/var/lib/jenkins/workspace/App-Coverage-Unittest/BUILD/app/
Note: There is a difference in the name of the workspace folder, "App-Coverage-Unittest" instead of "App-Coverage" since these two Jenkins jobs cannot have the same name.
So there is now for example
/var/lib/jenkins/workspace/App-Coverage-Unittest/BUILD/app/packages/subdir/Myclass.cpp
/var/lib/jenkins/workspace/App-Coverage-Unittest/BUILD/app/packages/subdir/o/Myclass.o
/var/lib/jenkins/workspace/App-Coverage-Unittest/BUILD/app/packages/subdir/o/Myclass.gcno
The unit tests are executed in
/opt/app/test/app
Using GCOV_PREFIX_STRIP and GCOV_PREFIX I make the gcda files appear in the same folders as the gcno files, so for example
/var/lib/jenkins/workspace/App-Coverage-Unittest/BUILD/app/packages/subdir/o/Myclass.gcno
/var/lib/jenkins/workspace/App-Coverage-Unittest/BUILD/app/packages/subdir/o/Myclass.gcda
Now I want to generate a coverage report using lcov, but I don't seem to understand how to set the paths correctly. The following examples where executed from /var/lib/jenkins/workspace/App-Coverage-Unittest/ by the Jenkins unittest job.
For example I tried
lcov -d BUILD/app/packages/ -c --no-external -o app.info -b /var/lib/jenkins/workspace/App-Coverage-Unittest/BUILD/app/
Reasoning: "-d BUILD/app/packages/" is what I want coverage for, "-b /var/lib/jenkins/workspace/App-Coverage-Unittest/BUILD/app/" is the root of my project in which I executed make (but on the build machine with a different workspace name...).
I also tried
lcov -d BUILD/app/packages/ --capture --no-external --output-file app.info
Reasoning : "-d BUILD/app/packages/" is what I want coverage for, don't set -b since relative path between each gcno/gcda and corresponding source file is the same as on the build machine, maybe lcov can figure it out.
In both cases get errors like "Cannot open source file /var/lib/jenkins/workspace/App-Coverage/BUILD/app/packages/subdir/Myclass.cpp"
Note: The workspace folder in this path is that of the build machine, not the unittest machine. I thought that this is what the -b option is intended to solve. Clearly this is very suspicious and a valuable clue.
I also get errors like "Cannot open source file ../../../packages/subdir/Myclass.h", which I guess has to do with how I include header files.
I have tried specifying all the paths here. Is it possible to generate the coverage report in the workspace of the unittest job using lcov, like I'm trying to do here? If yes, which are the correct paths to specify for lcov -d and -b flags? If not, what do I need to change to make it work?
Fortunately the answer is yes, it is possible. I got a reply from an lcov dev providing me with the solution, thank you Peter!
He pointed out that all source code paths are hard-coded during the compile step into the .gcno files. However, despite not finding the source files (and producing the warnings) lcov will generate code coverage output even when the source code cannot be found, based solely on the data found in .gcda and .gcno files. However, the genhtml step will fail because it won't be able to find the source code to annotate with code coverage data.
The solution is to use lcov's "geninfo_adjust_src_path" configuration setting. By using this setting, lcov is instructed to change source code paths as found in the .gcno files into the correct source code paths while writing the output .info files. So in my case:
lcov -d BUILD/app/packages/ --capture --no-external --output-file app.info
--rc geninfo_adjust_src_path="/var/lib/jenkins/workspace/App-Coverage/BUILD/
=> /var/lib/jenkins/workspace/App-Coverage-Unittest/BUILD/"
The warnings "Cannot open source file" will still be there when invoking lcov, but the resulting .info file will contain the correct paths and can therefore be converted to HTML on the test machine using genhtml.
Trying to build coverage data for Coveralls I get the following error messages during the Travis-CI build:
DTHTMLWriter.gcno:version '404*', prefer '402*'
File '/Users/travis/build/Cocoanetics/DTCoreText/Core/Source/DTHTMLWriter.m'
Lines executed:67.00% of 497
/Users/travis/build/Cocoanetics/DTCoreText/Core/Source/DTHTMLWriter.m:creating 'DTHTMLWriter.m.gcov'
File 'Core/Source/DTHTMLWriter.m'
Lines executed:0.00% of 10
Core/Source/DTHTMLWriter.m:creating 'DTHTMLWriter.m.gcov'
Core/Source/DTHTMLWriter.m:cannot open source file
File 'Core/Source/DTHTMLWriter.h'
Lines executed:66.67% of 3
Core/Source/DTHTMLWriter.h:creating 'DTHTMLWriter.h.gcov'
Core/Source/DTHTMLWriter.h:cannot open source file
There is coverage, namely 67%, but the result of this is that Coveralls shows this file as having 0 coverage.
How do I fix that?
Tests have shown that this error occurs with the gcov tool bundled with Xcode 4 and 5, version 4.2.1 in both cases. I dound that if I run the same unit test on Mac instead, then I don't get the warning and the files are found.
Which lewds me to believe that the gcov tool has a bug handling certain gcda files produced by iOS simulator. Some, not all.
The resultning coverage report is missing those files when run for iOS, but is complete for Mac.
So my second question is if there is a way to change those files to allow gcov to correctly process them?