--- a/common/bin/logger.sh Thu Sep 03 14:24:40 2015 -0700
+++ b/common/bin/logger.sh Thu Sep 03 16:11:51 2015 -0700
@@ -41,5 +41,19 @@
trap "rm -rf \"$RCDIR\"" EXIT
LOGFILE=$1
shift
+
+# We need to handle command likes like "VAR1=val1 /usr/bin/cmd VAR2=val2".
+# Do this by shifting away prepended variable assignments, and export them
+# instead.
+is_prefix=true
+for opt; do
+ if [[ "$is_prefix" = true && "$opt" =~ ^.*=.*$ ]]; then
+ export $opt
+ shift
+ else
+ is_prefix=false
+ fi
+done
+
(exec 3>&1 ; ("$@" 2>&1 1>&3; echo $? > "$RCDIR/rc") | tee -a $LOGFILE 1>&2 ; exec 3>&-) | tee -a $LOGFILE
exit `cat "$RCDIR/rc"`
--- a/make/Init.gmk Thu Sep 03 14:24:40 2015 -0700
+++ b/make/Init.gmk Thu Sep 03 16:11:51 2015 -0700
@@ -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 Thu Sep 03 14:24:40 2015 -0700
+++ b/make/InitSupport.gmk Thu Sep 03 16:11:51 2015 -0700
@@ -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 Thu Sep 03 14:24:40 2015 -0700
+++ b/make/common/JavaCompilation.gmk Thu Sep 03 16:11:51 2015 -0700
@@ -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 Thu Sep 03 14:24:40 2015 -0700
+++ b/make/common/MakeBase.gmk Thu Sep 03 16:11:51 2015 -0700
@@ -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 Thu Sep 03 14:24:40 2015 -0700
+++ b/make/common/NativeCompilation.gmk Thu Sep 03 16:11:51 2015 -0700
@@ -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