Cannot compile with coverage due to linker not including gcov library

For integration testing, I’m compiling my application with PLATFORM=gcc and run it on desktop while firing TCP requests at it. I’d like to track test coverage during the integration test, so I’m trying to compile my program with coverage.

This should be possible with:

# compile with coverage
CFLAGS += -g -fprofile-arcs -ftest-coverage
LDFLAGS += -lgcov

But if I add this to build.mk in my app directory, I’m getting ‘undefined reference’ errors:

/firmware/build/target/user/platform-3/firmware/cbox//libuser.a(DS2408.o): In function `_GLOBAL__sub_I_65535_0__ZN6DS240810accessReadEv':
/firmware/lib/src/DS2408.cpp:86: undefined reference to `__gcov_init'
/firmware/build/target/user/platform-3/firmware/cbox//libuser.a(DS2408.o):(.data..LPBX0+0x20): undefined reference to `__gcov_merge_add'
/firmware/build/target/user/platform-3/firmware/cbox//libuser.a(defaultDevices.o): In function `_GLOBAL__sub_I_65535_0__Z15defaultActuatorv':
/firmware/lib/src/defaultDevices.cpp:47: undefined reference to `__gcov_init'
/firmware/build/target/user/platform-3/firmware/cbox//libuser.a(defaultDevices.o):(.data..LPBX0+0x20): undefined reference to `__gcov_merge_add'
/firmware/build/target/user/platform-3/firmware/cbox//libuser.a(Pid.o): In function `_GLOBAL__sub_I_65535_0__ZN3PidC2ER12ProcessValueS1_':
/firmware/lib/src/Pid.cpp:192: undefined reference to `__gcov_init'

It seems that libgcov is not included in the final link and/or not compiled into libuser.

Can anyone help me add the linker flag in the right place to make this work?

I've never been able to make LDFLAGS add a library to a user firmware build. I had to manually hack the Makefile in the system firmware source to do it. There's likely a better way, but it wasn't immediately obvious.

2 Likes

Thank you! Adding ‘-lgcov’ in module.mk seems to work:

$(TARGET_BASE)$(EXECUTABLE_EXTENSION) : $(ALLOBJ) $(LIB_DEPS) $(LINKER_DEPS)
	$(call echo,'Building target: $@')
	$(call echo,'Invoking: GCC C++ Linker')
	$(VERBOSE)$(MKDIR) $(dir $@)
	$(VERBOSE)$(CCACHE) $(CPP) $(CFLAGS) $(ALLOBJ) --output $@ $(LDFLAGS) -lgcov
	$(call echo,)

Apparently the LDFLAGS for the user module are not passed to the final build step.