Merge "Use WriteFileRule instead of custom echo commands"
diff --git a/cc/test.go b/cc/test.go
index 2a4861c..16ef0ef 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -415,8 +415,16 @@
testInstallBase := getTestInstallBase(useVendor)
configs := getTradefedConfigOptions(ctx, &test.Properties, test.isolated(ctx))
- test.testConfig = tradefed.AutoGenNativeTestConfig(ctx, test.Properties.Test_config,
- test.Properties.Test_config_template, test.testDecorator.InstallerProperties.Test_suites, configs, test.Properties.Auto_gen_config, testInstallBase)
+ test.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
+ TestConfigProp: test.Properties.Test_config,
+ TestConfigTemplateProp: test.Properties.Test_config_template,
+ TestSuites: test.testDecorator.InstallerProperties.Test_suites,
+ Config: configs,
+ AutoGenConfig: test.Properties.Auto_gen_config,
+ TestInstallBase: testInstallBase,
+ DeviceTemplate: "${NativeTestConfigTemplate}",
+ HostTemplate: "${NativeHostTestConfigTemplate}",
+ })
test.extraTestConfigs = android.PathsForModuleSrc(ctx, test.Properties.Test_options.Extra_test_configs)
@@ -630,8 +638,15 @@
if Bool(benchmark.Properties.Require_root) {
configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
}
- benchmark.testConfig = tradefed.AutoGenNativeBenchmarkTestConfig(ctx, benchmark.Properties.Test_config,
- benchmark.Properties.Test_config_template, benchmark.Properties.Test_suites, configs, benchmark.Properties.Auto_gen_config)
+ benchmark.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
+ TestConfigProp: benchmark.Properties.Test_config,
+ TestConfigTemplateProp: benchmark.Properties.Test_config_template,
+ TestSuites: benchmark.Properties.Test_suites,
+ Config: configs,
+ AutoGenConfig: benchmark.Properties.Auto_gen_config,
+ DeviceTemplate: "${NativeBenchmarkTestConfigTemplate}",
+ HostTemplate: "${NativeBenchmarkTestConfigTemplate}",
+ })
benchmark.binaryDecorator.baseInstaller.dir = filepath.Join("benchmarktest", ctx.ModuleName())
benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("benchmarktest64", ctx.ModuleName())
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 744a10c..fe928ad 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -277,7 +277,7 @@
switch ctx.Config().BuildMode {
case android.GenerateModuleGraph:
stopBefore = bootstrap.StopBeforeWriteNinja
- case android.GenerateQueryView | android.GenerateDocFile:
+ case android.GenerateQueryView, android.GenerateDocFile:
stopBefore = bootstrap.StopBeforePrepareBuildActions
default:
stopBefore = bootstrap.DoEverything
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 713ccbe..8c99988 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -58,7 +58,7 @@
stdio func() terminal.StdioInterface
// run the command
- run func(ctx build.Context, config build.Config, args []string, logsDir string)
+ run func(ctx build.Context, config build.Config, args []string)
}
// list of supported commands (flags) supported by soong ui
@@ -91,6 +91,15 @@
config: buildActionConfig,
stdio: stdio,
run: runMake,
+ }, {
+ flag: "--upload-metrics-only",
+ description: "upload metrics without building anything",
+ config: uploadOnlyConfig,
+ stdio: stdio,
+ // Upload-only mode mostly skips to the metrics-uploading phase of soong_ui.
+ // However, this invocation marks the true "end of the build", and thus we
+ // need to update the total runtime of the build to include this upload step.
+ run: updateTotalRealTime,
},
}
@@ -182,18 +191,49 @@
}}
config := c.config(buildCtx, args...)
+ config.SetLogsPrefix(c.logsPrefix)
+ logsDir := config.LogsDir()
+ buildStarted = config.BuildStartedTimeOrDefault(buildStarted)
+ buildErrorFile := filepath.Join(logsDir, c.logsPrefix+"build_error")
+ soongMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_metrics")
+ rbeMetricsFile := filepath.Join(logsDir, c.logsPrefix+"rbe_metrics.pb")
+ bp2buildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"bp2build_metrics.pb")
+ metricsFiles := []string{
+ buildErrorFile, // build error strings
+ rbeMetricsFile, // high level metrics related to remote build execution.
+ bp2buildMetricsFile, // high level metrics related to bp2build.
+ soongMetricsFile, // high level metrics related to this build system.
+ config.BazelMetricsDir(), // directory that contains a set of bazel metrics.
+ }
+
+ os.MkdirAll(logsDir, 0777)
+
+ log.SetOutput(filepath.Join(logsDir, c.logsPrefix+"soong.log"))
+
+ trace.SetOutput(filepath.Join(logsDir, c.logsPrefix+"build.trace"))
+
+ c.run(buildCtx, config, args)
+
+ defer met.Dump(soongMetricsFile)
+ if !config.SkipMetricsUpload() {
+ defer build.UploadMetrics(buildCtx, config, c.simpleOutput, buildStarted, metricsFiles...)
+ }
+
+}
+
+func logAndSymlinkSetup(buildCtx build.Context, config build.Config) {
+ log := buildCtx.ContextImpl.Logger
+ logsPrefix := config.GetLogsPrefix()
build.SetupOutDir(buildCtx, config)
-
- // Set up files to be outputted in the log directory.
logsDir := config.LogsDir()
// Common list of metric file definition.
- buildErrorFile := filepath.Join(logsDir, c.logsPrefix+"build_error")
- rbeMetricsFile := filepath.Join(logsDir, c.logsPrefix+"rbe_metrics.pb")
- soongMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_metrics")
- bp2buildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"bp2build_metrics.pb")
- soongBuildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_build_metrics.pb")
+ buildErrorFile := filepath.Join(logsDir, logsPrefix+"build_error")
+ rbeMetricsFile := filepath.Join(logsDir, logsPrefix+"rbe_metrics.pb")
+ soongMetricsFile := filepath.Join(logsDir, logsPrefix+"soong_metrics")
+ bp2buildMetricsFile := filepath.Join(logsDir, logsPrefix+"bp2build_metrics.pb")
+ soongBuildMetricsFile := filepath.Join(logsDir, logsPrefix+"soong_build_metrics.pb")
//Delete the stale metrics files
staleFileSlice := []string{buildErrorFile, rbeMetricsFile, soongMetricsFile, bp2buildMetricsFile, soongBuildMetricsFile}
@@ -203,14 +243,12 @@
build.PrintOutDirWarning(buildCtx, config)
- os.MkdirAll(logsDir, 0777)
- log.SetOutput(filepath.Join(logsDir, c.logsPrefix+"soong.log"))
- trace.SetOutput(filepath.Join(logsDir, c.logsPrefix+"build.trace"))
- stat.AddOutput(status.NewVerboseLog(log, filepath.Join(logsDir, c.logsPrefix+"verbose.log")))
- stat.AddOutput(status.NewErrorLog(log, filepath.Join(logsDir, c.logsPrefix+"error.log")))
+ stat := buildCtx.Status
+ stat.AddOutput(status.NewVerboseLog(log, filepath.Join(logsDir, logsPrefix+"verbose.log")))
+ stat.AddOutput(status.NewErrorLog(log, filepath.Join(logsDir, logsPrefix+"error.log")))
stat.AddOutput(status.NewProtoErrorLog(log, buildErrorFile))
stat.AddOutput(status.NewCriticalPath(log))
- stat.AddOutput(status.NewBuildProgressLog(log, filepath.Join(logsDir, c.logsPrefix+"build_progress.pb")))
+ stat.AddOutput(status.NewBuildProgressLog(log, filepath.Join(logsDir, logsPrefix+"build_progress.pb")))
buildCtx.Verbosef("Detected %.3v GB total RAM", float32(config.TotalRAM())/(1024*1024*1024))
buildCtx.Verbosef("Parallelism (local/remote/highmem): %v/%v/%v",
@@ -218,27 +256,7 @@
setMaxFiles(buildCtx)
- {
- // The order of the function calls is important. The last defer function call
- // is the first one that is executed to save the rbe metrics to a protobuf
- // file. The soong metrics file is then next. Bazel profiles are written
- // before the uploadMetrics is invoked. The written files are then uploaded
- // if the uploading of the metrics is enabled.
- files := []string{
- buildErrorFile, // build error strings
- rbeMetricsFile, // high level metrics related to remote build execution.
- soongBuildMetricsFile, // high level metrics related to soong build(except bp2build).
- bp2buildMetricsFile, // high level metrics related to bp2build.
- soongMetricsFile, // high level metrics related to this build system.
- config.BazelMetricsDir(), // directory that contains a set of bazel metrics.
- }
-
- if !config.SkipMetricsUpload() {
- defer build.UploadMetrics(buildCtx, config, c.simpleOutput, buildStarted, files...)
- }
- defer met.Dump(soongMetricsFile)
- defer build.CheckProdCreds(buildCtx, config)
- }
+ defer build.CheckProdCreds(buildCtx, config)
// Read the time at the starting point.
if start, ok := os.LookupEnv("TRACE_BEGIN_SOONG"); ok {
@@ -253,7 +271,7 @@
}
if executable, err := os.Executable(); err == nil {
- trace.ImportMicrofactoryLog(filepath.Join(filepath.Dir(executable), "."+filepath.Base(executable)+".trace"))
+ buildCtx.ContextImpl.Tracer.ImportMicrofactoryLog(filepath.Join(filepath.Dir(executable), "."+filepath.Base(executable)+".trace"))
}
}
@@ -266,8 +284,6 @@
f := build.NewSourceFinder(buildCtx, config)
defer f.Shutdown()
build.FindSources(buildCtx, config, f)
-
- c.run(buildCtx, config, args, logsDir)
}
func fixBadDanglingLink(ctx build.Context, name string) {
@@ -284,7 +300,8 @@
}
}
-func dumpVar(ctx build.Context, config build.Config, args []string, _ string) {
+func dumpVar(ctx build.Context, config build.Config, args []string) {
+ logAndSymlinkSetup(ctx, config)
flags := flag.NewFlagSet("dumpvar", flag.ExitOnError)
flags.SetOutput(ctx.Writer)
@@ -336,7 +353,9 @@
}
}
-func dumpVars(ctx build.Context, config build.Config, args []string, _ string) {
+func dumpVars(ctx build.Context, config build.Config, args []string) {
+ logAndSymlinkSetup(ctx, config)
+
flags := flag.NewFlagSet("dumpvars", flag.ExitOnError)
flags.SetOutput(ctx.Writer)
@@ -421,6 +440,14 @@
return build.NewConfig(ctx)
}
+// uploadOnlyConfig explicitly requires no arguments.
+func uploadOnlyConfig(ctx build.Context, args ...string) build.Config {
+ if len(args) > 0 {
+ fmt.Printf("--upload-only does not require arguments.")
+ }
+ return build.UploadOnlyConfig(ctx)
+}
+
func buildActionConfig(ctx build.Context, args ...string) build.Config {
flags := flag.NewFlagSet("build-mode", flag.ContinueOnError)
flags.SetOutput(ctx.Writer)
@@ -514,7 +541,9 @@
return build.NewBuildActionConfig(buildAction, *dir, ctx, args...)
}
-func runMake(ctx build.Context, config build.Config, _ []string, logsDir string) {
+func runMake(ctx build.Context, config build.Config, _ []string) {
+ logAndSymlinkSetup(ctx, config)
+ logsDir := config.LogsDir()
if config.IsVerbose() {
writer := ctx.Writer
fmt.Fprintln(writer, "! The argument `showcommands` is no longer supported.")
@@ -659,3 +688,19 @@
ctx.Println("Failed to increase file limit:", err)
}
}
+
+func updateTotalRealTime(ctx build.Context, config build.Config, args []string) {
+ soongMetricsFile := filepath.Join(config.LogsDir(), "soong_metrics")
+
+ //read file into proto
+ data, err := os.ReadFile(soongMetricsFile)
+ if err != nil {
+ ctx.Fatal(err)
+ }
+ met := ctx.ContextImpl.Metrics
+
+ err = met.UpdateTotalRealTime(data)
+ if err != nil {
+ ctx.Fatal(err)
+ }
+}
diff --git a/java/base.go b/java/base.go
index 55d77dc..6e42aef 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1488,7 +1488,14 @@
}
// Dex compilation
var dexOutputFile android.OutputPath
- dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(ctx), implementationAndResourcesJar, jarName)
+ params := &compileDexParams{
+ flags: flags,
+ sdkVersion: j.SdkVersion(ctx),
+ minSdkVersion: j.MinSdkVersion(ctx),
+ classesJar: implementationAndResourcesJar,
+ jarName: jarName,
+ }
+ dexOutputFile = j.dexer.compileDex(ctx, params)
if ctx.Failed() {
return
}
diff --git a/java/dex.go b/java/dex.go
index 40ee99d..ed1f07b 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -180,7 +180,7 @@
"r8Flags", "zipFlags", "tmpJar", "mergeZipsFlags"}, []string{"implicits"})
func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
- minSdkVersion android.SdkSpec) (flags []string, deps android.Paths) {
+ dexParams *compileDexParams) (flags []string, deps android.Paths) {
flags = d.dexProperties.Dxflags
// Translate all the DX flags to D8 ones until all the build files have been migrated
@@ -209,11 +209,11 @@
// Note: Targets with a min SDK kind of core_platform (e.g., framework.jar) or unspecified (e.g.,
// services.jar), are not classified as stable, which is WAI.
// TODO(b/232073181): Expand to additional min SDK cases after validation.
- if !minSdkVersion.Stable() {
+ if !dexParams.sdkVersion.Stable() {
flags = append(flags, "--android-platform-build")
}
- effectiveVersion, err := minSdkVersion.EffectiveVersion(ctx)
+ effectiveVersion, err := dexParams.minSdkVersion.EffectiveVersion(ctx)
if err != nil {
ctx.PropertyErrorf("min_sdk_version", "%s", err)
}
@@ -317,20 +317,27 @@
return r8Flags, r8Deps
}
-func (d *dexer) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, minSdkVersion android.SdkSpec,
- classesJar android.Path, jarName string) android.OutputPath {
+type compileDexParams struct {
+ flags javaBuilderFlags
+ sdkVersion android.SdkSpec
+ minSdkVersion android.SdkSpec
+ classesJar android.Path
+ jarName string
+}
+
+func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParams) android.OutputPath {
// Compile classes.jar into classes.dex and then javalib.jar
- javalibJar := android.PathForModuleOut(ctx, "dex", jarName).OutputPath
+ javalibJar := android.PathForModuleOut(ctx, "dex", dexParams.jarName).OutputPath
outDir := android.PathForModuleOut(ctx, "dex")
- tmpJar := android.PathForModuleOut(ctx, "withres-withoutdex", jarName)
+ tmpJar := android.PathForModuleOut(ctx, "withres-withoutdex", dexParams.jarName)
zipFlags := "--ignore_missing_files"
if proptools.Bool(d.dexProperties.Uncompress_dex) {
zipFlags += " -L 0"
}
- commonFlags, commonDeps := d.dexCommonFlags(ctx, minSdkVersion)
+ commonFlags, commonDeps := d.dexCommonFlags(ctx, dexParams)
// Exclude kotlinc generated files when "exclude_kotlinc_generated_files" is set to true.
mergeZipsFlags := ""
@@ -347,7 +354,7 @@
android.ModuleNameWithPossibleOverride(ctx), "unused.txt")
proguardUsageZip := android.PathForModuleOut(ctx, "proguard_usage.zip")
d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip)
- r8Flags, r8Deps := d.r8Flags(ctx, flags)
+ r8Flags, r8Deps := d.r8Flags(ctx, dexParams.flags)
r8Deps = append(r8Deps, commonDeps...)
rule := r8
args := map[string]string{
@@ -370,12 +377,12 @@
Description: "r8",
Output: javalibJar,
ImplicitOutputs: android.WritablePaths{proguardDictionary, proguardUsageZip},
- Input: classesJar,
+ Input: dexParams.classesJar,
Implicits: r8Deps,
Args: args,
})
} else {
- d8Flags, d8Deps := d8Flags(flags)
+ d8Flags, d8Deps := d8Flags(dexParams.flags)
d8Deps = append(d8Deps, commonDeps...)
rule := d8
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8") {
@@ -385,7 +392,7 @@
Rule: rule,
Description: "d8",
Output: javalibJar,
- Input: classesJar,
+ Input: dexParams.classesJar,
Implicits: d8Deps,
Args: map[string]string{
"d8Flags": strings.Join(append(commonFlags, d8Flags...), " "),
@@ -397,7 +404,7 @@
})
}
if proptools.Bool(d.dexProperties.Uncompress_dex) {
- alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", jarName).OutputPath
+ alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", dexParams.jarName).OutputPath
TransformZipAlign(ctx, alignedJavalibJar, javalibJar)
javalibJar = alignedJavalibJar
}
diff --git a/java/dex_test.go b/java/dex_test.go
index fc6cd0f..cddd4ad 100644
--- a/java/dex_test.go
+++ b/java/dex_test.go
@@ -41,6 +41,7 @@
name: "core_platform_app",
srcs: ["foo.java"],
sdk_version: "core_platform",
+ min_sdk_version: "31",
}
java_library {
diff --git a/java/java.go b/java/java.go
index 275abbe..e83678e 100644
--- a/java/java.go
+++ b/java/java.go
@@ -915,6 +915,10 @@
// a list of extra test configuration files that should be installed with the module.
Extra_test_configs []string `android:"path,arch_variant"`
+
+ // Extra <option> tags to add to the auto generated test xml file. The "key"
+ // is optional in each of these.
+ Tradefed_options []tradefed.Option
}
type testProperties struct {
@@ -1192,9 +1196,18 @@
defaultUnitTest := !inList("tradefed", j.properties.Libs) && !inList("cts", j.testProperties.Test_suites)
j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest)
}
-
- j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
- j.testProperties.Test_suites, configs, j.testProperties.Auto_gen_config, j.testProperties.Test_options.Unit_test)
+ j.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
+ TestConfigProp: j.testProperties.Test_config,
+ TestConfigTemplateProp: j.testProperties.Test_config_template,
+ TestSuites: j.testProperties.Test_suites,
+ Config: configs,
+ OptionsForAutogenerated: j.testProperties.Test_options.Tradefed_options,
+ AutoGenConfig: j.testProperties.Auto_gen_config,
+ UnitTest: j.testProperties.Test_options.Unit_test,
+ DeviceTemplate: "${JavaTestConfigTemplate}",
+ HostTemplate: "${JavaHostTestConfigTemplate}",
+ HostUnitTestTemplate: "${JavaHostUnitTestConfigTemplate}",
+ })
j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
@@ -1239,8 +1252,13 @@
}
func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.prebuiltTestProperties.Test_config, nil,
- j.prebuiltTestProperties.Test_suites, nil, nil, nil)
+ j.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
+ TestConfigProp: j.prebuiltTestProperties.Test_config,
+ TestSuites: j.prebuiltTestProperties.Test_suites,
+ DeviceTemplate: "${JavaTestConfigTemplate}",
+ HostTemplate: "${JavaHostTestConfigTemplate}",
+ HostUnitTestTemplate: "${JavaHostUnitTestConfigTemplate}",
+ })
j.Import.GenerateAndroidBuildActions(ctx)
}
@@ -1987,7 +2005,15 @@
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
var dexOutputFile android.OutputPath
- dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(ctx), outputFile, jarName)
+ dexParams := &compileDexParams{
+ flags: flags,
+ sdkVersion: j.SdkVersion(ctx),
+ minSdkVersion: j.MinSdkVersion(ctx),
+ classesJar: outputFile,
+ jarName: jarName,
+ }
+
+ dexOutputFile = j.dexer.compileDex(ctx, dexParams)
if ctx.Failed() {
return
}
diff --git a/java/java_test.go b/java/java_test.go
index dff1fd0..085f627 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1945,3 +1945,27 @@
}
}
}
+
+func TestTradefedOptions(t *testing.T) {
+ result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
+java_test_host {
+ name: "foo",
+ test_options: {
+ tradefed_options: [
+ {
+ name: "exclude-path",
+ value: "org/apache"
+ }
+ ]
+ }
+}
+`)
+
+ buildOS := result.Config.BuildOS.String()
+ args := result.ModuleForTests("foo", buildOS+"_common").
+ Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args
+ expected := proptools.NinjaAndShellEscape("<option name=\"exclude-path\" value=\"org/apache\" />")
+ if args["extraConfigs"] != expected {
+ t.Errorf("Expected args[\"extraConfigs\"] to equal %q, was %q", expected, args["extraConfigs"])
+ }
+}
diff --git a/java/robolectric.go b/java/robolectric.go
index 6e8d591..68f27b8 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -131,9 +131,14 @@
r.forceOSType = ctx.Config().BuildOS
r.forceArchType = ctx.Config().BuildArch
- r.testConfig = tradefed.AutoGenRobolectricTestConfig(ctx, r.testProperties.Test_config,
- r.testProperties.Test_config_template, r.testProperties.Test_suites,
- r.testProperties.Auto_gen_config)
+ r.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
+ TestConfigProp: r.testProperties.Test_config,
+ TestConfigTemplateProp: r.testProperties.Test_config_template,
+ TestSuites: r.testProperties.Test_suites,
+ AutoGenConfig: r.testProperties.Auto_gen_config,
+ DeviceTemplate: "${RobolectricTestConfigTemplate}",
+ HostTemplate: "${RobolectricTestConfigTemplate}",
+ })
r.data = android.PathsForModuleSrc(ctx, r.testProperties.Data)
roboTestConfig := android.PathForModuleGen(ctx, "robolectric").
diff --git a/python/test.go b/python/test.go
index b9b3465..fc5c211 100644
--- a/python/test.go
+++ b/python/test.go
@@ -67,9 +67,14 @@
}
func (test *testDecorator) install(ctx android.ModuleContext, file android.Path) {
- test.testConfig = tradefed.AutoGenPythonBinaryHostTestConfig(ctx, test.testProperties.Test_config,
- test.testProperties.Test_config_template, test.binaryDecorator.binaryProperties.Test_suites,
- test.binaryDecorator.binaryProperties.Auto_gen_config)
+ test.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
+ TestConfigProp: test.testProperties.Test_config,
+ TestConfigTemplateProp: test.testProperties.Test_config_template,
+ TestSuites: test.binaryDecorator.binaryProperties.Test_suites,
+ AutoGenConfig: test.binaryDecorator.binaryProperties.Auto_gen_config,
+ DeviceTemplate: "${PythonBinaryHostTestConfigTemplate}",
+ HostTemplate: "${PythonBinaryHostTestConfigTemplate}",
+ })
test.binaryDecorator.pythonInstaller.dir = "nativetest"
test.binaryDecorator.pythonInstaller.dir64 = "nativetest64"
diff --git a/rust/benchmark.go b/rust/benchmark.go
index 0e84243..c0f1e24 100644
--- a/rust/benchmark.go
+++ b/rust/benchmark.go
@@ -112,12 +112,14 @@
}
func (benchmark *benchmarkDecorator) install(ctx ModuleContext) {
- benchmark.testConfig = tradefed.AutoGenRustBenchmarkConfig(ctx,
- benchmark.Properties.Test_config,
- benchmark.Properties.Test_config_template,
- benchmark.Properties.Test_suites,
- nil,
- benchmark.Properties.Auto_gen_config)
+ benchmark.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
+ TestConfigProp: benchmark.Properties.Test_config,
+ TestConfigTemplateProp: benchmark.Properties.Test_config_template,
+ TestSuites: benchmark.Properties.Test_suites,
+ AutoGenConfig: benchmark.Properties.Auto_gen_config,
+ DeviceTemplate: "${RustDeviceBenchmarkConfigTemplate}",
+ HostTemplate: "${RustHostBenchmarkConfigTemplate}",
+ })
// default relative install path is module name
if !Bool(benchmark.Properties.No_named_install_directory) {
diff --git a/rust/test.go b/rust/test.go
index 0cc3bca..4f922b4 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -130,13 +130,16 @@
configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options})
}
- test.testConfig = tradefed.AutoGenRustTestConfig(ctx,
- test.Properties.Test_config,
- test.Properties.Test_config_template,
- test.Properties.Test_suites,
- configs,
- test.Properties.Auto_gen_config,
- testInstallBase)
+ test.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
+ TestConfigProp: test.Properties.Test_config,
+ TestConfigTemplateProp: test.Properties.Test_config_template,
+ TestSuites: test.Properties.Test_suites,
+ Config: configs,
+ AutoGenConfig: test.Properties.Auto_gen_config,
+ TestInstallBase: testInstallBase,
+ DeviceTemplate: "${RustDeviceTestConfigTemplate}",
+ HostTemplate: "${RustHostTestConfigTemplate}",
+ })
dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 9627329..c921ca6 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -379,8 +379,16 @@
}
configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.PushFilePreparer", options})
}
- s.testConfig = tradefed.AutoGenShellTestConfig(ctx, s.testProperties.Test_config,
- s.testProperties.Test_config_template, s.testProperties.Test_suites, configs, s.testProperties.Auto_gen_config, s.outputFilePath.Base())
+ s.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
+ TestConfigProp: s.testProperties.Test_config,
+ TestConfigTemplateProp: s.testProperties.Test_config_template,
+ TestSuites: s.testProperties.Test_suites,
+ Config: configs,
+ AutoGenConfig: s.testProperties.Auto_gen_config,
+ OutputFileName: s.outputFilePath.Base(),
+ DeviceTemplate: "${ShellTestConfigTemplate}",
+ HostTemplate: "${ShellTestConfigTemplate}",
+ })
s.dataModules = make(map[string]android.Path)
ctx.VisitDirectDeps(func(dep android.Module) {
diff --git a/tradefed/autogen.go b/tradefed/autogen.go
index c2429ab..e93bac3 100644
--- a/tradefed/autogen.go
+++ b/tradefed/autogen.go
@@ -107,15 +107,10 @@
}
-func autogenTemplate(ctx android.ModuleContext, output android.WritablePath, template string, configs []Config, testInstallBase string) {
- autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), output, template, configs, "", testInstallBase)
-}
-
-func autogenTemplateWithName(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, testInstallBase string) {
- autogenTemplateWithNameAndOutputFile(ctx, name, output, template, configs, "", testInstallBase)
-}
-
-func autogenTemplateWithNameAndOutputFile(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, outputFileName string, testInstallBase string) {
+func autogenTemplate(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, outputFileName string, testInstallBase string) {
+ if template == "" {
+ ctx.ModuleErrorf("Empty template")
+ }
var configStrings []string
for _, config := range configs {
configStrings = append(configStrings, config.Config())
@@ -137,144 +132,49 @@
})
}
-func AutoGenNativeTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool, testInstallBase string) android.Path {
+// AutoGenTestConfigOptions is used so that we can supply many optional
+// arguments to the AutoGenTestConfig function.
+type AutoGenTestConfigOptions struct {
+ Name string
+ OutputFileName string
+ TestConfigProp *string
+ TestConfigTemplateProp *string
+ TestSuites []string
+ Config []Config
+ OptionsForAutogenerated []Option
+ AutoGenConfig *bool
+ UnitTest *bool
+ TestInstallBase string
+ DeviceTemplate string
+ HostTemplate string
+ HostUnitTestTemplate string
+}
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
+func AutoGenTestConfig(ctx android.ModuleContext, options AutoGenTestConfigOptions) android.Path {
+ configs := append([]Config{}, options.Config...)
+ for _, c := range options.OptionsForAutogenerated {
+ configs = append(configs, c)
+ }
+ path, autogenPath := testConfigPath(ctx, options.TestConfigProp, options.TestSuites, options.AutoGenConfig, options.TestConfigTemplateProp)
if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
+ templatePath := getTestConfigTemplate(ctx, options.TestConfigTemplateProp)
if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), config, testInstallBase)
+ autogenTemplate(ctx, options.Name, autogenPath, templatePath.String(), configs, options.OutputFileName, options.TestInstallBase)
} else {
if ctx.Device() {
- autogenTemplate(ctx, autogenPath, "${NativeTestConfigTemplate}", config, testInstallBase)
+ autogenTemplate(ctx, options.Name, autogenPath, options.DeviceTemplate, configs, options.OutputFileName, options.TestInstallBase)
} else {
- autogenTemplate(ctx, autogenPath, "${NativeHostTestConfigTemplate}", config, testInstallBase)
- }
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenShellTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool, outputFileName string) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), autogenPath, templatePath.String(), config, outputFileName, "")
- } else {
- autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), autogenPath, "${ShellTestConfigTemplate}", config, outputFileName, "")
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenNativeBenchmarkTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, configs []Config, autoGenConfig *bool) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), configs, "")
- } else {
- autogenTemplate(ctx, autogenPath, "${NativeBenchmarkTestConfigTemplate}", configs, "")
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenJavaTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string,
- testSuites []string, config []Config, autoGenConfig *bool, unitTest *bool) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), config, "")
- } else {
- if ctx.Device() {
- autogenTemplate(ctx, autogenPath, "${JavaTestConfigTemplate}", config, "")
- } else {
- if Bool(unitTest) {
- autogenTemplate(ctx, autogenPath, "${JavaHostUnitTestConfigTemplate}", config, "")
+ if Bool(options.UnitTest) {
+ autogenTemplate(ctx, options.Name, autogenPath, options.HostUnitTestTemplate, configs, options.OutputFileName, options.TestInstallBase)
} else {
- autogenTemplate(ctx, autogenPath, "${JavaHostTestConfigTemplate}", config, "")
+ autogenTemplate(ctx, options.Name, autogenPath, options.HostTemplate, configs, options.OutputFileName, options.TestInstallBase)
}
}
}
return autogenPath
}
- return path
-}
-
-func AutoGenPythonBinaryHostTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, autoGenConfig *bool) android.Path {
-
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), nil, "")
- } else {
- autogenTemplate(ctx, autogenPath, "${PythonBinaryHostTestConfigTemplate}", nil, "")
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenRustTestConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool, testInstallBase string) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), config, testInstallBase)
- } else {
- if ctx.Device() {
- autogenTemplate(ctx, autogenPath, "${RustDeviceTestConfigTemplate}", config, testInstallBase)
- } else {
- autogenTemplate(ctx, autogenPath, "${RustHostTestConfigTemplate}", config, testInstallBase)
- }
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenRustBenchmarkConfig(ctx android.ModuleContext, testConfigProp *string,
- testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), config, "")
- } else {
- if ctx.Device() {
- autogenTemplate(ctx, autogenPath, "${RustDeviceBenchmarkConfigTemplate}", config, "")
- } else {
- autogenTemplate(ctx, autogenPath, "${RustHostBenchmarkConfigTemplate}", config, "")
- }
- }
- return autogenPath
- }
- return path
-}
-
-func AutoGenRobolectricTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string,
- testSuites []string, autoGenConfig *bool) android.Path {
- path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
- if autogenPath != nil {
- templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
- if templatePath.Valid() {
- autogenTemplate(ctx, autogenPath, templatePath.String(), nil, "")
- } else {
- autogenTemplate(ctx, autogenPath, "${RobolectricTestConfigTemplate}", nil, "")
- }
- return autogenPath
+ if len(options.OptionsForAutogenerated) > 0 {
+ ctx.ModuleErrorf("Extra tradefed configurations were provided for an autogenerated xml file, but the autogenerated xml file was not used.")
}
return path
}
diff --git a/ui/build/config.go b/ui/build/config.go
index a6bba15..61f6b1c 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -63,6 +63,7 @@
environ *Environment
distDir string
buildDateTime string
+ logsPrefix string
// From the arguments
parallel int
@@ -84,6 +85,7 @@
skipSoongTests bool
searchApiDir bool // Scan the Android.bp files generated in out/api_surfaces
skipMetricsUpload bool
+ buildStartedTime int64 // For metrics-upload-only - manually specify a build-started time
// From the product config
katiArgs []string
@@ -255,6 +257,14 @@
return true
}
+func UploadOnlyConfig(ctx Context, _ ...string) Config {
+ ret := &configImpl{
+ environ: OsEnvironment(),
+ sandboxConfig: &SandboxConfig{},
+ }
+ return Config{ret}
+}
+
func NewConfig(ctx Context, args ...string) Config {
ret := &configImpl{
environ: OsEnvironment(),
@@ -266,9 +276,7 @@
ret.keepGoing = 1
ret.totalRAM = detectTotalRAM(ctx)
-
ret.parseArgs(ctx, args)
-
// Make sure OUT_DIR is set appropriately
if outDir, ok := ret.environ.Get("OUT_DIR"); ok {
ret.environ.Set("OUT_DIR", filepath.Clean(outDir))
@@ -756,6 +764,14 @@
ctx.Metrics.SetBuildCommand([]string{buildCmd})
} else if strings.HasPrefix(arg, "--bazel-force-enabled-modules=") {
c.bazelForceEnabledModules = strings.TrimPrefix(arg, "--bazel-force-enabled-modules=")
+ } else if strings.HasPrefix(arg, "--build-started-time-unix-millis=") {
+ buildTimeStr := strings.TrimPrefix(arg, "--build-started-time-unix-millis=")
+ val, err := strconv.ParseInt(buildTimeStr, 10, 64)
+ if err == nil {
+ c.buildStartedTime = val
+ } else {
+ ctx.Fatalf("Error parsing build-time-started-unix-millis", err)
+ }
} else if len(arg) > 0 && arg[0] == '-' {
parseArgNum := func(def int) int {
if len(arg) > 2 {
@@ -1092,6 +1108,14 @@
c.includeTags = i
}
+func (c *configImpl) GetLogsPrefix() string {
+ return c.logsPrefix
+}
+
+func (c *configImpl) SetLogsPrefix(prefix string) {
+ c.logsPrefix = prefix
+}
+
func (c *configImpl) HighmemParallel() int {
if i, ok := c.environ.GetInt("NINJA_HIGHMEM_NUM_JOBS"); ok {
return i
@@ -1519,6 +1543,15 @@
return c.skipMetricsUpload
}
+// Returns a Time object if one was passed via a command-line flag.
+// Otherwise returns the passed default.
+func (c *configImpl) BuildStartedTimeOrDefault(defaultTime time.Time) time.Time {
+ if c.buildStartedTime == 0 {
+ return defaultTime
+ }
+ return time.UnixMilli(c.buildStartedTime)
+}
+
func GetMetricsUploader(topDir string, env *Environment) string {
if p, ok := env.Get("METRICS_UPLOADER"); ok {
metricsUploader := filepath.Join(topDir, p)
diff --git a/ui/metrics/metrics.go b/ui/metrics/metrics.go
index ce2d946..717530c 100644
--- a/ui/metrics/metrics.go
+++ b/ui/metrics/metrics.go
@@ -32,13 +32,13 @@
// of what an event is and how the metrics system is a stack based system.
import (
+ "fmt"
"os"
"runtime"
"strings"
"time"
"android/soong/shared"
-
"google.golang.org/protobuf/proto"
soong_metrics_proto "android/soong/ui/metrics/metrics_proto"
@@ -223,6 +223,17 @@
m.metrics.BuildDateTimestamp = proto.Int64(buildTimestamp.UnixNano() / int64(time.Second))
}
+func (m *Metrics) UpdateTotalRealTime(data []byte) error {
+ if err := proto.Unmarshal(data, &m.metrics); err != nil {
+ return fmt.Errorf("Failed to unmarshal proto", err)
+ }
+ startTime := *m.metrics.Total.StartTime
+ endTime := uint64(time.Now().UnixNano())
+
+ *m.metrics.Total.RealTime = *proto.Uint64(endTime - startTime)
+ return nil
+}
+
// SetBuildCommand adds the build command specified by the user to the
// list of collected metrics.
func (m *Metrics) SetBuildCommand(cmd []string) {