PlatformIO Community

Codecoverage running natively on OSX

I am really struggling. I cannot get coverage reports to run on my native target on OS X. Has anyone gotten this working? Ideally we’d get a solution that would run both locally and in github actions (Unix)

I’m running 12.6 (Monterey) on an M2.

In the end, I get ld: library not found for -lgcov

Has anyone gotten this working?

In my platformio.ini I have:

[env:native]
platform = native
build_flags = -std=gnu++11 -lgcov --coverage
build_src_filter = 
	+<./native>
test_filter =
	test_example_lib
lib_deps = 
	example_lib @ 1.0.0
	fabiobatsilva/ArduinoFake @ ^0.3.1

Does this work standalone when you use your system compiler (probably clang) on the commandline? I read here that it uses some other flags and mechanisms. Maybe this helps too?

Your comment got me down the right path. Setting the -lgcov on the linker breaks, but setting --coverage fixes the issue.

Using pio test -e native -vvv I got the commandlines for compiling and linking the code. I see that my compile commands have the --coverage when compiling, but not when linking; and the -lgcov option is only passed to the linker. So somewhere platformio is splitting up the build flags.

Looking up the docs for --coverage for gnu: The option is a synonym for -fprofile-arcs -ftest-coverage (when compiling) and -lgcov (when linking) source. So this behavior platformio should be fine for gnu.
Now, digging through docs, I could not find docs for what this does on OS X.

On OS X, g++ is clang. I couldn’t find any docs about clang other than --coverage exists.

g++ --version                                                                                                                                                                                                                                                                                                                          
Apple clang version 14.0.0 (clang-1400.0.29.202)

So I compared commandlines which are generated by g++/clang when we have --coverage and when we do not by running -v. On OS X, when we have the --coverage option specified in a linker command, it adds this library to the ultimate commandline: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/lib/darwin/libclang_rt.profile_osx.a

tldr; I believe the --coverage option needs to be passed to the linker if the libraries are compiled with --coverage. Using just --coverage and not -lgcov will make this platform independent as --coverage is synonymous with -lgcov on gnu, but will be handled correctly by clang (at least on OS X).

edit:
I should clarify. I am referring to the final program link g++ -o .pio/build/native/program ... needs the --coverage option. I need a way to force an option into this command to move forward.

Okay. Digging some more, I found a solution in an issue.

The solution to get this working on OS X

[env:native]
platform = native
build_flags = 
    ${common.build_flags}
	; native is only used for unit testing
	-DPIO_UNIT_TESTING
	--coverage
build_src_filter = 
	+<./native>
test_filter =
	${native.test_filter}
lib_deps =
	${native.lib_deps}
extra_scripts = add_link_flags

And then the file add_link_flags (probably gonna rename that)

Import("env")

env.Append(
  LINKFLAGS=[
      "--coverage"
  ]
)