aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@spawned.biz>2018-02-27 21:46:08 +0100
committerJoel Klinghed <the_jk@spawned.biz>2018-02-27 21:58:05 +0100
commit6266089866469c2a2d298b79df74d2aad86bbeea (patch)
treedfdcd675b8a367c6433f7e3aa034a283be6379d7
parentda017702613d718ac69ae213ee91358566f7b622 (diff)
downloadmeson-6266089866469c2a2d298b79df74d2aad86bbeea.zip
meson-6266089866469c2a2d298b79df74d2aad86bbeea.tar.gz
meson-6266089866469c2a2d298b79df74d2aad86bbeea.tar.bz2
Allow gcovr >= 3.1 to be used to generate html coverage report
Modern gcovr includes html generation support so if lcov and genhtml are not available fallback to gcovr. Kept lcov and genhtml as default so to not surprise existing users of coverage-html with the different output of gcovr. gcovr added html support in 3.0 but as there already is a test for 3.1 because of the changes to -r/--rootdir I opted to only allow html generation for >= 3.1 to keep things simple.
-rw-r--r--docs/markdown/Feature-autodetection.md2
-rw-r--r--docs/markdown/Unit-tests.md2
-rw-r--r--mesonbuild/backend/ninjabackend.py13
-rw-r--r--mesonbuild/scripts/coverage.py10
-rwxr-xr-xrun_unittests.py7
5 files changed, 28 insertions, 6 deletions
diff --git a/docs/markdown/Feature-autodetection.md b/docs/markdown/Feature-autodetection.md
index 65318ec..f865174 100644
--- a/docs/markdown/Feature-autodetection.md
+++ b/docs/markdown/Feature-autodetection.md
@@ -16,4 +16,4 @@ If you do not wish to use CCache for some reason, just specify your compiler wit
Coverage
--
-When doing a code coverage build, Meson will check the existence of binaries `gcovr`, `lcov` and `genhtml`. If the first one is found, it will create targets called *coverage-text* and *coverage-xml*. If the latter two are found, it generates the target *coverage-html*. You can then generate coverage reports just by calling e.g. `ninja coverage-xml`.
+When doing a code coverage build, Meson will check the existence of binaries `gcovr`, `lcov` and `genhtml`. If the first one is found, it will create targets called *coverage-text* and *coverage-xml*. If the latter two or a new enough `gcovr` is found, it generates the target *coverage-html*. You can then generate coverage reports just by calling e.g. `ninja coverage-xml`.
diff --git a/docs/markdown/Unit-tests.md b/docs/markdown/Unit-tests.md
index afbeaa0..53ce9ec 100644
--- a/docs/markdown/Unit-tests.md
+++ b/docs/markdown/Unit-tests.md
@@ -30,7 +30,7 @@ Note how you need to specify multiple values as an array.
Coverage
--
-If you enable coverage measurements by giving Meson the command line flag `-Db_coverage=true`, you can generate coverage reports. Meson will autodetect what coverage generator tools you have installed and will generate the corresponding targets. These targets are `coverage-xml` and `coverage-text` which are both provided by [Gcovr](http://gcovr.com) and `coverage-html`, which requires [Lcov](https://ltp.sourceforge.io/coverage/lcov.php) and [GenHTML](https://linux.die.net/man/1/genhtml).
+If you enable coverage measurements by giving Meson the command line flag `-Db_coverage=true`, you can generate coverage reports. Meson will autodetect what coverage generator tools you have installed and will generate the corresponding targets. These targets are `coverage-xml` and `coverage-text` which are both provided by [Gcovr](http://gcovr.com) and `coverage-html`, which requires [Lcov](https://ltp.sourceforge.io/coverage/lcov.php) and [GenHTML](https://linux.die.net/man/1/genhtml) or [Gcovr](http://gcovr.com) with html support.
The output of these commands is written to the log directory `meson-logs` in your build directory.
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 92d7dfb..54d1545 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -668,6 +668,19 @@ int dummy;
elem.add_item('COMMAND', command)
elem.add_item('DESC', 'Generating HTML coverage report.')
elem.write(outfile)
+ elif gcovr_exe and gcovr_3_1:
+ added_rule = True
+ htmloutdir = os.path.join(self.environment.get_log_dir(), 'coveragereport')
+ phony_elem = NinjaBuildElement(self.all_outputs, 'meson-coverage-html', 'phony', os.path.join(htmloutdir, 'index.html'))
+ phony_elem.write(outfile)
+ # Alias that runs the target defined above
+ self.create_target_alias('meson-coverage-html', outfile)
+ elem = NinjaBuildElement(self.all_outputs, os.path.join(htmloutdir, 'index.html'), 'CUSTOM_COMMAND', '')
+ command = [gcovr_exe, '--html', '--html-details', '-r', self.environment.get_build_dir(),
+ '-o', os.path.join(htmloutdir, 'index.html')]
+ elem.add_item('COMMAND', command)
+ elem.add_item('DESC', 'Generating HTML coverage report.')
+ elem.write(outfile)
if not added_rule:
mlog.warning('coverage requested but neither gcovr nor lcov/genhtml found.')
diff --git a/mesonbuild/scripts/coverage.py b/mesonbuild/scripts/coverage.py
index 4746134..564286a 100644
--- a/mesonbuild/scripts/coverage.py
+++ b/mesonbuild/scripts/coverage.py
@@ -70,13 +70,21 @@ def coverage(source_root, build_root, log_dir):
'--show-details',
'--branch-coverage',
covinfo])
+ elif gcovr_exe and gcovr_3_1:
+ htmloutdir = os.path.join(log_dir, 'coveragereport')
+ subprocess.check_call([gcovr_exe,
+ '--html',
+ '--html-details',
+ '-r', build_root,
+ '-o', os.path.join(htmloutdir, 'index.html'),
+ ])
if gcovr_exe:
print('')
print('XML coverage report can be found at',
pathlib.Path(log_dir, 'coverage.xml').as_uri())
print('Text coverage report can be found at',
pathlib.Path(log_dir, 'coverage.txt').as_uri())
- if lcov_exe and genhtml_exe:
+ if (lcov_exe and genhtml_exe) or (gcovr_exe and gcovr_3_1):
print('Html coverage report can be found at',
pathlib.Path(htmloutdir, 'index.html').as_uri())
return 0
diff --git a/run_unittests.py b/run_unittests.py
index 41cbf39..4c48041 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -2554,10 +2554,11 @@ class LinuxlikeTests(BasePlatformTests):
self.assertIn("-fsanitize=address", i["command"])
def test_coverage(self):
- if not shutil.which('gcovr'):
+ gcovr_exe, gcovr_3_1 = mesonbuild.environment.detect_gcovr()
+ if not gcovr_exe:
raise unittest.SkipTest('gcovr not found')
- if not shutil.which('genhtml'):
- raise unittest.SkipTest('genhtml not found')
+ if not shutil.which('genhtml') and not gcovr_3_1:
+ raise unittest.SkipTest('genhtml not found and gcovr is too old')
if 'clang' in os.environ.get('CC', ''):
# We need to use llvm-cov instead of gcovr with clang
raise unittest.SkipTest('Coverage does not work with clang right now, help wanted!')