Add option for generating coverage info.
To enable building with coverage, the environment variable
NATIVE_COVERAGE must be set to true.
Set `LOCAL_NATIVE_COVERAGE := true` to generate coverage information for
a given component.
This is currently not supported for clang (b/17574078, b/17583330).
If static library A is included in a binary B (dynamic or static
executable, or shared library), and A is built with coverage
information, B is required to link with libgcov.a. Since the make does
not offer a good way to track this dependency, link libgcov.a even if
LOCAL_NATIVE_COVERAGE is not set (but still guarded by NATIVE_COVERAGE).
This ensures that all of the libgcov dependencies will always be
resolved, and causes no change in the resulting binary if coverage is
not used.
Bug: 10134489
Change-Id: Id5a19f2c215e4be80e6eae27ecc19b582f2f6813
diff --git a/core/binary.mk b/core/binary.mk
index 936b429..ae01860 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -113,6 +113,7 @@
my_cxx := $(LOCAL_CXX)
my_c_includes := $(LOCAL_C_INCLUDES)
my_generated_sources := $(LOCAL_GENERATED_SOURCES)
+my_native_coverage := $(LOCAL_NATIVE_COVERAGE)
# MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
# all code is position independent, and then those warnings get promoted to
@@ -321,6 +322,31 @@
my_target_global_ldflags := $($(LOCAL_2ND_ARCH_VAR_PREFIX)TARGET_GLOBAL_LDFLAGS)
endif # my_clang
+# If the global flag NATIVE_COVERAGE is set, my_native_coverage will be true
+# unless the module explicitly sets my_native_coverage := false.
+ifeq ($(NATIVE_COVERAGE),true)
+ ifeq ($(my_native_coverage),true)
+ # We can't currently generate coverage for clang binaries for two
+ # reasons:
+ #
+ # 1) b/17574078 We currently don't have a prebuilt
+ # libclang_rt.profile-<ARCH>.a, which clang is hardcoded to link if
+ # --coverage is passed in the link stage. For now we manually link
+ # libprofile_rt (which is the name it is built as from
+ # external/compiler-rt).
+ #
+ # 2) b/17583330 Clang doesn't generate .gcno files when using
+ # -no-integrated-as. Since most of the assembly in our tree is
+ # incompatible with clang's assembler, we can't turn off this flag.
+ ifneq ($(my_clang),true)
+ my_target_global_cflags += --coverage
+ my_target_global_ldflags += --coverage
+ endif
+ endif
+else
+ my_native_coverage := false
+endif
+
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_PROJECT_INCLUDES := $(my_target_project_includes)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_C_INCLUDES := $(my_target_c_includes)
$(LOCAL_INTERMEDIATE_TARGETS): PRIVATE_TARGET_GLOBAL_CFLAGS := $(my_target_global_cflags)