diff options
| -rw-r--r-- | android/prebuilt.go | 2 | ||||
| -rw-r--r-- | android/prebuilt_test.go | 135 | ||||
| -rw-r--r-- | apex/androidmk.go | 1 | ||||
| -rw-r--r-- | apex/builder.go | 2 | ||||
| -rw-r--r-- | cc/llndk_library.go | 2 | ||||
| -rw-r--r-- | java/aar.go | 2 | ||||
| -rwxr-xr-x | java/app.go | 4 | ||||
| -rw-r--r-- | java/droiddoc.go | 71 | ||||
| -rw-r--r-- | java/hiddenapi.go | 2 | ||||
| -rw-r--r-- | java/java_test.go | 38 | ||||
| -rw-r--r-- | java/lint.go | 31 | ||||
| -rw-r--r-- | rust/binary.go | 3 | ||||
| -rw-r--r-- | rust/builder.go | 1 | ||||
| -rw-r--r-- | rust/compiler.go | 24 | ||||
| -rw-r--r-- | rust/compiler_test.go | 2 | ||||
| -rw-r--r-- | rust/library.go | 3 | ||||
| -rw-r--r-- | rust/prebuilt.go | 3 | ||||
| -rw-r--r-- | rust/proc_macro.go | 3 | ||||
| -rw-r--r-- | rust/rust.go | 4 | ||||
| -rw-r--r-- | rust/rust_test.go | 30 | ||||
| -rw-r--r-- | rust/testing.go | 2 | ||||
| -rw-r--r-- | sdk/update.go | 2 | ||||
| -rw-r--r-- | ui/metrics/Android.bp | 3 | ||||
| -rw-r--r-- | ui/metrics/time.go | 36 | ||||
| -rw-r--r-- | ui/metrics/time_test.go | 42 |
25 files changed, 353 insertions, 95 deletions
diff --git a/android/prebuilt.go b/android/prebuilt.go index 9f4df2831..269ad5d8a 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -225,7 +225,7 @@ func PrebuiltRenameMutator(ctx BottomUpMutatorContext) { // PrebuiltSourceDepsMutator adds dependencies to the prebuilt module from the // corresponding source module, if one exists for the same variant. func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) { - if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil { + if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Enabled() && m.Prebuilt() != nil { p := m.Prebuilt() if !p.properties.PrebuiltRenamedToSource { name := m.base().BaseModuleName() diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go index 8029b85bd..6c3cd9eef 100644 --- a/android/prebuilt_test.go +++ b/android/prebuilt_test.go @@ -22,9 +22,10 @@ import ( ) var prebuiltsTests = []struct { - name string - modules string - prebuilt []OsClass + name string + replaceBp bool // modules is added to default bp boilerplate if false. + modules string + prebuilt []OsType }{ { name: "no prebuilt", @@ -42,7 +43,7 @@ var prebuiltsTests = []struct { prefer: false, srcs: ["prebuilt_file"], }`, - prebuilt: []OsClass{Device, Host}, + prebuilt: []OsType{Android, BuildOs}, }, { name: "no source prebuilt preferred", @@ -52,7 +53,7 @@ var prebuiltsTests = []struct { prefer: true, srcs: ["prebuilt_file"], }`, - prebuilt: []OsClass{Device, Host}, + prebuilt: []OsType{Android, BuildOs}, }, { name: "prebuilt not preferred", @@ -80,7 +81,7 @@ var prebuiltsTests = []struct { prefer: true, srcs: ["prebuilt_file"], }`, - prebuilt: []OsClass{Device, Host}, + prebuilt: []OsType{Android, BuildOs}, }, { name: "prebuilt no file not preferred", @@ -120,7 +121,7 @@ var prebuiltsTests = []struct { prefer: true, srcs: [":fg"], }`, - prebuilt: []OsClass{Device, Host}, + prebuilt: []OsType{Android, BuildOs}, }, { name: "prebuilt module for device only", @@ -135,7 +136,7 @@ var prebuiltsTests = []struct { prefer: true, srcs: ["prebuilt_file"], }`, - prebuilt: []OsClass{Device}, + prebuilt: []OsType{Android}, }, { name: "prebuilt file for host only", @@ -153,7 +154,7 @@ var prebuiltsTests = []struct { }, }, }`, - prebuilt: []OsClass{Host}, + prebuilt: []OsType{BuildOs}, }, { name: "prebuilt override not preferred", @@ -191,7 +192,72 @@ var prebuiltsTests = []struct { prefer: true, srcs: ["prebuilt_file"], }`, - prebuilt: []OsClass{Device, Host}, + prebuilt: []OsType{Android, BuildOs}, + }, + { + name: "prebuilt including default-disabled OS", + replaceBp: true, + modules: ` + source { + name: "foo", + deps: [":bar"], + target: { + windows: { + enabled: true, + }, + }, + } + + source { + name: "bar", + target: { + windows: { + enabled: true, + }, + }, + } + + prebuilt { + name: "bar", + prefer: true, + srcs: ["prebuilt_file"], + target: { + windows: { + enabled: true, + }, + }, + }`, + prebuilt: []OsType{Android, BuildOs, Windows}, + }, + { + name: "fall back to source for default-disabled OS", + replaceBp: true, + modules: ` + source { + name: "foo", + deps: [":bar"], + target: { + windows: { + enabled: true, + }, + }, + } + + source { + name: "bar", + target: { + windows: { + enabled: true, + }, + }, + } + + prebuilt { + name: "bar", + prefer: true, + srcs: ["prebuilt_file"], + }`, + prebuilt: []OsType{Android, BuildOs}, }, } @@ -203,14 +269,25 @@ func TestPrebuilts(t *testing.T) { for _, test := range prebuiltsTests { t.Run(test.name, func(t *testing.T) { - bp := ` - source { - name: "foo", - deps: [":bar"], - } - ` + test.modules + bp := test.modules + if !test.replaceBp { + bp = bp + ` + source { + name: "foo", + deps: [":bar"], + }` + } config := TestArchConfig(buildDir, nil, bp, fs) + // Add windows to the target list to test the logic when a variant is + // disabled by default. + if !Windows.DefaultDisabled { + t.Errorf("windows is assumed to be disabled by default") + } + config.config.Targets[Windows] = []Target{ + {Windows, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", ""}, + } + ctx := NewTestArchContext() registerTestPrebuiltBuildComponents(ctx) ctx.RegisterModuleType("filegroup", FileGroupFactory) @@ -223,7 +300,7 @@ func TestPrebuilts(t *testing.T) { for _, variant := range ctx.ModuleVariantsForTests("foo") { foo := ctx.ModuleForTests("foo", variant) - t.Run(foo.Module().Target().Os.Class.String(), func(t *testing.T) { + t.Run(foo.Module().Target().Os.String(), func(t *testing.T) { var dependsOnSourceModule, dependsOnPrebuiltModule bool ctx.VisitDirectDeps(foo.Module(), func(m blueprint.Module) { if _, ok := m.(*sourceModule); ok { @@ -237,26 +314,38 @@ func TestPrebuilts(t *testing.T) { } }) + moduleIsDisabled := !foo.Module().Enabled() deps := foo.Module().(*sourceModule).deps - if deps == nil || len(deps) != 1 { - t.Errorf("deps does not have single path, but is %v", deps) + if moduleIsDisabled { + if len(deps) > 0 { + t.Errorf("disabled module got deps: %v", deps) + } + } else { + if len(deps) != 1 { + t.Errorf("deps does not have single path, but is %v", deps) + } } + var usingSourceFile, usingPrebuiltFile bool - if deps[0].String() == "source_file" { + if len(deps) > 0 && deps[0].String() == "source_file" { usingSourceFile = true } - if deps[0].String() == "prebuilt_file" { + if len(deps) > 0 && deps[0].String() == "prebuilt_file" { usingPrebuiltFile = true } prebuilt := false for _, os := range test.prebuilt { - if os == foo.Module().Target().Os.Class { + if os == foo.Module().Target().Os { prebuilt = true } } if prebuilt { + if moduleIsDisabled { + t.Errorf("dependent module for prebuilt is disabled") + } + if !dependsOnPrebuiltModule { t.Errorf("doesn't depend on prebuilt module") } @@ -270,7 +359,7 @@ func TestPrebuilts(t *testing.T) { if usingSourceFile { t.Errorf("using source_file") } - } else { + } else if !moduleIsDisabled { if dependsOnPrebuiltModule { t.Errorf("depends on prebuilt module") } diff --git a/apex/androidmk.go b/apex/androidmk.go index 759523896..156906dba 100644 --- a/apex/androidmk.go +++ b/apex/androidmk.go @@ -203,6 +203,7 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, mo panic(fmt.Sprintf("Expected %s to be AndroidAppSet", fi.module)) } fmt.Fprintln(w, "LOCAL_APK_SET_MASTER_FILE :=", as.MasterFile()) + fmt.Fprintln(w, "LOCAL_APKCERTS_FILE :=", as.APKCertsFile().String()) fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_android_app_set.mk") case nativeSharedLib, nativeExecutable, nativeTest: fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.Stem()) diff --git a/apex/builder.go b/apex/builder.go index 5fb9a5fd4..49e4642bf 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -390,7 +390,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { } else { if fi.class == appSet { copyCommands = append(copyCommands, - fmt.Sprintf("unzip -q -d %s %s", destPathDir, fi.builtFile.String())) + fmt.Sprintf("unzip -qDD -d %s %s", destPathDir, fi.builtFile.String())) } else { copyCommands = append(copyCommands, "cp -f "+fi.builtFile.String()+" "+destPath) } diff --git a/cc/llndk_library.go b/cc/llndk_library.go index 7ff20f472..71c92042a 100644 --- a/cc/llndk_library.go +++ b/cc/llndk_library.go @@ -225,6 +225,8 @@ func (headers *llndkHeadersDecorator) Name(name string) string { func llndkHeadersFactory() android.Module { module, library := NewLibrary(android.DeviceSupported) library.HeaderOnly() + module.stl = nil + module.sanitize = nil decorator := &llndkHeadersDecorator{ libraryDecorator: library, diff --git a/java/aar.go b/java/aar.go index 500788f48..ad9b5e7d2 100644 --- a/java/aar.go +++ b/java/aar.go @@ -641,7 +641,7 @@ func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) { var unzipAAR = pctx.AndroidStaticRule("unzipAAR", blueprint.RuleParams{ Command: `rm -rf $outDir && mkdir -p $outDir && ` + - `unzip -qo -d $outDir $in && rm -rf $outDir/res && touch $out`, + `unzip -qoDD -d $outDir $in && rm -rf $outDir/res && touch $out`, }, "outDir") diff --git a/java/app.go b/java/app.go index 98bce9471..4071c0a7f 100755 --- a/java/app.go +++ b/java/app.go @@ -106,6 +106,10 @@ func (as *AndroidAppSet) MasterFile() string { return as.masterFile } +func (as *AndroidAppSet) APKCertsFile() android.Path { + return as.apkcertsFile +} + var TargetCpuAbi = map[string]string{ "arm": "ARMEABI_V7A", "arm64": "ARM64_V8A", diff --git a/java/droiddoc.go b/java/droiddoc.go index 99bfb6dc3..08865b666 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -112,13 +112,20 @@ type JavadocProperties struct { // local files that are used within user customized droiddoc options. Arg_files []string `android:"path"` - // user customized droiddoc args. + // user customized droiddoc args. Deprecated, use flags instead. // Available variables for substitution: // // $(location <label>): the path to the arg_files with name <label> // $$: a literal $ Args *string + // user customized droiddoc args. Not compatible with property args. + // Available variables for substitution: + // + // $(location <label>): the path to the arg_files with name <label> + // $$: a literal $ + Flags []string + // names of the output files used in args that will be generated Out []string @@ -382,7 +389,7 @@ type Javadoc struct { argFiles android.Paths implicits android.Paths - args string + args []string docZip android.WritablePath stubsSrcJar android.WritablePath @@ -619,8 +626,8 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { } srcFiles = filterHtml(srcFiles) - flags := j.collectAidlFlags(ctx, deps) - srcFiles = j.genSources(ctx, srcFiles, flags) + aidlFlags := j.collectAidlFlags(ctx, deps) + srcFiles = j.genSources(ctx, srcFiles, aidlFlags) // srcs may depend on some genrule output. j.srcJars = srcFiles.FilterByExt(".srcjar") @@ -649,24 +656,38 @@ func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps { } } - var err error - j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) { - if strings.HasPrefix(name, "location ") { - label := strings.TrimSpace(strings.TrimPrefix(name, "location ")) - if paths, ok := argFilesMap[label]; ok { - return paths, nil - } else { - return "", fmt.Errorf("unknown location label %q, expecting one of %q", - label, strings.Join(argFileLabels, ", ")) + var argsPropertyName string + flags := make([]string, 0) + if j.properties.Args != nil && j.properties.Flags != nil { + ctx.PropertyErrorf("args", "flags is set. Cannot set args") + } else if args := proptools.String(j.properties.Args); args != "" { + flags = append(flags, args) + argsPropertyName = "args" + } else { + flags = append(flags, j.properties.Flags...) + argsPropertyName = "flags" + } + + for _, flag := range flags { + args, err := android.Expand(flag, func(name string) (string, error) { + if strings.HasPrefix(name, "location ") { + label := strings.TrimSpace(strings.TrimPrefix(name, "location ")) + if paths, ok := argFilesMap[label]; ok { + return paths, nil + } else { + return "", fmt.Errorf("unknown location label %q, expecting one of %q", + label, strings.Join(argFileLabels, ", ")) + } + } else if name == "genDir" { + return android.PathForModuleGen(ctx).String(), nil } - } else if name == "genDir" { - return android.PathForModuleGen(ctx).String(), nil - } - return "", fmt.Errorf("unknown variable '$(%s)'", name) - }) + return "", fmt.Errorf("unknown variable '$(%s)'", name) + }) - if err != nil { - ctx.PropertyErrorf("args", "%s", err.Error()) + if err != nil { + ctx.PropertyErrorf(argsPropertyName, "%s", err.Error()) + } + j.args = append(j.args, args) } return deps @@ -1010,7 +1031,7 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) { d.stubsFlags(ctx, cmd, stubsDir) - cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles) + cmd.Flag(strings.Join(d.Javadoc.args, " ")).Implicits(d.Javadoc.argFiles) if d.properties.Compat_config != nil { compatConfig := android.PathForModuleSrc(ctx, String(d.properties.Compat_config)) @@ -1327,7 +1348,7 @@ func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.Ru cmd.Flag("--include-annotations") validatingNullability := - strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") || + android.InList("--validate-nullability-from-merged-stubs", d.Javadoc.args) || String(d.properties.Validate_nullability_from_list) != "" migratingNullability := String(d.properties.Previous_api) != "" @@ -1539,14 +1560,14 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { d.apiLevelsAnnotationsFlags(ctx, cmd) d.apiToXmlFlags(ctx, cmd) - if strings.Contains(d.Javadoc.args, "--generate-documentation") { + if android.InList("--generate-documentation", d.Javadoc.args) { // Currently Metalava have the ability to invoke Javadoc in a seperate process. // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives // "--generate-documentation" arg. This is not needed when Metalava removes this feature. - d.Javadoc.args = d.Javadoc.args + " -nodocs " + d.Javadoc.args = append(d.Javadoc.args, "-nodocs") } - cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles) + cmd.Flag(strings.Join(d.Javadoc.args, " ")).Implicits(d.Javadoc.argFiles) for _, o := range d.Javadoc.properties.Out { cmd.ImplicitOutput(android.PathForModuleGen(ctx, o)) } diff --git a/java/hiddenapi.go b/java/hiddenapi.go index 130b63496..b5a021785 100644 --- a/java/hiddenapi.go +++ b/java/hiddenapi.go @@ -146,7 +146,7 @@ func (h *hiddenAPI) hiddenAPIGenerateCSV(ctx android.ModuleContext, flagsCSV, me var hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", blueprint.RuleParams{ Command: `rm -rf $tmpDir && mkdir -p $tmpDir && mkdir $tmpDir/dex-input && mkdir $tmpDir/dex-output && - unzip -o -q $in 'classes*.dex' -d $tmpDir/dex-input && + unzip -qoDD $in 'classes*.dex' -d $tmpDir/dex-input && for INPUT_DEX in $$(find $tmpDir/dex-input -maxdepth 1 -name 'classes*.dex' | sort); do echo "--input-dex=$${INPUT_DEX}"; echo "--output-dex=$tmpDir/dex-output/$$(basename $${INPUT_DEX})"; diff --git a/java/java_test.go b/java/java_test.go index fb003619f..db3f18740 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1097,7 +1097,7 @@ func TestDroiddoc(t *testing.T) { ], proofread_file: "libcore-proofread.txt", todo_file: "libcore-docs-todo.html", - args: "-offlinemode -title \"libcore\"", + flags: ["-offlinemode -title \"libcore\""], } `, map[string][]byte{ @@ -1124,6 +1124,42 @@ func TestDroiddoc(t *testing.T) { } } +func TestDroiddocArgsAndFlagsCausesError(t *testing.T) { + testJavaError(t, "flags is set. Cannot set args", ` + droiddoc_exported_dir { + name: "droiddoc-templates-sdk", + path: ".", + } + filegroup { + name: "bar-doc-aidl-srcs", + srcs: ["bar-doc/IBar.aidl"], + path: "bar-doc", + } + droiddoc { + name: "bar-doc", + srcs: [ + "bar-doc/a.java", + "bar-doc/IFoo.aidl", + ":bar-doc-aidl-srcs", + ], + exclude_srcs: [ + "bar-doc/b.java" + ], + custom_template: "droiddoc-templates-sdk", + hdf: [ + "android.whichdoc offline", + ], + knowntags: [ + "bar-doc/known_oj_tags.txt", + ], + proofread_file: "libcore-proofread.txt", + todo_file: "libcore-docs-todo.html", + flags: ["-offlinemode -title \"libcore\""], + args: "-offlinemode -title \"libcore\"", + } + `) +} + func TestDroidstubsWithSystemModules(t *testing.T) { ctx, _ := testJava(t, ` droidstubs { diff --git a/java/lint.go b/java/lint.go index b73d6a51a..6fbef18c7 100644 --- a/java/lint.go +++ b/java/lint.go @@ -220,12 +220,21 @@ func (l *linter) lint(ctx android.ModuleContext) { rule.Command().Text("rm -rf").Flag(cacheDir.String()).Flag(homeDir.String()) rule.Command().Text("mkdir -p").Flag(cacheDir.String()).Flag(homeDir.String()) + var annotationsZipPath, apiVersionsXMLPath android.Path + if ctx.Config().UnbundledBuildUsePrebuiltSdks() { + annotationsZipPath = android.PathForSource(ctx, "prebuilts/sdk/current/public/data/annotations.zip") + apiVersionsXMLPath = android.PathForSource(ctx, "prebuilts/sdk/current/public/data/api-versions.xml") + } else { + annotationsZipPath = copiedAnnotationsZipPath(ctx) + apiVersionsXMLPath = copiedAPIVersionsXmlPath(ctx) + } + rule.Command(). Text("("). Flag("JAVA_OPTS=-Xmx2048m"). FlagWithArg("ANDROID_SDK_HOME=", homeDir.String()). - FlagWithInput("SDK_ANNOTATIONS=", annotationsZipPath(ctx)). - FlagWithInput("LINT_OPTS=-DLINT_API_DATABASE=", apiVersionsXmlPath(ctx)). + FlagWithInput("SDK_ANNOTATIONS=", annotationsZipPath). + FlagWithInput("LINT_OPTS=-DLINT_API_DATABASE=", apiVersionsXMLPath). Tool(android.PathForSource(ctx, "prebuilts/cmdline-tools/tools/bin/lint")). Implicit(android.PathForSource(ctx, "prebuilts/cmdline-tools/tools/lib/lint-classpath.jar")). Flag("--quiet"). @@ -271,7 +280,7 @@ func (l *lintSingleton) GenerateBuildActions(ctx android.SingletonContext) { } func (l *lintSingleton) copyLintDependencies(ctx android.SingletonContext) { - if ctx.Config().UnbundledBuild() { + if ctx.Config().UnbundledBuildUsePrebuiltSdks() { return } @@ -297,25 +306,29 @@ func (l *lintSingleton) copyLintDependencies(ctx android.SingletonContext) { ctx.Build(pctx, android.BuildParams{ Rule: android.Cp, Input: android.OutputFileForModule(ctx, frameworkDocStubs, ".annotations.zip"), - Output: annotationsZipPath(ctx), + Output: copiedAnnotationsZipPath(ctx), }) ctx.Build(pctx, android.BuildParams{ Rule: android.Cp, Input: android.OutputFileForModule(ctx, frameworkDocStubs, ".api_versions.xml"), - Output: apiVersionsXmlPath(ctx), + Output: copiedAPIVersionsXmlPath(ctx), }) } -func annotationsZipPath(ctx android.PathContext) android.WritablePath { +func copiedAnnotationsZipPath(ctx android.PathContext) android.WritablePath { return android.PathForOutput(ctx, "lint", "annotations.zip") } -func apiVersionsXmlPath(ctx android.PathContext) android.WritablePath { +func copiedAPIVersionsXmlPath(ctx android.PathContext) android.WritablePath { return android.PathForOutput(ctx, "lint", "api_versions.xml") } func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) { + if ctx.Config().UnbundledBuild() { + return + } + var outputs []*lintOutputs var dirs []string ctx.VisitAllModules(func(m android.Module) { @@ -370,7 +383,9 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) { } func (l *lintSingleton) MakeVars(ctx android.MakeVarsContext) { - ctx.DistForGoal("lint-check", l.htmlZip, l.textZip, l.xmlZip) + if !ctx.Config().UnbundledBuild() { + ctx.DistForGoal("lint-check", l.htmlZip, l.textZip, l.xmlZip) + } } var _ android.SingletonMakeVarsProvider = (*lintSingleton)(nil) diff --git a/rust/binary.go b/rust/binary.go index a1cd410c2..9fc52cdb8 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -106,7 +106,8 @@ func (binary *binaryDecorator) nativeCoverage() bool { func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path { fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix() - srcPath := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs) + srcPath, paths := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs) + deps.SrcDeps = paths outputFile := android.PathForModuleOut(ctx, fileName) binary.unstrippedOutputFile = outputFile diff --git a/rust/builder.go b/rust/builder.go index 16d730603..7f94bb514 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -166,6 +166,7 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...) implicits = append(implicits, deps.StaticLibs...) implicits = append(implicits, deps.SharedLibs...) + implicits = append(implicits, deps.SrcDeps...) if deps.CrtBegin.Valid() { implicits = append(implicits, deps.CrtBegin.Path(), deps.CrtEnd.Path()) } diff --git a/rust/compiler.go b/rust/compiler.go index 92a3b07f2..c20179bd0 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -253,10 +253,24 @@ func (compiler *baseCompiler) relativeInstallPath() string { return String(compiler.Properties.Relative_install_path) } -func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) android.Path { - srcPaths := android.PathsForModuleSrc(ctx, srcs) - if len(srcPaths) != 1 { - ctx.PropertyErrorf("srcs", "srcs can only contain one path for rust modules") +func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) { + // The srcs can contain strings with prefix ":". + // They are dependent modules of this module, with android.SourceDepTag. + // They are not the main source file compiled by rustc. + numSrcs := 0 + srcIndex := 0 + for i, s := range srcs { + if android.SrcIsModule(s) == "" { + numSrcs++ + srcIndex = i + } + } + if numSrcs != 1 { + ctx.PropertyErrorf("srcs", "srcs can only contain one path for a rust file") + } + if srcIndex != 0 { + ctx.PropertyErrorf("srcs", "main source file must be the first in srcs") } - return srcPaths[0] + paths := android.PathsForModuleSrc(ctx, srcs) + return paths[srcIndex], paths } diff --git a/rust/compiler_test.go b/rust/compiler_test.go index bcde75795..58ca52a0c 100644 --- a/rust/compiler_test.go +++ b/rust/compiler_test.go @@ -43,7 +43,7 @@ func TestFeaturesToFlags(t *testing.T) { // Test that we reject multiple source files. func TestEnforceSingleSourceFile(t *testing.T) { - singleSrcError := "srcs can only contain one path for rust modules" + singleSrcError := "srcs can only contain one path for a rust file" // Test libraries testRustError(t, singleSrcError, ` diff --git a/rust/library.go b/rust/library.go index 8b8e797a2..d718eb897 100644 --- a/rust/library.go +++ b/rust/library.go @@ -368,7 +368,8 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) F func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path { var outputFile android.WritablePath - srcPath := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs) + srcPath, paths := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs) + deps.SrcDeps = paths flags.RustFlags = append(flags.RustFlags, deps.depFlags...) diff --git a/rust/prebuilt.go b/rust/prebuilt.go index 67d649d35..3b4f40a55 100644 --- a/rust/prebuilt.go +++ b/rust/prebuilt.go @@ -95,7 +95,8 @@ func (prebuilt *prebuiltLibraryDecorator) compilerProps() []interface{} { func (prebuilt *prebuiltLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path { prebuilt.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...) - srcPath := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs()) + srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs()) + deps.SrcDeps = paths prebuilt.unstrippedOutputFile = srcPath diff --git a/rust/proc_macro.go b/rust/proc_macro.go index 2719161e5..49dbd8dc2 100644 --- a/rust/proc_macro.go +++ b/rust/proc_macro.go @@ -65,7 +65,8 @@ func (procMacro *procMacroDecorator) compile(ctx ModuleContext, flags Flags, dep fileName := procMacro.getStem(ctx) + ctx.toolchain().ProcMacroSuffix() outputFile := android.PathForModuleOut(ctx, fileName) - srcPath := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs) + srcPath, paths := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs) + deps.SrcDeps = paths procMacro.unstrippedOutputFile = outputFile diff --git a/rust/rust.go b/rust/rust.go index 72301a718..7a98c6468 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -239,6 +239,9 @@ type PathDeps struct { CrtBegin android.OptionalPath CrtEnd android.OptionalPath + + // Paths to generated source files + SrcDeps android.Paths } type RustLibraries []RustLibrary @@ -843,6 +846,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // Dedup exported flags from dependencies depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs) depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags) + depPaths.SrcDeps = android.FirstUniquePaths(depPaths.SrcDeps) return depPaths } diff --git a/rust/rust_test.go b/rust/rust_test.go index 08bc8ca48..e80392589 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -61,6 +61,7 @@ func testConfig(bp string) android.Config { "foo.rs": nil, "foo.c": nil, "src/bar.rs": nil, + "src/any.h": nil, "liby.so": nil, "libz.so": nil, } @@ -181,7 +182,7 @@ func TestDepsTracking(t *testing.T) { } rust_library_host_rlib { name: "librlib", - srcs: ["foo.rs"], + srcs: ["foo.rs", ":my_generator"], crate_name: "rlib", } rust_proc_macro { @@ -189,17 +190,38 @@ func TestDepsTracking(t *testing.T) { srcs: ["foo.rs"], crate_name: "pm", } + genrule { + name: "my_generator", + tools: ["any_rust_binary"], + cmd: "$(location) -o $(out) $(in)", + srcs: ["src/any.h"], + out: ["src/any.rs"], + } rust_binary_host { - name: "fizz-buzz", + name: "fizz-buzz-dep", dylibs: ["libdylib"], rlibs: ["librlib"], proc_macros: ["libpm"], static_libs: ["libstatic"], shared_libs: ["libshared"], - srcs: ["foo.rs"], + srcs: [ + "foo.rs", + ":my_generator", + ], } `) - module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module) + module := ctx.ModuleForTests("fizz-buzz-dep", "linux_glibc_x86_64").Module().(*Module) + rlibmodule := ctx.ModuleForTests("librlib", "linux_glibc_x86_64_rlib").Module().(*Module) + + srcs := module.compiler.(*binaryDecorator).baseCompiler.Properties.Srcs + if len(srcs) != 2 || !android.InList(":my_generator", srcs) { + t.Errorf("missing module dependency in fizz-buzz)") + } + + srcs = rlibmodule.compiler.(*libraryDecorator).baseCompiler.Properties.Srcs + if len(srcs) != 2 || !android.InList(":my_generator", srcs) { + t.Errorf("missing module dependency in rlib") + } // Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up. if !android.InList("libdylib", module.Properties.AndroidMkDylibs) { diff --git a/rust/testing.go b/rust/testing.go index 3d583e197..430b40bfd 100644 --- a/rust/testing.go +++ b/rust/testing.go @@ -17,6 +17,7 @@ package rust import ( "android/soong/android" "android/soong/cc" + "android/soong/genrule" ) func GatherRequiredDepsForTest() string { @@ -77,6 +78,7 @@ func GatherRequiredDepsForTest() string { func CreateTestContext() *android.TestContext { ctx := android.NewTestArchContext() cc.RegisterRequiredBuildComponentsForTest(ctx) + ctx.RegisterModuleType("genrule", genrule.GenRuleFactory) ctx.RegisterModuleType("rust_binary", RustBinaryFactory) ctx.RegisterModuleType("rust_binary_host", RustBinaryHostFactory) ctx.RegisterModuleType("rust_test", RustTestFactory) diff --git a/sdk/update.go b/sdk/update.go index 824115138..cf2500826 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -911,7 +911,7 @@ func newOsTypeSpecificInfo(ctx android.SdkMemberContext, osType android.OsType, if commonVariants, ok := variantsByArchName["common"]; ok { if len(osTypeVariants) != 1 { - panic("Expected to only have 1 variant when arch type is common but found " + string(len(osTypeVariants))) + panic(fmt.Errorf("Expected to only have 1 variant when arch type is common but found %d", len(osTypeVariants))) } // A common arch type only has one variant and its properties should be treated diff --git a/ui/metrics/Android.bp b/ui/metrics/Android.bp index 3596e1019..8188a69e9 100644 --- a/ui/metrics/Android.bp +++ b/ui/metrics/Android.bp @@ -25,6 +25,9 @@ bootstrap_go_package { "metrics.go", "time.go", ], + testSrcs: [ + "time_test.go", + ], } bootstrap_go_package { diff --git a/ui/metrics/time.go b/ui/metrics/time.go index b8baf16fd..401656337 100644 --- a/ui/metrics/time.go +++ b/ui/metrics/time.go @@ -19,13 +19,18 @@ import ( "android/soong/ui/metrics/metrics_proto" "android/soong/ui/tracer" + "github.com/golang/protobuf/proto" ) +// for testing purpose only +var _now = now + type timeEvent struct { desc string name string - atNanos uint64 // timestamp measured in nanoseconds since the reference date + // the time that the event started to occur. + start time.Time } type TimeTracer interface { @@ -39,33 +44,26 @@ type timeTracerImpl struct { var _ TimeTracer = &timeTracerImpl{} -func (t *timeTracerImpl) now() uint64 { - return uint64(time.Now().UnixNano()) -} - -func (t *timeTracerImpl) Begin(name, desc string, thread tracer.Thread) { - t.beginAt(name, desc, t.now()) +func now() time.Time { + return time.Now() } -func (t *timeTracerImpl) beginAt(name, desc string, atNanos uint64) { - t.activeEvents = append(t.activeEvents, timeEvent{name: name, desc: desc, atNanos: atNanos}) +func (t *timeTracerImpl) Begin(name, desc string, _ tracer.Thread) { + t.activeEvents = append(t.activeEvents, timeEvent{name: name, desc: desc, start: _now()}) } -func (t *timeTracerImpl) End(thread tracer.Thread) soong_metrics_proto.PerfInfo { - return t.endAt(t.now()) -} - -func (t *timeTracerImpl) endAt(atNanos uint64) soong_metrics_proto.PerfInfo { +func (t *timeTracerImpl) End(tracer.Thread) soong_metrics_proto.PerfInfo { if len(t.activeEvents) < 1 { panic("Internal error: No pending events for endAt to end!") } lastEvent := t.activeEvents[len(t.activeEvents)-1] t.activeEvents = t.activeEvents[:len(t.activeEvents)-1] - realTime := atNanos - lastEvent.atNanos + realTime := uint64(_now().Sub(lastEvent.start).Nanoseconds()) return soong_metrics_proto.PerfInfo{ - Desc: &lastEvent.desc, - Name: &lastEvent.name, - StartTime: &lastEvent.atNanos, - RealTime: &realTime} + Desc: proto.String(lastEvent.desc), + Name: proto.String(lastEvent.name), + StartTime: proto.Uint64(uint64(lastEvent.start.UnixNano())), + RealTime: proto.Uint64(realTime), + } } diff --git a/ui/metrics/time_test.go b/ui/metrics/time_test.go new file mode 100644 index 000000000..d73080ab2 --- /dev/null +++ b/ui/metrics/time_test.go @@ -0,0 +1,42 @@ +// Copyright 2020 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package metrics + +import ( + "testing" + "time" + + "android/soong/ui/tracer" +) + +func TestEnd(t *testing.T) { + startTime := time.Date(2020, time.July, 13, 13, 0, 0, 0, time.UTC) + dur := time.Nanosecond * 10 + initialNow := _now + _now = func() time.Time { return startTime.Add(dur) } + defer func() { _now = initialNow }() + + timeTracer := &timeTracerImpl{} + timeTracer.activeEvents = append(timeTracer.activeEvents, timeEvent{ + desc: "test", + name: "test", + start: startTime, + }) + + perf := timeTracer.End(tracer.Thread(0)) + if perf.GetRealTime() != uint64(dur.Nanoseconds()) { + t.Errorf("got %d, want %d nanoseconds for event duration", perf.GetRealTime(), dur.Nanoseconds()) + } +} |