xnu_quick_test: 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: I443850ed2b76992eb812ca7a7523072d4e89dd2e
Reviewed-on: https://gerrit.chromium.org/gerrit/42790
Tested-by: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
diff --git a/common.mk b/common.mk
index 357d1f9..058e906 100644
--- a/common.mk
+++ b/common.mk
@@ -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,16 +276,14 @@
# CXXFLAGS := -mahflag $(CXXFLAGS) # Prepend to the list
# CXXFLAGS := $(filter-out badflag,$(CXXFLAGS)) # Filter out a value
# The same goes for CFLAGS.
-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.
@@ -283,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
@@ -322,7 +342,7 @@
# 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)) \
@@ -346,7 +366,7 @@
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,) \
@@ -501,30 +521,30 @@
# $(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' \
@@ -627,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:
@@ -732,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.
@@ -775,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.