Merge "Adding USB exception for mschilder."
diff --git a/common.mk b/common.mk
index f375ce3..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' \
@@ -612,7 +632,6 @@
$(info - ARCH=$(ARCH))
$(info - QEMU_ARCH=$(QEMU_ARCH))
$(info - SYSROOT=$(SYSROOT))
- $(info - ROOT=$(ROOT))
$(info )
endif
@@ -628,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:
@@ -733,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.
@@ -776,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.