Merge "Add support for remote-execution / caching of jar/zip actions" into rvc-dev
diff --git a/android/paths.go b/android/paths.go
index 0edda38..1d8d92a 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -483,6 +483,15 @@
 	return list[:k]
 }
 
+// SortedUniquePaths returns what its name says
+func SortedUniquePaths(list Paths) Paths {
+	unique := FirstUniquePaths(list)
+	sort.Slice(unique, func(i, j int) bool {
+		return unique[i].String() < unique[j].String()
+	})
+	return unique
+}
+
 // LastUniquePaths returns all unique elements of a Paths, keeping the last copy of each.  It
 // modifies the Paths slice contents in place, and returns a subslice of the original slice.
 func LastUniquePaths(list Paths) Paths {
diff --git a/apex/builder.go b/apex/builder.go
index 5dcc1aa..2eb7672 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -238,7 +238,7 @@
 		return android.NoticeOutputs{}
 	}
 
-	return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.FirstUniquePaths(noticeFiles))
+	return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.SortedUniquePaths(noticeFiles))
 }
 
 func (a *apexBundle) buildInstalledFilesFile(ctx android.ModuleContext, builtApex android.Path, imageDir android.Path) android.OutputPath {
diff --git a/ui/build/build.go b/ui/build/build.go
index f3feac2..349a7de 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -142,7 +142,26 @@
 func Build(ctx Context, config Config, what int) {
 	ctx.Verboseln("Starting build with args:", config.Arguments())
 	ctx.Verboseln("Environment:", config.Environment().Environ())
-	ctx.Verbosef("Total RAM: %dGB", config.TotalRAM()/1024/1024/1024)
+
+	if totalRAM := config.TotalRAM(); totalRAM != 0 {
+		ram := float32(totalRAM) / (1024 * 1024 * 1024)
+		ctx.Verbosef("Total RAM: %.3vGB", ram)
+
+		if ram <= 16 {
+			ctx.Println("************************************************************")
+			ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
+			ctx.Println("")
+			ctx.Println("The minimum required amount of free memory is around 16GB,")
+			ctx.Println("and even with that, some configurations may not work.")
+			ctx.Println("")
+			ctx.Println("If you run into segfaults or other errors, try reducing your")
+			ctx.Println("-j value.")
+			ctx.Println("************************************************************")
+		} else if ram <= float32(config.Parallel()) {
+			ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
+			ctx.Println("If you run into segfaults or other errors, try a lower -j value")
+		}
+	}
 
 	ctx.BeginTrace(metrics.Total, "total")
 	defer ctx.EndTrace()
diff --git a/ui/build/config.go b/ui/build/config.go
index 9b19ede..3a1188b 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -738,6 +738,9 @@
 	} else if c.totalRAM == 0 {
 		// Couldn't detect the total RAM, don't restrict highmem processes.
 		return parallel
+	} else if c.totalRAM <= 16*1024*1024*1024 {
+		// Less than 16GB of ram, restrict to 1 highmem processes
+		return 1
 	} else if c.totalRAM <= 32*1024*1024*1024 {
 		// Less than 32GB of ram, restrict to 2 highmem processes
 		return 2