Merge "Support extract_apk in soong" into main
diff --git a/Android.bp b/Android.bp
index 47a195c..98552a7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -256,5 +256,8 @@
all_apex_certs {
name: "all_apex_certs",
- visibility: ["//cts/tests/tests/security"],
+ visibility: [
+ "//cts/tests/tests/security",
+ "//cts/hostsidetests/appsecurity",
+ ],
}
diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go
index 6ad54da..3262493 100644
--- a/aconfig/all_aconfig_declarations.go
+++ b/aconfig/all_aconfig_declarations.go
@@ -65,15 +65,16 @@
})
var numOffendingPkg = 0
+ offendingPkgsMessage := ""
for pkg, cnt := range packages {
if cnt > 1 {
- fmt.Printf("%d aconfig_declarations found for package %s\n", cnt, pkg)
+ offendingPkgsMessage += fmt.Sprintf("%d aconfig_declarations found for package %s\n", cnt, pkg)
numOffendingPkg++
}
}
if numOffendingPkg > 0 {
- panic(fmt.Errorf("Only one aconfig_declarations allowed for each package."))
+ panic("Only one aconfig_declarations allowed for each package.\n" + offendingPkgsMessage)
}
// Generate build action for aconfig (binary proto output)
diff --git a/android/Android.bp b/android/Android.bp
index bb16856..d27a8fa 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -79,6 +79,7 @@
"namespace.go",
"neverallow.go",
"ninja_deps.go",
+ "nothing.go",
"notices.go",
"onceper.go",
"override_module.go",
diff --git a/android/android_info.go b/android/android_info.go
index a8d3d4e..225c8f0 100644
--- a/android/android_info.go
+++ b/android/android_info.go
@@ -58,17 +58,19 @@
androidInfoTxtName := proptools.StringDefault(p.properties.Stem, ctx.ModuleName()+".txt")
androidInfoTxt := PathForModuleOut(ctx, androidInfoTxtName)
androidInfoProp := androidInfoTxt.ReplaceExtension(ctx, "prop")
+ timestamp := PathForModuleOut(ctx, "timestamp")
if boardInfoFiles := PathsForModuleSrc(ctx, p.properties.Board_info_files); len(boardInfoFiles) > 0 {
ctx.Build(pctx, BuildParams{
- Rule: mergeAndRemoveComments,
- Inputs: boardInfoFiles,
- Output: androidInfoTxt,
+ Rule: mergeAndRemoveComments,
+ Inputs: boardInfoFiles,
+ Output: androidInfoTxt,
+ Validation: timestamp,
})
} else if bootloaderBoardName := proptools.String(p.properties.Bootloader_board_name); bootloaderBoardName != "" {
- WriteFileRule(ctx, androidInfoTxt, "board="+bootloaderBoardName)
+ WriteFileRule(ctx, androidInfoTxt, "board="+bootloaderBoardName, timestamp)
} else {
- WriteFileRule(ctx, androidInfoTxt, "")
+ WriteFileRule(ctx, androidInfoTxt, "", timestamp)
}
// Create android_info.prop
@@ -79,6 +81,19 @@
})
ctx.SetOutputFiles(Paths{androidInfoProp}, "")
+ ctx.SetOutputFiles(Paths{androidInfoTxt}, ".txt")
+
+ builder := NewRuleBuilder(pctx, ctx)
+ builder.Command().Text("touch").Output(timestamp)
+ if !ctx.Config().KatiEnabled() {
+ cpPath := PathForModuleInPartitionInstall(ctx, "").Join(ctx, androidInfoTxtName)
+ builder.Command().
+ Text("rsync").
+ Flag("-a").
+ Input(androidInfoTxt).
+ Text(cpPath.String())
+ }
+ builder.Build("copy_android_info", "Copy android-info.txt")
}
// android_info module generate a file named android-info.txt that contains various information
@@ -86,6 +101,6 @@
func AndroidInfoFactory() Module {
module := &androidInfoModule{}
module.AddProperties(&module.properties)
- InitAndroidModule(module)
+ InitAndroidArchModule(module, DeviceSupported, MultilibCommon)
return module
}
diff --git a/android/androidmk.go b/android/androidmk.go
index 590cce3..87a93e3 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -701,11 +701,6 @@
type androidMkSingleton struct{}
func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) {
- // Skip if Soong wasn't invoked from Make.
- if !ctx.Config().KatiEnabled() {
- return
- }
-
var androidMkModulesList []blueprint.Module
ctx.VisitAllModulesBlueprint(func(module blueprint.Module) {
@@ -718,6 +713,12 @@
return ctx.ModuleName(androidMkModulesList[i]) < ctx.ModuleName(androidMkModulesList[j])
})
+ // If running in soong-only mode, do a different, more limited version of this singleton
+ if !ctx.Config().KatiEnabled() {
+ c.soongOnlyBuildActions(ctx, androidMkModulesList)
+ return
+ }
+
transMk := PathForOutput(ctx, "Android"+String(ctx.Config().productVariables.Make_suffix)+".mk")
if ctx.Failed() {
return
@@ -736,6 +737,122 @@
})
}
+// In soong-only mode, we don't do most of the androidmk stuff. But disted files are still largely
+// defined through the androidmk mechanisms, so this function is an alternate implementation of
+// the androidmk singleton that just focuses on getting the dist contributions
+func (c *androidMkSingleton) soongOnlyBuildActions(ctx SingletonContext, mods []blueprint.Module) {
+ allDistContributions := getDistContributionsFromMods(ctx, mods)
+
+ distMkFile := absolutePath(filepath.Join(ctx.Config().katiPackageMkDir(), "dist.mk"))
+
+ var goalOutputPairs []string
+ var srcDstPairs []string
+ for _, contributions := range allDistContributions {
+ for _, copiesForGoal := range contributions.copiesForGoals {
+ goals := strings.Fields(copiesForGoal.goals)
+ for _, copy := range copiesForGoal.copies {
+ for _, goal := range goals {
+ goalOutputPairs = append(goalOutputPairs, fmt.Sprintf(" %s:%s", goal, copy.dest))
+ }
+ srcDstPairs = append(srcDstPairs, fmt.Sprintf(" %s:%s", copy.from.String(), copy.dest))
+ }
+ }
+ }
+ // There are duplicates in the lists that we need to remove
+ goalOutputPairs = SortedUniqueStrings(goalOutputPairs)
+ srcDstPairs = SortedUniqueStrings(srcDstPairs)
+ var buf strings.Builder
+ buf.WriteString("DIST_SRC_DST_PAIRS :=")
+ for _, srcDstPair := range srcDstPairs {
+ buf.WriteString(srcDstPair)
+ }
+ buf.WriteString("\nDIST_GOAL_OUTPUT_PAIRS :=")
+ for _, goalOutputPair := range goalOutputPairs {
+ buf.WriteString(goalOutputPair)
+ }
+ buf.WriteString("\n")
+
+ writeValueIfChanged(ctx, distMkFile, buf.String())
+}
+
+func writeValueIfChanged(ctx SingletonContext, path string, value string) {
+ if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil {
+ ctx.Errorf("%s\n", err)
+ return
+ }
+ previousValue := ""
+ rawPreviousValue, err := os.ReadFile(path)
+ if err == nil {
+ previousValue = string(rawPreviousValue)
+ }
+
+ if previousValue != value {
+ if err = os.WriteFile(path, []byte(value), 0666); err != nil {
+ ctx.Errorf("Failed to write: %v", err)
+ }
+ }
+}
+
+func getDistContributionsFromMods(ctx fillInEntriesContext, mods []blueprint.Module) []distContributions {
+ var allDistContributions []distContributions
+ for _, mod := range mods {
+ if amod, ok := mod.(Module); ok && shouldSkipAndroidMkProcessing(ctx, amod.base()) {
+ continue
+ }
+ if info, ok := OtherModuleProvider(ctx, mod, AndroidMkInfoProvider); ok {
+ // Deep copy the provider info since we need to modify the info later
+ info := deepCopyAndroidMkProviderInfo(info)
+ info.PrimaryInfo.fillInEntries(ctx, mod)
+ if info.PrimaryInfo.disabled() {
+ continue
+ }
+ if contribution := info.PrimaryInfo.getDistContributions(ctx, mod); contribution != nil {
+ allDistContributions = append(allDistContributions, *contribution)
+ }
+ for _, ei := range info.ExtraInfo {
+ ei.fillInEntries(ctx, mod)
+ if ei.disabled() {
+ continue
+ }
+ if contribution := ei.getDistContributions(ctx, mod); contribution != nil {
+ allDistContributions = append(allDistContributions, *contribution)
+ }
+ }
+ } else {
+ switch x := mod.(type) {
+ case AndroidMkDataProvider:
+ data := x.AndroidMk()
+
+ if data.Include == "" {
+ data.Include = "$(BUILD_PREBUILT)"
+ }
+
+ data.fillInData(ctx, mod)
+ if data.Entries.disabled() {
+ continue
+ }
+ if contribution := data.Entries.getDistContributions(mod); contribution != nil {
+ allDistContributions = append(allDistContributions, *contribution)
+ }
+ case AndroidMkEntriesProvider:
+ entriesList := x.AndroidMkEntries()
+ for _, entries := range entriesList {
+ entries.fillInEntries(ctx, mod)
+ if entries.disabled() {
+ continue
+ }
+ if contribution := entries.getDistContributions(mod); contribution != nil {
+ allDistContributions = append(allDistContributions, *contribution)
+ }
+ }
+ default:
+ // Not exported to make so no make variables to set.
+ }
+ }
+ }
+ return allDistContributions
+}
+
func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []blueprint.Module) error {
buf := &bytes.Buffer{}
diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go
index 0b876c3..2f11df6 100644
--- a/android/compliance_metadata.go
+++ b/android/compliance_metadata.go
@@ -236,8 +236,8 @@
blueprint.RuleParams{
Command: `rm -rf $out && ` +
`${sqlite3} $out ".import --csv $in modules" && ` +
- `${sqlite3} $out ".import --csv ${make_metadata} make_metadata" && ` +
- `${sqlite3} $out ".import --csv ${make_modules} make_modules"`,
+ `([ -z "${make_metadata}" ] || ${sqlite3} $out ".import --csv ${make_metadata} make_metadata") && ` +
+ `([ -z "${make_modules}" ] || ${sqlite3} $out ".import --csv ${make_modules} make_modules")`,
CommandDeps: []string{"${sqlite3}"},
}, "make_metadata", "make_modules")
)
@@ -307,24 +307,29 @@
modulesCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "soong-modules.csv")
WriteFileRuleVerbatim(ctx, modulesCsv, buffer.String())
- // Metadata generated in Make
- makeMetadataCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-metadata.csv")
- makeModulesCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-modules.csv")
+ var implicits []Path
+ args := make(map[string]string)
+
+ if ctx.Config().KatiEnabled() {
+ // Metadata generated in Make
+ makeMetadataCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-metadata.csv")
+ makeModulesCsv := PathForOutput(ctx, "compliance-metadata", deviceProduct, "make-modules.csv")
+ implicits = append(implicits, makeMetadataCsv, makeModulesCsv)
+ args["make_metadata"] = makeMetadataCsv.String()
+ args["make_modules"] = makeModulesCsv.String()
+ } else {
+ args["make_metadata"] = ""
+ args["make_modules"] = ""
+ }
// Import metadata from Make and Soong to sqlite3 database
complianceMetadataDb := PathForOutput(ctx, "compliance-metadata", deviceProduct, "compliance-metadata.db")
ctx.Build(pctx, BuildParams{
- Rule: importCsv,
- Input: modulesCsv,
- Implicits: []Path{
- makeMetadataCsv,
- makeModulesCsv,
- },
- Output: complianceMetadataDb,
- Args: map[string]string{
- "make_metadata": makeMetadataCsv.String(),
- "make_modules": makeModulesCsv.String(),
- },
+ Rule: importCsv,
+ Input: modulesCsv,
+ Implicits: implicits,
+ Output: complianceMetadataDb,
+ Args: args,
})
// Phony rule "compliance-metadata.db". "m compliance-metadata.db" to create the compliance metadata database.
diff --git a/android/config.go b/android/config.go
index 00d5e2c..ec79a7d 100644
--- a/android/config.go
+++ b/android/config.go
@@ -83,6 +83,7 @@
OutDir string
SoongOutDir string
SoongVariables string
+ KatiSuffix string
ModuleGraphFile string
ModuleActionsFile string
@@ -349,6 +350,7 @@
// Changes behavior based on whether Kati runs after soong_build, or if soong_build
// runs standalone.
katiEnabled bool
+ katiSuffix string
captureBuild bool // true for tests, saves build parameters for each module
ignoreEnvironment bool // true for tests, returns empty from all Getenv calls
@@ -620,6 +622,7 @@
outDir: cmdArgs.OutDir,
soongOutDir: cmdArgs.SoongOutDir,
runGoTests: cmdArgs.RunGoTests,
+ katiSuffix: cmdArgs.KatiSuffix,
multilibConflicts: make(map[ArchType]bool),
moduleListFile: cmdArgs.ModuleListFile,
@@ -768,11 +771,7 @@
// BlueprintToolLocation returns the directory containing build system tools
// from Blueprint, like soong_zip and merge_zips.
func (c *config) HostToolDir() string {
- if c.KatiEnabled() {
- return filepath.Join(c.outDir, "host", c.PrebuiltOS(), "bin")
- } else {
- return filepath.Join(c.soongOutDir, "host", c.PrebuiltOS(), "bin")
- }
+ return filepath.Join(c.outDir, "host", c.PrebuiltOS(), "bin")
}
func (c *config) HostToolPath(ctx PathContext, tool string) Path {
@@ -1516,6 +1515,10 @@
return c.productVariables.GetBuildFlagBool("RELEASE_BOARD_API_LEVEL_FROZEN")
}
+func (c *config) katiPackageMkDir() string {
+ return filepath.Join(c.soongOutDir, "kati_packaging"+c.katiSuffix)
+}
+
func (c *deviceConfig) Arches() []Arch {
var arches []Arch
for _, target := range c.config.Targets[Android] {
@@ -2186,7 +2189,7 @@
"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "com.android.adservices",
"RELEASE_APEX_CONTRIBUTIONS_APPSEARCH": "com.android.appsearch",
"RELEASE_APEX_CONTRIBUTIONS_ART": "com.android.art",
- "RELEASE_APEX_CONTRIBUTIONS_BLUETOOTH": "com.android.btservices",
+ "RELEASE_APEX_CONTRIBUTIONS_BLUETOOTH": "com.android.bt",
"RELEASE_APEX_CONTRIBUTIONS_CAPTIVEPORTALLOGIN": "",
"RELEASE_APEX_CONTRIBUTIONS_CELLBROADCAST": "com.android.cellbroadcast",
"RELEASE_APEX_CONTRIBUTIONS_CONFIGINFRASTRUCTURE": "com.android.configinfrastructure",
@@ -2283,10 +2286,6 @@
return PathsForSource(ctx, c.productVariables.VendorPropFiles)
}
-func (c *config) ExtraAllowedDepsTxt() string {
- return String(c.productVariables.ExtraAllowedDepsTxt)
-}
-
func (c *config) EnableUffdGc() string {
return String(c.productVariables.EnableUffdGc)
}
diff --git a/android/container.go b/android/container.go
index 99e6a30..882535e 100644
--- a/android/container.go
+++ b/android/container.go
@@ -31,28 +31,25 @@
// and the corresponding functions are called from [exceptionHandleFunctionsTable] map.
// ----------------------------------------------------------------------------
-type exceptionHandleFunc func(ModuleContext, Module, Module) bool
+type exceptionHandleFunc func(ModuleContext, Module, ModuleProxy) bool
type StubsAvailableModule interface {
IsStubsModule() bool
}
// Returns true if the dependency module is a stubs module
-var depIsStubsModule exceptionHandleFunc = func(_ ModuleContext, _, dep Module) bool {
- if stubsModule, ok := dep.(StubsAvailableModule); ok {
- return stubsModule.IsStubsModule()
- }
- return false
+var depIsStubsModule exceptionHandleFunc = func(mctx ModuleContext, _ Module, dep ModuleProxy) bool {
+ return OtherModuleProviderOrDefault(mctx, dep, CommonModuleInfoKey).IsStubsModule
}
// Returns true if the dependency module belongs to any of the apexes.
-var depIsApexModule exceptionHandleFunc = func(mctx ModuleContext, _, dep Module) bool {
+var depIsApexModule exceptionHandleFunc = func(mctx ModuleContext, _ Module, dep ModuleProxy) bool {
depContainersInfo, _ := getContainerModuleInfo(mctx, dep)
return InList(ApexContainer, depContainersInfo.belongingContainers)
}
// Returns true if the module and the dependent module belongs to common apexes.
-var belongsToCommonApexes exceptionHandleFunc = func(mctx ModuleContext, m, dep Module) bool {
+var belongsToCommonApexes exceptionHandleFunc = func(mctx ModuleContext, m Module, dep ModuleProxy) bool {
mContainersInfo, _ := getContainerModuleInfo(mctx, m)
depContainersInfo, _ := getContainerModuleInfo(mctx, dep)
@@ -62,7 +59,7 @@
// Returns true when all apexes that the module belongs to are non updatable.
// For an apex module to be allowed to depend on a non-apex partition module,
// all apexes that the module belong to must be non updatable.
-var belongsToNonUpdatableApex exceptionHandleFunc = func(mctx ModuleContext, m, _ Module) bool {
+var belongsToNonUpdatableApex exceptionHandleFunc = func(mctx ModuleContext, m Module, _ ModuleProxy) bool {
mContainersInfo, _ := getContainerModuleInfo(mctx, m)
return !mContainersInfo.UpdatableApex()
@@ -70,7 +67,7 @@
// Returns true if the dependency is added via dependency tags that are not used to tag dynamic
// dependency tags.
-var depIsNotDynamicDepTag exceptionHandleFunc = func(ctx ModuleContext, m, dep Module) bool {
+var depIsNotDynamicDepTag exceptionHandleFunc = func(ctx ModuleContext, m Module, dep ModuleProxy) bool {
mInstallable, _ := m.(InstallableModule)
depTag := ctx.OtherModuleDependencyTag(dep)
return !InList(depTag, mInstallable.DynamicDependencyTags())
@@ -79,7 +76,7 @@
// Returns true if the dependency is added via dependency tags that are not used to tag static
// or dynamic dependency tags. These dependencies do not affect the module in compile time or in
// runtime, thus are not significant enough to raise an error.
-var depIsNotStaticOrDynamicDepTag exceptionHandleFunc = func(ctx ModuleContext, m, dep Module) bool {
+var depIsNotStaticOrDynamicDepTag exceptionHandleFunc = func(ctx ModuleContext, m Module, dep ModuleProxy) bool {
mInstallable, _ := m.(InstallableModule)
depTag := ctx.OtherModuleDependencyTag(dep)
return !InList(depTag, append(mInstallable.StaticDependencyTags(), mInstallable.DynamicDependencyTags()...))
@@ -106,7 +103,7 @@
}
// Returns true when the dependency is globally allowlisted for inter-container dependency
-var depIsGloballyAllowlisted exceptionHandleFunc = func(_ ModuleContext, _, dep Module) bool {
+var depIsGloballyAllowlisted exceptionHandleFunc = func(_ ModuleContext, _ Module, dep ModuleProxy) bool {
return InList(dep.Name(), globallyAllowlistedDependencies)
}
@@ -198,9 +195,7 @@
func determineUnstableModule(mctx ModuleContext) bool {
module := mctx.Module()
- // TODO(b/383559945) Remove "framework-minus-apex_jarjar-sharded" once
- // we remove this module.
- unstableModule := module.Name() == "framework-minus-apex" || module.Name() == "framework-minus-apex_jarjar-sharded"
+ unstableModule := module.Name() == "framework-minus-apex"
if installable, ok := module.(InstallableModule); ok {
for _, staticDepTag := range installable.StaticDependencyTags() {
mctx.VisitDirectDepsWithTag(staticDepTag, func(dep Module) {
@@ -403,7 +398,7 @@
var ContainersInfoProvider = blueprint.NewProvider[ContainersInfo]()
-func satisfyAllowedExceptions(ctx ModuleContext, allowedExceptionLabels []exceptionHandleFuncLabel, m, dep Module) bool {
+func satisfyAllowedExceptions(ctx ModuleContext, allowedExceptionLabels []exceptionHandleFuncLabel, m Module, dep ModuleProxy) bool {
for _, label := range allowedExceptionLabels {
if exceptionHandleFunctionsTable[label](ctx, m, dep) {
return true
@@ -412,7 +407,7 @@
return false
}
-func (c *ContainersInfo) GetViolations(mctx ModuleContext, m, dep Module, depInfo ContainersInfo) []string {
+func (c *ContainersInfo) GetViolations(mctx ModuleContext, m Module, dep ModuleProxy, depInfo ContainersInfo) []string {
var violations []string
// Any containers that the module belongs to but the dependency does not belong to must be examined.
@@ -458,7 +453,7 @@
}
func getContainerModuleInfo(ctx ModuleContext, module Module) (ContainersInfo, bool) {
- if ctx.Module() == module {
+ if ctx.EqualModules(ctx.Module(), module) {
return ctx.getContainersInfo(), true
}
@@ -482,8 +477,8 @@
func checkContainerViolations(ctx ModuleContext) {
if _, ok := ctx.Module().(InstallableModule); ok {
containersInfo, _ := getContainerModuleInfo(ctx, ctx.Module())
- ctx.VisitDirectDeps(func(dep Module) {
- if !dep.Enabled(ctx) {
+ ctx.VisitDirectDepsProxy(func(dep ModuleProxy) {
+ if !OtherModuleProviderOrDefault(ctx, dep, CommonModuleInfoKey).Enabled {
return
}
diff --git a/android/container_violations.go b/android/container_violations.go
index ba8f7d5..e1583c5 100644
--- a/android/container_violations.go
+++ b/android/container_violations.go
@@ -32,22 +32,22 @@
},
"Bluetooth": {
- "app-compat-annotations", // apex [com.android.btservices] -> system
- "framework-bluetooth-pre-jarjar", // apex [com.android.btservices] -> system
+ "app-compat-annotations", // apex [com.android.bt] -> system
+ "framework-bluetooth-pre-jarjar", // apex [com.android.bt] -> system
},
"bluetooth-nano-protos": {
- "libprotobuf-java-nano", // apex [com.android.btservices] -> apex [com.android.wifi, test_com.android.wifi]
+ "libprotobuf-java-nano", // apex [com.android.bt] -> apex [com.android.wifi, test_com.android.wifi]
},
"bluetooth.change-ids": {
- "app-compat-annotations", // apex [com.android.btservices] -> system
+ "app-compat-annotations", // apex [com.android.bt] -> system
},
"CarServiceUpdatable": {
"modules-utils-os", // apex [com.android.car.framework] -> apex [com.android.permission, test_com.android.permission]
"modules-utils-preconditions", // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.appsearch, com.android.cellbroadcast, com.android.extservices, com.android.ondevicepersonalization, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.cellbroadcast, test_com.android.wifi]
- "modules-utils-shell-command-handler", // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.art, com.android.art.debug, com.android.art.testing, com.android.btservices, com.android.configinfrastructure, com.android.mediaprovider, com.android.nfcservices, com.android.permission, com.android.scheduling, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.mediaprovider, test_com.android.permission, test_com.android.wifi, test_imgdiag_com.android.art, test_jitzygote_com.android.art]
+ "modules-utils-shell-command-handler", // apex [com.android.car.framework] -> apex [com.android.adservices, com.android.art, com.android.art.debug, com.android.art.testing, com.android.bt, com.android.configinfrastructure, com.android.mediaprovider, com.android.nfcservices, com.android.permission, com.android.scheduling, com.android.tethering, com.android.uwb, com.android.wifi, test_com.android.mediaprovider, test_com.android.permission, test_com.android.wifi, test_imgdiag_com.android.art, test_jitzygote_com.android.art]
},
"cellbroadcastreceiver_aconfig_flags_lib": {
@@ -414,10 +414,6 @@
"framework", // cts -> unstable
},
- "CtsMediaBetterTogetherTestCases": {
- "framework", // cts -> unstable
- },
-
"CtsMediaCodecTestCases": {
"framework", // cts -> unstable
},
@@ -478,6 +474,11 @@
"framework", // cts -> unstable
},
+ // TODO(b/387499846): Remove once migrated to sdk_version.
+ "CtsMediaRouterTestCases": {
+ "framework", // cts -> unstable
+ },
+
"CtsMediaRouterHostSideTestBluetoothPermissionsApp": {
"framework", // cts -> unstable
},
@@ -490,6 +491,11 @@
"framework", // cts -> unstable
},
+ // TODO(b/387500109): Remove once migrated to sdk_version.
+ "CtsMediaSessionTestCases": {
+ "framework", // cts -> unstable
+ },
+
"CtsMediaV2TestCases": {
"framework", // cts -> unstable
},
@@ -824,7 +830,7 @@
},
"devicelockcontroller-lib": {
- "modules-utils-expresslog", // apex [com.android.devicelock] -> apex [com.android.btservices, com.android.car.framework]
+ "modules-utils-expresslog", // apex [com.android.devicelock] -> apex [com.android.bt, com.android.car.framework]
},
"FederatedCompute": {
@@ -836,7 +842,7 @@
},
"framework-bluetooth.impl": {
- "app-compat-annotations", // apex [com.android.btservices] -> system
+ "app-compat-annotations", // apex [com.android.bt] -> system
},
"framework-configinfrastructure.impl": {
@@ -907,10 +913,6 @@
"libnativeloader_vendor_shared_lib", // system -> vendor
},
- "MctsMediaBetterTogetherTestCases": {
- "framework", // cts -> unstable
- },
-
"MctsMediaCodecTestCases": {
"framework", // cts -> unstable
},
@@ -947,6 +949,16 @@
"framework", // cts -> unstable
},
+ // TODO(b/387499846): Remove once migrated to sdk_version.
+ "MctsMediaRouterTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ // TODO(b/387500109): Remove once migrated to sdk_version.
+ "MctsMediaSessionTestCases": {
+ "framework", // cts -> unstable
+ },
+
"MctsMediaTranscodingTestCases": {
"framework", // cts -> unstable
},
@@ -1005,7 +1017,7 @@
},
"PlatformProperties": {
- "sysprop-library-stub-platform", // apex [com.android.btservices, com.android.nfcservices, com.android.tethering, com.android.virt, com.android.wifi, test_com.android.wifi] -> system
+ "sysprop-library-stub-platform", // apex [com.android.bt, com.android.nfcservices, com.android.tethering, com.android.virt, com.android.wifi, test_com.android.wifi] -> system
},
"safety-center-config": {
@@ -1041,8 +1053,8 @@
},
"service-bluetooth-pre-jarjar": {
- "framework-bluetooth-pre-jarjar", // apex [com.android.btservices] -> system
- "service-bluetooth.change-ids", // apex [com.android.btservices] -> system
+ "framework-bluetooth-pre-jarjar", // apex [com.android.bt] -> system
+ "service-bluetooth.change-ids", // apex [com.android.bt] -> system
},
"service-connectivity": {
diff --git a/android/module.go b/android/module.go
index b8f2cae..9e620fb 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1679,14 +1679,13 @@
}
})
- var deps Paths
-
var namespacePrefix string
nameSpace := ctx.Namespace().Path
if nameSpace != "." {
namespacePrefix = strings.ReplaceAll(nameSpace, "/", ".") + "-"
}
+ var deps Paths
var info FinalModuleBuildTargetsInfo
if len(allInstalledFiles) > 0 {
@@ -1853,9 +1852,9 @@
var SourceFilesInfoKey = blueprint.NewProvider[SourceFilesInfo]()
+// FinalModuleBuildTargetsInfo is used by buildTargetSingleton to create checkbuild and
+// per-directory build targets. Only set on the final variant of each module
type FinalModuleBuildTargetsInfo struct {
- // Used by buildTargetSingleton to create checkbuild and per-directory build targets
- // Only set on the final variant of each module
InstallTarget WritablePath
CheckbuildTarget WritablePath
BlueprintDir string
@@ -1868,12 +1867,14 @@
// Whether the module has been replaced by a prebuilt
ReplacedByPrebuilt bool
// The Target of artifacts that this module variant is responsible for creating.
- CompileTarget Target
+ Target Target
SkipAndroidMkProcessing bool
BaseModuleName string
CanHaveApexVariants bool
MinSdkVersion string
NotAvailableForPlatform bool
+ // There some subtle differences between this one and the one above.
+ NotInPlatform bool
// UninstallableApexPlatformVariant is set by MakeUninstallable called by the apex
// mutator. MakeUninstallable also sets HideFromMake. UninstallableApexPlatformVariant
// is used to avoid adding install or packaging dependencies into libraries provided
@@ -1881,15 +1882,17 @@
UninstallableApexPlatformVariant bool
HideFromMake bool
SkipInstall bool
+ IsStubsModule bool
+ Host bool
}
var CommonModuleInfoKey = blueprint.NewProvider[CommonModuleInfo]()
-type PrebuiltModuleProviderData struct {
- // Empty for now
+type PrebuiltModuleInfo struct {
+ SourceExists bool
}
-var PrebuiltModuleProviderKey = blueprint.NewProvider[PrebuiltModuleProviderData]()
+var PrebuiltModuleInfoProvider = blueprint.NewProvider[PrebuiltModuleInfo]()
type HostToolProviderData struct {
HostToolPath OptionalPath
@@ -1897,6 +1900,20 @@
var HostToolProviderKey = blueprint.NewProvider[HostToolProviderData]()
+type SourceFileGenerator interface {
+ GeneratedSourceFiles() Paths
+ GeneratedHeaderDirs() Paths
+ GeneratedDeps() Paths
+}
+
+type GeneratedSourceInfo struct {
+ GeneratedSourceFiles Paths
+ GeneratedHeaderDirs Paths
+ GeneratedDeps Paths
+}
+
+var GeneratedSourceInfoProvider = blueprint.NewProvider[GeneratedSourceInfo]()
+
func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
ctx := &moduleContext{
module: m.module,
@@ -2147,12 +2164,13 @@
commonData := CommonModuleInfo{
ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt,
- CompileTarget: m.commonProperties.CompileTarget,
+ Target: m.commonProperties.CompileTarget,
SkipAndroidMkProcessing: shouldSkipAndroidMkProcessing(ctx, m),
BaseModuleName: m.BaseModuleName(),
UninstallableApexPlatformVariant: m.commonProperties.UninstallableApexPlatformVariant,
HideFromMake: m.commonProperties.HideFromMake,
SkipInstall: m.commonProperties.SkipInstall,
+ Host: m.Host(),
}
if mm, ok := m.module.(interface {
MinSdkVersion(ctx EarlyModuleContext) ApiLevel
@@ -2173,10 +2191,16 @@
if am, ok := m.module.(ApexModule); ok {
commonData.CanHaveApexVariants = am.CanHaveApexVariants()
commonData.NotAvailableForPlatform = am.NotAvailableForPlatform()
+ commonData.NotInPlatform = am.NotInPlatform()
+ }
+ if st, ok := m.module.(StubsAvailableModule); ok {
+ commonData.IsStubsModule = st.IsStubsModule()
}
SetProvider(ctx, CommonModuleInfoKey, commonData)
if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil {
- SetProvider(ctx, PrebuiltModuleProviderKey, PrebuiltModuleProviderData{})
+ SetProvider(ctx, PrebuiltModuleInfoProvider, PrebuiltModuleInfo{
+ SourceExists: p.Prebuilt().SourceExists(),
+ })
}
if h, ok := m.module.(HostToolProvider); ok {
SetProvider(ctx, HostToolProviderKey, HostToolProviderData{
@@ -2186,6 +2210,14 @@
if p, ok := m.module.(AndroidMkProviderInfoProducer); ok && !commonData.SkipAndroidMkProcessing {
SetProvider(ctx, AndroidMkInfoProvider, p.PrepareAndroidMKProviderInfo(ctx.Config()))
}
+
+ if s, ok := m.module.(SourceFileGenerator); ok {
+ SetProvider(ctx, GeneratedSourceInfoProvider, GeneratedSourceInfo{
+ GeneratedSourceFiles: s.GeneratedSourceFiles(),
+ GeneratedHeaderDirs: s.GeneratedHeaderDirs(),
+ GeneratedDeps: s.GeneratedDeps(),
+ })
+ }
}
func SetJarJarPrefixHandler(handler func(ModuleContext)) {
diff --git a/android/module_context.go b/android/module_context.go
index b59e33d..f6a676d 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -75,7 +75,7 @@
// Validations is a slice of output path for a validation action. Validation outputs imply lower
// non-blocking priority to building non-validation outputs.
Validations Paths
- // Whether to skip outputting a default target statement which will be built by Ninja when no
+ // Whether to output a default target statement which will be built by Ninja when no
// targets are specified on Ninja's command line.
Default bool
// Args is a key value mapping for replacements of variables within the Rule
@@ -343,7 +343,7 @@
OrderOnly: params.OrderOnly.Strings(),
Validations: params.Validations.Strings(),
Args: params.Args,
- Optional: !params.Default,
+ Default: params.Default,
}
if params.Depfile != nil {
@@ -688,7 +688,6 @@
Input: srcPath,
Implicits: implicitDeps,
OrderOnly: orderOnlyDeps,
- Default: !m.Config().KatiEnabled(),
Args: map[string]string{
"extraCmds": extraCmds,
},
@@ -735,7 +734,6 @@
Description: "install symlink " + fullInstallPath.Base(),
Output: fullInstallPath,
Input: srcPath,
- Default: !m.Config().KatiEnabled(),
Args: map[string]string{
"fromPath": relPath,
},
@@ -782,7 +780,6 @@
Rule: Symlink,
Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
Output: fullInstallPath,
- Default: !m.Config().KatiEnabled(),
Args: map[string]string{
"fromPath": absPath,
},
diff --git a/android/neverallow.go b/android/neverallow.go
index fdcbe1c..e12e8b7 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -230,7 +230,7 @@
func createUncompressDexRules() []Rule {
return []Rule{
NeverAllow().
- NotIn("art").
+ NotIn("art", "cts/hostsidetests/compilation").
WithMatcher("uncompress_dex", isSetMatcherInstance).
Because("uncompress_dex is only allowed for certain jars for test in art."),
}
@@ -322,9 +322,6 @@
func createKotlinPluginRule() []Rule {
kotlinPluginProjectsAllowedList := []string{
- // TODO: Migrate compose plugin to the bundled compiler plugin
- // Actual path prebuilts/sdk/current/androidx/m2repository/androidx/compose/compiler/compiler-hosted
- "prebuilts/sdk/current/androidx",
"external/kotlinc",
}
diff --git a/android/nothing.go b/android/nothing.go
new file mode 100644
index 0000000..18bf85b
--- /dev/null
+++ b/android/nothing.go
@@ -0,0 +1,34 @@
+// Copyright 2025 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 android
+
+func init() {
+ RegisterParallelSingletonType("nothing_singleton", nothingSingletonFactory)
+}
+
+func nothingSingletonFactory() Singleton {
+ return ¬hingSingleton{}
+}
+
+type nothingSingleton struct{}
+
+func (s *nothingSingleton) GenerateBuildActions(ctx SingletonContext) {
+ rule := NewRuleBuilder(pctx, ctx)
+ rule.SetPhonyOutput()
+ rule.Command().
+ Text("echo Successfully read the makefiles.").
+ ImplicitOutput(PathForPhony(ctx, "nothing"))
+ rule.Build("nothing", "nothing")
+}
diff --git a/android/phony.go b/android/phony.go
index f8db88d..7bdd9d3 100644
--- a/android/phony.go
+++ b/android/phony.go
@@ -15,6 +15,7 @@
package android
import (
+ "strings"
"sync"
"github.com/google/blueprint"
@@ -68,13 +69,25 @@
}
if !ctx.Config().KatiEnabled() {
+ // In soong-only builds, the phonies can conflict with dist targets that will
+ // be generated in the packaging step. Instead of emitting a blueprint/ninja phony directly,
+ // create a makefile that defines the phonies that will be included in the packaging step.
+ // Make will dedup the phonies there.
+ var buildPhonyFileContents strings.Builder
for _, phony := range p.phonyList {
- ctx.Build(pctx, BuildParams{
- Rule: blueprint.Phony,
- Outputs: []WritablePath{PathForPhony(ctx, phony)},
- Implicits: p.phonyMap[phony],
- })
+ buildPhonyFileContents.WriteString(".PHONY: ")
+ buildPhonyFileContents.WriteString(phony)
+ buildPhonyFileContents.WriteString("\n")
+ buildPhonyFileContents.WriteString(phony)
+ buildPhonyFileContents.WriteString(":")
+ for _, dep := range p.phonyMap[phony] {
+ buildPhonyFileContents.WriteString(" ")
+ buildPhonyFileContents.WriteString(dep.String())
+ }
+ buildPhonyFileContents.WriteString("\n")
}
+ buildPhonyFile := PathForOutput(ctx, "soong_phony_targets.mk")
+ writeValueIfChanged(ctx, absolutePath(buildPhonyFile.String()), buildPhonyFileContents.String())
}
}
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 0ac67b3..bf27178 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -384,7 +384,7 @@
if !OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).ReplacedByPrebuilt {
return module
}
- if _, ok := OtherModuleProvider(ctx, module, PrebuiltModuleProviderKey); ok {
+ if _, ok := OtherModuleProvider(ctx, module, PrebuiltModuleInfoProvider); ok {
// If we're given a prebuilt then assume there's no source module around.
return module
}
diff --git a/android/raw_files.go b/android/raw_files.go
index 9d7f5e8..fd37196 100644
--- a/android/raw_files.go
+++ b/android/raw_files.go
@@ -18,7 +18,6 @@
"crypto/sha1"
"encoding/hex"
"fmt"
- "github.com/google/blueprint"
"io"
"io/fs"
"os"
@@ -26,25 +25,27 @@
"strings"
"testing"
+ "github.com/google/blueprint"
+
"github.com/google/blueprint/proptools"
)
// WriteFileRule creates a ninja rule to write contents to a file by immediately writing the
// contents, plus a trailing newline, to a file in out/soong/raw-${TARGET_PRODUCT}, and then creating
// a ninja rule to copy the file into place.
-func WriteFileRule(ctx BuilderContext, outputFile WritablePath, content string) {
- writeFileRule(ctx, outputFile, content, true, false)
+func WriteFileRule(ctx BuilderContext, outputFile WritablePath, content string, validations ...Path) {
+ writeFileRule(ctx, outputFile, content, true, false, validations)
}
// WriteFileRuleVerbatim creates a ninja rule to write contents to a file by immediately writing the
// contents to a file in out/soong/raw-${TARGET_PRODUCT}, and then creating a ninja rule to copy the file into place.
-func WriteFileRuleVerbatim(ctx BuilderContext, outputFile WritablePath, content string) {
- writeFileRule(ctx, outputFile, content, false, false)
+func WriteFileRuleVerbatim(ctx BuilderContext, outputFile WritablePath, content string, validations ...Path) {
+ writeFileRule(ctx, outputFile, content, false, false, validations)
}
// WriteExecutableFileRuleVerbatim is the same as WriteFileRuleVerbatim, but runs chmod +x on the result
-func WriteExecutableFileRuleVerbatim(ctx BuilderContext, outputFile WritablePath, content string) {
- writeFileRule(ctx, outputFile, content, false, true)
+func WriteExecutableFileRuleVerbatim(ctx BuilderContext, outputFile WritablePath, content string, validations ...Path) {
+ writeFileRule(ctx, outputFile, content, false, true, validations)
}
// tempFile provides a testable wrapper around a file in out/soong/.temp. It writes to a temporary file when
@@ -124,7 +125,7 @@
return tempFile, hex.EncodeToString(hash.Sum(nil))
}
-func writeFileRule(ctx BuilderContext, outputFile WritablePath, content string, newline bool, executable bool) {
+func writeFileRule(ctx BuilderContext, outputFile WritablePath, content string, newline bool, executable bool, validations Paths) {
// Write the contents to a temporary file while computing its hash.
tempFile, hash := writeContentToTempFileAndHash(ctx, content, newline)
@@ -186,6 +187,7 @@
Input: rawPath,
Output: outputFile,
Description: "raw " + outputFile.Base(),
+ Validations: validations,
})
}
diff --git a/android/test_asserts.go b/android/test_asserts.go
index c33ade5..22472c5 100644
--- a/android/test_asserts.go
+++ b/android/test_asserts.go
@@ -33,6 +33,23 @@
}
}
+// AssertSame checks if the expected and actual values are equal and if they are not then
+// it reports an error prefixed with the supplied message and including a reason for why it failed.
+func AssertSameArray[T comparable](t *testing.T, message string, expected []T, actual []T) {
+ t.Helper()
+ if len(actual) != len(expected) {
+ t.Errorf("%s: expected %d (%v), actual (%d) %v", message, len(expected), expected, len(actual), actual)
+ return
+ }
+ for i := range actual {
+ if actual[i] != expected[i] {
+ t.Errorf("%s: expected %d-th, %v (%v), actual %v (%v)",
+ message, i, expected[i], expected, actual[i], actual)
+ return
+ }
+ }
+}
+
// AssertBoolEquals checks if the expected and actual values are equal and if they are not then it
// reports an error prefixed with the supplied message and including a reason for why it failed.
func AssertBoolEquals(t *testing.T, message string, expected bool, actual bool) {
diff --git a/android/util.go b/android/util.go
index 3fc4608..30d8ec6 100644
--- a/android/util.go
+++ b/android/util.go
@@ -308,6 +308,20 @@
return
}
+// FilterListByPrefixes performs the same splitting as FilterList does, but treats the passed
+// filters as prefixes
+func FilterListByPrefix(list []string, filter []string) (remainder []string, filtered []string) {
+ for _, l := range list {
+ if HasAnyPrefix(l, filter) {
+ filtered = append(filtered, l)
+ } else {
+ remainder = append(remainder, l)
+ }
+ }
+
+ return
+}
+
// FilterListPred returns the elements of the given list for which the predicate
// returns true. Order is kept.
func FilterListPred(list []string, pred func(s string) bool) (filtered []string) {
diff --git a/android/variable.go b/android/variable.go
index ec84274..1de8796 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -162,6 +162,7 @@
Optimize struct {
Enabled *bool
}
+ Aaptflags []string
}
Uml struct {
@@ -542,8 +543,6 @@
PartitionVarsForSoongMigrationOnlyDoNotUse PartitionVariables
- ExtraAllowedDepsTxt *string `json:",omitempty"`
-
AdbKeys *string `json:",omitempty"`
DeviceMatrixFile []string `json:",omitempty"`
@@ -696,6 +695,8 @@
TargetScreenDensity string `json:",omitempty"`
PrivateRecoveryUiProperties map[string]string `json:",omitempty"`
+
+ PrebuiltBootloader string `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/apex/apex.go b/apex/apex.go
index 7734391..d39a17f 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1056,7 +1056,7 @@
"com.android.appsearch",
"com.android.art",
"com.android.art.debug",
- "com.android.btservices",
+ "com.android.bt",
"com.android.cellbroadcast",
"com.android.configinfrastructure",
"com.android.conscrypt",
@@ -2588,7 +2588,7 @@
})
a.WalkPayloadDepsProxy(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool {
- if ccInfo, ok := android.OtherModuleProvider(ctx, to, cc.CcInfoProvider); ok {
+ if info, ok := android.OtherModuleProvider(ctx, to, cc.LinkableInfoProvider); ok {
// If `to` is not actually in the same APEX as `from` then it does not need
// apex_available and neither do any of its dependencies.
if externalDep {
@@ -2609,7 +2609,7 @@
return false
}
- isStubLibraryFromOtherApex := ccInfo.HasStubsVariants && !librariesDirectlyInApex[toName]
+ isStubLibraryFromOtherApex := info.HasStubsVariants && !librariesDirectlyInApex[toName]
if isStubLibraryFromOtherApex && !externalDep {
ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
"It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false))
@@ -2740,7 +2740,7 @@
return
}
- if android.OtherModuleProviderOrDefault(ctx, module, cc.LinkableInfoKey).StaticExecutable {
+ if android.OtherModuleProviderOrDefault(ctx, module, cc.LinkableInfoProvider).StaticExecutable {
apex := a.ApexVariationName()
exec := ctx.OtherModuleName(module)
if isStaticExecutableAllowed(apex, exec) {
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go
index d46104e..263e0a5 100644
--- a/apex/apex_singleton.go
+++ b/apex/apex_singleton.go
@@ -59,9 +59,9 @@
// Diff two given lists while ignoring comments in the allowed deps file.
diffAllowedApexDepsInfoRule = pctx.AndroidStaticRule("diffAllowedApexDepsInfoRule", blueprint.RuleParams{
- Description: "Diff ${allowed_deps_list} and ${new_allowed_deps}",
+ Description: "Diff ${allowed_deps} and ${new_allowed_deps}",
Command: `
- if grep -v -h '^#' ${allowed_deps_list} | sort -u -f| diff -B -u - ${new_allowed_deps}; then
+ if grep -v '^#' ${allowed_deps} | diff -B - ${new_allowed_deps}; then
touch ${out};
else
echo;
@@ -85,62 +85,54 @@
exit 1;
fi;
`,
- }, "allowed_deps_list", "new_allowed_deps")
+ }, "allowed_deps", "new_allowed_deps")
)
func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContext) {
- allowedDepsSources := []android.OptionalPath{android.ExistentPathForSource(ctx, "packages/modules/common/build/allowed_deps.txt")}
- extraAllowedDepsPath := ctx.Config().ExtraAllowedDepsTxt()
- if extraAllowedDepsPath != "" {
- allowedDepsSources = append(allowedDepsSources, android.ExistentPathForSource(ctx, extraAllowedDepsPath))
- }
updatableFlatLists := android.Paths{}
ctx.VisitAllModules(func(module android.Module) {
if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok {
apexInfo, _ := android.OtherModuleProvider(ctx, module, android.ApexInfoProvider)
if path := binaryInfo.FlatListPath(); path != nil {
if binaryInfo.Updatable() || apexInfo.Updatable {
- updatableFlatLists = append(updatableFlatLists, path)
+ if strings.HasPrefix(module.String(), "com.android.") {
+ updatableFlatLists = append(updatableFlatLists, path)
+ }
}
}
}
})
+
+ allowedDepsSource := android.ExistentPathForSource(ctx, "packages/modules/common/build/allowed_deps.txt")
newAllowedDeps := android.PathForOutput(ctx, "apex", "depsinfo", "new-allowed-deps.txt")
s.allowedApexDepsInfoCheckResult = android.PathForOutput(ctx, newAllowedDeps.Rel()+".check")
- hasOneValidDepsPath := false
- for _, allowedDepsSource := range allowedDepsSources {
- if allowedDepsSource.Valid() {
- hasOneValidDepsPath = true
- updatableFlatLists = append(updatableFlatLists, allowedDepsSource.Path())
- }
- }
- allowedDepsStrList := make([]string, len(allowedDepsSources))
- for _, value := range allowedDepsSources {
- allowedDepsStrList = append(allowedDepsStrList, value.String())
- }
- allowedDepsListString := strings.Join(allowedDepsStrList, " ")
- if !hasOneValidDepsPath {
+
+ if !allowedDepsSource.Valid() {
// Unbundled projects may not have packages/modules/common/ checked out; ignore those.
ctx.Build(pctx, android.BuildParams{
Rule: android.Touch,
Output: s.allowedApexDepsInfoCheckResult,
})
} else {
+ allowedDeps := allowedDepsSource.Path()
+
ctx.Build(pctx, android.BuildParams{
Rule: generateApexDepsInfoFilesRule,
- Inputs: updatableFlatLists,
+ Inputs: append(updatableFlatLists, allowedDeps),
Output: newAllowedDeps,
})
+
ctx.Build(pctx, android.BuildParams{
Rule: diffAllowedApexDepsInfoRule,
Input: newAllowedDeps,
Output: s.allowedApexDepsInfoCheckResult,
Args: map[string]string{
- "allowed_deps_list": allowedDepsListString,
- "new_allowed_deps": newAllowedDeps.String(),
+ "allowed_deps": allowedDeps.String(),
+ "new_allowed_deps": newAllowedDeps.String(),
},
})
}
+
ctx.Phony("apex-allowed-deps-check", s.allowedApexDepsInfoCheckResult)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e1a9582..465789c 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2129,7 +2129,79 @@
android.AssertStringDoesContain(t, "cflags", cflags, "-target aarch64-linux-android29")
}
-func TestTrackAllowedDeps(t *testing.T) {
+func TestTrackAllowedDepsForAndroidApex(t *testing.T) {
+ t.Parallel()
+ ctx := testApex(t, `
+ apex {
+ name: "com.android.myapex",
+ key: "myapex.key",
+ updatable: true,
+ native_shared_libs: [
+ "mylib",
+ "yourlib",
+ ],
+ min_sdk_version: "29",
+ }
+
+ apex {
+ name: "myapex2",
+ key: "myapex.key",
+ updatable: false,
+ native_shared_libs: ["yourlib"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ shared_libs: ["libbar"],
+ min_sdk_version: "29",
+ apex_available: ["com.android.myapex"],
+ }
+
+ cc_library {
+ name: "libbar",
+ stubs: { versions: ["29", "30"] },
+ }
+
+ cc_library {
+ name: "yourlib",
+ srcs: ["mylib.cpp"],
+ min_sdk_version: "29",
+ apex_available: ["com.android.myapex", "myapex2", "//apex_available:platform"],
+ }
+ `, withFiles(android.MockFS{
+ "packages/modules/common/build/allowed_deps.txt": nil,
+ }),
+ android.FixtureMergeMockFs(android.MockFS{
+ "system/sepolicy/apex/com.android.myapex-file_contexts": nil,
+ }))
+
+ depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton")
+ inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings()
+
+ android.AssertStringListContains(t, "updatable com.android.myapex should generate depsinfo file", inputs,
+ "out/soong/.intermediates/com.android.myapex/android_common_com.android.myapex/depsinfo/flatlist.txt")
+ android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs,
+ "out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt")
+
+ myapex := ctx.ModuleForTests("com.android.myapex", "android_common_com.android.myapex")
+ flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
+ myapex.Output("depsinfo/flatlist.txt")), "\n")
+ android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
+ flatlist, "libbar(minSdkVersion:(no version)) (external)")
+ android.AssertStringListDoesNotContain(t, "do not track if not available for platform",
+ flatlist, "mylib:(minSdkVersion:29)")
+ android.AssertStringListContains(t, "track platform-available lib",
+ flatlist, "yourlib(minSdkVersion:29)")
+}
+
+func TestNotTrackAllowedDepsForNonAndroidApex(t *testing.T) {
t.Parallel()
ctx := testApex(t, `
apex {
@@ -2181,174 +2253,17 @@
depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton")
inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings()
- android.AssertStringListContains(t, "updatable myapex should generate depsinfo file", inputs,
+ android.AssertStringListDoesNotContain(t, "updatable myapex should generate depsinfo file", inputs,
"out/soong/.intermediates/myapex/android_common_myapex/depsinfo/flatlist.txt")
android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs,
"out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt")
-
- myapex := ctx.ModuleForTests("myapex", "android_common_myapex")
- flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
- myapex.Output("depsinfo/flatlist.txt")), "\n")
- android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
- flatlist, "libbar(minSdkVersion:(no version)) (external)")
- android.AssertStringListDoesNotContain(t, "do not track if not available for platform",
- flatlist, "mylib:(minSdkVersion:29)")
- android.AssertStringListContains(t, "track platform-available lib",
- flatlist, "yourlib(minSdkVersion:29)")
-}
-
-func TestTrackCustomAllowedDepsInvalidDefaultTxt(t *testing.T) {
- t.Parallel()
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: true,
- native_shared_libs: [
- "mylib",
- "yourlib",
- ],
- min_sdk_version: "29",
- }
-
- apex {
- name: "myapex2",
- key: "myapex.key",
- updatable: false,
- native_shared_libs: ["yourlib"],
- }
-
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["libbar"],
- min_sdk_version: "29",
- apex_available: ["myapex"],
- }
-
- cc_library {
- name: "libbar",
- stubs: { versions: ["29", "30"] },
- }
-
- cc_library {
- name: "yourlib",
- srcs: ["mylib.cpp"],
- min_sdk_version: "29",
- apex_available: ["myapex", "myapex2", "//apex_available:platform"],
- }
- `, withFiles(android.MockFS{
- "packages/modules/common/build/custom_allowed_deps.txt": nil,
- }),
- android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.ExtraAllowedDepsTxt = proptools.StringPtr("packages/modules/common/build/custom_allowed_deps.txt")
- },
- ))
-
- depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton")
- inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings()
- android.AssertStringListContains(t, "updatable myapex should generate depsinfo file", inputs,
- "out/soong/.intermediates/myapex/android_common_myapex/depsinfo/flatlist.txt")
- android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs,
- "out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt")
-
- myapex := ctx.ModuleForTests("myapex", "android_common_myapex")
- flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
- myapex.Output("depsinfo/flatlist.txt")), "\n")
- android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
- flatlist, "libbar(minSdkVersion:(no version)) (external)")
- android.AssertStringListDoesNotContain(t, "do not track if not available for platform",
- flatlist, "mylib:(minSdkVersion:29)")
- android.AssertStringListContains(t, "track platform-available lib",
- flatlist, "yourlib(minSdkVersion:29)")
-}
-
-func TestTrackCustomAllowedDepsWithDefaultTxt(t *testing.T) {
- t.Parallel()
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: true,
- native_shared_libs: [
- "mylib",
- "yourlib",
- ],
- min_sdk_version: "29",
- }
-
- apex {
- name: "myapex2",
- key: "myapex.key",
- updatable: false,
- native_shared_libs: ["yourlib"],
- }
-
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["libbar"],
- min_sdk_version: "29",
- apex_available: ["myapex"],
- }
-
- cc_library {
- name: "libbar",
- stubs: { versions: ["29", "30"] },
- }
-
- cc_library {
- name: "yourlib",
- srcs: ["mylib.cpp"],
- min_sdk_version: "29",
- apex_available: ["myapex", "myapex2", "//apex_available:platform"],
- }
- `, withFiles(android.MockFS{
- "packages/modules/common/build/custom_allowed_deps.txt": nil,
- "packages/modules/common/build/allowed_deps.txt": nil,
- }),
- android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.ExtraAllowedDepsTxt = proptools.StringPtr("packages/modules/common/build/custom_allowed_deps.txt")
- },
- ))
-
- depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton")
- inputs := depsinfo.Rule("generateApexDepsInfoFilesRule").BuildParams.Inputs.Strings()
- android.AssertStringListContains(t, "updatable myapex should generate depsinfo file", inputs,
- "out/soong/.intermediates/myapex/android_common_myapex/depsinfo/flatlist.txt")
- android.AssertStringListDoesNotContain(t, "non-updatable myapex2 should not generate depsinfo file", inputs,
- "out/soong/.intermediates/myapex2/android_common_myapex2/depsinfo/flatlist.txt")
-
- myapex := ctx.ModuleForTests("myapex", "android_common_myapex")
- flatlist := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
- myapex.Output("depsinfo/flatlist.txt")), "\n")
- android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
- flatlist, "libbar(minSdkVersion:(no version)) (external)")
- android.AssertStringListDoesNotContain(t, "do not track if not available for platform",
- flatlist, "mylib:(minSdkVersion:29)")
- android.AssertStringListContains(t, "track platform-available lib",
- flatlist, "yourlib(minSdkVersion:29)")
}
func TestTrackAllowedDeps_SkipWithoutAllowedDepsTxt(t *testing.T) {
t.Parallel()
ctx := testApex(t, `
apex {
- name: "myapex",
+ name: "com.android.myapex",
key: "myapex.key",
updatable: true,
min_sdk_version: "29",
@@ -2359,7 +2274,10 @@
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
- `)
+ `,
+ android.FixtureMergeMockFs(android.MockFS{
+ "system/sepolicy/apex/com.android.myapex-file_contexts": nil,
+ }))
depsinfo := ctx.SingletonForTests("apex_depsinfo_singleton")
if nil != depsinfo.MaybeRule("generateApexDepsInfoFilesRule").Output {
t.Error("apex_depsinfo_singleton shouldn't run when allowed_deps.txt doesn't exist")
diff --git a/apex/builder.go b/apex/builder.go
index c85d0a0..d9348c5 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -73,6 +73,7 @@
pctx.HostBinToolVariable("make_erofs", "mkfs.erofs")
pctx.HostBinToolVariable("apex_compression_tool", "apex_compression_tool")
pctx.HostBinToolVariable("dexdeps", "dexdeps")
+ pctx.HostBinToolVariable("apex_ls", "apex-ls")
pctx.HostBinToolVariable("apex_sepolicy_tests", "apex_sepolicy_tests")
pctx.HostBinToolVariable("deapexer", "deapexer")
pctx.HostBinToolVariable("debugfs_static", "debugfs_static")
@@ -210,11 +211,11 @@
}, "image_dir", "readelf")
apexSepolicyTestsRule = pctx.StaticRule("apexSepolicyTestsRule", blueprint.RuleParams{
- Command: `${deapexer} --debugfs_path ${debugfs_static} list -Z ${in} > ${out}.fc` +
- ` && ${apex_sepolicy_tests} -f ${out}.fc && touch ${out}`,
- CommandDeps: []string{"${apex_sepolicy_tests}", "${deapexer}", "${debugfs_static}"},
+ Command: `${apex_ls} -Z ${in} > ${out}.fc` +
+ ` && ${apex_sepolicy_tests} -f ${out}.fc --partition ${partition_tag} && touch ${out}`,
+ CommandDeps: []string{"${apex_sepolicy_tests}", "${apex_ls}"},
Description: "run apex_sepolicy_tests",
- })
+ }, "partition_tag")
apexLinkerconfigValidationRule = pctx.StaticRule("apexLinkerconfigValidationRule", blueprint.RuleParams{
Command: `${conv_linker_config} validate --type apex ${image_dir} && touch ${out}`,
@@ -918,9 +919,8 @@
}
var validations android.Paths
validations = append(validations, runApexLinkerconfigValidation(ctx, unsignedOutputFile, imageDir))
- // TODO(b/279688635) deapexer supports [ext4]
- if !a.skipValidation(apexSepolicyTests) && suffix == imageApexSuffix && ext4 == a.payloadFsType {
- validations = append(validations, runApexSepolicyTests(ctx, unsignedOutputFile))
+ if !a.skipValidation(apexSepolicyTests) && android.InList(a.payloadFsType, []fsType{ext4, erofs}) {
+ validations = append(validations, runApexSepolicyTests(ctx, a, unsignedOutputFile))
}
if !a.testApex && len(a.properties.Unwanted_transitive_deps) > 0 {
validations = append(validations,
@@ -1204,14 +1204,17 @@
// Runs apex_sepolicy_tests
//
-// $ deapexer list -Z {apex_file} > {file_contexts}
+// $ apex-ls -Z {apex_file} > {file_contexts}
// $ apex_sepolicy_tests -f {file_contexts}
-func runApexSepolicyTests(ctx android.ModuleContext, apexFile android.Path) android.Path {
+func runApexSepolicyTests(ctx android.ModuleContext, a *apexBundle, apexFile android.Path) android.Path {
timestamp := android.PathForModuleOut(ctx, "apex_sepolicy_tests.timestamp")
ctx.Build(pctx, android.BuildParams{
Rule: apexSepolicyTestsRule,
Input: apexFile,
Output: timestamp,
+ Args: map[string]string{
+ "partition_tag": a.PartitionTag(ctx.DeviceConfig()),
+ },
})
return timestamp
}
diff --git a/apex/key.go b/apex/key.go
index 9fa9d1e..1622c65 100644
--- a/apex/key.go
+++ b/apex/key.go
@@ -182,6 +182,7 @@
}
func (_ *allApexCerts) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ var avbpubkeys android.Paths
var certificatesPem android.Paths
ctx.VisitDirectDeps(func(m android.Module) {
if apex, ok := m.(*apexBundle); ok {
@@ -194,9 +195,12 @@
}
}
certificatesPem = append(certificatesPem, pem)
+ // avbpubkey for signing the apex payload
+ avbpubkeys = append(avbpubkeys, apex.publicKeyFile)
}
})
certificatesPem = android.SortedUniquePaths(certificatesPem) // For hermiticity
+ avbpubkeys = android.SortedUniquePaths(avbpubkeys) // For hermiticity
var certificatesDer android.Paths
for index, certificatePem := range certificatesPem {
certificateDer := android.PathForModuleOut(ctx, fmt.Sprintf("x509.%v.der", index))
@@ -209,6 +213,7 @@
}
ctx.SetOutputFiles(certificatesPem, ".pem")
ctx.SetOutputFiles(certificatesDer, ".der")
+ ctx.SetOutputFiles(avbpubkeys, ".avbpubkey")
}
func (_ *allApexCerts) GenerateSingletonBuildActions(ctx android.SingletonContext) {
diff --git a/cc/cc.go b/cc/cc.go
index 97d4533..af1b259 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -34,7 +34,6 @@
"android/soong/android"
"android/soong/cc/config"
"android/soong/fuzz"
- "android/soong/genrule"
)
type CcMakeVarsInfo struct {
@@ -79,49 +78,91 @@
// list of modules that should be dynamically linked into this module.
SharedLibs proptools.Configurable[[]string]
// list of modules that should only provide headers for this module.
- HeaderLibs proptools.Configurable[[]string]
- UnstrippedOutputFile android.Path
+ HeaderLibs proptools.Configurable[[]string]
+ ImplementationModuleName *string
BinaryDecoratorInfo *BinaryDecoratorInfo
LibraryDecoratorInfo *LibraryDecoratorInfo
TestBinaryInfo *TestBinaryInfo
BenchmarkDecoratorInfo *BenchmarkDecoratorInfo
ObjectLinkerInfo *ObjectLinkerInfo
+ StubDecoratorInfo *StubDecoratorInfo
}
type BinaryDecoratorInfo struct{}
type LibraryDecoratorInfo struct {
ExportIncludeDirs proptools.Configurable[[]string]
+ InjectBsslHash bool
}
-type LibraryInfo struct {
- StubsVersion string
+type SnapshotInfo struct {
+ SnapshotAndroidMkSuffix string
}
type TestBinaryInfo struct {
Gtest bool
}
type BenchmarkDecoratorInfo struct{}
+
+type StubDecoratorInfo struct{}
+
type ObjectLinkerInfo struct{}
+type LibraryInfo struct {
+ BuildStubs bool
+}
+
// Common info about the cc module.
type CcInfo struct {
- HasStubsVariants bool
IsPrebuilt bool
CmakeSnapshotSupported bool
+ HasLlndkStubs bool
CompilerInfo *CompilerInfo
LinkerInfo *LinkerInfo
+ SnapshotInfo *SnapshotInfo
LibraryInfo *LibraryInfo
}
-var CcInfoProvider = blueprint.NewProvider[CcInfo]()
+var CcInfoProvider = blueprint.NewProvider[*CcInfo]()
type LinkableInfo struct {
// StaticExecutable returns true if this is a binary module with "static_executable: true".
- StaticExecutable bool
+ StaticExecutable bool
+ Static bool
+ Shared bool
+ HasStubsVariants bool
+ StubsVersion string
+ IsStubs bool
+ UnstrippedOutputFile android.Path
+ OutputFile android.OptionalPath
+ CoverageFiles android.Paths
+ SAbiDumpFiles android.Paths
+ CcLibrary bool
+ CcLibraryInterface bool
+ RustLibraryInterface bool
+ // CrateName returns the crateName for a Rust library
+ CrateName string
+ // DepFlags returns a slice of Rustc string flags
+ ExportedCrateLinkDirs []string
+ // This can be different from the one on CommonModuleInfo
+ BaseModuleName string
+ HasNonSystemVariants bool
+ IsLlndk bool
+ InVendorOrProduct bool
+ // SubName returns the modules SubName, used for image and NDK/SDK variations.
+ SubName string
+ InRamdisk bool
+ OnlyInRamdisk bool
+ InVendorRamdisk bool
+ OnlyInVendorRamdisk bool
+ InRecovery bool
+ OnlyInRecovery bool
+ Installable *bool
+ // RelativeInstallPath returns the relative install path for this module.
+ RelativeInstallPath string
}
-var LinkableInfoKey = blueprint.NewProvider[LinkableInfo]()
+var LinkableInfoProvider = blueprint.NewProvider[*LinkableInfo]()
func init() {
RegisterCCBuildComponents(android.InitRegistrationContext)
@@ -2181,14 +2222,24 @@
android.SetProvider(ctx, CcObjectInfoProvider, ccObjectInfo)
}
- android.SetProvider(ctx, LinkableInfoKey, LinkableInfo{
- StaticExecutable: c.StaticExecutable(),
- })
+ linkableInfo := CreateCommonLinkableInfo(c)
+ if lib, ok := c.linker.(versionedInterface); ok {
+ linkableInfo.StubsVersion = lib.stubsVersion()
+ }
+ if c.linker != nil {
+ if library, ok := c.linker.(libraryInterface); ok {
+ linkableInfo.Static = library.static()
+ linkableInfo.Shared = library.shared()
+ linkableInfo.CoverageFiles = library.objs().coverageFiles
+ linkableInfo.SAbiDumpFiles = library.objs().sAbiDumpFiles
+ }
+ }
+ android.SetProvider(ctx, LinkableInfoProvider, linkableInfo)
ccInfo := CcInfo{
- HasStubsVariants: c.HasStubsVariants(),
IsPrebuilt: c.IsPrebuilt(),
CmakeSnapshotSupported: proptools.Bool(c.Properties.Cmake_snapshot_supported),
+ HasLlndkStubs: c.HasLlndkStubs(),
}
if c.compiler != nil {
ccInfo.CompilerInfo = &CompilerInfo{
@@ -2210,17 +2261,18 @@
}
if c.linker != nil {
ccInfo.LinkerInfo = &LinkerInfo{
- WholeStaticLibs: c.linker.baseLinkerProps().Whole_static_libs,
- StaticLibs: c.linker.baseLinkerProps().Static_libs,
- SharedLibs: c.linker.baseLinkerProps().Shared_libs,
- HeaderLibs: c.linker.baseLinkerProps().Header_libs,
- UnstrippedOutputFile: c.UnstrippedOutputFile(),
+ WholeStaticLibs: c.linker.baseLinkerProps().Whole_static_libs,
+ StaticLibs: c.linker.baseLinkerProps().Static_libs,
+ SharedLibs: c.linker.baseLinkerProps().Shared_libs,
+ HeaderLibs: c.linker.baseLinkerProps().Header_libs,
}
switch decorator := c.linker.(type) {
case *binaryDecorator:
ccInfo.LinkerInfo.BinaryDecoratorInfo = &BinaryDecoratorInfo{}
case *libraryDecorator:
- ccInfo.LinkerInfo.LibraryDecoratorInfo = &LibraryDecoratorInfo{}
+ ccInfo.LinkerInfo.LibraryDecoratorInfo = &LibraryDecoratorInfo{
+ InjectBsslHash: Bool(c.linker.(*libraryDecorator).Properties.Inject_bssl_hash),
+ }
case *testBinary:
ccInfo.LinkerInfo.TestBinaryInfo = &TestBinaryInfo{
Gtest: decorator.testDecorator.gtest(),
@@ -2229,14 +2281,26 @@
ccInfo.LinkerInfo.BenchmarkDecoratorInfo = &BenchmarkDecoratorInfo{}
case *objectLinker:
ccInfo.LinkerInfo.ObjectLinkerInfo = &ObjectLinkerInfo{}
+ case *stubDecorator:
+ ccInfo.LinkerInfo.StubDecoratorInfo = &StubDecoratorInfo{}
+ }
+
+ if s, ok := c.linker.(SnapshotInterface); ok {
+ ccInfo.SnapshotInfo = &SnapshotInfo{
+ SnapshotAndroidMkSuffix: s.SnapshotAndroidMkSuffix(),
+ }
+ }
+ if v, ok := c.linker.(versionedInterface); ok {
+ name := v.implementationModuleName(ctx.OtherModuleName(c))
+ ccInfo.LinkerInfo.ImplementationModuleName = &name
}
}
if c.library != nil {
ccInfo.LibraryInfo = &LibraryInfo{
- StubsVersion: c.library.stubsVersion(),
+ BuildStubs: c.library.buildStubs(),
}
}
- android.SetProvider(ctx, CcInfoProvider, ccInfo)
+ android.SetProvider(ctx, CcInfoProvider, &ccInfo)
c.setOutputFiles(ctx)
@@ -2245,6 +2309,32 @@
}
}
+func CreateCommonLinkableInfo(mod LinkableInterface) *LinkableInfo {
+ return &LinkableInfo{
+ StaticExecutable: mod.StaticExecutable(),
+ HasStubsVariants: mod.HasStubsVariants(),
+ OutputFile: mod.OutputFile(),
+ UnstrippedOutputFile: mod.UnstrippedOutputFile(),
+ IsStubs: mod.IsStubs(),
+ CcLibrary: mod.CcLibrary(),
+ CcLibraryInterface: mod.CcLibraryInterface(),
+ RustLibraryInterface: mod.RustLibraryInterface(),
+ BaseModuleName: mod.BaseModuleName(),
+ IsLlndk: mod.IsLlndk(),
+ HasNonSystemVariants: mod.HasNonSystemVariants(),
+ SubName: mod.SubName(),
+ InVendorOrProduct: mod.InVendorOrProduct(),
+ InRamdisk: mod.InRamdisk(),
+ OnlyInRamdisk: mod.OnlyInRamdisk(),
+ InVendorRamdisk: mod.InVendorRamdisk(),
+ OnlyInVendorRamdisk: mod.OnlyInVendorRamdisk(),
+ InRecovery: mod.InRecovery(),
+ OnlyInRecovery: mod.OnlyInRecovery(),
+ Installable: mod.Installable(),
+ RelativeInstallPath: mod.RelativeInstallPath(),
+ }
+}
+
func setOutputFilesIfNotEmpty(ctx ModuleContext, files android.Paths, tag string) {
if len(files) > 0 {
ctx.SetOutputFiles(files, tag)
@@ -3070,7 +3160,7 @@
skipModuleList := map[string]bool{}
- ctx.VisitDirectDeps(func(dep android.Module) {
+ ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
depName := ctx.OtherModuleName(dep)
depTag := ctx.OtherModuleDependencyTag(dep)
@@ -3079,8 +3169,17 @@
return
}
+ var ccInfo *CcInfo
+ v, hasCcInfo := android.OtherModuleProvider(ctx, dep, CcInfoProvider)
+ if hasCcInfo {
+ ccInfo = v
+ }
+ linkableInfo, hasLinkableInfo := android.OtherModuleProvider(ctx, dep, LinkableInfoProvider)
if depTag == android.DarwinUniversalVariantTag {
- depPaths.DarwinSecondArchOutput = dep.(*Module).OutputFile()
+ if !hasCcInfo {
+ panic(fmt.Errorf("dep is not a cc module: %s", dep.String()))
+ }
+ depPaths.DarwinSecondArchOutput = linkableInfo.OutputFile
return
}
@@ -3093,34 +3192,32 @@
}
}
- ccDep, ok := dep.(LinkableInterface)
- if !ok {
-
+ if !hasLinkableInfo {
// handling for a few module types that aren't cc Module but that are also supported
+ genRule, ok := android.OtherModuleProvider(ctx, dep, android.GeneratedSourceInfoProvider)
switch depTag {
case genSourceDepTag:
- if genRule, ok := dep.(genrule.SourceFileGenerator); ok {
+ if ok {
depPaths.GeneratedSources = append(depPaths.GeneratedSources,
- genRule.GeneratedSourceFiles()...)
+ genRule.GeneratedSourceFiles...)
} else {
ctx.ModuleErrorf("module %q is not a gensrcs or genrule", depName)
}
// Support exported headers from a generated_sources dependency
fallthrough
case genHeaderDepTag, genHeaderExportDepTag:
- if genRule, ok := dep.(genrule.SourceFileGenerator); ok {
+ if ok {
depPaths.GeneratedDeps = append(depPaths.GeneratedDeps,
- genRule.GeneratedDeps()...)
- dirs := genRule.GeneratedHeaderDirs()
+ genRule.GeneratedDeps...)
+ dirs := genRule.GeneratedHeaderDirs
depPaths.IncludeDirs = append(depPaths.IncludeDirs, dirs...)
if depTag == genHeaderExportDepTag {
depPaths.ReexportedDirs = append(depPaths.ReexportedDirs, dirs...)
depPaths.ReexportedGeneratedHeaders = append(depPaths.ReexportedGeneratedHeaders,
- genRule.GeneratedSourceFiles()...)
- depPaths.ReexportedDeps = append(depPaths.ReexportedDeps, genRule.GeneratedDeps()...)
+ genRule.GeneratedSourceFiles...)
+ depPaths.ReexportedDeps = append(depPaths.ReexportedDeps, genRule.GeneratedDeps...)
// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
c.sabi.Properties.ReexportedIncludes = append(c.sabi.Properties.ReexportedIncludes, dirs.Strings()...)
-
}
} else {
ctx.ModuleErrorf("module %q is not a genrule", depName)
@@ -3141,13 +3238,14 @@
return
}
- if dep.Target().Os != ctx.Os() {
+ commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoKey)
+ if commonInfo.Target.Os != ctx.Os() {
ctx.ModuleErrorf("OS mismatch between %q (%s) and %q (%s)", ctx.ModuleName(), ctx.Os().Name, depName, dep.Target().Os.Name)
return
}
- if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
+ if commonInfo.Target.Arch.ArchType != ctx.Arch().ArchType {
ctx.ModuleErrorf("Arch mismatch between %q(%v) and %q(%v)",
- ctx.ModuleName(), ctx.Arch().ArchType, depName, dep.Target().Arch.ArchType)
+ ctx.ModuleName(), ctx.Arch().ArchType, depName, commonInfo.Target.Arch.ArchType)
return
}
@@ -3172,7 +3270,7 @@
depPaths.LlndkSystemIncludeDirs = append(depPaths.LlndkSystemIncludeDirs, depExporterInfo.SystemIncludeDirs...)
}
- linkFile := ccDep.OutputFile()
+ linkFile := linkableInfo.OutputFile
if libDepTag, ok := depTag.(libraryDependencyTag); ok {
// Only use static unwinder for legacy (min_sdk_version = 29) apexes (b/144430859)
@@ -3250,8 +3348,8 @@
}
case libDepTag.static():
- if ccDep.RustLibraryInterface() {
- rlibDep := RustRlibDep{LibPath: linkFile.Path(), CrateName: ccDep.CrateName(), LinkDirs: ccDep.ExportedCrateLinkDirs()}
+ if linkableInfo.RustLibraryInterface {
+ rlibDep := RustRlibDep{LibPath: linkFile.Path(), CrateName: linkableInfo.CrateName, LinkDirs: linkableInfo.ExportedCrateLinkDirs}
depPaths.RustRlibDeps = append(depPaths.RustRlibDeps, rlibDep)
depPaths.IncludeDirs = append(depPaths.IncludeDirs, depExporterInfo.IncludeDirs...)
if libDepTag.wholeStatic {
@@ -3328,8 +3426,8 @@
}
}
- if libDepTag.static() && !libDepTag.wholeStatic && !ccDep.RustLibraryInterface() {
- if !ccDep.CcLibraryInterface() || !ccDep.Static() {
+ if libDepTag.static() && !libDepTag.wholeStatic && !linkableInfo.RustLibraryInterface {
+ if !linkableInfo.CcLibraryInterface || !linkableInfo.Static {
ctx.ModuleErrorf("module %q not a static library", depName)
return
}
@@ -3337,16 +3435,15 @@
// When combining coverage files for shared libraries and executables, coverage files
// in static libraries act as if they were whole static libraries. The same goes for
// source based Abi dump files.
- if c, ok := ccDep.(*Module); ok {
- staticLib := c.linker.(libraryInterface)
+ if hasCcInfo {
depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles,
- staticLib.objs().coverageFiles...)
+ linkableInfo.CoverageFiles...)
depPaths.StaticLibObjs.sAbiDumpFiles = append(depPaths.StaticLibObjs.sAbiDumpFiles,
- staticLib.objs().sAbiDumpFiles...)
+ linkableInfo.SAbiDumpFiles...)
} else {
// Handle non-CC modules here
depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles,
- ccDep.CoverageFiles()...)
+ linkableInfo.CoverageFiles...)
}
}
@@ -3392,7 +3489,7 @@
c.sabi.Properties.ReexportedSystemIncludes, depExporterInfo.SystemIncludeDirs.Strings()...)
}
- makeLibName := MakeLibName(ctx, c, ccDep, ccDep.BaseModuleName()) + libDepTag.makeSuffix
+ makeLibName := MakeLibName(ccInfo, linkableInfo, &commonInfo, linkableInfo.BaseModuleName) + libDepTag.makeSuffix
switch {
case libDepTag.header():
c.Properties.AndroidMkHeaderLibs = append(
@@ -3403,7 +3500,7 @@
c.Properties.AndroidMkSharedLibs = append(
c.Properties.AndroidMkSharedLibs, makeLibName)
case libDepTag.static():
- if !ccDep.RustLibraryInterface() {
+ if !linkableInfo.RustLibraryInterface {
if libDepTag.wholeStatic {
c.Properties.AndroidMkWholeStaticLibs = append(
c.Properties.AndroidMkWholeStaticLibs, makeLibName)
@@ -3419,7 +3516,7 @@
switch depTag {
case runtimeDepTag:
c.Properties.AndroidMkRuntimeLibs = append(
- c.Properties.AndroidMkRuntimeLibs, MakeLibName(ctx, c, ccDep, ccDep.BaseModuleName())+libDepTag.makeSuffix)
+ c.Properties.AndroidMkRuntimeLibs, MakeLibName(ccInfo, linkableInfo, &commonInfo, linkableInfo.BaseModuleName)+libDepTag.makeSuffix)
case objDepTag:
depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path())
case CrtBeginDepTag:
@@ -3473,7 +3570,7 @@
useStubs := false
- if lib := moduleLibraryInterface(dep); lib.buildStubs() && inVendorOrProduct { // LLNDK
+ if android.OtherModuleProviderOrDefault(ctx, dep, LinkableInfoProvider).IsStubs && inVendorOrProduct { // LLNDK
if !apexInfo.IsForPlatform() {
// For platform libraries, use current version of LLNDK
// If this is for use_vendor apex we will apply the same rules
@@ -3485,7 +3582,7 @@
// platform APIs, use stubs only when it is from an APEX (and not from
// platform) However, for host, ramdisk, vendor_ramdisk, recovery or
// bootstrap modules, always link to non-stub variant
- isNotInPlatform := dep.(android.ApexModule).NotInPlatform()
+ isNotInPlatform := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoKey).NotInPlatform
useStubs = isNotInPlatform && !bootstrap
} else {
@@ -3564,32 +3661,29 @@
return libName
}
-func MakeLibName(ctx android.ModuleContext, c LinkableInterface, ccDep LinkableInterface, depName string) string {
+func MakeLibName(ccInfo *CcInfo, linkableInfo *LinkableInfo, commonInfo *android.CommonModuleInfo, depName string) string {
libName := BaseLibName(depName)
- ccDepModule, _ := ccDep.(*Module)
- isLLndk := ccDepModule != nil && ccDepModule.IsLlndk()
- nonSystemVariantsExist := ccDep.HasNonSystemVariants() || isLLndk
+ isLLndk := ccInfo != nil && linkableInfo.IsLlndk
+ nonSystemVariantsExist := linkableInfo.HasNonSystemVariants || isLLndk
- if ccDepModule != nil {
+ if ccInfo != nil {
// Use base module name for snapshots when exporting to Makefile.
- if snapshotPrebuilt, ok := ccDepModule.linker.(SnapshotInterface); ok {
- baseName := ccDepModule.BaseModuleName()
-
- return baseName + snapshotPrebuilt.SnapshotAndroidMkSuffix()
+ if ccInfo.SnapshotInfo != nil {
+ return linkableInfo.BaseModuleName + ccInfo.SnapshotInfo.SnapshotAndroidMkSuffix
}
}
- if ccDep.InVendorOrProduct() && nonSystemVariantsExist {
+ if linkableInfo.InVendorOrProduct && nonSystemVariantsExist {
// The vendor and product modules in Make will have been renamed to not conflict with the
// core module, so update the dependency name here accordingly.
- return libName + ccDep.SubName()
- } else if ccDep.InRamdisk() && !ccDep.OnlyInRamdisk() {
+ return libName + linkableInfo.SubName
+ } else if linkableInfo.InRamdisk && !linkableInfo.OnlyInRamdisk {
return libName + RamdiskSuffix
- } else if ccDep.InVendorRamdisk() && !ccDep.OnlyInVendorRamdisk() {
+ } else if linkableInfo.InVendorRamdisk && !linkableInfo.OnlyInVendorRamdisk {
return libName + VendorRamdiskSuffix
- } else if ccDep.InRecovery() && !ccDep.OnlyInRecovery() {
+ } else if linkableInfo.InRecovery && !linkableInfo.OnlyInRecovery {
return libName + RecoverySuffix
- } else if ccDep.Target().NativeBridge == android.NativeBridgeEnabled {
+ } else if commonInfo.Target.NativeBridge == android.NativeBridgeEnabled {
return libName + NativeBridgeSuffix
} else {
return libName
diff --git a/cc/cmake_snapshot.go b/cc/cmake_snapshot.go
index a40b863..71fbcce 100644
--- a/cc/cmake_snapshot.go
+++ b/cc/cmake_snapshot.go
@@ -393,7 +393,7 @@
}{
&ctx,
dep,
- &ccInfo,
+ ccInfo,
m,
&pprop,
})
diff --git a/cc/config/darwin_host.go b/cc/config/darwin_host.go
index 1783f49..716965a 100644
--- a/cc/config/darwin_host.go
+++ b/cc/config/darwin_host.go
@@ -54,6 +54,7 @@
"12",
"13",
"14",
+ "15",
}
darwinAvailableLibraries = append(
diff --git a/cc/config/global.go b/cc/config/global.go
index b19682d..d969e97 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -366,8 +366,6 @@
"-Wno-array-parameter",
"-Wno-gnu-offsetof-extensions",
"-Wno-pessimizing-move",
- // TODO: Enable this warning http://b/315245071
- "-Wno-fortify-source",
}
llvmNextExtraCommonGlobalCflags = []string{
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index 1f6cf23..505ddfa 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -112,6 +112,7 @@
"imagehlp",
"iphlpapi",
"netapi32",
+ "ntdll",
"oleaut32",
"ole32",
"opengl32",
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 911a81c..056b0da 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -211,29 +211,30 @@
moduleInfoJSON.Class = []string{"EXECUTABLES"}
}
-// IsValidSharedDependency takes a module and determines if it is a unique shared library
+// isValidSharedDependency takes a module and determines if it is a unique shared library
// that should be installed in the fuzz target output directories. This function
// returns true, unless:
// - The module is not an installable shared library, or
// - The module is a header or stub, or
// - The module is a prebuilt and its source is available, or
// - The module is a versioned member of an SDK snapshot.
-func IsValidSharedDependency(dependency android.Module) bool {
+func isValidSharedDependency(ctx android.ModuleContext, dependency android.ModuleProxy) bool {
// TODO(b/144090547): We should be parsing these modules using
// ModuleDependencyTag instead of the current brute-force checking.
- linkable, ok := dependency.(LinkableInterface)
- if !ok || !linkable.CcLibraryInterface() {
+ linkable, ok := android.OtherModuleProvider(ctx, dependency, LinkableInfoProvider)
+ if !ok || !linkable.CcLibraryInterface {
// Discard non-linkables.
return false
}
- if !linkable.Shared() {
+ if !linkable.Shared {
// Discard static libs.
return false
}
- if lib := moduleLibraryInterface(dependency); lib != nil && lib.buildStubs() && linkable.CcLibrary() {
+ ccInfo, hasCcInfo := android.OtherModuleProvider(ctx, dependency, CcInfoProvider)
+ if hasCcInfo && ccInfo.LibraryInfo != nil && ccInfo.LibraryInfo.BuildStubs && linkable.CcLibrary {
// Discard stubs libs (only CCLibrary variants). Prebuilt libraries should not
// be excluded on the basis of they're not CCLibrary()'s.
return false
@@ -242,13 +243,13 @@
// We discarded module stubs libraries above, but the LLNDK prebuilts stubs
// libraries must be handled differently - by looking for the stubDecorator.
// Discard LLNDK prebuilts stubs as well.
- if ccLibrary, isCcLibrary := dependency.(*Module); isCcLibrary {
- if _, isLLndkStubLibrary := ccLibrary.linker.(*stubDecorator); isLLndkStubLibrary {
+ if hasCcInfo {
+ if ccInfo.LinkerInfo.StubDecoratorInfo != nil {
return false
}
// Discard installable:false libraries because they are expected to be absent
// in runtime.
- if !proptools.BoolDefault(ccLibrary.Installable(), true) {
+ if !proptools.BoolDefault(linkable.Installable, true) {
return false
}
}
@@ -256,7 +257,7 @@
// If the same library is present both as source and a prebuilt we must pick
// only one to avoid a conflict. Always prefer the source since the prebuilt
// probably won't be built with sanitizers enabled.
- if prebuilt := android.GetEmbeddedPrebuilt(dependency); prebuilt != nil && prebuilt.SourceExists() {
+ if prebuilt, ok := android.OtherModuleProvider(ctx, dependency, android.PrebuiltModuleInfoProvider); ok && prebuilt.SourceExists {
return false
}
@@ -607,17 +608,17 @@
// VisitDirectDeps is used first to avoid incorrectly using the core libraries (sanitizer
// runtimes, libc, libdl, etc.) from a dependency. This may cause issues when dependencies
// have explicit sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
-func CollectAllSharedDependencies(ctx android.ModuleContext) (android.RuleBuilderInstalls, []android.Module) {
+func CollectAllSharedDependencies(ctx android.ModuleContext) (android.RuleBuilderInstalls, []android.ModuleProxy) {
seen := make(map[string]bool)
recursed := make(map[string]bool)
- deps := []android.Module{}
+ deps := []android.ModuleProxy{}
var sharedLibraries android.RuleBuilderInstalls
// Enumerate the first level of dependencies, as we discard all non-library
// modules in the BFS loop below.
- ctx.VisitDirectDeps(func(dep android.Module) {
- if !IsValidSharedDependency(dep) {
+ ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
+ if !isValidSharedDependency(ctx, dep) {
return
}
sharedLibraryInfo, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, dep, SharedLibraryInfoProvider)
@@ -635,19 +636,21 @@
sharedLibraries = append(sharedLibraries, ruleBuilderInstall)
})
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ ctx.WalkDepsProxy(func(child, _ android.ModuleProxy) bool {
// If this is a Rust module which is not rust_ffi_shared, we still want to bundle any transitive
// shared dependencies (even for rust_ffi_static)
- if rustmod, ok := child.(LinkableInterface); ok && rustmod.RustLibraryInterface() && !rustmod.Shared() {
- if recursed[ctx.OtherModuleName(child)] {
- return false
+ if info, ok := android.OtherModuleProvider(ctx, child, LinkableInfoProvider); ok {
+ if info.RustLibraryInterface && !info.Shared {
+ if recursed[ctx.OtherModuleName(child)] {
+ return false
+ }
+ recursed[ctx.OtherModuleName(child)] = true
+ return true
}
- recursed[ctx.OtherModuleName(child)] = true
- return true
}
- if !IsValidSharedDependency(child) {
+ if !isValidSharedDependency(ctx, child) {
return false
}
sharedLibraryInfo, hasSharedLibraryInfo := android.OtherModuleProvider(ctx, child, SharedLibraryInfoProvider)
diff --git a/cc/library.go b/cc/library.go
index c9114fd..0566182 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1195,7 +1195,7 @@
library.linkSAbiDumpFiles(ctx, deps, objs, fileName, unstrippedOutputFile)
var transitiveStaticLibrariesForOrdering depset.DepSet[android.Path]
- if static := ctx.GetDirectDepsWithTag(staticVariantTag); len(static) > 0 {
+ if static := ctx.GetDirectDepsProxyWithTag(staticVariantTag); len(static) > 0 {
s, _ := android.OtherModuleProvider(ctx, static[0], StaticLibraryInfoProvider)
transitiveStaticLibrariesForOrdering = s.TransitiveStaticLibrariesForOrdering
}
@@ -1225,12 +1225,11 @@
continue
}
flagInfo, _ := android.OtherModuleProvider(ctx, stub, FlagExporterInfoProvider)
- ccInfo, ok := android.OtherModuleProvider(ctx, stub, CcInfoProvider)
- if !ok || ccInfo.LibraryInfo == nil {
- panic(fmt.Errorf("couldn't find library info for %s", stub))
+ if _, ok = android.OtherModuleProvider(ctx, stub, CcInfoProvider); !ok {
+ panic(fmt.Errorf("stub is not a cc module %s", stub))
}
stubsInfo = append(stubsInfo, SharedStubLibrary{
- Version: ccInfo.LibraryInfo.StubsVersion,
+ Version: android.OtherModuleProviderOrDefault(ctx, stub, LinkableInfoProvider).StubsVersion,
SharedLibraryInfo: stubInfo,
FlagExporterInfo: flagInfo,
})
@@ -1387,6 +1386,11 @@
extraFlags = append(extraFlags,
"-allow-unreferenced-changes",
"-allow-unreferenced-elf-symbol-changes")
+ // The functions in standard libraries are not always declared in the headers.
+ // Allow them to be added or removed without changing the symbols.
+ if isBionic(ctx.ModuleName()) {
+ extraFlags = append(extraFlags, "-allow-adding-removing-referenced-apis")
+ }
}
if isLlndk {
extraFlags = append(extraFlags, "-consider-opaque-types-different")
@@ -2409,13 +2413,11 @@
inject *bool, fileName string) android.ModuleOutPath {
// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries.
injectBoringSSLHash := Bool(inject)
- ctx.VisitDirectDeps(func(dep android.Module) {
+ ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
if tag, ok := ctx.OtherModuleDependencyTag(dep).(libraryDependencyTag); ok && tag.static() {
- if cc, ok := dep.(*Module); ok {
- if library, ok := cc.linker.(*libraryDecorator); ok {
- if Bool(library.Properties.Inject_bssl_hash) {
- injectBoringSSLHash = true
- }
+ if ccInfo, ok := android.OtherModuleProvider(ctx, dep, CcInfoProvider); ok && ccInfo.LinkerInfo.LibraryDecoratorInfo != nil {
+ if ccInfo.LinkerInfo.LibraryDecoratorInfo.InjectBsslHash {
+ injectBoringSSLHash = true
}
}
}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 197a4b2..27a9f66 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -302,12 +302,11 @@
ctx.ModuleErrorf("Could not find implementation for stub: ")
return nil
}
- info, ok := android.OtherModuleProvider(ctx, *dep, CcInfoProvider)
- if !ok {
+ if _, ok := android.OtherModuleProvider(ctx, *dep, CcInfoProvider); !ok {
ctx.ModuleErrorf("Implementation for stub is not correct module type")
return nil
}
- output := info.LinkerInfo.UnstrippedOutputFile
+ output := android.OtherModuleProviderOrDefault(ctx, *dep, LinkableInfoProvider).UnstrippedOutputFile
if output == nil {
ctx.ModuleErrorf("implementation module (%s) has no output", *dep)
return nil
diff --git a/cc/stub_library.go b/cc/stub_library.go
index 5911be0..75d649f 100644
--- a/cc/stub_library.go
+++ b/cc/stub_library.go
@@ -38,8 +38,8 @@
}
// Check if the module defines stub, or itself is stub
-func IsStubTarget(m *Module) bool {
- return m.IsStubs() || m.HasStubsVariants()
+func IsStubTarget(info *LinkableInfo) bool {
+ return info != nil && (info.IsStubs || info.HasStubsVariants)
}
// Get target file name to be installed from this module
@@ -59,7 +59,7 @@
vendorStubLibraryMap := make(map[string]bool)
ctx.VisitAllModules(func(module android.Module) {
if m, ok := module.(*Module); ok {
- if IsStubTarget(m) {
+ if IsStubTarget(android.OtherModuleProviderOrDefault(ctx, m, LinkableInfoProvider)) {
if name := getInstalledFileName(ctx, m); name != "" {
stubLibraryMap[name] = true
if m.InVendor() {
diff --git a/cc/test.go b/cc/test.go
index abec19a..abf9162 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -342,28 +342,28 @@
test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath})
}
- ctx.VisitDirectDepsWithTag(dataLibDepTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(dataLibDepTag, func(dep android.ModuleProxy) {
depName := ctx.OtherModuleName(dep)
- linkableDep, ok := dep.(LinkableInterface)
+ linkableDep, ok := android.OtherModuleProvider(ctx, dep, LinkableInfoProvider)
if !ok {
ctx.ModuleErrorf("data_lib %q is not a LinkableInterface module", depName)
}
- if linkableDep.OutputFile().Valid() {
+ if linkableDep.OutputFile.Valid() {
test.data = append(test.data,
- android.DataPath{SrcPath: linkableDep.OutputFile().Path(),
- RelativeInstallPath: linkableDep.RelativeInstallPath()})
+ android.DataPath{SrcPath: linkableDep.OutputFile.Path(),
+ RelativeInstallPath: linkableDep.RelativeInstallPath})
}
})
- ctx.VisitDirectDepsWithTag(dataBinDepTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(dataBinDepTag, func(dep android.ModuleProxy) {
depName := ctx.OtherModuleName(dep)
- linkableDep, ok := dep.(LinkableInterface)
+ linkableDep, ok := android.OtherModuleProvider(ctx, dep, LinkableInfoProvider)
if !ok {
ctx.ModuleErrorf("data_bin %q is not a LinkableInterface module", depName)
}
- if linkableDep.OutputFile().Valid() {
+ if linkableDep.OutputFile.Valid() {
test.data = append(test.data,
- android.DataPath{SrcPath: linkableDep.OutputFile().Path(),
- RelativeInstallPath: linkableDep.RelativeInstallPath()})
+ android.DataPath{SrcPath: linkableDep.OutputFile.Path(),
+ RelativeInstallPath: linkableDep.RelativeInstallPath})
}
})
diff --git a/cc/tidy.go b/cc/tidy.go
index 18e6f35..2373658 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -220,7 +220,7 @@
// (1) Collect all obj/tidy files into OS-specific groups.
ctx.VisitAllModuleVariantProxies(module, func(variant android.ModuleProxy) {
- osName := android.OtherModuleProviderOrDefault(ctx, variant, android.CommonModuleInfoKey).CompileTarget.Os.Name
+ osName := android.OtherModuleProviderOrDefault(ctx, variant, android.CommonModuleInfoKey).Target.Os.Name
info := android.OtherModuleProviderOrDefault(ctx, variant, CcObjectInfoProvider)
addToOSGroup(osName, info.ObjFiles, allObjFileGroups, subsetObjFileGroups)
addToOSGroup(osName, info.TidyFiles, allTidyFileGroups, subsetTidyFileGroups)
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 6642023..cd4e9bd 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -64,6 +64,7 @@
flag.StringVar(&usedEnvFile, "used_env", "", "File containing used environment variables")
flag.StringVar(&cmdlineArgs.OutDir, "out", "", "the ninja builddir directory")
flag.StringVar(&cmdlineArgs.ModuleListFile, "l", "", "file that lists filepaths to parse")
+ flag.StringVar(&cmdlineArgs.KatiSuffix, "kati_suffix", "", "the suffix for kati and ninja files, so that different configurations don't clobber each other")
// Debug flags
flag.StringVar(&delveListen, "delve_listen", "", "Delve port to listen on for debugging")
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 19e93ae..6a939e8 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -15,6 +15,9 @@
package filesystem
import (
+ "strings"
+ "sync/atomic"
+
"android/soong/android"
"github.com/google/blueprint"
@@ -44,21 +47,41 @@
Vbmeta_partitions []string
// Name of the userdata partition filesystem module
Userdata_partition_name *string
+ // Name of the system_dlkm partition filesystem module
+ System_dlkm_partition_name *string
+ // Name of the vendor_dlkm partition filesystem module
+ Vendor_dlkm_partition_name *string
+ // Name of the odm_dlkm partition filesystem module
+ Odm_dlkm_partition_name *string
+}
+
+type DeviceProperties struct {
+ // Path to the prebuilt bootloader that would be copied to PRODUCT_OUT
+ Bootloader *string `android:"path"`
+ // Path to android-info.txt file containing board specific info.
+ Android_info *string `android:"path"`
}
type androidDevice struct {
android.ModuleBase
partitionProps PartitionNameProperties
+
+ deviceProps DeviceProperties
+
+ // copyToProductOutTimestamp for copying necessary files to PRODUCT_OUT
+ copyToProductOutTimestamp android.WritablePath
}
func AndroidDeviceFactory() android.Module {
module := &androidDevice{}
- module.AddProperties(&module.partitionProps)
- android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ module.AddProperties(&module.partitionProps, &module.deviceProps)
+ android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibFirst)
return module
}
+var numAutogeneratedAndroidDevicesOnceKey android.OnceKey = android.NewOnceKey("num_auto_generated_anroid_devices")
+
type partitionDepTagType struct {
blueprint.BaseDependencyTag
}
@@ -68,24 +91,95 @@
func (a *androidDevice) DepsMutator(ctx android.BottomUpMutatorContext) {
addDependencyIfDefined := func(dep *string) {
if dep != nil {
- ctx.AddFarVariationDependencies(nil, filesystemDepTag, proptools.String(dep))
+ ctx.AddDependency(ctx.Module(), filesystemDepTag, proptools.String(dep))
}
}
addDependencyIfDefined(a.partitionProps.Boot_partition_name)
+ addDependencyIfDefined(a.partitionProps.Init_boot_partition_name)
+ addDependencyIfDefined(a.partitionProps.Vendor_boot_partition_name)
addDependencyIfDefined(a.partitionProps.System_partition_name)
addDependencyIfDefined(a.partitionProps.System_ext_partition_name)
addDependencyIfDefined(a.partitionProps.Product_partition_name)
addDependencyIfDefined(a.partitionProps.Vendor_partition_name)
addDependencyIfDefined(a.partitionProps.Odm_partition_name)
addDependencyIfDefined(a.partitionProps.Userdata_partition_name)
+ addDependencyIfDefined(a.partitionProps.System_dlkm_partition_name)
+ addDependencyIfDefined(a.partitionProps.Vendor_dlkm_partition_name)
+ addDependencyIfDefined(a.partitionProps.Odm_dlkm_partition_name)
+ addDependencyIfDefined(a.partitionProps.Recovery_partition_name)
for _, vbmetaPartition := range a.partitionProps.Vbmeta_partitions {
ctx.AddDependency(ctx.Module(), filesystemDepTag, vbmetaPartition)
}
}
+func (a *androidDevice) copyToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, src android.Path, dest string) {
+ destPath := android.PathForModuleInPartitionInstall(ctx, "").Join(ctx, dest)
+ builder.Command().Text("rsync").Flag("-a").Flag("--checksum").Input(src).Text(destPath.String())
+}
+
+func (a *androidDevice) copyFilesToProductOut(ctx android.ModuleContext) {
+ a.copyToProductOutTimestamp = android.PathForModuleOut(ctx, "timestamp")
+ builder := android.NewRuleBuilder(pctx, ctx)
+ builder.Command().Text("touch").Output(a.copyToProductOutTimestamp)
+
+ // List all individual files to be copied to PRODUCT_OUT here
+ if a.deviceProps.Bootloader != nil {
+ a.copyToProductOut(ctx, builder, android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Bootloader)), "bootloader")
+ }
+
+ builder.Build("copy_to_product_out", "Copy files to PRODUCT_OUT")
+}
+
func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.buildTargetFilesZip(ctx)
+ var deps []android.Path
+ ctx.VisitDirectDepsWithTag(filesystemDepTag, func(m android.Module) {
+ imageOutput, ok := android.OtherModuleProvider(ctx, m, android.OutputFilesProvider)
+ if !ok {
+ ctx.ModuleErrorf("Partition module %s doesn't set OutputfilesProvider", m.Name())
+ }
+ if len(imageOutput.DefaultOutputFiles) != 1 {
+ ctx.ModuleErrorf("Partition module %s should provide exact 1 output file", m.Name())
+ }
+ deps = append(deps, imageOutput.DefaultOutputFiles[0])
+ })
+
+ a.copyFilesToProductOut(ctx)
+
+ allImagesStamp := android.PathForModuleOut(ctx, "all_images_stamp")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Touch,
+ Output: allImagesStamp,
+ Implicits: deps,
+ Validation: a.copyToProductOutTimestamp,
+ })
+ ctx.SetOutputFiles(android.Paths{allImagesStamp}, "")
+ ctx.CheckbuildFile(allImagesStamp)
+
+ if ctx.OtherModuleIsAutoGenerated(ctx.Module()) {
+ numAutogeneratedAndroidDevices := ctx.Config().Once(numAutogeneratedAndroidDevicesOnceKey, func() interface{} {
+ return &atomic.Int32{}
+ }).(*atomic.Int32)
+ total := numAutogeneratedAndroidDevices.Add(1)
+ if total > 1 {
+ // There should only be 1 autogenerated android_device module. That one will be
+ // made the default thing to build in soong-only builds.
+ ctx.ModuleErrorf("There cannot be more than 1 autogenerated android_device module")
+ }
+ }
+
+ if !ctx.Config().KatiEnabled() && ctx.OtherModuleIsAutoGenerated(ctx.Module()) {
+ // In soong-only builds, build this module by default.
+ // This is the analogue to this make code:
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/main.mk;l=1396;drc=6595459cdd8164a6008335f6372c9f97b9094060
+ ctx.Phony("droidcore-unbundled", allImagesStamp)
+ }
+}
+
+type targetFilesZipCopy struct {
+ srcModule *string
+ destSubdir string
}
func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext) {
@@ -95,14 +189,88 @@
builder := android.NewRuleBuilder(pctx, ctx)
builder.Command().Textf("rm -rf %s", targetFilesDir.String())
builder.Command().Textf("mkdir -p %s", targetFilesDir.String())
- if a.partitionProps.Vendor_partition_name != nil {
- fsInfo := a.getFilesystemInfo(ctx, *a.partitionProps.Vendor_partition_name)
- builder.Command().Textf("mkdir -p %s/VENDOR", targetFilesDir.String())
+ toCopy := []targetFilesZipCopy{
+ targetFilesZipCopy{a.partitionProps.System_partition_name, "SYSTEM"},
+ targetFilesZipCopy{a.partitionProps.System_ext_partition_name, "SYSTEM_EXT"},
+ targetFilesZipCopy{a.partitionProps.Product_partition_name, "PRODUCT"},
+ targetFilesZipCopy{a.partitionProps.Vendor_partition_name, "VENDOR"},
+ targetFilesZipCopy{a.partitionProps.Odm_partition_name, "ODM"},
+ targetFilesZipCopy{a.partitionProps.System_dlkm_partition_name, "SYSTEM_DLKM"},
+ targetFilesZipCopy{a.partitionProps.Vendor_dlkm_partition_name, "VENDOR_DLKM"},
+ targetFilesZipCopy{a.partitionProps.Odm_dlkm_partition_name, "ODM_DLKM"},
+ targetFilesZipCopy{a.partitionProps.Init_boot_partition_name, "BOOT/RAMDISK"},
+ targetFilesZipCopy{a.partitionProps.Init_boot_partition_name, "INIT_BOOT/RAMDISK"},
+ targetFilesZipCopy{a.partitionProps.Vendor_boot_partition_name, "VENDOR_BOOT/RAMDISK"},
+ }
+ // TODO: Handle cases where recovery files are copied to BOOT/ or RECOVERY/
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=6211-6219?q=core%2FMakefile&ss=android%2Fplatform%2Fsuperproject%2Fmain
+ if ctx.DeviceConfig().BoardMoveRecoveryResourcesToVendorBoot() {
+ toCopy = append(toCopy, targetFilesZipCopy{a.partitionProps.Recovery_partition_name, "VENDOR_BOOT/RAMDISK"})
+ }
+
+ // Create an IMAGES/ subdirectory
+ builder.Command().Textf("mkdir -p %s/IMAGES/", targetFilesDir.String())
+ if a.deviceProps.Bootloader != nil {
+ builder.Command().Textf("cp ").Input(android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Bootloader))).Textf(" %s/IMAGES/bootloader", targetFilesDir.String())
+ }
+
+ for _, zipCopy := range toCopy {
+ if zipCopy.srcModule == nil {
+ continue
+ }
+ fsInfo := a.getFilesystemInfo(ctx, *zipCopy.srcModule)
+ subdir := zipCopy.destSubdir
+ rootDirString := fsInfo.RootDir.String()
+ if subdir == "SYSTEM" {
+ rootDirString = rootDirString + "/system"
+ }
+ builder.Command().Textf("mkdir -p %s/%s", targetFilesDir.String(), subdir)
builder.Command().
BuiltTool("acp").
- Textf("-rd %s/. %s/VENDOR", fsInfo.RootDir, targetFilesDir).
+ Textf("-rd %s/. %s/%s", rootDirString, targetFilesDir, subdir).
Implicit(fsInfo.Output) // so that the staging dir is built
+
+ if subdir == "SYSTEM" {
+ // Create the ROOT partition in target_files.zip
+ builder.Command().Textf("rsync --links --exclude=system/* %s/ -r %s/ROOT", fsInfo.RootDir, targetFilesDir.String())
+ }
+ builder.Command().Textf("cp %s %s/IMAGES/", fsInfo.Output, targetFilesDir.String())
}
+ // Copy cmdline, kernel etc. files of boot images
+ if a.partitionProps.Vendor_boot_partition_name != nil {
+ bootImg := ctx.GetDirectDepWithTag(proptools.String(a.partitionProps.Vendor_boot_partition_name), filesystemDepTag)
+ bootImgInfo, _ := android.OtherModuleProvider(ctx, bootImg, BootimgInfoProvider)
+ builder.Command().Textf("echo %s > %s/VENDOR_BOOT/cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir)
+ builder.Command().Textf("echo %s > %s/VENDOR_BOOT/vendor_cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir)
+ if bootImgInfo.Dtb != nil {
+ builder.Command().Textf("cp %s %s/VENDOR_BOOT/dtb", bootImgInfo.Dtb, targetFilesDir)
+ }
+ if bootImgInfo.Bootconfig != nil {
+ builder.Command().Textf("cp %s %s/VENDOR_BOOT/vendor_bootconfig", bootImgInfo.Bootconfig, targetFilesDir)
+ }
+ }
+ if a.partitionProps.Boot_partition_name != nil {
+ bootImg := ctx.GetDirectDepWithTag(proptools.String(a.partitionProps.Boot_partition_name), filesystemDepTag)
+ bootImgInfo, _ := android.OtherModuleProvider(ctx, bootImg, BootimgInfoProvider)
+ builder.Command().Textf("echo %s > %s/BOOT/cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir)
+ if bootImgInfo.Dtb != nil {
+ builder.Command().Textf("cp %s %s/BOOT/dtb", bootImgInfo.Dtb, targetFilesDir)
+ }
+ if bootImgInfo.Kernel != nil {
+ builder.Command().Textf("cp %s %s/BOOT/kernel", bootImgInfo.Kernel, targetFilesDir)
+ // Even though kernel is not used to build vendor_boot, copy the kernel to VENDOR_BOOT to match the behavior of make packaging.
+ builder.Command().Textf("cp %s %s/VENDOR_BOOT/kernel", bootImgInfo.Kernel, targetFilesDir)
+ }
+ if bootImgInfo.Bootconfig != nil {
+ builder.Command().Textf("cp %s %s/BOOT/bootconfig", bootImgInfo.Bootconfig, targetFilesDir)
+ }
+ }
+
+ if a.deviceProps.Android_info != nil {
+ builder.Command().Textf("mkdir -p %s/OTA", targetFilesDir)
+ builder.Command().Textf("cp %s %s/OTA/android-info.txt", android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Android_info)), targetFilesDir)
+ }
+
builder.Command().
BuiltTool("soong_zip").
Text("-d").
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 36b1a18..0a3a177 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -197,12 +197,8 @@
ctx.PropertyErrorf("kernel_prebuilt", "boot partition must have kernel")
return
}
- var kernel android.Path
- if kernelProp != "" {
- kernel = android.PathForModuleSrc(ctx, kernelProp)
- }
- unsignedOutput := b.buildBootImage(ctx, kernel)
+ unsignedOutput := b.buildBootImage(ctx, b.getKernelPath(ctx))
output := unsignedOutput
if proptools.Bool(b.properties.Use_avb) {
@@ -213,7 +209,7 @@
case "default":
output = b.signImage(ctx, unsignedOutput)
case "make_legacy":
- output = b.addAvbFooter(ctx, unsignedOutput, kernel)
+ output = b.addAvbFooter(ctx, unsignedOutput, b.getKernelPath(ctx))
default:
ctx.PropertyErrorf("avb_mode", `Unknown value for avb_mode, expected "default" or "make_legacy", got: %q`, *b.properties.Avb_mode)
}
@@ -224,6 +220,58 @@
ctx.SetOutputFiles([]android.Path{output}, "")
b.output = output
+
+ // Set the Filesystem info of the ramdisk dependency.
+ // `android_device` will use this info to package `target_files.zip`
+ if ramdisk := proptools.String(b.properties.Ramdisk_module); ramdisk != "" {
+ ramdiskModule := ctx.GetDirectDepWithTag(ramdisk, bootimgRamdiskDep)
+ fsInfo, _ := android.OtherModuleProvider(ctx, ramdiskModule, FilesystemProvider)
+ android.SetProvider(ctx, FilesystemProvider, fsInfo)
+ }
+
+ // Set BootimgInfo for building target_files.zip
+ android.SetProvider(ctx, BootimgInfoProvider, BootimgInfo{
+ Cmdline: b.properties.Cmdline,
+ Kernel: b.getKernelPath(ctx),
+ Dtb: b.getDtbPath(ctx),
+ Bootconfig: b.getBootconfigPath(ctx),
+ })
+}
+
+var BootimgInfoProvider = blueprint.NewProvider[BootimgInfo]()
+
+type BootimgInfo struct {
+ Cmdline []string
+ Kernel android.Path
+ Dtb android.Path
+ Bootconfig android.Path
+}
+
+func (b *bootimg) getKernelPath(ctx android.ModuleContext) android.Path {
+ var kernelPath android.Path
+ kernelName := proptools.String(b.properties.Kernel_prebuilt)
+ if kernelName != "" {
+ kernelPath = android.PathForModuleSrc(ctx, kernelName)
+ }
+ return kernelPath
+}
+
+func (b *bootimg) getDtbPath(ctx android.ModuleContext) android.Path {
+ var dtbPath android.Path
+ dtbName := proptools.String(b.properties.Dtb_prebuilt)
+ if dtbName != "" {
+ dtbPath = android.PathForModuleSrc(ctx, dtbName)
+ }
+ return dtbPath
+}
+
+func (b *bootimg) getBootconfigPath(ctx android.ModuleContext) android.Path {
+ var bootconfigPath android.Path
+ bootconfigName := proptools.String(b.properties.Bootconfig)
+ if bootconfigName != "" {
+ bootconfigPath = android.PathForModuleSrc(ctx, bootconfigName)
+ }
+ return bootconfigPath
}
func (b *bootimg) buildBootImage(ctx android.ModuleContext, kernel android.Path) android.Path {
@@ -242,10 +290,8 @@
cmd.FlagWithArg("--os_patch_level ", ctx.Config().PlatformSecurityPatch())
}
- dtbName := proptools.String(b.properties.Dtb_prebuilt)
- if dtbName != "" {
- dtb := android.PathForModuleSrc(ctx, dtbName)
- cmd.FlagWithInput("--dtb ", dtb)
+ if b.getDtbPath(ctx) != nil {
+ cmd.FlagWithInput("--dtb ", b.getDtbPath(ctx))
}
cmdline := strings.Join(b.properties.Cmdline, " ")
@@ -372,6 +418,10 @@
cmd.FlagWithArg("--rollback_index ", strconv.FormatInt(*b.properties.Avb_rollback_index, 10))
}
+ if !ctx.Config().KatiEnabled() {
+ copyImageFileToProductOut(ctx, builder, b.bootImageType.String(), output)
+ }
+
builder.Build("add_avb_footer", fmt.Sprintf("Adding avb footer to %s", b.BaseModuleName()))
return output
}
@@ -387,6 +437,10 @@
Implicits(toolDeps).
Output(output)
+ if !ctx.Config().KatiEnabled() {
+ copyImageFileToProductOut(ctx, builder, b.bootImageType.String(), output)
+ }
+
builder.Build("sign_bootimg", fmt.Sprintf("Signing %s", b.BaseModuleName()))
return output
}
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 43fd390..993c46e 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -215,6 +215,9 @@
// Additional dependencies used for building android products
Android_filesystem_deps AndroidFilesystemDeps
+
+ // Name of the output. Default is $(module_name).img
+ Stem *string
}
type AndroidFilesystemDeps struct {
@@ -357,6 +360,14 @@
var FilesystemProvider = blueprint.NewProvider[FilesystemInfo]()
+type FilesystemDefaultsInfo struct {
+ // Identifies which partition this is for //visibility:any_system_image (and others) visibility
+ // checks, and will be used in the future for API surface checks.
+ PartitionType string
+}
+
+var FilesystemDefaultsInfoProvider = blueprint.NewProvider[FilesystemDefaultsInfo]()
+
func GetFsTypeFromString(ctx android.EarlyModuleContext, typeStr string) fsType {
switch typeStr {
case "ext4":
@@ -384,7 +395,7 @@
}
func (f *filesystem) installFileName() string {
- return f.BaseModuleName() + ".img"
+ return proptools.StringDefault(f.properties.Stem, f.BaseModuleName()+".img")
}
func (f *filesystem) partitionName() string {
@@ -459,6 +470,7 @@
FileListFile: fileListFile,
RootDir: rootDir,
})
+
f.fileListFile = fileListFile
if proptools.Bool(f.properties.Unchecked_module) {
@@ -524,12 +536,12 @@
ctx.PropertyErrorf("partition_type", "partition_type must be one of %s, found: %s", validPartitions, p.PartitionType())
}
- ctx.VisitDirectDepsWithTag(android.DefaultsDepTag, func(m android.Module) {
- if fdm, ok := m.(*filesystemDefaults); ok {
- if p.PartitionType() != fdm.PartitionType() {
+ ctx.VisitDirectDepsProxyWithTag(android.DefaultsDepTag, func(m android.ModuleProxy) {
+ if fdm, ok := android.OtherModuleProvider(ctx, m, FilesystemDefaultsInfoProvider); ok {
+ if p.PartitionType() != fdm.PartitionType {
ctx.PropertyErrorf("partition_type",
"%s doesn't match with the partition type %s of the filesystem default module %s",
- p.PartitionType(), fdm.PartitionType(), m.Name())
+ p.PartitionType(), fdm.PartitionType, m.Name())
}
}
})
@@ -593,11 +605,16 @@
}
func (f *filesystem) copyFilesToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) {
- if f.Name() != ctx.Config().SoongDefinedSystemImage() {
+ if !(f.Name() == ctx.Config().SoongDefinedSystemImage() || proptools.Bool(f.properties.Is_auto_generated)) {
return
}
installPath := android.PathForModuleInPartitionInstall(ctx, f.partitionName())
- builder.Command().Textf("cp -prf %s/* %s", rebasedDir, installPath)
+ builder.Command().Textf("rsync --checksum %s %s", rebasedDir, installPath)
+}
+
+func copyImageFileToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, partition string, output android.Path) {
+ copyDir := android.PathForModuleInPartitionInstall(ctx, "").Join(ctx, fmt.Sprintf("%s.img", partition))
+ builder.Command().Textf("rsync -a %s %s", output, copyDir)
}
func (f *filesystem) rootDirString() string {
@@ -651,6 +668,10 @@
Output(output).
Text(rootDir.String()) // directory where to find fs_config_files|dirs
+ if !ctx.Config().KatiEnabled() {
+ copyImageFileToProductOut(ctx, builder, f.partitionName(), output)
+ }
+
// rootDir is not deleted. Might be useful for quick inspection.
builder.Build("build_filesystem_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName()))
@@ -751,7 +772,10 @@
}
if timestamp := proptools.String(f.properties.Fake_timestamp); timestamp != "" {
addStr("timestamp", timestamp)
+ } else if ctx.Config().Getenv("USE_FIXED_TIMESTAMP_IMG_FILES") == "true" {
+ addStr("use_fixed_timestamp", "true")
}
+
if uuid := proptools.String(f.properties.Uuid); uuid != "" {
addStr("uuid", uuid)
addStr("hash_seed", uuid)
@@ -1063,6 +1087,9 @@
func (f *filesystemDefaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
validatePartitionType(ctx, f)
+ android.SetProvider(ctx, FilesystemDefaultsInfoProvider, FilesystemDefaultsInfo{
+ PartitionType: f.PartitionType(),
+ })
}
// getLibsForLinkerConfig returns
@@ -1072,13 +1099,16 @@
// `linkerconfig.BuildLinkerConfig` will convert these two to a linker.config.pb for the filesystem
// (1) will be added to --provideLibs if they are C libraries with a stable interface (has stubs)
// (2) will be added to --requireLibs if they are C libraries with a stable interface (has stubs)
-func (f *filesystem) getLibsForLinkerConfig(ctx android.ModuleContext) ([]android.Module, []android.Module) {
+func (f *filesystem) getLibsForLinkerConfig(ctx android.ModuleContext) ([]android.ModuleProxy, []android.ModuleProxy) {
// we need "Module"s for packaging items
- modulesInPackageByModule := make(map[android.Module]bool)
+ modulesInPackageByModule := make(map[android.ModuleProxy]bool)
modulesInPackageByName := make(map[string]bool)
deps := f.gatherFilteredPackagingSpecs(ctx)
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
+ if !android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoKey).Enabled {
+ return false
+ }
for _, ps := range android.OtherModuleProviderOrDefault(
ctx, child, android.InstallFilesProvider).PackagingSpecs {
if _, ok := deps[ps.RelPathInPackage()]; ok && ps.Partition() == f.PartitionType() {
@@ -1090,13 +1120,16 @@
return true
})
- provideModules := make([]android.Module, 0, len(modulesInPackageByModule))
+ provideModules := make([]android.ModuleProxy, 0, len(modulesInPackageByModule))
for mod := range modulesInPackageByModule {
provideModules = append(provideModules, mod)
}
- var requireModules []android.Module
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ var requireModules []android.ModuleProxy
+ ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
+ if !android.OtherModuleProviderOrDefault(ctx, child, android.CommonModuleInfoKey).Enabled {
+ return false
+ }
_, parentInPackage := modulesInPackageByModule[parent]
_, childInPackageName := modulesInPackageByName[child.Name()]
diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go
index 6a47859..c8b4675 100644
--- a/filesystem/vbmeta.go
+++ b/filesystem/vbmeta.go
@@ -281,6 +281,10 @@
FlagWithArg("-s ", strconv.Itoa(vbmetaMaxSize)).
Output(output)
+ if !ctx.Config().KatiEnabled() {
+ copyImageFileToProductOut(ctx, builder, v.partitionName(), output)
+ }
+
builder.Build("vbmeta", fmt.Sprintf("vbmeta %s", ctx.ModuleName()))
v.installDir = android.PathForModuleInstall(ctx, "etc")
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index 0160159..a070e01 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -128,6 +128,8 @@
f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, partitionType)
}
}
+ // Create android_info.prop
+ f.createAndroidInfo(ctx)
partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
dtbImg := createDtbImgFilegroup(ctx)
@@ -161,7 +163,7 @@
if buildingSuperImage(partitionVars) {
createSuperImage(ctx, finalSoongGeneratedPartitions, partitionVars)
- f.properties.Super_image = ":" + generatedModuleName(ctx.Config(), "super")
+ f.properties.Super_image = ":" + generatedModuleNameForPartition(ctx.Config(), "super")
}
ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions = finalSoongGeneratedPartitions
@@ -180,15 +182,37 @@
return generatedModuleName(cfg, fmt.Sprintf("%s_image", partitionType))
}
+func (f *filesystemCreator) createBootloaderFilegroup(ctx android.LoadHookContext) (string, bool) {
+ bootloaderPath := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.PrebuiltBootloader
+ if len(bootloaderPath) == 0 {
+ return "", false
+ }
+
+ bootloaderFilegroupName := generatedModuleName(ctx.Config(), "bootloader")
+ filegroupProps := &struct {
+ Name *string
+ Srcs []string
+ Visibility []string
+ }{
+ Name: proptools.StringPtr(bootloaderFilegroupName),
+ Srcs: []string{bootloaderPath},
+ Visibility: []string{"//visibility:public"},
+ }
+ ctx.CreateModuleInDirectory(android.FileGroupFactory, ".", filegroupProps)
+ return bootloaderFilegroupName, true
+}
+
func (f *filesystemCreator) createDeviceModule(
ctx android.LoadHookContext,
generatedPartitionTypes []string,
vbmetaPartitions []string,
) {
baseProps := &struct {
- Name *string
+ Name *string
+ Android_info *string
}{
- Name: proptools.StringPtr(generatedModuleName(ctx.Config(), "device")),
+ Name: proptools.StringPtr(generatedModuleName(ctx.Config(), "device")),
+ Android_info: proptools.StringPtr(":" + generatedModuleName(ctx.Config(), "android_info.prop{.txt}")),
}
// Currently, only the system and system_ext partition module is created.
@@ -214,6 +238,15 @@
if android.InList("recovery", f.properties.Generated_partition_types) {
partitionProps.Recovery_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "recovery"))
}
+ if android.InList("system_dlkm", f.properties.Generated_partition_types) {
+ partitionProps.System_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_dlkm"))
+ }
+ if android.InList("vendor_dlkm", f.properties.Generated_partition_types) {
+ partitionProps.Vendor_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_dlkm"))
+ }
+ if android.InList("odm_dlkm", f.properties.Generated_partition_types) {
+ partitionProps.Odm_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm_dlkm"))
+ }
if f.properties.Boot_image != "" {
partitionProps.Boot_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "boot"))
}
@@ -225,7 +258,12 @@
}
partitionProps.Vbmeta_partitions = vbmetaPartitions
- ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps)
+ deviceProps := &filesystem.DeviceProperties{}
+ if bootloader, ok := f.createBootloaderFilegroup(ctx); ok {
+ deviceProps.Bootloader = proptools.StringPtr(":" + bootloader)
+ }
+
+ ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps, deviceProps)
}
func partitionSpecificFsProps(ctx android.EarlyModuleContext, fsProps *filesystem.FilesystemProperties, partitionVars android.PartitionVariables, partitionType string) {
@@ -283,6 +321,7 @@
if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
fsProps.Import_aconfig_flags_from = []string{generatedModuleNameForPartition(ctx.Config(), "system_ext")}
}
+ fsProps.Stem = proptools.StringPtr("system.img")
case "system_ext":
if partitionVars.ProductFsverityGenerateMetadata {
fsProps.Fsverity.Inputs = []string{
@@ -293,6 +332,7 @@
fsProps.Fsverity.Libs = []string{":framework-res{.export-package.apk}"}
}
fsProps.Security_patch = proptools.StringPtr(ctx.Config().PlatformSecurityPatch())
+ fsProps.Stem = proptools.StringPtr("system_ext.img")
case "product":
fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
fsProps.Android_filesystem_deps.System = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
@@ -300,6 +340,7 @@
fsProps.Android_filesystem_deps.System_ext = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
}
fsProps.Security_patch = proptools.StringPtr(ctx.Config().PlatformSecurityPatch())
+ fsProps.Stem = proptools.StringPtr("product.img")
case "vendor":
fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
fsProps.Symlinks = []filesystem.SymlinkDefinition{
@@ -317,6 +358,7 @@
fsProps.Android_filesystem_deps.System_ext = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
}
fsProps.Security_patch = proptools.StringPtr(partitionVars.VendorSecurityPatch)
+ fsProps.Stem = proptools.StringPtr("vendor.img")
case "odm":
fsProps.Symlinks = []filesystem.SymlinkDefinition{
filesystem.SymlinkDefinition{
@@ -325,8 +367,10 @@
},
}
fsProps.Security_patch = proptools.StringPtr(partitionVars.OdmSecurityPatch)
+ fsProps.Stem = proptools.StringPtr("odm.img")
case "userdata":
fsProps.Base_dir = proptools.StringPtr("data")
+ fsProps.Stem = proptools.StringPtr("userdata.img")
case "ramdisk":
// Following the logic in https://cs.android.com/android/platform/superproject/main/+/c3c5063df32748a8806ce5da5dd0db158eab9ad9:build/make/core/Makefile;l=1307
fsProps.Dirs = android.NewSimpleConfigurable([]string{
@@ -349,6 +393,7 @@
"first_stage_ramdisk/sys",
})
}
+ fsProps.Stem = proptools.StringPtr("ramdisk.img")
case "recovery":
dirs := append(commonPartitionDirs, []string{
"sdcard",
@@ -364,16 +409,21 @@
Target: proptools.StringPtr("prop.default"),
Name: proptools.StringPtr("default.prop"),
}), "root")
+ fsProps.Stem = proptools.StringPtr("recovery.img")
case "system_dlkm":
fsProps.Security_patch = proptools.StringPtr(partitionVars.SystemDlkmSecurityPatch)
+ fsProps.Stem = proptools.StringPtr("system_dlkm.img")
case "vendor_dlkm":
fsProps.Security_patch = proptools.StringPtr(partitionVars.VendorDlkmSecurityPatch)
+ fsProps.Stem = proptools.StringPtr("vendor_dlkm.img")
case "odm_dlkm":
fsProps.Security_patch = proptools.StringPtr(partitionVars.OdmDlkmSecurityPatch)
+ fsProps.Stem = proptools.StringPtr("odm_dlkm.img")
case "vendor_ramdisk":
if android.InList("recovery", generatedPartitions(ctx)) {
fsProps.Include_files_of = []string{generatedModuleNameForPartition(ctx.Config(), "recovery")}
}
+ fsProps.Stem = proptools.StringPtr("vendor_ramdisk.img")
}
}
@@ -566,8 +616,8 @@
(*fsGenState.fsDeps[partitionType])[name] = defaultDepCandidateProps(ctx.Config())
}
-// Create a build_prop and android_info module. This will be used to create /vendor/build.prop
-func (f *filesystemCreator) createVendorBuildProp(ctx android.LoadHookContext) {
+// Create an android_info module. This will be used to create /vendor/build.prop
+func (f *filesystemCreator) createAndroidInfo(ctx android.LoadHookContext) {
// Create a android_info for vendor
// The board info files might be in a directory outside the root soong namespace, so create
// the module in "."
@@ -580,7 +630,7 @@
}{
Name: proptools.StringPtr(generatedModuleName(ctx.Config(), "android_info.prop")),
Board_info_files: partitionVars.BoardInfoFiles,
- Stem: proptools.StringPtr("android_info.txt"),
+ Stem: proptools.StringPtr("android-info.txt"),
}
if len(androidInfoProps.Board_info_files) == 0 {
androidInfoProps.Bootloader_board_name = proptools.StringPtr(partitionVars.BootLoaderBoardName)
@@ -591,7 +641,9 @@
androidInfoProps,
)
androidInfoProp.HideFromMake()
- // Create a build prop for vendor
+}
+
+func (f *filesystemCreator) createVendorBuildProp(ctx android.LoadHookContext) {
vendorBuildProps := &struct {
Name *string
Vendor *bool
@@ -604,7 +656,7 @@
Vendor: proptools.BoolPtr(true),
Stem: proptools.StringPtr("build.prop"),
Product_config: proptools.StringPtr(":product_config"),
- Android_info: proptools.StringPtr(":" + androidInfoProp.Name()),
+ Android_info: proptools.StringPtr(":" + generatedModuleName(ctx.Config(), "android_info.prop")),
Licenses: []string{"Android-Apache-2.0"},
}
vendorBuildProp := ctx.CreateModule(
@@ -849,8 +901,8 @@
func (f *filesystemCreator) createFileListDiffTest(ctx android.ModuleContext, partitionType string) android.Path {
partitionModuleName := generatedModuleNameForPartition(ctx.Config(), partitionType)
- systemImage := ctx.GetDirectDepWithTag(partitionModuleName, generatedFilesystemDepTag)
- filesystemInfo, ok := android.OtherModuleProvider(ctx, systemImage, filesystem.FilesystemProvider)
+ partitionImage := ctx.GetDirectDepWithTag(partitionModuleName, generatedFilesystemDepTag)
+ filesystemInfo, ok := android.OtherModuleProvider(ctx, partitionImage, filesystem.FilesystemProvider)
if !ok {
ctx.ModuleErrorf("Expected module %s to provide FileysystemInfo", partitionModuleName)
}
@@ -905,12 +957,12 @@
builder.Build("diff test "+diffTestResultFile.String(), "diff test")
}
-type systemImageDepTagType struct {
+type imageDepTagType struct {
blueprint.BaseDependencyTag
}
-var generatedFilesystemDepTag systemImageDepTagType
-var generatedVbmetaPartitionDepTag systemImageDepTagType
+var generatedFilesystemDepTag imageDepTagType
+var generatedVbmetaPartitionDepTag imageDepTagType
func (f *filesystemCreator) DepsMutator(ctx android.BottomUpMutatorContext) {
for _, partitionType := range f.properties.Generated_partition_types {
diff --git a/fsgen/super_img.go b/fsgen/super_img.go
index 8ee3bf2..a36f614 100644
--- a/fsgen/super_img.go
+++ b/fsgen/super_img.go
@@ -19,6 +19,7 @@
"android/soong/android"
"android/soong/filesystem"
+
"github.com/google/blueprint/proptools"
)
@@ -30,7 +31,7 @@
baseProps := &struct {
Name *string
}{
- Name: proptools.StringPtr(generatedModuleName(ctx.Config(), "super")),
+ Name: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "super")),
}
superImageProps := &filesystem.SuperImageProperties{
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 6137c70..9a8524b 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -88,9 +88,7 @@
}
type SourceFileGenerator interface {
- GeneratedSourceFiles() android.Paths
- GeneratedHeaderDirs() android.Paths
- GeneratedDeps() android.Paths
+ android.SourceFileGenerator
}
// Alias for android.HostToolProvider
diff --git a/golang/golang_test.go b/golang/golang_test.go
index 0a4baed..d555d14 100644
--- a/golang/golang_test.go
+++ b/golang/golang_test.go
@@ -47,7 +47,7 @@
bin := result.ModuleForTests("gobin", result.Config.BuildOSTarget.String())
- expected := "^out/soong/host/" + result.Config.PrebuiltOS() + "/bin/go/gobin/?[^/]*/obj/gobin$"
+ expected := "^out/host/" + result.Config.PrebuiltOS() + "/bin/go/gobin/?[^/]*/obj/gobin$"
actual := android.PathsRelativeToTop(bin.OutputFiles(result.TestContext, t, ""))
if len(actual) != 1 {
t.Fatalf("Expected 1 output file, got %v", actual)
diff --git a/java/aar.go b/java/aar.go
index 3c62441..7c63a29 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -391,8 +391,9 @@
versionName = proptools.NinjaEscape(versionName)
linkFlags = append(linkFlags, "--version-name ", versionName)
}
-
- linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"})
+ // Split the flags by prefix, as --png-compression-level has the "=value" suffix.
+ linkFlags, compileFlags = android.FilterListByPrefix(linkFlags,
+ []string{"--legacy", "--png-compression-level"})
// Always set --pseudo-localize, it will be stripped out later for release
// builds that don't want it.
@@ -875,13 +876,15 @@
rroDirsDepSetBuilder := depset.NewBuilder[rroDir](depset.TOPOLOGICAL)
manifestsDepSetBuilder := depset.NewBuilder[android.Path](depset.TOPOLOGICAL)
- ctx.VisitDirectDeps(func(module android.Module) {
+ ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
depTag := ctx.OtherModuleDependencyTag(module)
var exportPackage android.Path
- aarDep, _ := module.(AndroidLibraryDependency)
- if aarDep != nil {
- exportPackage = aarDep.ExportPackage()
+ var aarDep *AndroidLibraryDependencyInfo
+ javaInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider)
+ if ok && javaInfo.AndroidLibraryDependencyInfo != nil {
+ aarDep = javaInfo.AndroidLibraryDependencyInfo
+ exportPackage = aarDep.ExportPackage
}
switch depTag {
@@ -889,7 +892,7 @@
// Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
case sdkLibTag, libTag, rroDepTag:
if exportPackage != nil {
- sharedResourcesNodeDepSets = append(sharedResourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
+ sharedResourcesNodeDepSets = append(sharedResourcesNodeDepSets, aarDep.ResourcesNodeDepSet)
sharedLibs = append(sharedLibs, exportPackage)
}
case frameworkResTag:
@@ -898,9 +901,9 @@
}
case staticLibTag:
if exportPackage != nil {
- staticResourcesNodeDepSets = append(staticResourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
- rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet())
- manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet())
+ staticResourcesNodeDepSets = append(staticResourcesNodeDepSets, aarDep.ResourcesNodeDepSet)
+ rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet)
+ manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet)
}
}
@@ -1022,7 +1025,7 @@
extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
}
- a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
+ javaInfo := a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
var res android.Paths
@@ -1048,6 +1051,11 @@
android.SetProvider(ctx, AndroidLibraryInfoProvider, AndroidLibraryInfo{})
+ if javaInfo != nil {
+ setExtraJavaInfo(ctx, a, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ }
+
a.setOutputFiles(ctx)
}
@@ -1536,7 +1544,7 @@
ctx.CheckbuildFile(a.implementationJarFile)
}
- android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+ javaInfo := &JavaInfo{
HeaderJars: android.PathsIfNonNil(a.headerJarFile),
LocalHeaderJars: android.PathsIfNonNil(classpathFile),
TransitiveStaticLibsHeaderJars: completeStaticLibsHeaderJars,
@@ -1549,7 +1557,9 @@
ImplementationJars: android.PathsIfNonNil(a.implementationJarFile),
StubsLinkType: Implementation,
// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
- })
+ }
+ setExtraJavaInfo(ctx, a, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
if proptools.Bool(a.properties.Extract_jni) {
for _, t := range ctx.MultiTargets() {
diff --git a/java/app.go b/java/app.go
index b0dcbb0..31c338f 100644
--- a/java/app.go
+++ b/java/app.go
@@ -495,18 +495,24 @@
// This check is enforced for "updatable" APKs (including APK-in-APEX).
func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion android.ApiLevel) {
// It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType()
- ctx.VisitDirectDeps(func(m android.Module) {
+ ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) {
return
}
- dep, _ := m.(*cc.Module)
+ if _, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); !ok {
+ panic(fmt.Errorf("jni dependency is not a cc module: %v", m))
+ }
+ commonInfo, ok := android.OtherModuleProvider(ctx, m, android.CommonModuleInfoKey)
+ if !ok {
+ panic(fmt.Errorf("jni dependency doesn't have CommonModuleInfo provider: %v", m))
+ }
// The domain of cc.sdk_version is "current" and <number>
// We can rely on android.SdkSpec to convert it to <number> so that "current" is
// handled properly regardless of sdk finalization.
- jniSdkVersion, err := android.SdkSpecFrom(ctx, dep.MinSdkVersion()).EffectiveVersion(ctx)
+ jniSdkVersion, err := android.SdkSpecFrom(ctx, commonInfo.MinSdkVersion).EffectiveVersion(ctx)
if err != nil || minSdkVersion.LessThan(jniSdkVersion) {
- ctx.OtherModuleErrorf(dep, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
- dep.MinSdkVersion(), minSdkVersion, ctx.ModuleName())
+ ctx.OtherModuleErrorf(m, "min_sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)",
+ commonInfo.MinSdkVersion, minSdkVersion, ctx.ModuleName())
return
}
@@ -569,7 +575,7 @@
}
func getAconfigFilePaths(ctx android.ModuleContext) (aconfigTextFilePaths android.Paths) {
- ctx.VisitDirectDeps(func(dep android.Module) {
+ ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
tag := ctx.OtherModuleDependencyTag(dep)
switch tag {
case staticLibTag:
@@ -724,6 +730,7 @@
var packageResources = a.exportPackage
+ javaInfo := &JavaInfo{}
if ctx.ModuleName() != "framework-res" {
if a.dexProperties.resourceShrinkingEnabled(ctx) {
protoFile := android.PathForModuleOut(ctx, packageResources.Base()+".proto.apk")
@@ -747,13 +754,17 @@
extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
}
- a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
+ javaInfo = a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars, nil)
if a.dexProperties.resourceShrinkingEnabled(ctx) {
binaryResources := android.PathForModuleOut(ctx, packageResources.Base()+".binary.out.apk")
aapt2Convert(ctx, binaryResources, a.dexer.resourcesOutput.Path(), "binary")
packageResources = binaryResources
}
}
+ if javaInfo != nil {
+ setExtraJavaInfo(ctx, a, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ }
return a.dexJarFile.PathOrNil(), packageResources
}
@@ -1565,6 +1576,9 @@
}
a.generateAndroidBuildActions(ctx)
+ for _, c := range a.testProperties.Test_options.Tradefed_options {
+ configs = append(configs, c)
+ }
for _, module := range a.testProperties.Test_mainline_modules {
configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
}
@@ -1684,7 +1698,7 @@
module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
module.appProperties.AlwaysPackageNativeLibs = true
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.addHostAndDeviceProperties()
module.AddProperties(
@@ -1735,12 +1749,14 @@
// TODO(b/192032291): Disable by default after auditing downstream usage.
module.Module.dexProperties.Optimize.EnabledByDefault = true
+ module.Module.dexProperties.Optimize.Ignore_library_extends_program = proptools.BoolPtr(true)
+ module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
module.Module.properties.Installable = proptools.BoolPtr(true)
module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
module.appProperties.AlwaysPackageNativeLibs = true
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.addHostAndDeviceProperties()
module.AddProperties(
diff --git a/java/app_import.go b/java/app_import.go
index e209135..b77e31a 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -43,6 +43,12 @@
Description: "Uncompress embedded JNI libs",
})
+ stripEmbeddedJniLibsUnusedArchRule = pctx.AndroidStaticRule("strip-embedded-jni-libs-from-unused-arch", blueprint.RuleParams{
+ Command: `${config.Zip2ZipCmd} -i $in -o $out -x 'lib/**/*.so' $extraArgs`,
+ CommandDeps: []string{"${config.Zip2ZipCmd}"},
+ Description: "Remove all JNI libs from unused architectures",
+ }, "extraArgs")
+
uncompressDexRule = pctx.AndroidStaticRule("uncompress-dex", blueprint.RuleParams{
Command: `if (zipinfo $in '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then ` +
`${config.Zip2ZipCmd} -i $in -o $out -0 'classes*.dex'` +
@@ -155,6 +161,9 @@
// the prebuilt is Name() without "prebuilt_" prefix
Source_module_name *string
+ // Whether stripping all libraries from unused architectures.
+ Strip_unused_jni_arch *bool
+
// Path to the .prebuilt_info file of the prebuilt app.
// In case of mainline modules, the .prebuilt_info file contains the build_id that was used
// to generate the prebuilt.
@@ -313,6 +322,26 @@
return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
}
+func (a *AndroidAppImport) stripEmbeddedJniLibsUnusedArch(
+ ctx android.ModuleContext, inputPath android.Path, outputPath android.WritablePath) {
+ var wantedJniLibSlice []string
+ for _, target := range ctx.MultiTargets() {
+ supported_abis := target.Arch.Abi
+ for _, arch := range supported_abis {
+ wantedJniLibSlice = append(wantedJniLibSlice, " -X lib/"+arch+"/*.so")
+ }
+ }
+ wantedJniLibString := strings.Join(wantedJniLibSlice, " ")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: stripEmbeddedJniLibsUnusedArchRule,
+ Input: inputPath,
+ Output: outputPath,
+ Args: map[string]string{
+ "extraArgs": wantedJniLibString,
+ },
+ })
+}
+
func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.generateAndroidBuildActions(ctx)
}
@@ -372,6 +401,13 @@
jnisUncompressed := android.PathForModuleOut(ctx, "jnis-uncompressed", ctx.ModuleName()+".apk")
a.uncompressEmbeddedJniLibs(ctx, srcApk, jnisUncompressed)
+ // Strip all embedded JNI libs and include only required ones accordingly to the module's compile_multilib
+ if Bool(a.properties.Strip_unused_jni_arch) {
+ jnisStripped := android.PathForModuleOut(ctx, "jnis-stripped", ctx.ModuleName()+".apk")
+ a.stripEmbeddedJniLibsUnusedArch(ctx, jnisUncompressed, jnisStripped)
+ jnisUncompressed = jnisStripped
+ }
+
var pathFragments []string
relInstallPath := String(a.properties.Relative_install_path)
diff --git a/java/app_test.go b/java/app_test.go
index 4e915d2..bde801b 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -18,6 +18,7 @@
"fmt"
"path/filepath"
"reflect"
+ "regexp"
"sort"
"strings"
"testing"
@@ -4589,6 +4590,75 @@
assertTestOnlyAndTopLevel(t, ctx, expectedTestOnly, expectedTopLevel)
}
+func TestTestConfigTemplate(t *testing.T) {
+ t.Parallel()
+ ctx := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ ).RunTestWithBp(t, `
+ android_test {
+ name: "android-test",
+ test_config_template: "AndroidTestTemplate.xml",
+ test_options: {
+ tradefed_options: [
+ {
+ name: "name1",
+ key: "key1",
+ value: "value1",
+ },
+ {
+ name: "name2",
+ key: "key2",
+ value: "value2",
+ },
+ ],
+ test_runner_options: [
+ {
+ name: "name3",
+ key: "key3",
+ value: "value3",
+ },
+ {
+ name: "name4",
+ key: "key4",
+ value: "value4",
+ },
+ ],
+ },
+ }
+ `)
+ type option struct {
+ name string
+ key string
+ value string
+ }
+ re := regexp.MustCompile(`<option name="(.*)" key="(.*)" value="(.*)" />`)
+ parse_options := func(optionsString string) []option {
+ lines := strings.Split(optionsString, `\n`)
+ var ret []option
+ for _, l := range lines {
+ sm := re.FindStringSubmatch(l)
+ if sm == nil {
+ continue
+ }
+ ret = append(ret, option{sm[1], sm[2], sm[3]})
+ }
+ return ret
+ }
+ rule := ctx.ModuleForTests("android-test", "android_common").Rule("autogenInstrumentationTest")
+ android.AssertSameArray(t, "extraConfigs mismatch",
+ []option{
+ {"name1", "key1", "value1"},
+ {"name2", "key2", "value2"},
+ },
+ parse_options(rule.Args["extraConfigs"]))
+ android.AssertSameArray(t, "extraTestRunnerConfigs mismatch",
+ []option{
+ {"name3", "key3", "value3"},
+ {"name4", "key4", "value4"},
+ },
+ parse_options(rule.Args["extraTestRunnerConfigs"]))
+}
+
func TestAppStem(t *testing.T) {
ctx := testApp(t, `
android_app {
diff --git a/java/base.go b/java/base.go
index 1aef37c..f8050de 100644
--- a/java/base.go
+++ b/java/base.go
@@ -90,6 +90,10 @@
// list of module-specific flags that will be used for kotlinc compiles
Kotlincflags []string `android:"arch_variant"`
+ // Kotlin language version to target. Currently only 1.9 and 2 are supported.
+ // See kotlinc's `-language-version` flag.
+ Kotlin_lang_version *string
+
// list of java libraries that will be in the classpath
Libs []string `android:"arch_variant"`
@@ -1153,7 +1157,7 @@
j.properties.Generated_srcjars = append(j.properties.Generated_srcjars, path)
}
-func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars, extraDepCombinedJars android.Paths) {
+func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars, extraDepCombinedJars android.Paths) *JavaInfo {
// Auto-propagating jarjar rules
jarjarProviderData := j.collectJarJarRules(ctx)
if jarjarProviderData != nil {
@@ -1287,7 +1291,7 @@
transitiveStaticLibsHeaderJars = nil
}
if ctx.Failed() {
- return
+ return nil
}
j.headerJarFile = combinedHeaderJarFile
@@ -1302,7 +1306,8 @@
ctx.CheckbuildFile(j.headerJarFile)
}
- android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+ j.outputFile = j.headerJarFile
+ return &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
LocalHeaderJars: localHeaderJars,
TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
@@ -1315,10 +1320,7 @@
StubsLinkType: j.stubsLinkType,
AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles,
SdkVersion: j.SdkVersion(ctx),
- })
-
- j.outputFile = j.headerJarFile
- return
+ }
}
if srcFiles.HasExt(".kt") {
@@ -1331,6 +1333,16 @@
kotlincFlags := j.properties.Kotlincflags
CheckKotlincFlags(ctx, kotlincFlags)
+ kotlin_lang_version := proptools.StringDefault(j.properties.Kotlin_lang_version, "1.9")
+ if kotlin_lang_version == "1.9" {
+ kotlincFlags = append(kotlincFlags, "-language-version 1.9")
+ } else if kotlin_lang_version == "2" {
+ kotlincFlags = append(kotlincFlags, "-Xsuppress-version-warnings", "-Xconsistent-data-class-copy-visibility")
+ } else {
+ ctx.PropertyErrorf("kotlin_lang_version", "Must be one of `1.9` or `2`")
+
+ }
+
// Workaround for KT-46512
kotlincFlags = append(kotlincFlags, "-Xsam-conversions=class")
@@ -1375,7 +1387,7 @@
kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName)
j.kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
if ctx.Failed() {
- return
+ return nil
}
kotlinJarPath, _ := j.repackageFlagsIfNecessary(ctx, kotlinJar, jarName, "kotlinc")
@@ -1502,7 +1514,7 @@
localImplementationJars = append(localImplementationJars, classes)
}
if ctx.Failed() {
- return
+ return nil
}
}
@@ -1542,7 +1554,7 @@
resourceJar := android.PathForModuleOut(ctx, "res", jarName)
TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
if ctx.Failed() {
- return
+ return nil
}
localResourceJars = append(localResourceJars, resourceJar)
}
@@ -1664,7 +1676,7 @@
}
if ctx.Failed() {
- return
+ return nil
}
if j.ravenizer.enabled {
@@ -1728,7 +1740,7 @@
CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages)
if ctx.Failed() {
- return
+ return nil
}
}
@@ -1753,7 +1765,7 @@
// enforce syntax check to jacoco filters for any build (http://b/183622051)
specs := j.jacocoModuleToZipCommand(ctx)
if ctx.Failed() {
- return
+ return nil
}
completeStaticLibsImplementationJarsToCombine := completeStaticLibsImplementationJars
@@ -1821,7 +1833,7 @@
}
dexOutputFile, dexArtProfileOutput := j.dexer.compileDex(ctx, params)
if ctx.Failed() {
- return
+ return nil
}
// If r8/d8 provides a profile that matches the optimized dex, use that for dexpreopt.
@@ -1880,7 +1892,7 @@
}
if ctx.Failed() {
- return
+ return nil
}
}
@@ -1927,7 +1939,10 @@
ctx.CheckbuildFile(j.headerJarFile)
}
- android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+ // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
+ j.outputFile = outputFile.WithoutRel()
+
+ return &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
RepackagedHeaderJars: android.PathsIfNonNil(repackagedHeaderJarFile),
@@ -1952,10 +1967,7 @@
StubsLinkType: j.stubsLinkType,
AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles,
SdkVersion: j.SdkVersion(ctx),
- })
-
- // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
- j.outputFile = outputFile.WithoutRel()
+ }
}
func (j *Module) useCompose(ctx android.BaseModuleContext) bool {
@@ -2059,7 +2071,9 @@
} else if strings.HasPrefix(flag, "-Xintellij-plugin-root") {
ctx.PropertyErrorf("kotlincflags",
"Bad flag: `%s`, only use internal compiler for consistency.", flag)
- } else if inList(flag, config.KotlincIllegalFlags) {
+ } else if slices.ContainsFunc(config.KotlincIllegalFlags, func(f string) bool {
+ return strings.HasPrefix(flag, f)
+ }) {
ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag)
} else if flag == "-include-runtime" {
ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag)
@@ -2220,7 +2234,7 @@
func (j *Module) hasCode(ctx android.ModuleContext) bool {
srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
- return len(srcFiles) > 0 || len(ctx.GetDirectDepsWithTag(staticLibTag)) > 0
+ return len(srcFiles) > 0 || len(ctx.GetDirectDepsProxyWithTag(staticLibTag)) > 0
}
// Implements android.ApexModule
diff --git a/java/builder.go b/java/builder.go
index 88058e0..f1d5e99 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -56,7 +56,7 @@
`$zipTemplate${config.SoongZipCmd} -jar -o $out.tmp -C $outDir -D $outDir && ` +
`if ! cmp -s "$out.tmp" "$out"; then mv "$out.tmp" "$out"; fi && ` +
`if ! cmp -s "$annoSrcJar.tmp" "$annoSrcJar"; then mv "$annoSrcJar.tmp" "$annoSrcJar"; fi && ` +
- `if [[ -f "$out.pc_state.new" ]]; then mv "$out.pc_state.new" "$out.pc_state"; fi && ` +
+ `if [ -f "$out.pc_state.new" ]; then mv "$out.pc_state.new" "$out.pc_state"; fi && ` +
`rm -rf "$srcJarDir" "$outDir"`,
CommandDeps: []string{
"${config.FindInputDeltaCmd}",
@@ -226,6 +226,12 @@
},
"jarArgs")
+ extractR8Rules = pctx.AndroidStaticRule("extractR8Rules",
+ blueprint.RuleParams{
+ Command: `${config.ExtractR8RulesCmd} --rules-output $out --include-origin-comments $in`,
+ CommandDeps: []string{"${config.ExtractR8RulesCmd}"},
+ })
+
jarjar = pctx.AndroidStaticRule("jarjar",
blueprint.RuleParams{
Command: "" +
@@ -462,6 +468,7 @@
android.WriteFileRule(ctx, srcJarRspFile, strings.Join(srcJars.Strings(), "\n"))
srcJarArgs = "@" + srcJarRspFile.String()
implicits = append(implicits, srcJarRspFile)
+ rspFiles = append(rspFiles, srcJarRspFile)
rbeInputs = append(rbeInputs, srcJarRspFile)
} else {
rbeInputs = append(rbeInputs, srcJars...)
@@ -739,6 +746,16 @@
})
}
+func TransformJarToR8Rules(ctx android.ModuleContext, outputFile android.WritablePath,
+ jar android.Path) {
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: extractR8Rules,
+ Output: outputFile,
+ Input: jar,
+ })
+}
+
func convertImplementationJarToHeaderJar(ctx android.ModuleContext, implementationJarFile android.Path,
headerJarFile android.WritablePath) {
ctx.Build(pctx, android.BuildParams{
diff --git a/java/config/config.go b/java/config/config.go
index 19d6952..71025de 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -42,9 +42,6 @@
InstrumentFrameworkModules = []string{
"framework",
"framework-minus-apex",
- // TODO(b/383559945) Remove "framework-minus-apex_jarjar-sharded" once
- // we remove this module.
- "framework-minus-apex_jarjar-sharded",
"ims-common",
"telephony-common",
"services",
@@ -174,6 +171,7 @@
pctx.HostBinToolVariable("ApiCheckCmd", "apicheck")
pctx.HostBinToolVariable("D8Cmd", "d8")
pctx.HostBinToolVariable("R8Cmd", "r8")
+ pctx.HostBinToolVariable("ExtractR8RulesCmd", "extract-r8-rules")
pctx.HostBinToolVariable("ResourceShrinkerCmd", "resourceshrinker")
pctx.HostBinToolVariable("HiddenAPICmd", "hiddenapi")
pctx.HostBinToolVariable("ExtractApksCmd", "extract_apks")
diff --git a/java/config/kotlin.go b/java/config/kotlin.go
index bf4c886..ffb025d 100644
--- a/java/config/kotlin.go
+++ b/java/config/kotlin.go
@@ -21,6 +21,7 @@
KotlincIllegalFlags = []string{
"-no-jdk",
"-no-stdlib",
+ "-language-version",
}
)
@@ -49,12 +50,12 @@
"-J--add-opens=java.base/java.util=ALL-UNNAMED", // https://youtrack.jetbrains.com/issue/KT-43704
}, " "))
- pctx.StaticVariable("KotlincGlobalFlags", strings.Join([]string{"-language-version 1.9"}, " "))
+ pctx.StaticVariable("KotlincGlobalFlags", strings.Join([]string{}, " "))
// Use KotlincKytheGlobalFlags to prevent kotlinc version skew issues between android and
// g3 kythe indexers.
// This is necessary because there might be instances of kotlin code in android
// platform that are not fully compatible with the kotlinc used in g3 kythe indexers.
// e.g. uninitialized variables are a warning in 1.*, but an error in 2.*
// https://github.com/JetBrains/kotlin/blob/master/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt#L748
- pctx.StaticVariable("KotlincKytheGlobalFlags", strings.Join([]string{"-language-version 1.9"}, " "))
+ pctx.StaticVariable("KotlincKytheGlobalFlags", strings.Join([]string{}, " "))
}
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index bfacea6..04def3e 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -140,7 +140,7 @@
d.combinedHeaderJar = d.headerJars[0]
}
- android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+ javaInfo := &JavaInfo{
HeaderJars: d.headerJars,
LocalHeaderJars: d.headerJars,
TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, nil, transitiveHeaderJars),
@@ -154,7 +154,9 @@
StubsLinkType: Implementation,
// TODO: Not sure if aconfig flags that have been moved between device and host variants
// make sense.
- })
+ }
+ setExtraJavaInfo(ctx, d, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
}
diff --git a/java/dex.go b/java/dex.go
index 168a231..7b99549 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -42,11 +42,15 @@
// True if the module containing this has it set by default.
EnabledByDefault bool `blueprint:"mutated"`
+ // Whether to allow that library classes inherit from program classes.
+ // Defaults to false.
+ Ignore_library_extends_program *bool
+
// Whether to continue building even if warnings are emitted. Defaults to true.
Ignore_warnings *bool
// If true, runs R8 in Proguard compatibility mode, otherwise runs R8 in full mode.
- // Defaults to false for apps, true for libraries and tests.
+ // Defaults to false for apps and tests, true for libraries.
Proguard_compatibility *bool
// If true, optimize for size by removing unused code. Defaults to true for apps,
@@ -356,6 +360,10 @@
r8Flags = append(r8Flags, opt.Proguard_flags...)
+ if BoolDefault(opt.Ignore_library_extends_program, false) {
+ r8Flags = append(r8Flags, "--ignore-library-extends-program")
+ }
+
if BoolDefault(opt.Proguard_compatibility, true) {
r8Flags = append(r8Flags, "--force-proguard-compatibility")
}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index e955949..fa1fb86 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -629,8 +629,8 @@
cmd.Implicit(dep)
} else if filename != "android.jar" && depBase == "android.jar" {
// Metalava implicitly searches these patterns:
- // prebuilts/tools/common/api-versions/android-%/android.jar
- // prebuilts/sdk/%/public/android.jar
+ // prebuilts/tools/common/api-versions/android-{version:level}/android.jar
+ // prebuilts/sdk/{version:level}/public/android.jar
// Add android.jar files from the api_levels_annotations_dirs directories to try
// to satisfy these patterns. If Metalava can't find a match for an API level
// between 1 and 28 in at least one pattern it will fail.
@@ -646,11 +646,11 @@
})
// Generate the list of --android-jar-pattern options. The order matters so the first one which
- // matches will be the one that is used for a specific api level..
+ // matches will be the one that is used for a specific api level.
for _, sdkDir := range sdkDirs {
for _, dir := range dirs {
addPattern := func(jarFilename string) {
- cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, jarFilename))
+ cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:level}/%s/%s", dir, sdkDir, jarFilename))
}
if sdkDir == "module-lib" || sdkDir == "system-server" {
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index 1e8362c..37740ae 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -88,7 +88,7 @@
cmdline := String(sboxProto.Commands[0].Command)
android.AssertStringContainsEquals(t, "api-versions generation flag", cmdline, "--generate-api-levels", c.generate_xml)
if c.expectedJarFilename != "" {
- expected := "--android-jar-pattern ./%/public/" + c.expectedJarFilename
+ expected := "--android-jar-pattern ./{version:level}/public/" + c.expectedJarFilename
if !strings.Contains(cmdline, expected) {
t.Errorf("For %q, expected metalava argument %q, but was not found %q", c.moduleName, expected, cmdline)
}
@@ -142,8 +142,8 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "public")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/%/public/android.jar",
- "--android-jar-pattern someotherdir/%/public/android.jar",
+ "--android-jar-pattern somedir/{version:level}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
}, patterns)
}
@@ -151,10 +151,10 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "system")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/%/system/android.jar",
- "--android-jar-pattern someotherdir/%/system/android.jar",
- "--android-jar-pattern somedir/%/public/android.jar",
- "--android-jar-pattern someotherdir/%/public/android.jar",
+ "--android-jar-pattern somedir/{version:level}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/system/android.jar",
+ "--android-jar-pattern somedir/{version:level}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
}, patterns)
}
@@ -162,12 +162,12 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "module-lib")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/%/module-lib/android.jar",
- "--android-jar-pattern someotherdir/%/module-lib/android.jar",
- "--android-jar-pattern somedir/%/system/android.jar",
- "--android-jar-pattern someotherdir/%/system/android.jar",
- "--android-jar-pattern somedir/%/public/android.jar",
- "--android-jar-pattern someotherdir/%/public/android.jar",
+ "--android-jar-pattern somedir/{version:level}/module-lib/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/module-lib/android.jar",
+ "--android-jar-pattern somedir/{version:level}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/system/android.jar",
+ "--android-jar-pattern somedir/{version:level}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
}, patterns)
}
@@ -175,14 +175,14 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "system-server")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/%/system-server/android.jar",
- "--android-jar-pattern someotherdir/%/system-server/android.jar",
- "--android-jar-pattern somedir/%/module-lib/android.jar",
- "--android-jar-pattern someotherdir/%/module-lib/android.jar",
- "--android-jar-pattern somedir/%/system/android.jar",
- "--android-jar-pattern someotherdir/%/system/android.jar",
- "--android-jar-pattern somedir/%/public/android.jar",
- "--android-jar-pattern someotherdir/%/public/android.jar",
+ "--android-jar-pattern somedir/{version:level}/system-server/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/system-server/android.jar",
+ "--android-jar-pattern somedir/{version:level}/module-lib/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/module-lib/android.jar",
+ "--android-jar-pattern somedir/{version:level}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/system/android.jar",
+ "--android-jar-pattern somedir/{version:level}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
}, patterns)
}
diff --git a/java/fuzz.go b/java/fuzz.go
index 79cd042..5973957 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -63,7 +63,7 @@
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
module.Module.sourceProperties.Top_level_test_target = true
diff --git a/java/java.go b/java/java.go
index a975ca6..48ba8de 100644
--- a/java/java.go
+++ b/java/java.go
@@ -250,6 +250,32 @@
var ProguardSpecInfoProvider = blueprint.NewProvider[ProguardSpecInfo]()
+type AndroidLibraryDependencyInfo struct {
+ ExportPackage android.Path
+ ResourcesNodeDepSet depset.DepSet[*resourcesNode]
+ RRODirsDepSet depset.DepSet[rroDir]
+ ManifestsDepSet depset.DepSet[android.Path]
+}
+
+type UsesLibraryDependencyInfo struct {
+ DexJarBuildPath OptionalDexJarPath
+ DexJarInstallPath android.Path
+ ClassLoaderContexts dexpreopt.ClassLoaderContextMap
+}
+
+type SdkLibraryComponentDependencyInfo struct {
+ // The name of the implementation library for the optional SDK library or nil, if there isn't one.
+ OptionalSdkLibraryImplementation *string
+}
+
+type ProvidesUsesLibInfo struct {
+ ProvidesUsesLib *string
+}
+
+type ModuleWithUsesLibraryInfo struct {
+ UsesLibrary *usesLibrary
+}
+
// JavaInfo contains information about a java module for use by modules that depend on it.
type JavaInfo struct {
// HeaderJars is a list of jars that can be passed as the javac classpath in order to link
@@ -328,6 +354,16 @@
AconfigIntermediateCacheOutputPaths android.Paths
SdkVersion android.SdkSpec
+
+ AndroidLibraryDependencyInfo *AndroidLibraryDependencyInfo
+
+ UsesLibraryDependencyInfo *UsesLibraryDependencyInfo
+
+ SdkLibraryComponentDependencyInfo *SdkLibraryComponentDependencyInfo
+
+ ProvidesUsesLibInfo *ProvidesUsesLibInfo
+
+ ModuleWithUsesLibraryInfo *ModuleWithUsesLibraryInfo
}
var JavaInfoProvider = blueprint.NewProvider[*JavaInfo]()
@@ -1002,7 +1038,7 @@
j.dexpreopter.disableDexpreopt()
}
}
- j.compile(ctx, nil, nil, nil, nil)
+ javaInfo := j.compile(ctx, nil, nil, nil, nil)
j.setInstallRules(ctx)
@@ -1011,6 +1047,11 @@
TopLevelTarget: j.sourceProperties.Top_level_test_target,
})
+ if javaInfo != nil {
+ setExtraJavaInfo(ctx, j, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ }
+
setOutputFiles(ctx, j.Module)
}
@@ -1740,7 +1781,7 @@
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
module.Module.sourceProperties.Top_level_test_target = true
@@ -1757,7 +1798,7 @@
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
InitJavaModule(module, android.HostAndDeviceSupported)
@@ -2427,7 +2468,7 @@
ctx.Phony(ctx.ModuleName(), al.stubsJar)
- android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+ javaInfo := &JavaInfo{
HeaderJars: android.PathsIfNonNil(al.stubsJar),
LocalHeaderJars: android.PathsIfNonNil(al.stubsJar),
TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, android.PathsIfNonNil(al.stubsJar), nil),
@@ -2437,7 +2478,9 @@
AidlIncludeDirs: android.Paths{},
StubsLinkType: Stubs,
// No aconfig libraries on api libraries
- })
+ }
+ setExtraJavaInfo(ctx, al, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
}
func (al *ApiLibrary) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
@@ -2827,6 +2870,23 @@
outputFile = combinedJar
}
+ proguardFlags := android.PathForModuleOut(ctx, "proguard_flags")
+ TransformJarToR8Rules(ctx, proguardFlags, outputFile)
+
+ transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx)
+ android.SetProvider(ctx, ProguardSpecInfoProvider, ProguardSpecInfo{
+ ProguardFlagsFiles: depset.New[android.Path](
+ depset.POSTORDER,
+ android.Paths{proguardFlags},
+ transitiveProguardFlags,
+ ),
+ UnconditionallyExportedProguardFlags: depset.New[android.Path](
+ depset.POSTORDER,
+ nil,
+ transitiveUnconditionalExportedFlags,
+ ),
+ })
+
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource.
// Also strip the relative path from the header output file so that the reuseImplementationJarAsHeaderJar check
// in a module that depends on this module considers them equal.
@@ -2895,7 +2955,7 @@
}
}
- android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
+ javaInfo := &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.combinedHeaderFile),
LocalHeaderJars: android.PathsIfNonNil(j.combinedHeaderFile),
TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
@@ -2909,7 +2969,9 @@
AidlIncludeDirs: j.exportAidlIncludeDirs,
StubsLinkType: j.stubsLinkType,
// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
- })
+ }
+ setExtraJavaInfo(ctx, j, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, "")
ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, ".jar")
@@ -3323,8 +3385,8 @@
func addCLCFromDep(ctx android.ModuleContext, depModule android.Module,
clcMap dexpreopt.ClassLoaderContextMap) {
- dep, ok := depModule.(UsesLibraryDependency)
- if !ok {
+ dep, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider)
+ if !ok || dep.UsesLibraryDependencyInfo == nil {
return
}
@@ -3334,14 +3396,14 @@
if lib, ok := android.OtherModuleProvider(ctx, depModule, SdkLibraryInfoProvider); ok && lib.SharedLibrary {
// A shared SDK library. This should be added as a top-level CLC element.
sdkLib = &depName
- } else if lib, ok := depModule.(SdkLibraryComponentDependency); ok && lib.OptionalSdkLibraryImplementation() != nil {
- if depModule.Name() == proptools.String(lib.OptionalSdkLibraryImplementation())+".impl" {
- sdkLib = lib.OptionalSdkLibraryImplementation()
+ } else if lib := dep.SdkLibraryComponentDependencyInfo; lib != nil && lib.OptionalSdkLibraryImplementation != nil {
+ if depModule.Name() == proptools.String(lib.OptionalSdkLibraryImplementation)+".impl" {
+ sdkLib = lib.OptionalSdkLibraryImplementation
}
- } else if ulib, ok := depModule.(ProvidesUsesLib); ok {
+ } else if ulib := dep.ProvidesUsesLibInfo; ulib != nil {
// A non-SDK library disguised as an SDK library by the means of `provides_uses_lib`
// property. This should be handled in the same way as a shared SDK library.
- sdkLib = ulib.ProvidesUsesLib()
+ sdkLib = ulib.ProvidesUsesLib
}
depTag := ctx.OtherModuleDependencyTag(depModule)
@@ -3373,21 +3435,22 @@
}
}
clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, optional,
- dep.DexJarBuildPath(ctx).PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
+ dep.UsesLibraryDependencyInfo.DexJarBuildPath.PathOrNil(),
+ dep.UsesLibraryDependencyInfo.DexJarInstallPath, dep.UsesLibraryDependencyInfo.ClassLoaderContexts)
} else {
- clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
+ clcMap.AddContextMap(dep.UsesLibraryDependencyInfo.ClassLoaderContexts, depName)
}
}
func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.Module,
usesLibrary *usesLibrary) {
- dep, ok := depModule.(ModuleWithUsesLibrary)
- if !ok {
+ dep, ok := android.OtherModuleProvider(ctx, depModule, JavaInfoProvider)
+ if !ok || dep.ModuleWithUsesLibraryInfo == nil {
return
}
- for _, lib := range dep.UsesLibrary().usesLibraryProperties.Missing_optional_uses_libs {
+ for _, lib := range dep.ModuleWithUsesLibraryInfo.UsesLibrary.usesLibraryProperties.Missing_optional_uses_libs {
if !android.InList(lib, usesLibrary.usesLibraryProperties.Missing_optional_uses_libs) {
usesLibrary.usesLibraryProperties.Missing_optional_uses_libs =
append(usesLibrary.usesLibraryProperties.Missing_optional_uses_libs, lib)
@@ -3443,3 +3506,40 @@
func (ap *JavaApiContributionImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ap.JavaApiContribution.GenerateAndroidBuildActions(ctx)
}
+
+func setExtraJavaInfo(ctx android.ModuleContext, module android.Module, javaInfo *JavaInfo) {
+ if alDep, ok := module.(AndroidLibraryDependency); ok {
+ javaInfo.AndroidLibraryDependencyInfo = &AndroidLibraryDependencyInfo{
+ ExportPackage: alDep.ExportPackage(),
+ ResourcesNodeDepSet: alDep.ResourcesNodeDepSet(),
+ RRODirsDepSet: alDep.RRODirsDepSet(),
+ ManifestsDepSet: alDep.ManifestsDepSet(),
+ }
+ }
+
+ if ulDep, ok := module.(UsesLibraryDependency); ok {
+ javaInfo.UsesLibraryDependencyInfo = &UsesLibraryDependencyInfo{
+ DexJarBuildPath: ulDep.DexJarBuildPath(ctx),
+ DexJarInstallPath: ulDep.DexJarInstallPath(),
+ ClassLoaderContexts: ulDep.ClassLoaderContexts(),
+ }
+ }
+
+ if slcDep, ok := module.(SdkLibraryComponentDependency); ok {
+ javaInfo.SdkLibraryComponentDependencyInfo = &SdkLibraryComponentDependencyInfo{
+ OptionalSdkLibraryImplementation: slcDep.OptionalSdkLibraryImplementation(),
+ }
+ }
+
+ if pul, ok := module.(ProvidesUsesLib); ok {
+ javaInfo.ProvidesUsesLibInfo = &ProvidesUsesLibInfo{
+ ProvidesUsesLib: pul.ProvidesUsesLib(),
+ }
+ }
+
+ if mwul, ok := module.(ModuleWithUsesLibrary); ok {
+ javaInfo.ModuleWithUsesLibraryInfo = &ModuleWithUsesLibraryInfo{
+ UsesLibrary: mwul.UsesLibrary(),
+ }
+ }
+}
diff --git a/java/kotlin.go b/java/kotlin.go
index e1a3f71..308bb03 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -198,7 +198,7 @@
`$kaptProcessor ` +
`-Xbuild-file=$kotlinBuildFile && ` +
`${config.SoongZipCmd} -jar -write_if_changed -o $out -C $kaptDir/stubs -D $kaptDir/stubs && ` +
- `if [[ -f "$out.pc_state.new" ]]; then mv "$out.pc_state.new" "$out.pc_state"; fi && ` +
+ `if [ -f "$out.pc_state.new" ]; then mv "$out.pc_state.new" "$out.pc_state"; fi && ` +
`rm -rf "$srcJarDir"`,
CommandDeps: []string{
"${config.FindInputDeltaCmd}",
diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go
index 6128ce3..4be7d04 100644
--- a/java/legacy_core_platform_api_usage.go
+++ b/java/legacy_core_platform_api_usage.go
@@ -28,9 +28,6 @@
"FloralClocks",
"framework-jobscheduler",
"framework-minus-apex",
- // TODO(b/383559945) Remove "framework-minus-apex_jarjar-sharded" once
- // we remove this module.
- "framework-minus-apex_jarjar-sharded",
"framework-minus-apex-headers",
"framework-minus-apex-intdefs",
"FrameworksCoreTests",
diff --git a/java/lint.go b/java/lint.go
index ac90e19..cee25a8 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -69,6 +69,11 @@
// If soong gets support for testonly, this flag should be replaced with that.
Test *bool
+ // Same as the regular Test property, but set by internal soong code based on if the module
+ // type is a test module type. This will act as the default value for the test property,
+ // but can be overridden by the user.
+ Test_module_type *bool `blueprint:"mutated"`
+
// Whether to ignore the exit code of Android lint. This is the --exit_code
// option. Defaults to false.
Suppress_exit_code *bool
@@ -257,7 +262,12 @@
if l.library {
cmd.Flag("--library")
}
- if proptools.BoolDefault(l.properties.Lint.Test, false) {
+
+ test := proptools.BoolDefault(l.properties.Lint.Test_module_type, false)
+ if l.properties.Lint.Test != nil {
+ test = *l.properties.Lint.Test
+ }
+ if test {
cmd.Flag("--test")
}
if l.manifest != nil {
@@ -470,7 +480,7 @@
cmd := rule.Command()
- cmd.Flag(`JAVA_OPTS="-Xmx3072m --add-opens java.base/java.util=ALL-UNNAMED"`).
+ cmd.Flag(`JAVA_OPTS="-Xmx4096m --add-opens java.base/java.util=ALL-UNNAMED"`).
FlagWithArg("ANDROID_SDK_HOME=", lintPaths.homeDir.String()).
FlagWithInput("SDK_ANNOTATIONS=", annotationsZipPath).
FlagWithInput("LINT_OPTS=-DLINT_API_DATABASE=", apiVersionsXMLPath)
diff --git a/java/lint_test.go b/java/lint_test.go
index afe3914..617dc54 100644
--- a/java/lint_test.go
+++ b/java/lint_test.go
@@ -276,3 +276,50 @@
ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Don't use --disable, --enable, or --check in the flags field, instead use the dedicated disabled_checks, warning_checks, error_checks, or fatal_checks fields")).
RunTestWithBp(t, bp)
}
+
+// b/358643466
+func TestNotTestViaDefault(t *testing.T) {
+ bp := `
+ java_defaults {
+ name: "mydefaults",
+ lint: {
+ test: false,
+ },
+ }
+ android_test {
+ name: "foo",
+ srcs: [
+ "a.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "current",
+ defaults: ["mydefaults"],
+ }
+ android_test {
+ name: "foo2",
+ srcs: [
+ "a.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "current",
+ }
+ `
+ result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(t, bp)
+ ctx := result.TestContext
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+ sboxProto := android.RuleBuilderSboxProtoForTests(t, ctx, foo.Output("lint.sbox.textproto"))
+ command := *sboxProto.Commands[0].Command
+
+ if strings.Contains(command, "--test") {
+ t.Fatalf("Expected command to not contain --test")
+ }
+
+ foo2 := ctx.ModuleForTests("foo2", "android_common")
+ sboxProto2 := android.RuleBuilderSboxProtoForTests(t, ctx, foo2.Output("lint.sbox.textproto"))
+ command2 := *sboxProto2.Commands[0].Command
+
+ if !strings.Contains(command2, "--test") {
+ t.Fatalf("Expected command to contain --test")
+ }
+}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index d09a02e..152eb1e 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -172,7 +172,7 @@
// Do not add implLibModule to allModules as the impl lib is only used to collect the
// transitive source files
var implLibModule []android.Module
- ctx.VisitDirectDepsWithTag(implLibraryTag, func(m android.Module) {
+ ctx.VisitDirectDepsWithTag(platformBootclasspathImplLibDepTag, func(m android.Module) {
implLibModule = append(implLibModule, m)
})
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index f2768db..1f691a0 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -30,18 +30,23 @@
preparer := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
FixtureConfigureBootJars("platform:foo", "system_ext:bar"),
+ android.FixtureMergeMockFs(android.MockFS{
+ "api/current.txt": nil,
+ "api/removed.txt": nil,
+ }),
android.FixtureWithRootAndroidBp(`
platform_bootclasspath {
name: "platform-bootclasspath",
}
- java_library {
+ java_sdk_library {
name: "bar",
srcs: ["a.java"],
system_modules: "none",
sdk_version: "none",
compile_dex: true,
system_ext_specific: true,
+ unsafe_ignore_missing_latest_api: true,
}
`),
)
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 5b145c6..bb98944 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -51,6 +51,10 @@
type platformCompatConfigProperties struct {
Src *string `android:"path"`
+
+ // If true, we include it in the "merged" XML (merged_compat_config.xml).
+ // Default is true.
+ Include_in_merged_xml *bool
}
type platformCompatConfig struct {
@@ -60,6 +64,7 @@
installDirPath android.InstallPath
configFile android.OutputPath
metadataFile android.OutputPath
+ doMerge bool
installConfigFile android.InstallPath
}
@@ -68,6 +73,10 @@
return p.metadataFile
}
+func (p *platformCompatConfig) includeInMergedXml() bool {
+ return p.doMerge
+}
+
func (p *platformCompatConfig) CompatConfig() android.OutputPath {
return p.configFile
}
@@ -78,6 +87,9 @@
type platformCompatConfigMetadataProvider interface {
compatConfigMetadata() android.Path
+
+ // Whether to include it in the "merged" XML (merged_compat_config.xml) or not.
+ includeInMergedXml() bool
}
type PlatformCompatConfigIntf interface {
@@ -98,6 +110,7 @@
metadataFileName := p.Name() + "_meta.xml"
p.configFile = android.PathForModuleOut(ctx, configFileName).OutputPath
p.metadataFile = android.PathForModuleOut(ctx, metadataFileName).OutputPath
+ p.doMerge = proptools.BoolDefault(p.properties.Include_in_merged_xml, true)
path := android.PathForModuleSrc(ctx, String(p.properties.Src))
rule.Command().
@@ -201,6 +214,10 @@
return module.metadataFile
}
+func (module *prebuiltCompatConfigModule) includeInMergedXml() bool {
+ return true // Always include in merged.xml
+}
+
func (module *prebuiltCompatConfigModule) BaseModuleName() string {
return proptools.StringDefault(module.properties.Source_module_name, module.ModuleBase.Name())
}
@@ -237,6 +254,9 @@
if !android.IsModulePreferred(module) {
return
}
+ if !c.includeInMergedXml() {
+ return
+ }
metadata := c.compatConfigMetadata()
compatConfigMetadata = append(compatConfigMetadata, metadata)
}
diff --git a/java/platform_compat_config_test.go b/java/platform_compat_config_test.go
index 80d991c..f7529a7 100644
--- a/java/platform_compat_config_test.go
+++ b/java/platform_compat_config_test.go
@@ -26,6 +26,7 @@
android.FixtureWithRootAndroidBp(`
platform_compat_config {
name: "myconfig2",
+ include_in_merged_xml: false,
}
platform_compat_config {
name: "myconfig1",
@@ -38,7 +39,6 @@
CheckMergedCompatConfigInputs(t, result, "myconfig",
"out/soong/.intermediates/myconfig1/myconfig1_meta.xml",
- "out/soong/.intermediates/myconfig2/myconfig2_meta.xml",
"out/soong/.intermediates/myconfig3/myconfig3_meta.xml",
)
}
diff --git a/java/ravenwood.go b/java/ravenwood.go
index 4c43a9f..84d6a9f 100644
--- a/java/ravenwood.go
+++ b/java/ravenwood.go
@@ -110,7 +110,7 @@
module.AddProperties(&module.testProperties, &module.ravenwoodTestProperties)
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.testProperties.Test_suites = []string{
"general-tests",
diff --git a/java/robolectric.go b/java/robolectric.go
index 3b2c656..29aa2f0 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -21,6 +21,7 @@
"android/soong/java/config"
"android/soong/tradefed"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -28,6 +29,17 @@
RegisterRobolectricBuildComponents(android.InitRegistrationContext)
}
+type roboRuntimeOnlyDependencyTag struct {
+ blueprint.BaseDependencyTag
+}
+
+var roboRuntimeOnlyDepTag roboRuntimeOnlyDependencyTag
+
+// Mark this tag so dependencies that use it are excluded from visibility enforcement.
+func (t roboRuntimeOnlyDependencyTag) ExcludeFromVisibilityEnforcement() {}
+
+var _ android.ExcludeFromVisibilityEnforcementTag = roboRuntimeOnlyDepTag
+
func RegisterRobolectricBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("android_robolectric_test", RobolectricTestFactory)
ctx.RegisterModuleType("android_robolectric_runtimes", robolectricRuntimesFactory)
@@ -47,7 +59,6 @@
var (
roboCoverageLibsTag = dependencyTag{name: "roboCoverageLibs"}
roboRuntimesTag = dependencyTag{name: "roboRuntimes"}
- roboRuntimeOnlyTag = dependencyTag{name: "roboRuntimeOnlyTag"}
)
type robolectricProperties struct {
@@ -65,10 +76,6 @@
Shards *int64
}
- // The version number of a robolectric prebuilt to use from prebuilts/misc/common/robolectric
- // instead of the one built from source in external/robolectric-shadows.
- Robolectric_prebuilt_version *string
-
// Use /external/robolectric rather than /external/robolectric-shadows as the version of robolectric
// to use. /external/robolectric closely tracks github's master, and will fully replace /external/robolectric-shadows
Upstream *bool
@@ -107,23 +114,12 @@
ctx.PropertyErrorf("instrumentation_for", "missing required instrumented module")
}
- ctx.AddVariationDependencies(nil, staticLibTag, clearcutJunitLib)
-
- if v := String(r.robolectricProperties.Robolectric_prebuilt_version); v != "" {
- ctx.AddVariationDependencies(nil, staticLibTag, fmt.Sprintf(robolectricPrebuiltLibPattern, v))
- } else if !proptools.BoolDefault(r.robolectricProperties.Strict_mode, true) {
- if proptools.Bool(r.robolectricProperties.Upstream) {
- ctx.AddVariationDependencies(nil, staticLibTag, robolectricCurrentLib+"_upstream")
- } else {
- ctx.AddVariationDependencies(nil, staticLibTag, robolectricCurrentLib)
- }
- }
+ ctx.AddVariationDependencies(nil, roboRuntimeOnlyDepTag, clearcutJunitLib)
if proptools.BoolDefault(r.robolectricProperties.Strict_mode, true) {
- ctx.AddVariationDependencies(nil, roboRuntimeOnlyTag, robolectricCurrentLib+"_upstream")
+ ctx.AddVariationDependencies(nil, roboRuntimeOnlyDepTag, robolectricCurrentLib)
} else {
- // opting out from strict mode, robolectric_non_strict_mode_permission lib should be added
- ctx.AddVariationDependencies(nil, staticLibTag, "robolectric_non_strict_mode_permission")
+ ctx.AddVariationDependencies(nil, staticLibTag, robolectricCurrentLib)
}
ctx.AddVariationDependencies(nil, staticLibTag, robolectricDefaultLibs...)
@@ -197,7 +193,7 @@
handleLibDeps(dep)
}
// handle the runtimeOnly tag for strict_mode
- for _, dep := range ctx.GetDirectDepsWithTag(roboRuntimeOnlyTag) {
+ for _, dep := range ctx.GetDirectDepsWithTag(roboRuntimeOnlyDepTag) {
handleLibDeps(dep)
}
@@ -208,7 +204,7 @@
r.stem = proptools.StringDefault(r.overridableProperties.Stem, ctx.ModuleName())
r.classLoaderContexts = r.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
r.dexpreopter.disableDexpreopt()
- r.compile(ctx, nil, nil, nil, extraCombinedJars)
+ javaInfo := r.compile(ctx, nil, nil, nil, extraCombinedJars)
installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
var installDeps android.InstallPaths
@@ -245,6 +241,11 @@
}
r.installFile = ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...)
+
+ if javaInfo != nil {
+ setExtraJavaInfo(ctx, r, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ }
}
func generateSameDirRoboTestConfigJar(ctx android.ModuleContext, outputFile android.ModuleOutPath) {
@@ -295,7 +296,7 @@
&module.testProperties)
module.Module.dexpreopter.isTest = true
- module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.linter.properties.Lint.Test_module_type = proptools.BoolPtr(true)
module.testProperties.Test_suites = []string{"robolectric-tests"}
diff --git a/java/robolectric_test.go b/java/robolectric_test.go
index a2474e8..78326ab 100644
--- a/java/robolectric_test.go
+++ b/java/robolectric_test.go
@@ -32,6 +32,11 @@
}
java_library {
+ name: "Robolectric_all-target",
+ srcs: ["Robo.java"]
+ }
+
+ java_library {
name: "mockito-robolectric-prebuilt",
srcs: ["Mockito.java"]
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index a0affe0..155bea4 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -964,6 +964,10 @@
removedApiFilePaths[kind] = removedApiFilePath
}
+ javaInfo := &JavaInfo{}
+ setExtraJavaInfo(ctx, ctx.Module(), javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+
return SdkLibraryInfo{
EverythingStubDexJarPaths: everythingStubPaths,
ExportableStubDexJarPaths: exportableStubPaths,
diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go
index 7684db2..4f1ef9d 100644
--- a/linkerconfig/linkerconfig.go
+++ b/linkerconfig/linkerconfig.go
@@ -91,8 +91,8 @@
func BuildLinkerConfig(
ctx android.ModuleContext,
inputs android.Paths,
- provideModules []android.Module,
- requireModules []android.Module,
+ provideModules []android.ModuleProxy,
+ requireModules []android.ModuleProxy,
output android.WritablePath,
) {
// First, convert the input json to protobuf format
@@ -110,9 +110,10 @@
// Secondly, if there's provideLibs gathered from provideModules, append them
var provideLibs []string
for _, m := range provideModules {
- if c, ok := m.(*cc.Module); ok && (cc.IsStubTarget(c) || c.HasLlndkStubs()) {
+ ccInfo, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider)
+ if ok && (cc.IsStubTarget(android.OtherModuleProviderOrDefault(ctx, m, cc.LinkableInfoProvider)) || ccInfo.HasLlndkStubs) {
for _, ps := range android.OtherModuleProviderOrDefault(
- ctx, c, android.InstallFilesProvider).PackagingSpecs {
+ ctx, m, android.InstallFilesProvider).PackagingSpecs {
provideLibs = append(provideLibs, ps.FileName())
}
}
@@ -122,8 +123,15 @@
var requireLibs []string
for _, m := range requireModules {
- if c, ok := m.(*cc.Module); ok && c.HasStubsVariants() && !c.Host() {
- requireLibs = append(requireLibs, c.ImplementationModuleName(ctx)+".so")
+ if _, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); ok {
+ if android.OtherModuleProviderOrDefault(ctx, m, cc.LinkableInfoProvider).HasStubsVariants &&
+ !android.OtherModuleProviderOrDefault(ctx, m, android.CommonModuleInfoKey).Host {
+ name := ctx.OtherModuleName(m)
+ if ccInfo, ok := android.OtherModuleProvider(ctx, m, cc.CcInfoProvider); ok && ccInfo.LinkerInfo != nil && ccInfo.LinkerInfo.ImplementationModuleName != nil {
+ name = *ccInfo.LinkerInfo.ImplementationModuleName
+ }
+ requireLibs = append(requireLibs, name+".so")
+ }
}
}
diff --git a/python/python.go b/python/python.go
index be9411b..914b77e 100644
--- a/python/python.go
+++ b/python/python.go
@@ -95,6 +95,11 @@
// device.
Device_common_data []string `android:"path_device_common"`
+ // Same as data, but will add dependencies on modules via a device os variation and the
+ // device's first supported arch's variation. Useful for a host test that wants to embed a
+ // module built for device.
+ Device_first_data []string `android:"path_device_first"`
+
// list of java modules that provide data that should be installed alongside the test.
Java_data []string
@@ -456,6 +461,7 @@
// expand data files from "data" property.
expandedData := android.PathsForModuleSrc(ctx, p.properties.Data)
expandedData = append(expandedData, android.PathsForModuleSrc(ctx, p.properties.Device_common_data)...)
+ expandedData = append(expandedData, android.PathsForModuleSrc(ctx, p.properties.Device_first_data)...)
// Emulate the data property for java_data dependencies.
for _, javaData := range ctx.GetDirectDepsWithTag(javaDataTag) {
diff --git a/python/test.go b/python/test.go
index 9f57bea..37947dd 100644
--- a/python/test.go
+++ b/python/test.go
@@ -68,6 +68,11 @@
// device.
Device_common_data []string `android:"path_device_common"`
+ // Same as data, but will add dependencies on modules via a device os variation and the
+ // device's first supported arch's variation. Useful for a host test that wants to embed a
+ // module built for device.
+ Device_first_data []string `android:"path_device_first"`
+
// list of java modules that provide data that should be installed alongside the test.
Java_data []string
@@ -189,6 +194,9 @@
for _, dataSrcPath := range android.PathsForModuleSrc(ctx, p.testProperties.Device_common_data) {
p.data = append(p.data, android.DataPath{SrcPath: dataSrcPath})
}
+ for _, dataSrcPath := range android.PathsForModuleSrc(ctx, p.testProperties.Device_first_data) {
+ p.data = append(p.data, android.DataPath{SrcPath: dataSrcPath})
+ }
if p.isTestHost() && len(p.testProperties.Data_device_bins_both) > 0 {
ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) {
diff --git a/rust/builder.go b/rust/builder.go
index e5434ef..8a869aa 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -264,7 +264,7 @@
libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
}
for _, lib := range deps.DyLibs {
- libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
+ libFlags = append(libFlags, "--extern force:"+lib.CrateName+"="+lib.Path.String())
}
for _, proc_macro := range deps.ProcMacros {
libFlags = append(libFlags, "--extern "+proc_macro.CrateName+"="+proc_macro.Path.String())
diff --git a/rust/config/global.go b/rust/config/global.go
index 66ffc0b..0a4b314 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -42,6 +42,8 @@
}
GlobalRustFlags = []string{
+ // Allow `--extern force:foo` for dylib support
+ "-Z unstable-options",
"-Z stack-protector=strong",
"-Z remap-cwd-prefix=.",
"-C debuginfo=2",
diff --git a/rust/library.go b/rust/library.go
index 14a2b65..2d62dcf 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -457,13 +457,6 @@
cfgs := library.baseCompiler.Properties.Cfgs.GetOrDefault(ctx, nil)
- if library.dylib() {
- // We need to add a dependency on std in order to link crates as dylibs.
- // The hack to add this dependency is guarded by the following cfg so
- // that we don't force a dependency when it isn't needed.
- cfgs = append(cfgs, "android_dylib")
- }
-
cfgFlags := cfgsToFlags(cfgs)
flags.RustFlags = append(flags.RustFlags, cfgFlags...)
diff --git a/rust/library_test.go b/rust/library_test.go
index 256cb35..e5fd5e0 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -89,22 +89,6 @@
}
}
-// Check that we are passing the android_dylib config flag
-func TestAndroidDylib(t *testing.T) {
- ctx := testRust(t, `
- rust_library_host_dylib {
- name: "libfoo",
- srcs: ["foo.rs"],
- crate_name: "foo",
- }`)
-
- libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
-
- if !strings.Contains(libfooDylib.Args["rustcFlags"], "--cfg 'android_dylib'") {
- t.Errorf("missing android_dylib cfg flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
- }
-}
-
func TestValidateLibraryStem(t *testing.T) {
testRustError(t, "crate_name must be defined.", `
rust_library_host {
diff --git a/rust/rust.go b/rust/rust.go
index 246670f..ba6e293 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -34,6 +34,35 @@
var pctx = android.NewPackageContext("android/soong/rust")
+type LibraryInfo struct {
+ Rlib bool
+ Dylib bool
+}
+
+type CompilerInfo struct {
+ StdLinkageForDevice RustLinkage
+ StdLinkageForNonDevice RustLinkage
+ NoStdlibs bool
+ LibraryInfo *LibraryInfo
+}
+
+type ProtobufDecoratorInfo struct{}
+
+type SourceProviderInfo struct {
+ ProtobufDecoratorInfo *ProtobufDecoratorInfo
+}
+
+type RustInfo struct {
+ AndroidMkSuffix string
+ RustSubName string
+ TransitiveAndroidMkSharedLibs depset.DepSet[string]
+ CompilerInfo *CompilerInfo
+ SnapshotInfo *cc.SnapshotInfo
+ SourceProviderInfo *SourceProviderInfo
+}
+
+var RustInfoProvider = blueprint.NewProvider[*RustInfo]()
+
func init() {
android.RegisterModuleType("rust_defaults", defaultsFactory)
android.PreDepsMutators(registerPreDepsMutators)
@@ -996,9 +1025,44 @@
ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
}
- android.SetProvider(ctx, cc.LinkableInfoKey, cc.LinkableInfo{
- StaticExecutable: mod.StaticExecutable(),
- })
+ linkableInfo := cc.CreateCommonLinkableInfo(mod)
+ linkableInfo.Static = mod.Static()
+ linkableInfo.Shared = mod.Shared()
+ linkableInfo.CrateName = mod.CrateName()
+ linkableInfo.ExportedCrateLinkDirs = mod.ExportedCrateLinkDirs()
+ android.SetProvider(ctx, cc.LinkableInfoProvider, linkableInfo)
+
+ rustInfo := &RustInfo{
+ AndroidMkSuffix: mod.AndroidMkSuffix(),
+ RustSubName: mod.Properties.RustSubName,
+ TransitiveAndroidMkSharedLibs: mod.transitiveAndroidMkSharedLibs,
+ }
+ if mod.compiler != nil {
+ rustInfo.CompilerInfo = &CompilerInfo{
+ NoStdlibs: mod.compiler.noStdlibs(),
+ StdLinkageForDevice: mod.compiler.stdLinkage(true),
+ StdLinkageForNonDevice: mod.compiler.stdLinkage(false),
+ }
+ if lib, ok := mod.compiler.(libraryInterface); ok {
+ rustInfo.CompilerInfo.LibraryInfo = &LibraryInfo{
+ Dylib: lib.dylib(),
+ Rlib: lib.rlib(),
+ }
+ }
+ if lib, ok := mod.compiler.(cc.SnapshotInterface); ok {
+ rustInfo.SnapshotInfo = &cc.SnapshotInfo{
+ SnapshotAndroidMkSuffix: lib.SnapshotAndroidMkSuffix(),
+ }
+ }
+ }
+ if mod.sourceProvider != nil {
+ if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
+ rustInfo.SourceProviderInfo = &SourceProviderInfo{
+ ProtobufDecoratorInfo: &ProtobufDecoratorInfo{},
+ }
+ }
+ }
+ android.SetProvider(ctx, RustInfoProvider, rustInfo)
mod.setOutputFiles(ctx)
@@ -1175,21 +1239,21 @@
return nil
}
-func rustMakeLibName(ctx android.ModuleContext, c cc.LinkableInterface, dep cc.LinkableInterface, depName string) string {
- if rustDep, ok := dep.(*Module); ok {
+func rustMakeLibName(rustInfo *RustInfo, linkableInfo *cc.LinkableInfo, commonInfo *android.CommonModuleInfo, depName string) string {
+ if rustInfo != nil {
// Use base module name for snapshots when exporting to Makefile.
- if snapshotPrebuilt, ok := rustDep.compiler.(cc.SnapshotInterface); ok {
- baseName := rustDep.BaseModuleName()
- return baseName + snapshotPrebuilt.SnapshotAndroidMkSuffix() + rustDep.AndroidMkSuffix()
+ if rustInfo.SnapshotInfo != nil {
+ baseName := linkableInfo.BaseModuleName
+ return baseName + rustInfo.SnapshotInfo.SnapshotAndroidMkSuffix + rustInfo.AndroidMkSuffix
}
}
- return cc.MakeLibName(ctx, c, dep, depName)
+ return cc.MakeLibName(nil, linkableInfo, commonInfo, depName)
}
-func collectIncludedProtos(mod *Module, dep *Module) {
+func collectIncludedProtos(mod *Module, rustInfo *RustInfo, linkableInfo *cc.LinkableInfo) {
if protoMod, ok := mod.sourceProvider.(*protobufDecorator); ok {
- if _, ok := dep.sourceProvider.(*protobufDecorator); ok {
- protoMod.additionalCrates = append(protoMod.additionalCrates, dep.CrateName())
+ if rustInfo.SourceProviderInfo.ProtobufDecoratorInfo != nil {
+ protoMod.additionalCrates = append(protoMod.additionalCrates, linkableInfo.CrateName)
}
}
}
@@ -1197,13 +1261,13 @@
func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
var depPaths PathDeps
- directRlibDeps := []*Module{}
- directDylibDeps := []*Module{}
- directProcMacroDeps := []*Module{}
+ directRlibDeps := []*cc.LinkableInfo{}
+ directDylibDeps := []*cc.LinkableInfo{}
+ directProcMacroDeps := []*cc.LinkableInfo{}
directSharedLibDeps := []cc.SharedLibraryInfo{}
- directStaticLibDeps := [](cc.LinkableInterface){}
- directSrcProvidersDeps := []*Module{}
- directSrcDeps := [](android.SourceFileProducer){}
+ directStaticLibDeps := [](*cc.LinkableInfo){}
+ directSrcProvidersDeps := []*android.ModuleProxy{}
+ directSrcDeps := []android.SourceFilesInfo{}
// For the dependency from platform to apex, use the latest stubs
mod.apexSdkVersion = android.FutureApiLevel
@@ -1224,7 +1288,7 @@
var transitiveAndroidMkSharedLibs []depset.DepSet[string]
var directAndroidMkSharedLibs []string
- ctx.VisitDirectDeps(func(dep android.Module) {
+ ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
depName := ctx.OtherModuleName(dep)
depTag := ctx.OtherModuleDependencyTag(dep)
modStdLinkage := mod.compiler.stdLinkage(ctx.Device())
@@ -1237,18 +1301,22 @@
return
}
- if rustDep, ok := dep.(*Module); ok && !rustDep.Static() && !rustDep.Shared() {
+ rustInfo, hasRustInfo := android.OtherModuleProvider(ctx, dep, RustInfoProvider)
+ ccInfo, _ := android.OtherModuleProvider(ctx, dep, cc.CcInfoProvider)
+ linkableInfo, hasLinkableInfo := android.OtherModuleProvider(ctx, dep, cc.LinkableInfoProvider)
+ commonInfo := android.OtherModuleProviderOrDefault(ctx, dep, android.CommonModuleInfoKey)
+ if hasRustInfo && !linkableInfo.Static && !linkableInfo.Shared {
//Handle Rust Modules
- makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName)
+ makeLibName := rustMakeLibName(rustInfo, linkableInfo, &commonInfo, depName+rustInfo.RustSubName)
switch {
case depTag == dylibDepTag:
- dylib, ok := rustDep.compiler.(libraryInterface)
- if !ok || !dylib.dylib() {
+ dylib := rustInfo.CompilerInfo.LibraryInfo
+ if dylib == nil || !dylib.Dylib {
ctx.ModuleErrorf("mod %q not an dylib library", depName)
return
}
- directDylibDeps = append(directDylibDeps, rustDep)
+ directDylibDeps = append(directDylibDeps, linkableInfo)
mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, makeLibName)
mod.Properties.SnapshotDylibs = append(mod.Properties.SnapshotDylibs, cc.BaseLibName(depName))
@@ -1257,8 +1325,11 @@
depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
}
- if !rustDep.compiler.noStdlibs() {
- rustDepStdLinkage := rustDep.compiler.stdLinkage(ctx.Device())
+ if !rustInfo.CompilerInfo.NoStdlibs {
+ rustDepStdLinkage := rustInfo.CompilerInfo.StdLinkageForNonDevice
+ if ctx.Device() {
+ rustDepStdLinkage = rustInfo.CompilerInfo.StdLinkageForDevice
+ }
if rustDepStdLinkage != modStdLinkage {
ctx.ModuleErrorf("Rust dependency %q has the wrong StdLinkage; expected %#v, got %#v", depName, modStdLinkage, rustDepStdLinkage)
return
@@ -1266,27 +1337,30 @@
}
case depTag == rlibDepTag:
- rlib, ok := rustDep.compiler.(libraryInterface)
- if !ok || !rlib.rlib() {
+ rlib := rustInfo.CompilerInfo.LibraryInfo
+ if rlib == nil || !rlib.Rlib {
ctx.ModuleErrorf("mod %q not an rlib library", makeLibName)
return
}
- directRlibDeps = append(directRlibDeps, rustDep)
+ directRlibDeps = append(directRlibDeps, linkableInfo)
mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName)
mod.Properties.SnapshotRlibs = append(mod.Properties.SnapshotRlibs, cc.BaseLibName(depName))
// rust_ffi rlibs may export include dirs, so collect those here.
exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider)
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
- depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(rustDep.OutputFile().Path()))
+ depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(linkableInfo.OutputFile.Path()))
// rlibs are not installed, so don't add the output file to directImplementationDeps
if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok {
depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
}
- if !rustDep.compiler.noStdlibs() {
- rustDepStdLinkage := rustDep.compiler.stdLinkage(ctx.Device())
+ if !rustInfo.CompilerInfo.NoStdlibs {
+ rustDepStdLinkage := rustInfo.CompilerInfo.StdLinkageForNonDevice
+ if ctx.Device() {
+ rustDepStdLinkage = rustInfo.CompilerInfo.StdLinkageForDevice
+ }
if rustDepStdLinkage != modStdLinkage {
ctx.ModuleErrorf("Rust dependency %q has the wrong StdLinkage; expected %#v, got %#v", depName, modStdLinkage, rustDepStdLinkage)
return
@@ -1294,14 +1368,14 @@
}
case depTag == procMacroDepTag:
- directProcMacroDeps = append(directProcMacroDeps, rustDep)
+ directProcMacroDeps = append(directProcMacroDeps, linkableInfo)
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
// proc_macro link dirs need to be exported, so collect those here.
- depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(rustDep.OutputFile().Path()))
+ depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(linkableInfo.OutputFile.Path()))
case depTag == sourceDepTag:
if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
- collectIncludedProtos(mod, rustDep)
+ collectIncludedProtos(mod, rustInfo, linkableInfo)
}
case cc.IsStaticDepTag(depTag):
// Rust FFI rlibs should not be declared in a Rust modules
@@ -1314,7 +1388,7 @@
}
- transitiveAndroidMkSharedLibs = append(transitiveAndroidMkSharedLibs, rustDep.transitiveAndroidMkSharedLibs)
+ transitiveAndroidMkSharedLibs = append(transitiveAndroidMkSharedLibs, rustInfo.TransitiveAndroidMkSharedLibs)
if android.IsSourceDepTagWithOutputTag(depTag, "") {
// Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct
@@ -1326,14 +1400,14 @@
helper = "device module defined?"
}
- if dep.Target().Os != ctx.Os() {
+ if commonInfo.Target.Os != ctx.Os() {
ctx.ModuleErrorf("OS mismatch on dependency %q (%s)", dep.Name(), helper)
return
- } else if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
+ } else if commonInfo.Target.Arch.ArchType != ctx.Arch().ArchType {
ctx.ModuleErrorf("Arch mismatch on dependency %q (%s)", dep.Name(), helper)
return
}
- directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep)
+ directSrcProvidersDeps = append(directSrcProvidersDeps, &dep)
}
exportedInfo, _ := android.OtherModuleProvider(ctx, dep, FlagExporterInfoProvider)
@@ -1345,7 +1419,7 @@
}
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
- linkFile := rustDep.UnstrippedOutputFile()
+ linkFile := linkableInfo.UnstrippedOutputFile
linkDir := linkPathFromFilePath(linkFile)
if lib, ok := mod.compiler.(exportedFlagsProducer); ok {
lib.exportLinkDirs(linkDir)
@@ -1354,26 +1428,26 @@
if depTag == sourceDepTag {
if _, ok := mod.sourceProvider.(*protobufDecorator); ok && mod.Source() {
- if _, ok := rustDep.sourceProvider.(*protobufDecorator); ok {
+ if rustInfo.SourceProviderInfo.ProtobufDecoratorInfo != nil {
exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider)
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
}
}
}
- } else if ccDep, ok := dep.(cc.LinkableInterface); ok {
+ } else if hasLinkableInfo {
//Handle C dependencies
- makeLibName := cc.MakeLibName(ctx, mod, ccDep, depName)
- if _, ok := ccDep.(*Module); !ok {
- if ccDep.Module().Target().Os != ctx.Os() {
+ makeLibName := cc.MakeLibName(ccInfo, linkableInfo, &commonInfo, depName)
+ if !hasRustInfo {
+ if commonInfo.Target.Os != ctx.Os() {
ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
return
}
- if ccDep.Module().Target().Arch.ArchType != ctx.Arch().ArchType {
+ if commonInfo.Target.Arch.ArchType != ctx.Arch().ArchType {
ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName)
return
}
}
- linkObject := ccDep.OutputFile()
+ linkObject := linkableInfo.OutputFile
if !linkObject.Valid() {
if !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName())
@@ -1413,7 +1487,7 @@
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
- directStaticLibDeps = append(directStaticLibDeps, ccDep)
+ directStaticLibDeps = append(directStaticLibDeps, linkableInfo)
// Record baseLibName for snapshots.
mod.Properties.SnapshotStaticLibs = append(mod.Properties.SnapshotStaticLibs, cc.BaseLibName(depName))
@@ -1484,7 +1558,7 @@
}
}
- if srcDep, ok := dep.(android.SourceFileProducer); ok {
+ if srcDep, ok := android.OtherModuleProvider(ctx, dep, android.SourceFilesInfoKey); ok {
if android.IsSourceDepTagWithOutputTag(depTag, "") {
// These are usually genrules which don't have per-target variants.
directSrcDeps = append(directSrcDeps, srcDep)
@@ -1497,32 +1571,32 @@
var rlibDepFiles RustLibraries
aliases := mod.compiler.Aliases()
for _, dep := range directRlibDeps {
- crateName := dep.CrateName()
+ crateName := dep.CrateName
if alias, aliased := aliases[crateName]; aliased {
crateName = alias
}
- rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName})
+ rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile, CrateName: crateName})
}
var dylibDepFiles RustLibraries
for _, dep := range directDylibDeps {
- crateName := dep.CrateName()
+ crateName := dep.CrateName
if alias, aliased := aliases[crateName]; aliased {
crateName = alias
}
- dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName})
+ dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile, CrateName: crateName})
}
var procMacroDepFiles RustLibraries
for _, dep := range directProcMacroDeps {
- crateName := dep.CrateName()
+ crateName := dep.CrateName
if alias, aliased := aliases[crateName]; aliased {
crateName = alias
}
- procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName})
+ procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile, CrateName: crateName})
}
var staticLibDepFiles android.Paths
for _, dep := range directStaticLibDeps {
- staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile().Path())
+ staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile.Path())
}
var sharedLibFiles android.Paths
@@ -1538,11 +1612,11 @@
var srcProviderDepFiles android.Paths
for _, dep := range directSrcProvidersDeps {
- srcs := android.OutputFilesForModule(ctx, dep, "")
+ srcs := android.OutputFilesForModule(ctx, *dep, "")
srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
}
for _, dep := range directSrcDeps {
- srcs := dep.Srcs()
+ srcs := dep.Srcs
srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
}
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 90c1f61..9f65dec 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -424,11 +424,11 @@
}`)
fooRustc := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
- if !strings.Contains(fooRustc.Args["libFlags"], "--extern bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so") {
- t.Errorf("--extern bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
+ if !strings.Contains(fooRustc.Args["libFlags"], "--extern force:bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so") {
+ t.Errorf("--extern force:bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
}
- if !strings.Contains(fooRustc.Args["libFlags"], "--extern baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so") {
- t.Errorf("--extern baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
+ if !strings.Contains(fooRustc.Args["libFlags"], "--extern force:baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so") {
+ t.Errorf("--extern force:baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
}
}
diff --git a/ui/build/build.go b/ui/build/build.go
index 110ee95..26f5969 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -87,6 +87,17 @@
// without changing the command line every time. Avoids rebuilds
// when using ninja.
writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_number.txt", buildNumber)
+
+ hostname, ok := config.environ.Get("BUILD_HOSTNAME")
+ if !ok {
+ var err error
+ hostname, err = os.Hostname()
+ if err != nil {
+ ctx.Println("Failed to read hostname:", err)
+ hostname = "unknown"
+ }
+ }
+ writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_hostname.txt", hostname)
}
var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
@@ -96,8 +107,11 @@
{{end -}}
pool highmem_pool
depth = {{.HighmemParallel}}
-{{if and (not .SkipKatiNinja) .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
+{{if and (not .SkipKatiNinja) .HasKatiSuffix}}
+subninja {{.KatiBuildNinjaFile}}
subninja {{.KatiPackageNinjaFile}}
+{{else}}
+subninja {{.KatiSoongOnlyPackageNinjaFile}}
{{end -}}
subninja {{.SoongNinjaFile}}
`))
@@ -335,25 +349,31 @@
return
}
+ // Still generate the kati suffix in soong-only builds because soong-only still uses kati for
+ // the packaging step. Also, the kati suffix is used for the combined ninja file.
+ genKatiSuffix(ctx, config)
+
if what&RunSoong != 0 {
runSoong(ctx, config)
}
if what&RunKati != 0 {
- genKatiSuffix(ctx, config)
runKatiCleanSpec(ctx, config)
runKatiBuild(ctx, config)
- runKatiPackage(ctx, config)
+ runKatiPackage(ctx, config, false)
- ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
} else if what&RunKatiNinja != 0 {
// Load last Kati Suffix if it exists
- if katiSuffix, err := ioutil.ReadFile(config.LastKatiSuffixFile()); err == nil {
+ if katiSuffix, err := os.ReadFile(config.LastKatiSuffixFile()); err == nil {
ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
config.SetKatiSuffix(string(katiSuffix))
}
+ } else if what&RunSoong != 0 {
+ runKatiPackage(ctx, config, true)
}
+ os.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
+
// Write combined ninja file
createCombinedBuildNinjaFile(ctx, config)
diff --git a/ui/build/config.go b/ui/build/config.go
index dc468c2..4f2d213 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -1592,6 +1592,10 @@
return filepath.Join(c.OutDir(), "build"+c.KatiSuffix()+katiPackageSuffix+".ninja")
}
+func (c *configImpl) KatiSoongOnlyPackageNinjaFile() string {
+ return filepath.Join(c.OutDir(), "build"+c.KatiSuffix()+katiSoongOnlyPackageSuffix+".ninja")
+}
+
func (c *configImpl) SoongVarsFile() string {
targetProduct, err := c.TargetProductOrErr()
if err != nil {
@@ -1647,7 +1651,7 @@
}
func (c *configImpl) KatiPackageMkDir() string {
- return filepath.Join(c.ProductOut(), "obj", "CONFIG", "kati_packaging")
+ return filepath.Join(c.SoongOutDir(), "kati_packaging"+c.KatiSuffix())
}
func (c *configImpl) hostOutRoot() string {
diff --git a/ui/build/kati.go b/ui/build/kati.go
index 4dfb710..6519573 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -31,6 +31,7 @@
const katiBuildSuffix = ""
const katiCleanspecSuffix = "-cleanspec"
const katiPackageSuffix = "-package"
+const katiSoongOnlyPackageSuffix = "-soong-only-package"
// genKatiSuffix creates a filename suffix for kati-generated files so that we
// can cache them based on their inputs. Such files include the generated Ninja
@@ -40,8 +41,12 @@
// Currently that includes the TARGET_PRODUCT and kati-processed command line
// arguments.
func genKatiSuffix(ctx Context, config Config) {
+ targetProduct := "unknown"
+ if p, err := config.TargetProductOrErr(); err == nil {
+ targetProduct = p
+ }
// Construct the base suffix.
- katiSuffix := "-" + config.TargetProduct() + config.CoverageSuffix()
+ katiSuffix := "-" + targetProduct + config.CoverageSuffix()
// Append kati arguments to the suffix.
if args := config.KatiArgs(); len(args) > 0 {
@@ -68,13 +73,13 @@
func writeValueIfChanged(ctx Context, config Config, dir string, filename string, value string) {
filePath := filepath.Join(dir, filename)
previousValue := ""
- rawPreviousValue, err := ioutil.ReadFile(filePath)
+ rawPreviousValue, err := os.ReadFile(filePath)
if err == nil {
previousValue = string(rawPreviousValue)
}
if previousValue != value {
- if err = ioutil.WriteFile(filePath, []byte(value), 0666); err != nil {
+ if err = os.WriteFile(filePath, []byte(value), 0666); err != nil {
ctx.Fatalf("Failed to write: %v", err)
}
}
@@ -200,18 +205,10 @@
// fi
cmd.Environment.Unset("SOONG_USE_PARTIAL_COMPILE")
- hostname, ok := cmd.Environment.Get("BUILD_HOSTNAME")
// Unset BUILD_HOSTNAME during kati run to avoid kati rerun, kati will use BUILD_HOSTNAME from a file.
cmd.Environment.Unset("BUILD_HOSTNAME")
- if !ok {
- hostname, err = os.Hostname()
- if err != nil {
- ctx.Println("Failed to read hostname:", err)
- hostname = "unknown"
- }
- }
- writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_hostname.txt", hostname)
- _, ok = cmd.Environment.Get("BUILD_NUMBER")
+
+ _, ok := cmd.Environment.Get("BUILD_NUMBER")
// Unset BUILD_NUMBER during kati run to avoid kati rerun, kati will use BUILD_NUMBER from a file.
cmd.Environment.Unset("BUILD_NUMBER")
if ok {
@@ -342,10 +339,19 @@
// Generate the Ninja file containing the packaging command lines for the dist
// dir.
-func runKatiPackage(ctx Context, config Config) {
+func runKatiPackage(ctx Context, config Config, soongOnly bool) {
ctx.BeginTrace(metrics.RunKati, "kati package")
defer ctx.EndTrace()
+ entryPoint := "build/make/packaging/main.mk"
+ suffix := katiPackageSuffix
+ ninjaFile := config.KatiPackageNinjaFile()
+ if soongOnly {
+ entryPoint = "build/make/packaging/main_soong_only.mk"
+ suffix = katiSoongOnlyPackageSuffix
+ ninjaFile = config.KatiSoongOnlyPackageNinjaFile()
+ }
+
args := []string{
// Mark the dist dir as writable.
"--writable", config.DistDir() + "/",
@@ -354,14 +360,14 @@
// Fail when redefining / duplicating a target.
"--werror_overriding_commands",
// Entry point.
- "-f", "build/make/packaging/main.mk",
+ "-f", entryPoint,
// Directory containing .mk files for packaging purposes, such as
// the dist.mk file, containing dist-for-goals data.
"KATI_PACKAGE_MK_DIR=" + config.KatiPackageMkDir(),
}
// Run Kati against a restricted set of environment variables.
- runKati(ctx, config, katiPackageSuffix, args, func(env *Environment) {
+ runKati(ctx, config, suffix, args, func(env *Environment) {
env.Allow([]string{
// Some generic basics
"LANG",
@@ -389,7 +395,7 @@
})
// Compress and dist the packaging Ninja file.
- distGzipFile(ctx, config, config.KatiPackageNinjaFile())
+ distGzipFile(ctx, config, ninjaFile)
}
// Run Kati on the cleanspec files to clean the build.
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 82e5c96..58334a9 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -197,6 +197,8 @@
func (pb PrimaryBuilderFactory) primaryBuilderInvocation(config Config) bootstrap.PrimaryBuilderInvocation {
commonArgs := make([]string, 0, 0)
+ commonArgs = append(commonArgs, "--kati_suffix", config.KatiSuffix())
+
if !pb.config.skipSoongTests {
commonArgs = append(commonArgs, "-t")
}
diff --git a/ui/metrics/proc/status_linux_test.go b/ui/metrics/proc/status_linux_test.go
index 6709850..0edc400 100644
--- a/ui/metrics/proc/status_linux_test.go
+++ b/ui/metrics/proc/status_linux_test.go
@@ -1,7 +1,6 @@
package proc
import (
- "fmt"
"path/filepath"
"reflect"
"strconv"
@@ -29,7 +28,6 @@
t.Fatalf("got %v, want nil for error", err)
}
- fmt.Printf("%d %d\b", status.VmPeak, expectedStatus.VmPeak)
if !reflect.DeepEqual(status, expectedStatus) {
t.Errorf("got %v, expecting %v for ProcStatus", status, expectedStatus)
}