verity: 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: I5b1dd04e8eec9b1320ee8d9945a87a9f45c61c20
Reviewed-on: https://gerrit.chromium.org/gerrit/42781
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Tested-by: Ryan Harrison <rharrison@chromium.org>
diff --git a/Makefile b/Makefile
index 6c9f6f0..bffde42 100644
--- a/Makefile
+++ b/Makefile
@@ -57,7 +57,7 @@
                           $(filter %dm-bht-userspace.o,$(C_OBJECTS)) \
                            CXX_STATIC_LIBRARY(kernel/libkernel.pie.a) \
                            CXX_STATIC_LIBRARY(simple_file/libsimple_file.pie.a)
-	$(call cxx_binary,-lgtest -lgmock -lpthread)
+CXX_BINARY(verity_testrunner): LDLIBS += -lgtest -lgmock -lpthread
 
 all: CXX_BINARY(verity_testrunner)
 clean: CLEAN(verity_testrunner)
diff --git a/common.mk b/common.mk
index 4b1071d..058e906 100644
--- a/common.mk
+++ b/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 @@
 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 @@
 _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 @@
 # 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 @@
 # 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,18 +276,14 @@
 #  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.
-CXXFLAGS := $(CXXFLAGS) -Wall -Werror -fstack-protector-all \
-  -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ggdb3 -Wa,--noexecstack -O1 \
-  -fvisibility=internal -Wformat=2
-CFLAGS := $(CFLAGS) -Wall -Werror -fstack-protector-all -fno-strict-aliasing \
-  -DFORTIFY_SOURCE=2 -ggdb3 -Wa,--noexecstack -O1 -fvisibility=internal \
-  -Wformat=2
+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.
@@ -285,6 +297,12 @@
   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
@@ -324,12 +342,13 @@
 # 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)) \
     $(foreach so,$(filter %.so,$^),-L$(dir $(so)) \
                             -l$(patsubst lib%,%,$(basename $(notdir $(so))))) \
-    $(2) $(LDFLAGS)
+    $(LDLIBS)
   $(call conditional_strip)
   @$(ECHO) -n "BIN		"
   @$(ECHO) "$(COLOR_GREEN)$(subst $(PWD)/,,$(TARGET_OR_MEMBER))$(COLOR_RESET)"
@@ -347,15 +366,16 @@
 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,) \
     $(filter %.o ,$(^:.o=.pic.o)) \
     $(foreach a,$(filter %.a,$^),-L$(dir $(a)) \
                             -l$(patsubst lib%,%,$(basename $(notdir $(a))))) \
     $(foreach so,$(filter %.so,$^),-L$(dir $(so)) \
                             -l$(patsubst lib%,%,$(basename $(notdir $(so))))) \
-    $(2) $(LDFLAGS)
+    $(LDLIBS)
   $(call conditional_strip)
   @$(ECHO) -n "LIB		$(COLOR_GREEN)"
   @$(ECHO) "$(subst $(PWD)/,,$(TARGET_OR_MEMBER))$(COLOR_RESET)"
@@ -497,33 +517,34 @@
 # $(1) list of .o files
 # $(2) source type (CC or CXX)
 # $(3) source suffix (cc or c)
-# $(4) source dir: _only_ if $(SRC). Leave blank for obj tree.
+# $(4) compiler flag name (CFLAGS or CXXFLAGS)
+# $(5) source dir: _only_ if $(SRC). Leave blank for obj tree.
 define add_object_rules
-$(patsubst %.o,%.pie.o,$(1)): %.pie.o: $(4)%.$(3) %.o.depends
-	$$(QUIET)mkdir -p "$$(dir $$@)"
+$(patsubst %.o,%.pie.o,$(1)): %.pie.o: $(5)%.$(3) %.o.depends
+	$$(call auto_mkdir,$$@)
 	$$(call OBJECT_PATTERN_implementation,$(2),\
-          $$(basename $$@),$$(CXXFLAGS) $$(OBJ_PIE_FLAG))
+          $$(basename $$@),$$($(4)) $$(CPPFLAGS) $$(OBJ_PIE_FLAG))
 
-$(patsubst %.o,%.pic.o,$(1)): %.pic.o: $(4)%.$(3) %.o.depends
-	$$(QUIET)mkdir -p "$$(dir $$@)"
+$(patsubst %.o,%.pic.o,$(1)): %.pic.o: $(5)%.$(3) %.o.depends
+	$$(call auto_mkdir,$$@)
 	$$(call OBJECT_PATTERN_implementation,$(2),\
-          $$(basename $$@),$$(CXXFLAGS) -fPIC)
+          $$(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' \
@@ -531,8 +552,8 @@
 endef
 
 # Now actually register handlers for C(XX)_OBJECTS.
-$(eval $(call add_object_rules,$(C_OBJECTS),CC,c,$(SRC)/))
-$(eval $(call add_object_rules,$(CXX_OBJECTS),CXX,cc,$(SRC)/))
+$(eval $(call add_object_rules,$(C_OBJECTS),CC,c,CFLAGS,$(SRC)/))
+$(eval $(call add_object_rules,$(CXX_OBJECTS),CXX,cc,CXXFLAGS,$(SRC)/))
 
 # Disable default pattern rules to help avoid leakage.
 # These may already be handled by '-r', but let's keep it to be safe.
@@ -626,7 +647,27 @@
 
 # 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:
@@ -731,6 +772,8 @@
 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.
@@ -774,6 +817,9 @@
 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.
@@ -787,8 +833,8 @@
 # Note, $(MODULE) is implicit in the path to the %.c.
 # See $(C_OBJECTS) for more details.
 # Register rules for the module objects.
-$(eval $(call add_object_rules,$(MODULE_C_OBJECTS),CC,c,$(SRC)/))
-$(eval $(call add_object_rules,$(MODULE_CXX_OBJECTS),CXX,cc,$(SRC)/))
+$(eval $(call add_object_rules,$(MODULE_C_OBJECTS),CC,c,CFLAGS,$(SRC)/))
+$(eval $(call add_object_rules,$(MODULE_CXX_OBJECTS),CXX,cc,CXXFLAGS,$(SRC)/))
 
 # Continue recursive inclusion of module.mk files
 SUBMODULE_DIRS = $(wildcard $(SRC)/$(MODULE)/*/module.mk)