-
Notifications
You must be signed in to change notification settings - Fork 130
split lcov and genhtml cmake opts for the Coverage profile #224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 29.x-knots
Are you sure you want to change the base?
Conversation
fa8fc63 to
7aa60c6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend moving lines 5-17 to after the find_program() calls (after line 40) to ensure variables exist before use.
build the Coverage profile, run the tests and generate the lcov html
reports with:
cmake -S . -B ${PWD}/cmake-build-debug -DCMAKE_BUILD_TYPE=Coverage
cmake --build ${PWD}/cmake-build-debug
LCOV_OPTS="--ignore-errors inconsistent,gcov,source,format --base-directory ${PWD}/src --rc geninfo_auto_base=1" GENHTML_OPTS="--ignore-errors unsupported,inconsistent,count,category --filter missing" cmake -P ${PWD}/cmake-build-debug/Coverage.cmake
e4b821d to
842bf4f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously genhtml incorrectly received LCOV_OPTS
Now that they are properly separated, you may want to document the behavior change to confirm no one was relying on passing genhtml options via LCOV_OPTS
Also may want to rename HTML_OPTS to GENHTML_OPTS throughout for consistency and clarity.
hi @kwsantiago yes I was thinking about that yesterday in the point you make about confirming no one was relying on passing LCOV_OPTS - haven't tried it yet but could solve it by falling back to LCOV_OPTS by default and then only overriding with HTML_OPTS if it's passed and that way no ones existing setups would be affected |
…option (not envvar), update doc ref
842bf4f to
b71b968
Compare
doc/developer-notes.md
Outdated
| ``` | ||
|
|
||
| HTML_OPTS can be specified to provide an options override to genhtml from the default LCOV_OPTS, the program that generates the | ||
| html report from lcov: `HTML_OPTS="--exclude boost"`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tested this?
From my understanding, --exclude boost is a lcov option not a genhtml option, so this example will fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is an option for both lcov and genhtml - so I've used it as a reference, certainly tested it to filter out the boost entries in the coverage report, however, because there is currently no genhtml distribution in homebrew you need to install a custom binary which may or may not support the same options. In my case the version I'm using doesn't support the same options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be better to provide a reference in the docs for a compatible genhtml implementation that would officially "work" on macOs/windows (if it exists) that would render this OPTS overriding change irrelevant, but I don't know what that is or would look like currently
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good but the _HTML_OPTS_WAS_DEFINED pattern seems overly complex.
| # If HTML_OPTS is not provided at all, implicitly pass LCOV_OPTS to genhtml. | ||
| # If HTML_OPTS is provided but empty (e.g. -DHTML_OPTS=""), use an empty list | ||
| # and do NOT inherit LCOV_OPTS. | ||
| set(_HTML_OPTS_WAS_DEFINED FALSE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why track _HTML_OPTS_WAS_DEFINED separately instead of checking DEFINED HTML_OPTS directly in line 37?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kwsantiago I've tried removing that and it doesn't cause an obvious issue but because separate_arguments(HTML_OPTS) (called earlier) creates/modifies the HTML_OPTS variable, if you checked if(DEFINED HTML_OPTS) after that, it would always be true, losing the ability to distinguish “user didn’t provide HTML_OPTS” from “user provided it (possibly empty)”. The _HTML_OPTS_WAS_DEFINED flag captured whether it was defined before separate_arguments() ran.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is probably the cleanest way, setting the default to LCOV_OPTS, but I need to test:
# HTML_OPTS is optionally passed via -D flag.
-# If HTML_OPTS is not provided at all, implicitly pass LCOV_OPTS to genhtml.
-# If HTML_OPTS is provided but empty (e.g. -DHTML_OPTS=""), use an empty list
-# and do NOT inherit LCOV_OPTS.
-set(_HTML_OPTS_WAS_DEFINED FALSE)
+# Default: inherit LCOV_OPTS. If HTML_OPTS is provided (even if empty), use it instead.
+set(GENHTML_OPTS ${LCOV_OPTS})
if(DEFINED HTML_OPTS)
- set(_HTML_OPTS_WAS_DEFINED TRUE)
-endif()
-separate_arguments(HTML_OPTS)
-if(_HTML_OPTS_WAS_DEFINED)
+ separate_arguments(HTML_OPTS)
set(GENHTML_OPTS ${HTML_OPTS})
-else()
- set(GENHTML_OPTS ${LCOV_OPTS})
endif()
set(GENHTML_COMMAND ${GENHTML_EXECUTABLE} --show-details ${GENHTML_OPTS})There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kwsantiago with regards to this change b581b44 I've tested this locally and for brevity just summarised the output here: tl;dr: each mode renders a different result on my machine and the only one that succeeds is when passing the specific HTML_OPTS (not empty)
The three modes:
1) pass specific HTML_OPTS
rm -rf build
cmake -S . -B build -DCMAKE_BUILD_TYPE=Coverage
cmake --build build
TMPDIR=/tmp LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 cmake -DLCOV_OPTS="--ignore-errors inconsistent,gcov,source,format --base-directory $(pwd -P)/src --rc geninfo_auto_base=1" -DHTML_OPTS="--ignore-errors unsupported,inconsistent,count,category --filter missing" -P build/Coverage.cmake
should complete and generate coverage report:
Overall coverage rate:
source files: 762
lines.......: 87.5% (101483 of 115966 lines)
functions...: 78.2% (33941 of 43392 functions)
Message summary:
200 warning messages:
category: 100
inconsistent: 100
1361 ignore messages:
category: 351
count: 2
inconsistent: 1007
unsupported: 1
➜ bitcoin-knots git:(rcov-and-genhtml)
2) pass empty HTML_OPTS
TMPDIR=/tmp LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 cmake -DLCOV_OPTS="--ignore-errors inconsistent,gcov,source,format --base-directory $(pwd -P)/src --rc geninfo_auto_base=1" -DHTML_OPTS="" -P build/Coverage.cmake
was previously untested but now fails with a corrupt trace error:
Reading tracefile test_bitcoin_coverage.info.
genhtml: ERROR: (corrupt) unable to read trace file 'test_bitcoin_coverage.info': genhtml: ERROR: (inconsistent) "./bitcoin-knots/src/wallet/coincontrol.h":27: function '_ZN6wallet16PreselectedInputC1Ev' is hit but no contained lines are hit.
To skip consistency checks, see the 'check_data_consistency' section in man lcovrc(5).
(use "genhtml --ignore-errors inconsistent ..." to bypass this error)
(use "genhtml --ignore-errors corrupt ..." to bypass this error)
CMake Error at build/Coverage.cmake:46 (execute_process):
execute_process failed command indexes:
1: "Child return code: 1"
2) Do not pass HTML_OPTS (fall through to LCOV_OPTS)
TMPDIR=/tmp LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 cmake -DLCOV_OPTS="--ignore-errors inconsistent,gcov,source,format --base-directory $(pwd -P)/src --rc geninfo_auto_base=1" -P build/Coverage.cmake
should fail as it did, with unknown options:
lcov: WARNING: (count) max_message_count=100 reached for 'inconsistent' messages: no more will be reported.
To increase or decrease this limit use '--rc max_message_count=value'.
(use "lcov --ignore-errors count,count ..." to suppress this warning)
Combining tracefiles.
.. found 2 files to aggregate.
Combining tracefiles.
Merging baseline_filtered.info..1 remaining
Merging test_bitcoin_filtered.info..0 remaining
Writing data to test_bitcoin_coverage.info
Summary coverage rate:
source files: 762
lines.......: 69.4% (80524 of 115966 lines)
functions...: 70.1% (30439 of 43392 functions)
Message summary:
102 warning messages:
count: 1
inconsistent: 100
unsupported: 1
1544 ignore messages:
inconsistent: 1544
genhtml: WARNING: Unknown option: base-directory
Use genhtml --help to get usage information
CMake Error at build/Coverage.cmake:46 (execute_process):
execute_process failed command indexes: 1: "Child return code: 1"
| if(DEFINED HTML_OPTS) | ||
| set(_HTML_OPTS_WAS_DEFINED TRUE) | ||
| endif() | ||
| separate_arguments(HTML_OPTS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should separate_arguments(HTML_OPTS) be called after checking if it's defined to avoid modifying an undefined variable?
|
|
||
| HTML_OPTS can be specified to provide an options override to genhtml from the default LCOV_OPTS, the program that generates the | ||
| html report from lcov: `HTML_OPTS="--exclude boost"`. | ||
| HTML_OPTS can override the genhtml options (which default to LCOV_OPTS). If HTML_OPTS is omitted, LCOV_OPTS are implicitly passed to genhtml. If HTML_OPTS is provided but empty (e.g. -DHTML_OPTS=""), no options are passed to genhtml and LCOV_OPTS are not inherited. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May want to add an example showing combined use of both LCOV_OPTS and HTML_OPTS to clarify precedence.
055bb3e to
97a898f
Compare
Summary
Introduce
HTML_OPTSforgenhtmlwith a sensible default: inheritLCOV_OPTSwhenHTML_OPTSis not provided. This removes duplication for shared settings while keeping a clear escape hatch forgenhtml-specific control.Background (previous behavior)
genhtml) always receivedLCOV_OPTS.--rcflags likebranch_coverage=1) but made it awkward to pass options that apply only togenhtml.What’s changing
HTML_OPTS, forgenhtml.HTML_OPTSis omitted, passLCOV_OPTStogenhtml(maintains the historical behavior and keeps shared config in sync).HTML_OPTSis provided, use it instead ofLCOV_OPTSforgenhtml.HTML_OPTSis explicitly set to an empty string, pass no extra options togenhtmland do not inheritLCOV_OPTS.Why this change
lcovandgenhtmlare separate tools with partially overlapping options.--rc), but some aregenhtml-only (e.g.,--title).genhtmlwhen needed.User-facing behavior
genhtmlreceivesLCOV_OPTSautomatically.genhtmlreceivesHTML_OPTSinstead ofLCOV_OPTS.genhtmlreceives no options; nothing is inherited.Examples
Implementation notes
cmake/script/CoverageInclude.cmake.in:HTML_OPTSwas defined (even if empty) before splitting.GENHTML_OPTStoHTML_OPTSwhen defined; otherwise fall back toLCOV_OPTS.GENHTML_COMMANDwithGENHTML_OPTS.Key snippet:
Backward compatibility
HTML_OPTSis omitted,genhtmlstill receivesLCOV_OPTS.HTML_OPTScontinue to behave as before.genhtmloptions via-DHTML_OPTS="".Documentation
doc/developer-notes.mdto describe the default inheritance, the explicit override, and the empty override, with examples using agenhtml-only flag (--title).Impact and risk
genhtml-specific customization and intentional minimalism.