Merge "Pass -Brepro ldflag to Windows builds" into rvc-dev
diff --git a/android/config.go b/android/config.go
index 5e09214..a0418d8 100644
--- a/android/config.go
+++ b/android/config.go
@@ -570,8 +570,8 @@
 	return String(c.productVariables.BuildId)
 }
 
-func (c *config) BuildNumberFromFile() string {
-	return String(c.productVariables.BuildNumberFromFile)
+func (c *config) BuildNumberFile(ctx PathContext) Path {
+	return PathForOutput(ctx, String(c.productVariables.BuildNumberFile))
 }
 
 // DeviceName returns the name of the current device target
diff --git a/android/rule_builder.go b/android/rule_builder.go
index b4f144a..9005f07 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -162,9 +162,10 @@
 	r.Command().Text("rm").Flag("-f").Outputs(temporariesList)
 }
 
-// Inputs returns the list of paths that were passed to the RuleBuilderCommand methods that take input paths, such
-// as RuleBuilderCommand.Input, RuleBuilderComand.Implicit, or RuleBuilderCommand.FlagWithInput.  Inputs to a command
-// that are also outputs of another command in the same RuleBuilder are filtered out.
+// Inputs returns the list of paths that were passed to the RuleBuilderCommand methods that take
+// input paths, such as RuleBuilderCommand.Input, RuleBuilderComand.Implicit, or
+// RuleBuilderCommand.FlagWithInput.  Inputs to a command that are also outputs of another command
+// in the same RuleBuilder are filtered out.  The list is sorted and duplicates removed.
 func (r *RuleBuilder) Inputs() Paths {
 	outputs := r.outputSet()
 	depFiles := r.depFileSet()
@@ -193,6 +194,28 @@
 	return inputList
 }
 
+// OrderOnlys returns the list of paths that were passed to the RuleBuilderCommand.OrderOnly or
+// RuleBuilderCommand.OrderOnlys.  The list is sorted and duplicates removed.
+func (r *RuleBuilder) OrderOnlys() Paths {
+	orderOnlys := make(map[string]Path)
+	for _, c := range r.commands {
+		for _, orderOnly := range c.orderOnlys {
+			orderOnlys[orderOnly.String()] = orderOnly
+		}
+	}
+
+	var orderOnlyList Paths
+	for _, orderOnly := range orderOnlys {
+		orderOnlyList = append(orderOnlyList, orderOnly)
+	}
+
+	sort.Slice(orderOnlyList, func(i, j int) bool {
+		return orderOnlyList[i].String() < orderOnlyList[j].String()
+	})
+
+	return orderOnlyList
+}
+
 func (r *RuleBuilder) outputSet() map[string]WritablePath {
 	outputs := make(map[string]WritablePath)
 	for _, c := range r.commands {
@@ -203,8 +226,9 @@
 	return outputs
 }
 
-// Outputs returns the list of paths that were passed to the RuleBuilderCommand methods that take output paths, such
-// as RuleBuilderCommand.Output, RuleBuilderCommand.ImplicitOutput, or RuleBuilderCommand.FlagWithInput.
+// Outputs returns the list of paths that were passed to the RuleBuilderCommand methods that take
+// output paths, such as RuleBuilderCommand.Output, RuleBuilderCommand.ImplicitOutput, or
+// RuleBuilderCommand.FlagWithInput.  The list is sorted and duplicates removed.
 func (r *RuleBuilder) Outputs() WritablePaths {
 	outputs := r.outputSet()
 
@@ -262,7 +286,8 @@
 	return tools
 }
 
-// Tools returns the list of paths that were passed to the RuleBuilderCommand.Tool method.
+// Tools returns the list of paths that were passed to the RuleBuilderCommand.Tool method.  The
+// list is sorted and duplicates removed.
 func (r *RuleBuilder) Tools() Paths {
 	toolsSet := r.toolsSet()
 
@@ -337,6 +362,7 @@
 		ctx.Build(pctx, BuildParams{
 			Rule:        ErrorRule,
 			Outputs:     r.Outputs(),
+			OrderOnly:   r.OrderOnlys(),
 			Description: desc,
 			Args: map[string]string{
 				"error": "missing dependencies: " + strings.Join(r.missingDeps, ", "),
@@ -453,6 +479,7 @@
 type RuleBuilderCommand struct {
 	buf           strings.Builder
 	inputs        Paths
+	orderOnlys    Paths
 	outputs       WritablePaths
 	depFiles      WritablePaths
 	tools         Paths
@@ -475,6 +502,10 @@
 	return path.String()
 }
 
+func (c *RuleBuilderCommand) addOrderOnly(path Path) {
+	c.orderOnlys = append(c.orderOnlys, path)
+}
+
 func (c *RuleBuilderCommand) outputStr(path Path) string {
 	if c.sbox {
 		// Errors will be handled in RuleBuilder.Build where we have a context to report them
@@ -604,6 +635,22 @@
 	return c
 }
 
+// OrderOnly adds the specified input path to the dependencies returned by RuleBuilder.OrderOnlys
+// without modifying the command line.
+func (c *RuleBuilderCommand) OrderOnly(path Path) *RuleBuilderCommand {
+	c.addOrderOnly(path)
+	return c
+}
+
+// OrderOnlys adds the specified input paths to the dependencies returned by RuleBuilder.OrderOnlys
+// without modifying the command line.
+func (c *RuleBuilderCommand) OrderOnlys(paths Paths) *RuleBuilderCommand {
+	for _, path := range paths {
+		c.addOrderOnly(path)
+	}
+	return c
+}
+
 // Output adds the specified output path to the command line.  The path will also be added to the outputs returned by
 // RuleBuilder.Outputs.
 func (c *RuleBuilderCommand) Output(path WritablePath) *RuleBuilderCommand {
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index acf8127..c41b067 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -265,14 +265,16 @@
 
 func TestRuleBuilder(t *testing.T) {
 	fs := map[string][]byte{
-		"dep_fixer": nil,
-		"input":     nil,
-		"Implicit":  nil,
-		"Input":     nil,
-		"Tool":      nil,
-		"input2":    nil,
-		"tool2":     nil,
-		"input3":    nil,
+		"dep_fixer":  nil,
+		"input":      nil,
+		"Implicit":   nil,
+		"Input":      nil,
+		"OrderOnly":  nil,
+		"OrderOnlys": nil,
+		"Tool":       nil,
+		"input2":     nil,
+		"tool2":      nil,
+		"input3":     nil,
 	}
 
 	ctx := PathContextForTesting(TestConfig("out", nil, "", fs))
@@ -290,6 +292,7 @@
 			ImplicitOutput(PathForOutput(ctx, "ImplicitOutput")).
 			Input(PathForSource(ctx, "Input")).
 			Output(PathForOutput(ctx, "Output")).
+			OrderOnly(PathForSource(ctx, "OrderOnly")).
 			Text("Text").
 			Tool(PathForSource(ctx, "Tool"))
 
@@ -298,6 +301,7 @@
 			DepFile(PathForOutput(ctx, "depfile2")).
 			Input(PathForSource(ctx, "input2")).
 			Output(PathForOutput(ctx, "output2")).
+			OrderOnlys(PathsForSource(ctx, []string{"OrderOnlys"})).
 			Tool(PathForSource(ctx, "tool2"))
 
 		// Test updates to the first command after the second command has been started
@@ -317,6 +321,7 @@
 	wantOutputs := PathsForOutput(ctx, []string{"ImplicitOutput", "Output", "output", "output2", "output3"})
 	wantDepFiles := PathsForOutput(ctx, []string{"DepFile", "depfile", "ImplicitDepFile", "depfile2"})
 	wantTools := PathsForSource(ctx, []string{"Tool", "tool2"})
+	wantOrderOnlys := PathsForSource(ctx, []string{"OrderOnly", "OrderOnlys"})
 
 	t.Run("normal", func(t *testing.T) {
 		rule := NewRuleBuilder()
@@ -346,6 +351,9 @@
 		if g, w := rule.Tools(), wantTools; !reflect.DeepEqual(w, g) {
 			t.Errorf("\nwant rule.Tools() = %#v\n                got %#v", w, g)
 		}
+		if g, w := rule.OrderOnlys(), wantOrderOnlys; !reflect.DeepEqual(w, g) {
+			t.Errorf("\nwant rule.OrderOnlys() = %#v\n                got %#v", w, g)
+		}
 
 		if g, w := rule.depFileMergerCmd(ctx, rule.DepFiles()).String(), wantDepMergerCommand; g != w {
 			t.Errorf("\nwant rule.depFileMergerCmd() = %#v\n                   got %#v", w, g)
@@ -380,6 +388,9 @@
 		if g, w := rule.Tools(), wantTools; !reflect.DeepEqual(w, g) {
 			t.Errorf("\nwant rule.Tools() = %#v\n                got %#v", w, g)
 		}
+		if g, w := rule.OrderOnlys(), wantOrderOnlys; !reflect.DeepEqual(w, g) {
+			t.Errorf("\nwant rule.OrderOnlys() = %#v\n                got %#v", w, g)
+		}
 
 		if g, w := rule.depFileMergerCmd(ctx, rule.DepFiles()).String(), wantDepMergerCommand; g != w {
 			t.Errorf("\nwant rule.depFileMergerCmd() = %#v\n                   got %#v", w, g)
diff --git a/android/variable.go b/android/variable.go
index 4bc3d8a..4d1b5e4 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -140,9 +140,8 @@
 	// Suffix to add to generated Makefiles
 	Make_suffix *string `json:",omitempty"`
 
-	BuildId             *string `json:",omitempty"`
-	BuildNumberFromFile *string `json:",omitempty"`
-	DateFromFile        *string `json:",omitempty"`
+	BuildId         *string `json:",omitempty"`
+	BuildNumberFile *string `json:",omitempty"`
 
 	Platform_version_name                     *string  `json:",omitempty"`
 	Platform_sdk_version                      *int     `json:",omitempty"`
@@ -346,7 +345,7 @@
 
 func (v *productVariables) SetDefaultConfig() {
 	*v = productVariables{
-		BuildNumberFromFile: stringPtr("123456789"),
+		BuildNumberFile: stringPtr("build_number.txt"),
 
 		Platform_version_name:             stringPtr("Q"),
 		Platform_sdk_version:              intPtr(28),
diff --git a/cc/linker.go b/cc/linker.go
index af4cbf3..a7b621a 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -501,19 +501,21 @@
 var injectVersionSymbol = pctx.AndroidStaticRule("injectVersionSymbol",
 	blueprint.RuleParams{
 		Command: "$symbolInjectCmd -i $in -o $out -s soong_build_number " +
-			"-from 'SOONG BUILD NUMBER PLACEHOLDER' -v $buildNumberFromFile",
+			"-from 'SOONG BUILD NUMBER PLACEHOLDER' -v $$(cat $buildNumberFile)",
 		CommandDeps: []string{"$symbolInjectCmd"},
 	},
-	"buildNumberFromFile")
+	"buildNumberFile")
 
 func (linker *baseLinker) injectVersionSymbol(ctx ModuleContext, in android.Path, out android.WritablePath) {
+	buildNumberFile := ctx.Config().BuildNumberFile(ctx)
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        injectVersionSymbol,
 		Description: "inject version symbol",
 		Input:       in,
 		Output:      out,
+		OrderOnly:   android.Paths{buildNumberFile},
 		Args: map[string]string{
-			"buildNumberFromFile": proptools.NinjaEscape(ctx.Config().BuildNumberFromFile()),
+			"buildNumberFile": buildNumberFile.String(),
 		},
 	})
 }
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 70d997a..1ac7444 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -773,6 +773,7 @@
 }
 
 func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
+	buildNumberFile := ctx.Config().BuildNumberFile(ctx)
 	// Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources.  For modules with 1.9
 	// sources, droiddoc will get sources produced by metalava which will have already stripped out the
 	// 1.9 language features.
@@ -782,7 +783,7 @@
 		Flag("-XDignore.symbol.file").
 		FlagWithArg("-doclet ", "com.google.doclava.Doclava").
 		FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
-		FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
+		FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-$(cat "+buildNumberFile.String()+")").OrderOnly(buildNumberFile).
 		FlagWithArg("-hdf page.now ", `"$(date -d @$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
 
 	if String(d.properties.Custom_template) == "" {
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index cb17fee..86eddb1 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -28,10 +28,6 @@
 
 func RegisterPrebuiltApisBuildComponents(ctx android.RegistrationContext) {
 	ctx.RegisterModuleType("prebuilt_apis", PrebuiltApisFactory)
-
-	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("prebuilt_apis", PrebuiltApisMutator).Parallel()
-	})
 }
 
 type prebuiltApisProperties struct {
@@ -48,7 +44,7 @@
 	// no need to implement
 }
 
-func parseJarPath(ctx android.BaseModuleContext, path string) (module string, apiver string, scope string) {
+func parseJarPath(path string) (module string, apiver string, scope string) {
 	elements := strings.Split(path, "/")
 
 	apiver = elements[0]
@@ -58,7 +54,7 @@
 	return
 }
 
-func parseApiFilePath(ctx android.BaseModuleContext, path string) (module string, apiver string, scope string) {
+func parseApiFilePath(ctx android.LoadHookContext, path string) (module string, apiver string, scope string) {
 	elements := strings.Split(path, "/")
 	apiver = elements[0]
 
@@ -73,7 +69,7 @@
 	return
 }
 
-func createImport(mctx android.TopDownMutatorContext, module string, scope string, apiver string, path string) {
+func createImport(mctx android.LoadHookContext, module string, scope string, apiver string, path string) {
 	props := struct {
 		Name        *string
 		Jars        []string
@@ -89,7 +85,7 @@
 	mctx.CreateModule(ImportFactory, &props)
 }
 
-func createFilegroup(mctx android.TopDownMutatorContext, module string, scope string, apiver string, path string) {
+func createFilegroup(mctx android.LoadHookContext, module string, scope string, apiver string, path string) {
 	fgName := module + ".api." + scope + "." + apiver
 	filegroupProps := struct {
 		Name *string
@@ -100,7 +96,7 @@
 	mctx.CreateModule(android.FileGroupFactory, &filegroupProps)
 }
 
-func getPrebuiltFiles(mctx android.TopDownMutatorContext, name string) []string {
+func getPrebuiltFiles(mctx android.LoadHookContext, name string) []string {
 	mydir := mctx.ModuleDir() + "/"
 	var files []string
 	for _, apiver := range mctx.Module().(*prebuiltApis).properties.Api_dirs {
@@ -115,7 +111,7 @@
 	return files
 }
 
-func prebuiltSdkStubs(mctx android.TopDownMutatorContext) {
+func prebuiltSdkStubs(mctx android.LoadHookContext) {
 	mydir := mctx.ModuleDir() + "/"
 	// <apiver>/<scope>/<module>.jar
 	files := getPrebuiltFiles(mctx, "*.jar")
@@ -123,12 +119,12 @@
 	for _, f := range files {
 		// create a Import module for each jar file
 		localPath := strings.TrimPrefix(f, mydir)
-		module, apiver, scope := parseJarPath(mctx, localPath)
+		module, apiver, scope := parseJarPath(localPath)
 		createImport(mctx, module, scope, apiver, localPath)
 	}
 }
 
-func prebuiltApiFiles(mctx android.TopDownMutatorContext) {
+func prebuiltApiFiles(mctx android.LoadHookContext) {
 	mydir := mctx.ModuleDir() + "/"
 	// <apiver>/<scope>/api/<module>.txt
 	files := getPrebuiltFiles(mctx, "api/*.txt")
@@ -178,7 +174,7 @@
 	}
 }
 
-func PrebuiltApisMutator(mctx android.TopDownMutatorContext) {
+func createPrebuiltApiModules(mctx android.LoadHookContext) {
 	if _, ok := mctx.Module().(*prebuiltApis); ok {
 		prebuiltApiFiles(mctx)
 		prebuiltSdkStubs(mctx)
@@ -191,9 +187,15 @@
 // generates a filegroup module named <module>-api.<scope>.<ver>.
 //
 // It also creates <module>-api.<scope>.latest for the latest <ver>.
+//
+// Similarly, it generates a java_import for all API .jar files found under the
+// directory where the Android.bp is located. Specifically, an API file located
+// at ./<ver>/<scope>/api/<module>.jar generates a java_import module named
+// <prebuilt-api-module>.<scope>.<ver>.<module>.
 func PrebuiltApisFactory() android.Module {
 	module := &prebuiltApis{}
 	module.AddProperties(&module.properties)
 	android.InitAndroidModule(module)
+	android.AddLoadHook(module, createPrebuiltApiModules)
 	return module
 }