From 570dd0ccae1ca812e3cd1289c414158f2cab9dda Mon Sep 17 00:00:00 2001 From: Ryan Harrison Date: Wed, 6 Feb 2013 16:33:15 -0500 Subject: [PATCH] crash-reporter: Updating common.mk to ToT to enable profiling This update replaces the current common.mk used in this project with the newest version. This will allow all of the common.mk based projects to be on the same version for debugging and enables profiling support. BUG=chromium-os:37854 TEST=Exectuted the following commands to confirm the build works: MODE=profiling cros_workon_make --board=link MODE=profiling cros_workon_make --board=link --test cros_workon_make --board=link cros_workon_make --board=link --test Repeated these with emerge-link, USE=profiling, and FEATURES=test as need. For the emerge command with profiling and testing enable, confirmed the appropriate coverage files were created in /usr/share/profiling/... Change-Id: I12fcd4a590994223ddc42cf22670db82e94f0e03 Reviewed-on: https://gerrit.chromium.org/gerrit/42777 Tested-by: Ryan Harrison Reviewed-by: Mike Frysinger Commit-Queue: Ryan Harrison --- crash_reporter/common.mk | 122 ++++++++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 39 deletions(-) diff --git a/crash_reporter/common.mk b/crash_reporter/common.mk index 5b36080d8..058e9063a 100644 --- a/crash_reporter/common.mk +++ b/crash_reporter/common.mk @@ -1,4 +1,4 @@ -# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # @@ -64,7 +64,11 @@ # Possible command line variables: # - COLOR=[0|1] to set ANSI color output (default: 1) # - VERBOSE=[0|1] to hide/show commands (default: 0) -# - MODE=dbg to turn down optimizations (default: opt) +# - MODE=[opt|dbg|profiling] (default: opt) +# opt - Enable optimizations for release builds +# dbg - Turn down optimization for debugging +# profiling - Turn off optimization and turn on profiling/coverage +# support. # - ARCH=[x86|arm|supported qemu name] (default: from portage or uname -m) # - SPLITDEBUG=[0|1] splits debug info in target.debug (default: 0) # If NOSTRIP=1, SPLITDEBUG will never strip the final emitted objects. @@ -97,8 +101,6 @@ COLOR ?= 1 VERBOSE ?= 0 MODE ?= opt ARCH ?= $(shell uname -m) -# TODO: profiling support not completed. -PROFILING ?= 0 NEEDS_ROOT = 0 NEEDS_MOUNTS = 0 @@ -161,8 +163,7 @@ MAKECMDGOALS ?= all _all:: %:: $(if $(filter 0,$(RUN_ONCE)), \ - $(QUIET)mkdir -p "$(OUT)" && \ - cd $(OUT) && \ + cd "$(OUT)" && \ $(MAKE) -r -I "$(SRC)" -f "$(CURDIR)/Makefile" \ SRC="$(CURDIR)" OUT="$(OUT)" $(foreach g,$(MAKECMDGOALS),"$(g)"),) $(eval RUN_ONCE := 1) @@ -182,10 +183,15 @@ ifeq ($(words $(filter-out Makefile common.mk %.d $(SRC)/Makefile \ # Helper macros # +# Create the directory if it doesn't yet exist. +define auto_mkdir + $(if $(wildcard $(dir $1)),$2,$(QUIET)mkdir -p "$(dir $1)") +endef + # Creates the actual archive with an index. # The target $@ must end with .pic.a or .pie.a. define update_archive - $(QUIET)mkdir -p "$(dir $(TARGET_OR_MEMBER))" + $(call auto_mkdir,$(TARGET_OR_MEMBER)) $(QUIET)# Create the archive in one step to avoid parallel use accessing it $(QUIET)# before all the symbols are present. @$(ECHO) "AR $(subst \ @@ -235,24 +241,34 @@ endef # Default variable values # -OBJCOPY ?= objcopy -STRIP ?= strip +# Only override toolchain vars if they are from make. +CROSS_COMPILE ?= +define override_var +ifneq ($(filter undefined default,$(origin $1)),) +$1 = $(CROSS_COMPILE)$2 +endif +endef +$(eval $(call override_var,AR,ar)) +$(eval $(call override_var,CC,gcc)) +$(eval $(call override_var,CXX,g++)) +$(eval $(call override_var,OBJCOPY,objcopy)) +$(eval $(call override_var,PKG_CONFIG,pkg-config)) +$(eval $(call override_var,RANLIB,ranlib)) +$(eval $(call override_var,STRIP,strip)) + RMDIR ?= rmdir -# Only override CC and CXX if they are from make. -ifeq ($(origin CC), default) - CC = gcc -endif -ifeq ($(origin CXX), default) - CXX = g++ -endif -ifeq ($(origin RANLIB), default) - RANLIB = ranlib -endif -RANLIB ?= ranlib ECHO = /bin/echo -e -ifeq ($(PROFILING),1) - $(warning PROFILING=1 disables relocatable executables.) +ifeq ($(lastword $(subst /, ,$(CC))),clang) +CDRIVER = clang +else +CDRIVER = gcc +endif + +ifeq ($(lastword $(subst /, ,$(CXX))),clang++) +CXXDRIVER = clang +else +CXXDRIVER = gcc endif # To update these from an including Makefile: @@ -260,17 +276,14 @@ endif # CXXFLAGS := -mahflag $(CXXFLAGS) # Prepend to the list # CXXFLAGS := $(filter-out badflag,$(CXXFLAGS)) # Filter out a value # The same goes for CFLAGS. -# TODO(wad) Moving to -fvisibility=internal by default would be nice too. -COMMON_CFLAGS := -Wall -Werror -fstack-protector-strong -fno-strict-aliasing \ - -ggdb3 -Wa,--noexecstack -O1 -fvisibility=internal -Wformat=2 -CXXFLAGS += $(COMMON_CFLAGS) -CFLAGS += $(COMMON_CFLAGS) +COMMON_CFLAGS-gcc := -fstack-protector-strong -fvisibility=internal -ggdb3 \ + -Wa,--noexecstack +COMMON_CFLAGS-clang := -fstack-protector-all -fvisibility=hidden -ggdb +COMMON_CFLAGS := -Wall -Werror -fno-strict-aliasing -O1 -Wformat=2 +CXXFLAGS += $(COMMON_CFLAGS) $(COMMON_CFLAGS-$(CXXDRIVER)) +CFLAGS += $(COMMON_CFLAGS) $(COMMON_CFLAGS-$(CDRIVER)) CPPFLAGS += -D_FORTIFY_SOURCE=2 -ifeq ($(PROFILING),1) - CFLAGS := -pg - CXXFLAGS := -pg -endif ifeq ($(MODE),opt) # Up the optimizations. @@ -284,6 +297,12 @@ ifeq ($(MODE),opt) endif endif +ifeq ($(MODE),profiling) + CFLAGS := $(CFLAGS) -O0 -g --coverage + CXXFLAGS := $(CXXFLAGS) -O0 -g --coverage + LDFLAGS := $(LDFLAGS) --coverage +endif + LDFLAGS := $(LDFLAGS) -Wl,-z,relro -Wl,-z,noexecstack -Wl,-z,now # Fancy helpers for color if a prompt is defined @@ -323,7 +342,7 @@ TARGET_OR_MEMBER = $(lastword $(subst $(LP), ,$(subst $(RP),,$(or $%,$@)))) # all non-.o files. define COMPILE_BINARY_implementation @$(ECHO) "LD$(1) $(subst $(PWD)/,,$(TARGET_OR_MEMBER))" - $(QUIET)mkdir -p "$(dir $(TARGET_OR_MEMBER))" + $(call auto_mkdir,$(TARGET_OR_MEMBER)) $(QUIET)$($(1)) $(COMPILE_PIE_FLAGS) -o $(TARGET_OR_MEMBER) \ $(2) $(LDFLAGS) \ $(filter %.o %.a,$(^:.o=.pie.o)) \ @@ -347,7 +366,7 @@ endef COMMA := , define COMPILE_LIBRARY_implementation @$(ECHO) "SHARED$(1) $(subst $(PWD)/,,$(TARGET_OR_MEMBER))" - $(QUIET)mkdir -p "$(dir $(TARGET_OR_MEMBER))" + $(call auto_mkdir,$(TARGET_OR_MEMBER)) $(QUIET)$($(1)) -shared -Wl,-E -o $(TARGET_OR_MEMBER) \ $(2) $(LDFLAGS) \ $(if $(filter %.a,$^),-Wl$(COMMA)--whole-archive,) \ @@ -502,30 +521,30 @@ CXX_OBJECTS = $(patsubst $(SRC)/%.cc,%.o,$(wildcard $(SRC)/*.cc)) # $(5) source dir: _only_ if $(SRC). Leave blank for obj tree. define add_object_rules $(patsubst %.o,%.pie.o,$(1)): %.pie.o: $(5)%.$(3) %.o.depends - $$(QUIET)mkdir -p "$$(dir $$@)" + $$(call auto_mkdir,$$@) $$(call OBJECT_PATTERN_implementation,$(2),\ $$(basename $$@),$$($(4)) $$(CPPFLAGS) $$(OBJ_PIE_FLAG)) $(patsubst %.o,%.pic.o,$(1)): %.pic.o: $(5)%.$(3) %.o.depends - $$(QUIET)mkdir -p "$$(dir $$@)" + $$(call auto_mkdir,$$@) $$(call OBJECT_PATTERN_implementation,$(2),\ $$(basename $$@),$$($(4)) $$(CPPFLAGS) -fPIC) # Placeholder for depends $(patsubst %.o,%.o.depends,$(1)): - $$(QUIET)mkdir -p "$$(dir $$@)" + $$(call auto_mkdir,$$@) $$(QUIET)touch "$$@" $(1): %.o: %.pic.o %.pie.o - $$(QUIET)mkdir -p "$$(dir $$@)" + $$(call auto_mkdir,$$@) $$(QUIET)touch "$$@" endef define OBJECT_PATTERN_implementation @$(ECHO) "$(1) $(subst $(SRC)/,,$<) -> $(2).o" - $(QUIET)mkdir -p "$(dir $(2))" + $(call auto_mkdir,$@) $(QUIET)$($(1)) -c -MD -MF $(2).d $(3) -o $(2).o $< - $(QUIET)# Wrap all the deps in $(wildcard) so a missing header + $(QUIET)# Wrap all the deps in $$(wildcard) so a missing header $(QUIET)# won't cause weirdness. First we remove newlines and \, $(QUIET)# then wrap it. $(QUIET)sed -i -e :j -e '$$!N;s|\\\s*\n| |;tj' \ @@ -628,7 +647,27 @@ all: # Builds and runs tests for the target arch # Run them in parallel +# After the test have completed, if profiling, run coverage analysis tests: +ifeq ($(MODE),profiling) + @$(ECHO) -n "COVERAGE gcov " + @$(ECHO) "[$(COLOR_YELLOW)STARTED$(COLOR_RESET)]" + $(QUIET)(FILES=""; \ + for GCNO in `find . -name "*.gcno"`; \ + do \ + GCDA="$${GCNO%.gcno}.gcda"; \ + [ -e $${GCDA} ] && FILES="$${FILES} $${GCDA}"; \ + done; \ + gcov -l $${FILES}) + @$(ECHO) -n "COVERAGE gcov " + @$(ECHO) "[$(COLOR_YELLOW)FINISHED$(COLOR_RESET)]" + @$(ECHO) -n "COVERAGE lcov " + @$(ECHO) "[$(COLOR_YELLOW)STARTED$(COLOR_RESET)]" + $(QUIET)lcov --capture --directory . --output-file=lcov-coverage.info + $(QUIET)genhtml lcov-coverage.info --output-directory lcov-html + @$(ECHO) -n "COVERAGE lcov " + @$(ECHO) "[$(COLOR_YELLOW)FINISHED$(COLOR_RESET)]" +endif .PHONY: tests qemu_clean: @@ -733,6 +772,8 @@ endef clean: qemu_clean clean: CLEAN($(OUT)*.d) CLEAN($(OUT)*.o) CLEAN($(OUT)*.debug) clean: CLEAN($(OUT)*.test) CLEAN($(OUT)*.depends) +clean: CLEAN($(OUT)*.gcno) CLEAN($(OUT)*.gcda) CLEAN($(OUT)*.gcov) +clean: CLEAN($(OUT)lcov-coverage.info) CLEAN($(OUT)lcov-html) clean: $(QUIET)# Always delete the containing directory last. @@ -776,6 +817,9 @@ $(eval LD_DIRS := $(LD_DIRS):$(OUT)$(MODULE)) clean: CLEAN($(OUT)$(MODULE)/*.d) CLEAN($(OUT)$(MODULE)/*.o) clean: CLEAN($(OUT)$(MODULE)/*.debug) CLEAN($(OUT)$(MODULE)/*.test) clean: CLEAN($(OUT)$(MODULE)/*.depends) +clean: CLEAN($(OUT)$(MODULE)/*.gcno) CLEAN($(OUT)$(MODULE)/*.gcda) +clean: CLEAN($(OUT)$(MODULE)/*.gcov) CLEAN($(OUT)lcov-coverage.info) +clean: CLEAN($(OUT)lcov-html) $(info + submodule: $(MODULE_NAME)) # We must eval otherwise they may be dropped.