I need to perform some test coverage with gcov
on a shared library I am working on.
The problem is libtool
renames the object files from my-name.c
to libmylib_la-my-name.lo
and gcov
is unable to handle that conversion. Everytime I run it, the error cannot open notes file
is generated.
If I manually rename my-name.c
to libmylib_la-my-name.c
after the build gcov
works fine, so there is no other problem apart the filename mangling.
Trying to provide a minimal working example I discovered the filename mangling happens only when lib..._la_CFLAGS
is set (and also when it is set to an empty value).
cat <<EOT > configure.ac
AC_INIT(sample,0.0.1)
AC_CONFIG_SRCDIR(configure.ac)
AM_INIT_AUTOMAKE(foreign)
LT_INIT
AC_PROG_CC
AC_CONFIG_FILES(Makefile)
AC_OUTPUT
EOT
cat <<EOT > Makefile.am
lib_LTLIBRARIES=libsample.la
libsample_la_SOURCES=sample.c
# The following line triggers the filename mangling (libsample_la-sample.lo instead of sample.lo)
libsample_la_CFLAGS=
EOT
touch sample.c && autoreconf -if && ./configure && make
Is there a way to avoid the filename mangling operated by libtool or to let gcov
understand the filename mangling scheme?
Gcov gcda
and gcno
files are named after object files. You can run gcov
from source directory directly on object file or you can use -o
option of gcov
to specify the object file and corresponding gcov
files.
For example I have a small project that builds a shared library. I pass gcov
flags to make command:
make CFLAGS="-O0 --coverage" LDFLAGS=--coverage
Object files and corresponding gcno
files are created in src/.libs
folder:
$ ls -la src/.libs
libtest_la-test.o
libtest_la-test.gcno
The source file is in src
folder
$ ls src/
test.c
Next I run my test suite and gcda
files are created:
$ ls -la src/.libs
libtest_la-test.o
libtest_la-test.gcno
libtest_la-test.gcda
Now I can enter src
directory and run gcov
, specifiying object file name:
$ gcov -o .libs/libtest_la-test.o test.c
File ‘test.c’
Lines executed:27.08% of 96
Creating ‘test.c.gcov'
It is also possible to just run gcov
on object file:
$ gcov .libs/libtest_la-test.o
File ’test.c’
Lines executed:27.08% of 96
Creating ’test.c.gcov'
Or even just specifying base name of object file and gcov
files:
$ gcov .libs/libtest_la-test
File ’test.c’
Lines executed:27.08% of 96
Creating ’test.c.gcov'
But I would suggest another automated approach that works very well for me, using lcov. I invoke it from top directory specifying paths to source files and object files:
$ lcov --base-directory src --directory src/.libs/ --capture --output-file gcov.info
Capturing coverage data from src/.libs/
Found gcov version: 4.8.2
Scanning src/.libs/ for .gcda files ...
Found 10 data files in src/.libs/
Processing .libs/test_la-test.gcda
[…]
Finished .info-file creation
$ genhtml -o html/coverage gcov.info
Reading data file gcov.info
Found 10 entries.
Found common filename prefix "/usr/src/libtest”
Writing .css and .png files.
Generating output.
Processing file src/test.c
[…]
Writing directory view page.
Overall coverage rate:
lines......: 56.1% (2098 of 3737 lines)
functions..: 68.8% (139 of 202 functions)
Now html/coverage
directory contains html files that can be easily analyzed in a web browser.
Libtool shouldn't change .c file names. However, it does change .o file names; this is because it needs to compile libraries twice on some platforms (once to create position-independent code (PIC) for .so (shared) libraries, once to create code which is not PIC for .a (static) libraries).
What you may be seeing is the fact that gcov
has issues with shared libraries. See "can gcov deal with shared object?" for details.
If that doesn't fix it, I'll have to agree with Brett that you ned to supply more info.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With