update common.mk This includes updated LFS flags. BUG=chromium:464024 TEST=precq passes Change-Id: I9c0f3b22885ddabaa36b3e85290b7f9bd2989272 Reviewed-on: https://chromium-review.googlesource.com/262674 Reviewed-by: Daniel Ehrenberg <dehrenberg@chromium.org> Tested-by: Mike Frysinger <vapier@chromium.org> Commit-Queue: Mike Frysinger <vapier@chromium.org>
diff --git a/common.mk b/common.mk index 9206735..fb8d727 100644 --- a/common.mk +++ b/common.mk
@@ -7,7 +7,7 @@ # # NOTE NOTE NOTE # The authoritative common.mk is located in: -# https://chromium.googlesource.com/chromiumos/platform/common-mk.git +# https://chromium.googlesource.com/chromiumos/platform2/+/master/common-mk # Please make all changes there, then copy into place in other repos. # NOTE NOTE NOTE # @@ -51,9 +51,9 @@ # compiling the objects. This can be done by adding one of the following # to the Makefile: # - For C source files -# $(eval $(call add_object_rules,sub/dir/gen_a.o sub/dir/gen_b.o,CC,c)) +# $(eval $(call add_object_rules,sub/dir/gen_a.o sub/dir/b.o,CC,c,CFLAGS)) # - For C++ source files -# $(eval $(call add_object_rules,sub/dir/gen_a.o sub/dir/gen_b.o,CXX,cc)) +# $(eval $(call add_object_rules,sub/dir/gen_a.o sub/dir/b.o,CXX,cc,CXXFLAGS)) # # Exported targets meant to have prerequisites added to: # - all - Your desired targets should be given @@ -80,9 +80,7 @@ # # Per-target(-ish) variable: # - NEEDS_ROOT=[0|1] allows a TEST() target to run with root. -# Default is 0 unless it is running under QEmu. -# - NEEDS_MOUNTS=[0|1] allows a TEST() target running on QEmu to get -# setup mounts in the $(SYSROOT) +# Default is 0. # # Caveats: # - Directories or files with spaces in them DO NOT get along with GNU Make. @@ -100,9 +98,9 @@ COLOR ?= 1 VERBOSE ?= 0 MODE ?= opt +CXXEXCEPTIONS ?= 0 +RUN_TESTS ?= 1 ARCH ?= $(shell uname -m) -NEEDS_ROOT = 0 -NEEDS_MOUNTS = 0 # Put objects in a separate tree based on makefile locations # This means you can build a tree without touching it: @@ -271,19 +269,60 @@ CXXDRIVER = gcc endif +# Internal macro to support check_XXX macros below. +# Usage: $(call check_compile, [code], [compiler], [code_type], [c_flags], +# [extra_c_flags], [library_flags], [success_ret], [fail_ret]) +# Return: [success_ret] if compile succeeded, otherwise [fail_ret] +check_compile = $(shell printf '%b\n' $(1) | \ + $($(2)) $($(4)) -x $(3) $(LDFLAGS) $(5) - $(6) -o /dev/null > /dev/null 2>&1 \ + && echo "$(7)" || echo "$(8)") + +# Helper macro to check whether a test program will compile with the specified +# compiler flags. +# Usage: $(call check_compile_cc, [code], [flags], [alternate_flags]) +# Return: [flags] if compile succeeded, otherwise [alternate_flags] +check_compile_cc = $(call check_compile,$(1),CC,c,CFLAGS,$(2),,$(2),$(3)) +check_compile_cxx = $(call check_compile,$(1),CXX,c++,CXXFLAGS,$(2),,$(2),$(3)) + +# Helper macro to check whether a test program will compile with the specified +# libraries. +# Usage: $(call check_compile_cc, [code], [library_flags], [alternate_flags]) +# Return: [library_flags] if compile succeeded, otherwise [alternate_flags] +check_libs_cc = $(call check_compile,$(1),CC,c,CFLAGS,,$(2),$(2),$(3)) +check_libs_cxx = $(call check_compile,$(1),CXX,c++,CXXFLAGS,,$(2),$(2),$(3)) + +# Helper macro to check whether the compiler accepts the specified flags. +# Usage: $(call check_compile_cc, [flags], [alternate_flags]) +# Return: [flags] if compile succeeded, otherwise [alternate_flags] +check_cc = $(call check_compile_cc,'int main() { return 0; }',$(1),$(2)) +check_cxx = $(call check_compile_cxx,'int main() { return 0; }',$(1),$(2)) + +# Choose the stack protector flags based on whats supported by the compiler. +SSP_CFLAGS := $(call check_cc,-fstack-protector-strong) +ifeq ($(SSP_CFLAGS),) + SSP_CFLAGS := $(call check_cc,-fstack-protector-all) +endif + # To update these from an including Makefile: # CXXFLAGS += -mahflag # Append to the list # CXXFLAGS := -mahflag $(CXXFLAGS) # Prepend to the list # CXXFLAGS := $(filter-out badflag,$(CXXFLAGS)) # Filter out a value # The same goes for 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 +COMMON_CFLAGS-gcc := -fvisibility=internal -ggdb3 -Wa,--noexecstack +COMMON_CFLAGS-clang := -fvisibility=hidden -ggdb +COMMON_CFLAGS := -Wall -Werror -fno-strict-aliasing $(SSP_CFLAGS) -O1 -Wformat=2 CXXFLAGS += $(COMMON_CFLAGS) $(COMMON_CFLAGS-$(CXXDRIVER)) CFLAGS += $(COMMON_CFLAGS) $(COMMON_CFLAGS-$(CDRIVER)) CPPFLAGS += -D_FORTIFY_SOURCE=2 +# Enable large file support. +CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE + +# Disable exceptions based on the CXXEXCEPTIONS setting. +ifeq ($(CXXEXCEPTIONS),0) + CXXFLAGS := $(CXXFLAGS) -fno-exceptions -fno-unwind-tables \ + -fno-asynchronous-unwind-tables +endif ifeq ($(MODE),opt) # Up the optimizations. @@ -473,8 +512,11 @@ $(error Typo alert! LIBARY != LIBRARY) -TEST(%): % qemu_chroot_install +TEST(%): % $(call TEST_implementation) +ifneq ($(RUN_TESTS),0) +TEST(%): sysroot_install +endif .PHONY: TEST # multiple targets with a wildcard need to share an directory. @@ -569,42 +611,15 @@ # explicit object they expect on the prerequisite line. # -# Architecture detection and QEMU wrapping +# Architecture detection # HOST_ARCH ?= $(shell uname -m) override ARCH := $(strip $(ARCH)) override HOST_ARCH := $(strip $(HOST_ARCH)) -# emake will supply "x86" or "arm" for ARCH, but -# if uname -m runs and you get x86_64, then this subst -# will break. -ifeq ($(subst x86,i386,$(ARCH)),i386) - QEMU_ARCH := $(subst x86,i386,$(ARCH)) # x86 -> i386 -else ifeq ($(subst amd64,x86_64,$(ARCH)),x86_64) - QEMU_ARCH := $(subst amd64,x86_64,$(ARCH)) # amd64 -> x86_64 -else - QEMU_ARCH = $(ARCH) -endif -override QEMU_ARCH := $(strip $(QEMU_ARCH)) -# If we're cross-compiling, try to use qemu for running the tests. -ifneq ($(QEMU_ARCH),$(HOST_ARCH)) - ifeq ($(SYSROOT),) - $(info SYSROOT not defined. qemu-based testing disabled) - else - # A SYSROOT is assumed for QEmu use. - USE_QEMU ?= 1 - - # Allow 64-bit hosts to run 32-bit without qemu. - ifeq ($(HOST_ARCH),x86_64) - ifeq ($(QEMU_ARCH),i386) - USE_QEMU = 0 - endif - endif - endif -else - USE_QEMU ?= 0 -endif +# Normally we don't need to run as root. +NEEDS_ROOT ?= 0 SYSROOT_OUT = $(OUT) ifneq ($(SYSROOT),) @@ -614,7 +629,6 @@ SYSROOT = / endif - # # Output full configuration at top level # @@ -629,8 +643,9 @@ $(info - NOSTRIP=$(NOSTRIP)) $(info - VALGRIND=$(VALGRIND)) $(info - COLOR=$(COLOR)) + $(info - CXXEXCEPTIONS=$(CXXEXCEPTIONS)) $(info - ARCH=$(ARCH)) - $(info - QEMU_ARCH=$(QEMU_ARCH)) + $(info - NEEDS_ROOT=$(NEEDS_ROOT)) $(info - SYSROOT=$(SYSROOT)) $(info ) endif @@ -650,118 +665,66 @@ # 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 \ + @$(ECHO) "COVERAGE [$(COLOR_YELLOW)STARTED$(COLOR_RESET)]" + $(QUIET)FILES=""; \ + for GCNO in `find . -name "*.gcno"`; do \ GCDA="$${GCNO%.gcno}.gcda"; \ - [ -e $${GCDA} ] && FILES="$${FILES} $${GCDA}"; \ + if [ -e $${GCDA} ]; then \ + FILES="$${FILES} $${GCDA}"; \ + fi \ 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)]" + if [ -n "$${FILES}" ]; then \ + gcov -l $${FILES}; \ + lcov --capture --directory . \ + --output-file=lcov-coverage.info; \ + genhtml lcov-coverage.info \ + --output-directory lcov-html; \ + fi + @$(ECHO) "COVERAGE [$(COLOR_YELLOW)FINISHED$(COLOR_RESET)]" endif -.PHONY: tests +# Standard name everyone else uses. +check: tests +.PHONY: check tests -qemu_clean: - $(call if_qemu,$(call silent_rm,$(OUT)/qemu-$(QEMU_ARCH))) +TEST_BASE_CMD = \ + $(SRC)/../common-mk/platform2_test.py \ + --sysroot "$(SYSROOT)" \ + --use_flags "$(USE)" \ + --cache_dir "$(OUT)" \ + $(if $(filter 1,$(NEEDS_ROOT)),--run_as_root) -qemu_chroot_install: -ifeq ($(USE_QEMU),1) - $(QUIET)$(ECHO) "QEMU Preparing qemu-$(QEMU_ARCH)" - $(QUIET)cp -fu /usr/bin/qemu-$(QEMU_ARCH) $(OUT)/qemu-$(QEMU_ARCH) - $(QUIET)chmod a+rx $(OUT)/qemu-$(QEMU_ARCH) +ifneq ($(SYSROOT),) +sysroot_install: + @$(ECHO) "TEST [$(COLOR_YELLOW)SETUP$(COLOR_RESET)]" + $(QUIET)$(TEST_BASE_CMD) --action pre_test endif -.PHONY: qemu_clean qemu_chroot_install - -# TODO(wad) Move to -L $(SYSROOT) and fakechroot when qemu-user -# doesn't hang traversing /proc from SYSROOT. -QEMU_CMD = -ROOT_CMD = $(if $(filter 1,$(NEEDS_ROOT)),sudo , ) -MOUNT_CMD = $(if $(filter 1,$(NEEDS_MOUNTS)),$(ROOT_CMD) mount, \#) -UMOUNT_CMD = $(if $(filter 1,$(NEEDS_MOUNTS)),$(ROOT_CMD) umount, \#) -QEMU_LDPATH = $(SYSROOT_LDPATH):/lib64:/lib:/usr/lib64:/usr/lib -ROOT_CMD_LDPATH = $(SYSROOT_LDPATH):$(SYSROOT)/lib64: -ROOT_CMD_LDPATH := $(ROOT_CMD_LDPATH):$(SYSROOT)/lib:$(SYSROOT)/usr/lib64: -ROOT_CMD_LDPATH := $(ROOT_CMD_LDPATH):$(SYSROOT)/usr/lib -ifeq ($(USE_QEMU),1) - export QEMU_CMD = \ - sudo chroot $(SYSROOT) $(SYSROOT_OUT)qemu-$(QEMU_ARCH) \ - -drop-ld-preload \ - -E LD_LIBRARY_PATH="$(QEMU_LDPATH):$(patsubst $(OUT),,$(LD_DIRS))" \ - -E HOME="$(HOME)" -- - # USE_QEMU conditional function - define if_qemu - $(1) - endef -else - ROOT_CMD = $(if $(filter 1,$(NEEDS_ROOT)),sudo, ) \ - LD_LIBRARY_PATH="$(ROOT_CMD_LDPATH):$(LD_DIRS)" - define if_qemu - $(2) - endef -endif +.PHONY: sysroot_install VALGRIND_CMD = ifeq ($(VALGRIND),1) VALGRIND_CMD = /usr/bin/valgrind --tool=memcheck $(VALGRIND_ARGS) -- endif +ifneq ($(RUN_TESTS),0) define TEST_implementation - $(QUIET)$(call TEST_setup) $(QUIET)$(call TEST_run) - $(QUIET)$(call TEST_teardown) - $(QUIET)exit $$(cat $(OUT)$(TARGET_OR_MEMBER).status.test) endef - -define TEST_setup - @$(ECHO) -n "TEST $(TARGET_OR_MEMBER) " - @$(ECHO) "[$(COLOR_YELLOW)SETUP$(COLOR_RESET)]" - $(QUIET)# Setup a target-specific results file - $(QUIET)(echo 1 > $(OUT)$(TARGET_OR_MEMBER).status.test) - $(QUIET)(echo > $(OUT)$(TARGET_OR_MEMBER).cleanup.test) - $(QUIET)# No setup if we are not using QEMU - $(QUIET)# TODO(wad) this is racy until we use a vfs namespace - $(call if_qemu,\ - $(QUIET)sudo mkdir -p "$(SYSROOT)/proc" "$(SYSROOT)/dev") - $(call if_qemu,\ - $(QUIET)$(MOUNT_CMD) --bind /proc "$(SYSROOT)/proc") - $(call if_qemu,\ - $(QUIET)$(MOUNT_CMD) --bind /dev "$(SYSROOT)/dev") - $(call if_qemu,\ - $(QUIET)(echo "$(UMOUNT_CMD) -l '$(SYSROOT)/proc'" \ - >> "$(OUT)$(TARGET_OR_MEMBER).cleanup.test")) - $(call if_qemu,\ - $(QUIET)(echo "$(UMOUNT_CMD) -l '$(SYSROOT)/dev'" \ - >> "$(OUT)$(TARGET_OR_MEMBER).cleanup.test")) +else +define TEST_implementation endef - -define TEST_teardown - @$(ECHO) -n "TEST $(TARGET_OR_MEMBER) " - @$(ECHO) "[$(COLOR_YELLOW)TEARDOWN$(COLOR_RESET)]" - $(call if_qemu, $(QUIET)$(SHELL) "$(OUT)$(TARGET_OR_MEMBER).cleanup.test") -endef +endif # Use GTEST_ARGS.[arch] if defined. +GTEST_ARGS.qemu.$(QEMU_ARCH) ?= $(GTEST_ARGS.qemu) +GTEST_ARGS.host.$(HOST_ARCH) ?= $(GTEST_ARGS.host) override GTEST_ARGS.real = \ $(call if_qemu,$(GTEST_ARGS.qemu.$(QEMU_ARCH)),$(GTEST_ARGS.host.$(HOST_ARCH))) define TEST_run @$(ECHO) -n "TEST $(TARGET_OR_MEMBER) " @$(ECHO) "[$(COLOR_GREEN)RUN$(COLOR_RESET)]" - $(QUIET)(echo 1 > "$(OUT)$(TARGET_OR_MEMBER).status.test") - -($(ROOT_CMD) $(QEMU_CMD) $(VALGRIND_CMD) \ - "$(strip $(call if_qemu, $(SYSROOT_OUT),$(OUT))$(TARGET_OR_MEMBER))" \ - $(if $(filter-out 0,$(words $(GTEST_ARGS.real))),$(GTEST_ARGS.real),\ - $(GTEST_ARGS)) && \ - echo 0 > "$(OUT)$(TARGET_OR_MEMBER).status.test") + $(QUIET)$(TEST_BASE_CMD) -- $(SYSROOT_OUT)$(TARGET_OR_MEMBER) \ +$(GTEST_ARGS.real) endef # Recursive list reversal so that we get RMDIR_ON_CLEAN in reverse order. @@ -769,7 +732,6 @@ $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) 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)