8062618: Create a build failure summary at end of build log
authorihse
Thu, 03 Sep 2015 11:05:49 +0200
changeset 32344 0b288e0efcfa
parent 32341 3c9f5bd909ae
child 32345 ed4ddf0bdb63
8062618: Create a build failure summary at end of build log Reviewed-by: erikj
make/Init.gmk
make/InitSupport.gmk
make/common/JavaCompilation.gmk
make/common/MakeBase.gmk
make/common/NativeCompilation.gmk
--- a/make/Init.gmk	Wed Jul 05 20:47:29 2017 +0200
+++ b/make/Init.gmk	Thu Sep 03 11:05:49 2015 +0200
@@ -253,6 +253,7 @@
   main: $(INIT_TARGETS)
         ifneq ($(SEQUENTIAL_TARGETS)$(PARALLEL_TARGETS), )
 	  $(call RotateLogFiles)
+	  $(call PrepareFailureLogs)
 	  $(BUILD_LOG_WRAPPER) $(PRINTF) "Building $(TARGET_DESCRIPTION)\n"
           ifneq ($(SEQUENTIAL_TARGETS), )
             # Don't touch build output dir since we might be cleaning. That
@@ -266,10 +267,13 @@
 	    $(call PrepareSmartJavac)
 	    ( cd $(TOPDIR) && \
 	        $(BUILD_LOG_WRAPPER) $(MAKE) $(MAKE_ARGS) $(OUTPUT_SYNC_FLAG) \
-	        -j $(JOBS) -f make/Main.gmk $(USER_MAKE_VARS) \
-	        $(PARALLEL_TARGETS) || \
-	        ( exitcode=$$? && $(BUILD_LOG_WRAPPER) $(PRINTF) "\nERROR: Build failed for $(TARGET_DESCRIPTION) (exit code $$exitcode) \n" && \
-	        $(PRINTF) "Hint: If caused by a warning, try configure --disable-warnings-as-errors \n\n" && exit $$exitcode ) )
+	            -j $(JOBS) -f make/Main.gmk $(USER_MAKE_VARS) \
+	            $(PARALLEL_TARGETS) || \
+	        ( exitcode=$$? && $(BUILD_LOG_WRAPPER) \
+	        $(PRINTF) "\nERROR: Build failed for $(TARGET_DESCRIPTION) (exit code $$exitcode) \n" && \
+	        cd $(TOPDIR) && $(MAKE) $(MAKE_ARGS) -j 1 -f make/Init.gmk \
+	            HAS_SPEC=true on-failure ; \
+	        exit $$exitcode ) )
 	    $(call CleanupSmartJavac)
 	    $(call StopGlobalTimer)
 	    $(call ReportBuildTimes)
@@ -277,5 +281,25 @@
 	  $(BUILD_LOG_WRAPPER) $(PRINTF) "Finished building $(TARGET_DESCRIPTION)\n"
         endif
 
-  .PHONY: print-targets print-modules reconfigure main
+    on-failure:
+        ifneq ($(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*), )
+	  $(PRINTF) "=== Output from failing command(s) repeated here ===\n"
+	  $(foreach logfile, $(sort $(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*)), \
+	      $(PRINTF) "* For target $(notdir $(basename $(logfile))):\n" $(NEWLINE) \
+	      $(CAT) $(logfile) | $(GREP) -v -e "^Note: including file:" $(NEWLINE) \
+	  )
+	  $(PRINTF) "=== End of repeated output ===\n"
+        endif
+	if $(GREP) -q "recipe for target .* failed" $(BUILD_LOG) 2> /dev/null; then  \
+	  $(PRINTF) "=== Make failure sequence repeated here ===\n" ; \
+	  $(GREP) "recipe for target .* failed" $(BUILD_LOG) ; \
+	  $(PRINTF) "=== End of repeated output ===\n" ; \
+	  $(PRINTF) "Hint: Try searching the build log for the name of the first failed target.\n" ; \
+	else \
+	  $(PRINTF) "No indication of failed target found.\n" ; \
+	  $(PRINTF) "Hint: Try searching the build log for '] Error'.\n" ; \
+	fi
+	$(PRINTF) "Hint: If caused by a warning, try configure --disable-warnings-as-errors.\n\n"
+
+  .PHONY: print-targets print-modules reconfigure main on-failure
 endif
--- a/make/InitSupport.gmk	Wed Jul 05 20:47:29 2017 +0200
+++ b/make/InitSupport.gmk	Thu Sep 03 11:05:49 2015 +0200
@@ -318,6 +318,11 @@
 	)
   endef
 
+  define PrepareFailureLogs
+	$(RM) -r $(MAKESUPPORT_OUTPUTDIR)/failure-logs 2> /dev/null
+	$(MKDIR) -p $(MAKESUPPORT_OUTPUTDIR)/failure-logs
+  endef
+
   # Remove any javac server logs and port files. This
   # prevents a new make run to reuse the previous servers.
   define PrepareSmartJavac
--- a/make/common/JavaCompilation.gmk	Wed Jul 05 20:47:29 2017 +0200
+++ b/make/common/JavaCompilation.gmk	Thu Sep 03 11:05:49 2015 +0200
@@ -563,18 +563,19 @@
 	$(MKDIR) -p $$(@D) $$(dir $$($1_SJAVAC_PORTFILE))
 	$$(call ListPathsSafely,$1_SRCS,\n, >> $$($1_BIN)/_the.$1_batch.tmp)
 	$(ECHO) Compiling $1
-	($$($1_JVM) $$($1_SJAVAC) \
-	    $$($1_REMOTE) \
-	    -j 1 \
-	    --permit-unidentified-artifacts \
-	    --permit-sources-without-package \
-	    --compare-found-sources $$($1_BIN)/_the.$1_batch.tmp \
-	    --log=$(LOG_LEVEL) \
-	    $$($1_SJAVAC_ARGS) \
-	    $$($1_FLAGS) \
-	    $$($1_HEADERS_ARG) \
-	    -d $$($1_BIN) && \
-	$(MV) $$($1_BIN)/_the.$1_batch.tmp $$($1_BIN)/_the.$1_batch)
+	$(call LogFailures, $$($1_BIN)/_the.$1_batch.log, $1, \
+	    $$($1_JVM) $$($1_SJAVAC) \
+	        $$($1_REMOTE) \
+	        -j 1 \
+	        --permit-unidentified-artifacts \
+	        --permit-sources-without-package \
+	        --compare-found-sources $$($1_BIN)/_the.$1_batch.tmp \
+	        --log=$(LOG_LEVEL) \
+	        $$($1_SJAVAC_ARGS) \
+	        $$($1_FLAGS) \
+	        $$($1_HEADERS_ARG) \
+	        -d $$($1_BIN)) && \
+	$(MV) $$($1_BIN)/_the.$1_batch.tmp $$($1_BIN)/_the.$1_batch
         # Create a pubapi file that only changes when the pubapi changes. Dependent
         # compilations can use this file to only get recompiled when pubapi has changed.
         # Grep returns 1 if no matching lines are found. Do not fail for this.
@@ -619,11 +620,11 @@
 	$(RM) $$($1_BIN)/_the.$1_batch $$($1_BIN)/_the.$1_batch.tmp
 	$$(call ListPathsSafely,$1_SRCS,\n, >> $$($1_BIN)/_the.$1_batch.tmp)
 	$(ECHO) Compiling `$(WC) $$($1_BIN)/_the.$1_batch.tmp | $(TR) -s ' ' | $(CUT) -f 2 -d ' '` files for $1
-	($$($1_JVM) $$($1_JAVAC) $$($1_FLAGS) \
-	    -implicit:none \
-	    -d $$($1_BIN) $$($1_HEADERS_ARG) @$$($1_BIN)/_the.$1_batch.tmp && \
-	$(MV) $$($1_BIN)/_the.$1_batch.tmp $$($1_BIN)/_the.$1_batch)
-
+	$(call LogFailures, $$($1_BIN)/_the.$1_batch.log, $1, \
+	    $$($1_JVM) $$($1_JAVAC) $$($1_FLAGS) \
+	        -implicit:none \
+	        -d $$($1_BIN) $$($1_HEADERS_ARG) @$$($1_BIN)/_the.$1_batch.tmp) && \
+	$(MV) $$($1_BIN)/_the.$1_batch.tmp $$($1_BIN)/_the.$1_batch
   endif
 
   # Add all targets to main variable
--- a/make/common/MakeBase.gmk	Wed Jul 05 20:47:29 2017 +0200
+++ b/make/common/MakeBase.gmk	Thu Sep 03 11:05:49 2015 +0200
@@ -755,6 +755,20 @@
     $(call DependOnVariableHelper,$(strip $1),$(strip $2))
 
 ################################################################################
+# Failure logging support macros. These are supposed to be used by the Setup*
+# compilation macros.
+#
+# LogFailures will run a command and store a copy of output in a specified file.
+# If the command succeeds, the file is deleted, otherwise it is moved to the
+# failure-logs directory.
+# Param 1 - The log file of the failed command
+# Param 2 - A compact but representative name to describe this command
+# Param 3 - Command to run
+LogFailures = \
+  ( ($(BASH) $(SRC_ROOT)/common/bin/logger.sh $1 $3 && $(RM) $1) || \
+  (exitcode=$(DOLLAR)$(DOLLAR)? && $(MV) $1 $(MAKESUPPORT_OUTPUTDIR)/failure-logs/$(strip $2).log && exit $(DOLLAR)$(DOLLAR)exitcode) )
+
+################################################################################
 # Find lib dir for module
 # Param 1 - module name
 ifeq ($(OPENJDK_TARGET_OS_TYPE), unix)
--- a/make/common/NativeCompilation.gmk	Wed Jul 05 20:47:29 2017 +0200
+++ b/make/common/NativeCompilation.gmk	Thu Sep 03 11:05:49 2015 +0200
@@ -201,23 +201,25 @@
     $$($1_$2_OBJ) : $2 $$($1_COMPILE_VARDEPS_FILE) | $$($1_BUILD_INFO)
 	$(ECHO) $(LOG_INFO) "Compiling $$(notdir $2) (for $$(notdir $$($1_TARGET)))"
         ifneq ($(TOOLCHAIN_TYPE), microsoft)
-          # The Solaris studio compiler doesn't output the full path to the object file in the
-          # generated deps files. Fixing it with sed. If compiling assembly, don't try this.
           ifeq ($(TOOLCHAIN_TYPE)$$(filter %.s,$2), solstudio)
-	    $$($1_$2_COMP) $$($1_$2_FLAGS) $$($1_$2_DEP_FLAG) $$($1_$2_DEP).tmp $(CC_OUT_OPTION)$$($1_$2_OBJ) $2
+            # The Solaris studio compiler doesn't output the full path to the object file in the
+            # generated deps files. Fixing it with sed. If compiling assembly, don't try this.
+	    $(call LogFailures, $$($1_$2_OBJ).log, $1_$$(notdir $2), \
+	        $$($1_$2_COMP) $$($1_$2_FLAGS) $$($1_$2_DEP_FLAG) $$($1_$2_DEP).tmp $(CC_OUT_OPTION)$$($1_$2_OBJ) $2)
 	    $(SED) 's|^$$(@F):|$$@:|' $$($1_$2_DEP).tmp > $$($1_$2_DEP)
           else
-	    $$($1_$2_COMP) $$($1_$2_FLAGS) $$($1_$2_DEP_FLAG) $$($1_$2_DEP) $(CC_OUT_OPTION)$$($1_$2_OBJ) $2
+	    $(call LogFailures, $$($1_$2_OBJ).log, $1_$$(notdir $2), \
+	        $$($1_$2_COMP) $$($1_$2_FLAGS) $$($1_$2_DEP_FLAG) $$($1_$2_DEP) $(CC_OUT_OPTION)$$($1_$2_OBJ) $2)
           endif
-        endif
-        # The Visual Studio compiler lacks a feature for generating make dependencies, but by
-        # setting -showIncludes, all included files are printed. These are filtered out and
-        # parsed into make dependences.
-        ifeq ($(TOOLCHAIN_TYPE), microsoft)
-	  ($$($1_$2_COMP) $$($1_$2_FLAGS) -showIncludes $$($1_$2_DEBUG_OUT_FLAGS) \
-	      $(CC_OUT_OPTION)$$($1_$2_OBJ) $2 ; echo $$$$? > $$($1_$2_DEP).exitvalue) \
+        else
+          # The Visual Studio compiler lacks a feature for generating make dependencies, but by
+          # setting -showIncludes, all included files are printed. These are filtered out and
+          # parsed into make dependences.
+	  ($(call LogFailures, $$($1_$2_OBJ).log, $1_$$(notdir $2), \
+	      $$($1_$2_COMP) $$($1_$2_FLAGS) -showIncludes $$($1_$2_DEBUG_OUT_FLAGS) \
+	          $(CC_OUT_OPTION)$$($1_$2_OBJ) $2) ; echo $$$$? > $$($1_$2_DEP).exitvalue) \
 	      | $(TEE) $$($1_$2_DEP).raw | $(GREP) -v -e "^Note: including file:" \
-	      -e "^$(notdir $2)$$$$" || test "$$$$?" = "1" ; \
+	          -e "^$(notdir $2)$$$$" || test "$$$$?" = "1" ; \
 	      exit `cat $$($1_$2_DEP).exitvalue`
 	  $(RM) $$($1_$2_DEP).exitvalue
 	  ($(ECHO) $$@: \\ \
@@ -694,10 +696,11 @@
     $$($1_TARGET): $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_REAL_MAPFILE) \
         $$($1_DEBUGINFO_EXTRA_DEPS) $$($1_VARDEPS_FILE)
 		$(ECHO) $(LOG_INFO) "Linking $$($1_BASENAME)"
-		$$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
+		$(call LogFailures, $$($1_OBJECT_DIR)/$1_link.log, $1_link, \
+		    $$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
 		    $(LD_OUT_OPTION)$$@ \
 		    $$($1_EXPECTED_OBJS) $$($1_RES) \
-		    $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX)
+		    $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX))
 		$$($1_CREATE_DEBUGINFO_CMDS)
                 # Touch target to make sure it has a later time stamp than the debug
                 # symbol files to avoid unnecessary relinking on rebuild.
@@ -716,8 +719,9 @@
     # Generating a static library, ie object file archive.
     $$($1_TARGET): $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_VARDEPS_FILE)
 	$(ECHO) $(LOG_INFO) "Archiving $$($1_STATIC_LIBRARY)"
-	$$($1_AR) $$($1_ARFLAGS) $(AR_OUT_OPTION)$$($1_TARGET) $$($1_EXPECTED_OBJS) \
-	    $$($1_RES) $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX)
+	$(call LogFailures, $$($1_OBJECT_DIR)/$1_link.log, $1_link, \
+	    $$($1_AR) $$($1_ARFLAGS) $(AR_OUT_OPTION)$$($1_TARGET) $$($1_EXPECTED_OBJS) \
+	        $$($1_RES) $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX))
   endif
 
   ifneq (,$$($1_PROGRAM))
@@ -733,10 +737,11 @@
     $$($1_TARGET): $$($1_EXPECTED_OBJS) $$($1_RES) $$($1_MANIFEST) \
         $$($1_DEBUGINFO_EXTRA_DEPS) $$($1_VARDEPS_FILE)
 		$(ECHO) $(LOG_INFO) "Linking executable $$($1_BASENAME)"
-		$$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
-		    $(EXE_OUT_OPTION)$$($1_TARGET) \
-		    $$($1_EXPECTED_OBJS) $$($1_RES) \
-		    $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX)
+		$(call LogFailures, $$($1_OBJECT_DIR)/$1_link.log, $1_link, \
+		    $$($1_LD) $$($1_LDFLAGS) $$($1_EXTRA_LDFLAGS) $$($1_SYSROOT_LDFLAGS) \
+		        $(EXE_OUT_OPTION)$$($1_TARGET) \
+		        $$($1_EXPECTED_OBJS) $$($1_RES) \
+		        $$($1_LDFLAGS_SUFFIX) $$($1_EXTRA_LDFLAGS_SUFFIX))
                 ifeq ($(OPENJDK_TARGET_OS), windows)
                   ifneq ($$($1_MANIFEST), )
 		    $$($1_MT) -nologo -manifest $$($1_MANIFEST) -identity:"$$($1_PROGRAM).exe, version=$$($1_MANIFEST_VERSION)" -outputresource:$$@;#1