Merge "Remove more unused code" into main
diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go
index 72fe495..e771d05 100644
--- a/aconfig/all_aconfig_declarations.go
+++ b/aconfig/all_aconfig_declarations.go
@@ -89,7 +89,7 @@
func (this *allAconfigDeclarationsSingleton) MakeVars(ctx android.MakeVarsContext) {
ctx.DistForGoal("droid", this.intermediateBinaryProtoPath)
- for _, goal := range []string{"droid", "sdk"} {
+ for _, goal := range []string{"docs", "droid", "sdk"} {
ctx.DistForGoalWithFilename(goal, this.intermediateBinaryProtoPath, "flags.pb")
ctx.DistForGoalWithFilename(goal, this.intermediateTextProtoPath, "flags.textproto")
}
diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go
index 1378dfe..a46ce52 100644
--- a/aconfig/codegen/java_aconfig_library.go
+++ b/aconfig/codegen/java_aconfig_library.go
@@ -76,7 +76,7 @@
}
}
-func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuildActions(module *java.GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path {
+func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuildActions(module *java.GeneratedJavaLibraryModule, ctx android.ModuleContext) (android.Path, android.Path) {
// Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag
declarationsModules := ctx.GetDirectDepsWithTag(declarationsTag)
if len(declarationsModules) != 1 {
@@ -129,7 +129,11 @@
}},
})
- return srcJarPath
+ return srcJarPath, declarations.IntermediateCacheOutputPath
+}
+
+func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) AconfigDeclarations() *string {
+ return proptools.StringPtr(callbacks.properties.Aconfig_declarations)
}
func isModeSupported(mode string) bool {
diff --git a/aconfig/codegen/rust_aconfig_library.go b/aconfig/codegen/rust_aconfig_library.go
index 3f7495b..ad8d632 100644
--- a/aconfig/codegen/rust_aconfig_library.go
+++ b/aconfig/codegen/rust_aconfig_library.go
@@ -99,8 +99,11 @@
func (a *aconfigDecorator) SourceProviderDeps(ctx rust.DepsContext, deps rust.Deps) rust.Deps {
deps = a.BaseSourceProvider.SourceProviderDeps(ctx, deps)
+ deps.Rustlibs = append(deps.Rustlibs, "libaconfig_storage_read_api")
deps.Rustlibs = append(deps.Rustlibs, "libflags_rust")
deps.Rustlibs = append(deps.Rustlibs, "liblazy_static")
+ deps.Rustlibs = append(deps.Rustlibs, "liblogger")
+ deps.Rustlibs = append(deps.Rustlibs, "liblog_rust")
ctx.AddDependency(ctx.Module(), rustDeclarationsTag, a.Properties.Aconfig_declarations)
return deps
}
diff --git a/aconfig/codegen/rust_aconfig_library_test.go b/aconfig/codegen/rust_aconfig_library_test.go
index 60bc9f7..fe28f94 100644
--- a/aconfig/codegen/rust_aconfig_library_test.go
+++ b/aconfig/codegen/rust_aconfig_library_test.go
@@ -11,7 +11,7 @@
func TestRustAconfigLibrary(t *testing.T) {
result := android.GroupFixturePreparers(
PrepareForTestWithAconfigBuildComponents,
- rust.PrepareForTestWithRustIncludeVndk,
+ rust.PrepareForIntegrationTestWithRust,
android.PrepareForTestWithArchMutator,
android.PrepareForTestWithDefaults,
android.PrepareForTestWithPrebuilts,
@@ -28,6 +28,21 @@
crate_name: "lazy_static",
srcs: ["src/lib.rs"],
}
+ rust_library {
+ name: "libaconfig_storage_read_api", // test mock
+ crate_name: "aconfig_storage_read_api",
+ srcs: ["lib.rs"],
+ }
+ rust_library {
+ name: "liblogger", // test mock
+ crate_name: "logger",
+ srcs: ["lib.rs"],
+ }
+ rust_library {
+ name: "liblog_rust", // test mock
+ crate_name: "log_rust",
+ srcs: ["lib.rs"],
+ }
aconfig_declarations {
name: "my_aconfig_declarations",
package: "com.example.package",
@@ -85,7 +100,7 @@
t.Helper()
result := android.GroupFixturePreparers(
PrepareForTestWithAconfigBuildComponents,
- rust.PrepareForTestWithRustIncludeVndk).
+ rust.PrepareForIntegrationTestWithRust).
ExtendWithErrorHandler(android.FixtureExpectsNoErrors).
RunTestWithBp(t, fmt.Sprintf(`
rust_library {
@@ -98,6 +113,21 @@
crate_name: "lazy_static",
srcs: ["src/lib.rs"],
}
+ rust_library {
+ name: "libaconfig_storage_read_api", // test mock
+ crate_name: "aconfig_storage_read_api",
+ srcs: ["lib.rs"],
+ }
+ rust_library {
+ name: "liblogger", // test mock
+ crate_name: "logger",
+ srcs: ["lib.rs"],
+ }
+ rust_library {
+ name: "liblog_rust", // test mock
+ crate_name: "log_rust",
+ srcs: ["lib.rs"],
+ }
aconfig_declarations {
name: "my_aconfig_declarations",
package: "com.example.package",
@@ -132,7 +162,7 @@
t.Helper()
android.GroupFixturePreparers(
PrepareForTestWithAconfigBuildComponents,
- rust.PrepareForTestWithRustIncludeVndk).
+ rust.PrepareForIntegrationTestWithRust).
ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(err)).
RunTestWithBp(t, fmt.Sprintf(`
rust_library {
@@ -145,6 +175,21 @@
crate_name: "lazy_static",
srcs: ["src/lib.rs"],
}
+ rust_library {
+ name: "libaconfig_storage_read_api", // test mock
+ crate_name: "aconfig_storage_read_api",
+ srcs: ["lib.rs"],
+ }
+ rust_library {
+ name: "liblogger", // test mock
+ crate_name: "logger",
+ srcs: ["lib.rs"],
+ }
+ rust_library {
+ name: "liblog_rust", // test mock
+ crate_name: "log_rust",
+ srcs: ["lib.rs"],
+ }
aconfig_declarations {
name: "my_aconfig_declarations",
package: "com.example.package",
diff --git a/android/Android.bp b/android/Android.bp
index 03619f4..4c59592 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -41,7 +41,6 @@
"buildinfo_prop.go",
"config.go",
"test_config.go",
- "config_bp2build.go",
"configured_jars.go",
"csuite_config.go",
"deapexer.go",
@@ -90,6 +89,7 @@
"sandbox.go",
"sdk.go",
"sdk_version.go",
+ "shared_properties.go",
"singleton.go",
"singleton_module.go",
"soong_config_modules.go",
@@ -103,6 +103,7 @@
"visibility.go",
],
testSrcs: [
+ "all_teams_test.go",
"android_test.go",
"androidmk_test.go",
"apex_test.go",
diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go
index fcc57e1..4c1782b 100644
--- a/android/aconfig_providers.go
+++ b/android/aconfig_providers.go
@@ -105,7 +105,8 @@
}
})
- for container, aconfigFiles := range *mergedAconfigFiles {
+ for _, container := range SortedKeys(*mergedAconfigFiles) {
+ aconfigFiles := (*mergedAconfigFiles)[container]
(*mergedAconfigFiles)[container] = mergeAconfigFiles(ctx, container, aconfigFiles, false)
}
@@ -172,7 +173,8 @@
})
// We only need to set the provider if we have aconfig files.
if len(mergedAconfigFiles) > 0 {
- for container, aconfigFiles := range mergedAconfigFiles {
+ for _, container := range SortedKeys(mergedAconfigFiles) {
+ aconfigFiles := mergedAconfigFiles[container]
mergedAconfigFiles[container] = mergeAconfigFiles(ctx, container, aconfigFiles, true)
}
diff --git a/android/all_teams.go b/android/all_teams.go
index b177e20..d4bf7d0 100644
--- a/android/all_teams.go
+++ b/android/all_teams.go
@@ -23,9 +23,18 @@
}
// For each module, list the team or the bpFile the module is defined in.
-type moduleTeamInfo struct {
+type moduleTeamAndTestInfo struct {
+ // Name field from bp file for the team
teamName string
- bpFile string
+ // Blueprint file the module is located in.
+ bpFile string
+ // Is this module only used by tests.
+ testOnly bool
+ // Is this a directly testable target by running the module directly
+ // or via tradefed.
+ topLevelTestTarget bool
+ // String name indicating the module, like `java_library` for reporting.
+ kind string
}
type allTeamsSingleton struct {
@@ -37,16 +46,16 @@
// Map of all team modules we visit during GenerateBuildActions
teams map[string]teamProperties
// Keeps track of team information or bp file for each module we visit.
- teams_for_mods map[string]moduleTeamInfo
+ teams_for_mods map[string]moduleTeamAndTestInfo
}
// See if there is a package module for the given bpFilePath with a team defined, if so return the team.
// If not ascend up to the parent directory and do the same.
-func (this *allTeamsSingleton) lookupDefaultTeam(bpFilePath string) (teamProperties, bool) {
+func (t *allTeamsSingleton) lookupDefaultTeam(bpFilePath string) (teamProperties, bool) {
// return the Default_team listed in the package if is there.
- if p, ok := this.packages[bpFilePath]; ok {
- if t := p.Default_team; t != nil {
- return this.teams[*p.Default_team], true
+ if p, ok := t.packages[bpFilePath]; ok {
+ if defaultTeam := p.Default_team; defaultTeam != nil {
+ return t.teams[*defaultTeam], true
}
}
// Strip a directory and go up.
@@ -57,15 +66,15 @@
if current == "." {
return teamProperties{}, false
}
- return this.lookupDefaultTeam(filepath.Join(parent, base))
+ return t.lookupDefaultTeam(filepath.Join(parent, base))
}
-// Create a rule to run a tool to collect all the intermediate files
-// which list the team per module into one proto file.
-func (this *allTeamsSingleton) GenerateBuildActions(ctx SingletonContext) {
- this.packages = make(map[string]packageProperties)
- this.teams = make(map[string]teamProperties)
- this.teams_for_mods = make(map[string]moduleTeamInfo)
+// Visit all modules and collect all teams and use WriteFileRuleVerbatim
+// to write it out.
+func (t *allTeamsSingleton) GenerateBuildActions(ctx SingletonContext) {
+ t.packages = make(map[string]packageProperties)
+ t.teams = make(map[string]teamProperties)
+ t.teams_for_mods = make(map[string]moduleTeamAndTestInfo)
ctx.VisitAllModules(func(module Module) {
bpFile := ctx.BlueprintFile(module)
@@ -73,56 +82,75 @@
// Package Modules and Team Modules are stored in a map so we can look them up by name for
// modules without a team.
if pack, ok := module.(*packageModule); ok {
- // Packages don't have names, use the blueprint file as the key. we can't get qualifiedModuleId in this context.
+ // Packages don't have names, use the blueprint file as the key. we can't get qualifiedModuleId in t context.
pkgKey := bpFile
- this.packages[pkgKey] = pack.properties
+ t.packages[pkgKey] = pack.properties
return
}
if team, ok := module.(*teamModule); ok {
- this.teams[team.Name()] = team.properties
+ t.teams[team.Name()] = team.properties
return
}
- // If a team name is given for a module, store it.
- // Otherwise store the bpFile so we can do a package walk later.
- if module.base().Team() != "" {
- this.teams_for_mods[module.Name()] = moduleTeamInfo{teamName: module.base().Team(), bpFile: bpFile}
- } else {
- this.teams_for_mods[module.Name()] = moduleTeamInfo{bpFile: bpFile}
+ testModInfo := TestModuleInformation{}
+ if tmi, ok := SingletonModuleProvider(ctx, module, TestOnlyProviderKey); ok {
+ testModInfo = tmi
}
+
+ // Some modules, like java_test_host don't set the provider when the module isn't enabled:
+ // test_only, top_level
+ // AVFHostTestCases{os:linux_glibc,arch:common} {true true}
+ // AVFHostTestCases{os:windows,arch:common} {false false}
+ // Generally variant information of true override false or unset.
+ if testModInfo.TestOnly == false {
+ if prevValue, exists := t.teams_for_mods[module.Name()]; exists {
+ if prevValue.testOnly == true {
+ return
+ }
+ }
+ }
+ entry := moduleTeamAndTestInfo{
+ bpFile: bpFile,
+ testOnly: testModInfo.TestOnly,
+ topLevelTestTarget: testModInfo.TopLevelTarget,
+ kind: ctx.ModuleType(module),
+ teamName: module.base().Team(),
+ }
+ t.teams_for_mods[module.Name()] = entry
+
})
// Visit all modules again and lookup the team name in the package or parent package if the team
// isn't assignged at the module level.
- allTeams := this.lookupTeamForAllModules()
+ allTeams := t.lookupTeamForAllModules()
- this.outputPath = PathForOutput(ctx, ownershipDirectory, allTeamsFile)
+ t.outputPath = PathForOutput(ctx, ownershipDirectory, allTeamsFile)
data, err := proto.Marshal(allTeams)
if err != nil {
ctx.Errorf("Unable to marshal team data. %s", err)
}
- WriteFileRuleVerbatim(ctx, this.outputPath, string(data))
- ctx.Phony("all_teams", this.outputPath)
+ WriteFileRuleVerbatim(ctx, t.outputPath, string(data))
+ ctx.Phony("all_teams", t.outputPath)
}
-func (this *allTeamsSingleton) MakeVars(ctx MakeVarsContext) {
- ctx.DistForGoal("all_teams", this.outputPath)
+func (t *allTeamsSingleton) MakeVars(ctx MakeVarsContext) {
+ ctx.DistForGoal("all_teams", t.outputPath)
}
// Visit every (non-package, non-team) module and write out a proto containing
// either the declared team data for that module or the package default team data for that module.
-func (this *allTeamsSingleton) lookupTeamForAllModules() *team_proto.AllTeams {
- teamsProto := make([]*team_proto.Team, len(this.teams_for_mods))
- for i, moduleName := range SortedKeys(this.teams_for_mods) {
- m, _ := this.teams_for_mods[moduleName]
+func (t *allTeamsSingleton) lookupTeamForAllModules() *team_proto.AllTeams {
+ teamsProto := make([]*team_proto.Team, len(t.teams_for_mods))
+ for i, moduleName := range SortedKeys(t.teams_for_mods) {
+ m, _ := t.teams_for_mods[moduleName]
teamName := m.teamName
var teamProperties teamProperties
found := false
if teamName != "" {
- teamProperties, found = this.teams[teamName]
+ teamProperties, found = t.teams[teamName]
} else {
- teamProperties, found = this.lookupDefaultTeam(m.bpFile)
+ teamProperties, found = t.lookupDefaultTeam(m.bpFile)
}
trendy_team_id := ""
@@ -130,22 +158,18 @@
trendy_team_id = *teamProperties.Trendy_team_id
}
- var files []string
teamData := new(team_proto.Team)
+ *teamData = team_proto.Team{
+ TargetName: proto.String(moduleName),
+ Path: proto.String(m.bpFile),
+ TestOnly: proto.Bool(m.testOnly),
+ TopLevelTarget: proto.Bool(m.topLevelTestTarget),
+ Kind: proto.String(m.kind),
+ }
if trendy_team_id != "" {
- *teamData = team_proto.Team{
- TrendyTeamId: proto.String(trendy_team_id),
- TargetName: proto.String(moduleName),
- Path: proto.String(m.bpFile),
- File: files,
- }
+ teamData.TrendyTeamId = proto.String(trendy_team_id)
} else {
// Clients rely on the TrendyTeamId optional field not being set.
- *teamData = team_proto.Team{
- TargetName: proto.String(moduleName),
- Path: proto.String(m.bpFile),
- File: files,
- }
}
teamsProto[i] = teamData
}
diff --git a/android/all_teams_test.go b/android/all_teams_test.go
index a02b86e..96ed92f 100644
--- a/android/all_teams_test.go
+++ b/android/all_teams_test.go
@@ -24,9 +24,10 @@
func TestAllTeams(t *testing.T) {
t.Parallel()
ctx := GroupFixturePreparers(
- PrepareForTestWithTeamBuildComponents,
+ prepareForTestWithTeamAndFakes,
+ // This adds two variants, one armv7-a-neon, one armv8-a
+ PrepareForTestWithArchMutator,
FixtureRegisterWithContext(func(ctx RegistrationContext) {
- ctx.RegisterModuleType("fake", fakeModuleFactory)
ctx.RegisterParallelSingletonType("all_teams", AllTeamsFactory)
}),
).RunTestWithBp(t, `
@@ -51,6 +52,37 @@
fake {
name: "noteam",
+ test_only: true,
+ }
+ // write the test-only provider value once
+ fake {
+ name: "test-and-team-and-top1",
+ test_only: true,
+ team: "team2",
+ arch: {arm: { skip: false},
+ arm64: { skip: true}},
+ }
+ // write the test-only provider once, but on the other arch
+ fake {
+ name: "test-and-team-and-top2",
+ test_only: true,
+ team: "team2",
+ arch: {arm: { skip: true},
+ arm64: { skip: false}},
+ }
+ // write the test-only provider value twice
+ fake {
+ name: "test-and-team-and-top3",
+ test_only: true,
+ team: "team2",
+ }
+ // Don't write the test-only provider value
+ fake {
+ name: "test-and-team-and-top4",
+ test_only: true,
+ team: "team2",
+ arch: {arm: { skip: true},
+ arm64: { skip: true}},
}
`)
@@ -58,17 +90,43 @@
teams = getTeamProtoOutput(t, ctx)
// map of module name -> trendy team name.
- actualTeams := make(map[string]*string)
+ actualTeams := make(map[string]string)
+ actualTests := []string{}
+ actualTopLevelTests := []string{}
+
for _, teamProto := range teams.Teams {
- actualTeams[teamProto.GetTargetName()] = teamProto.TrendyTeamId
+ if teamProto.TrendyTeamId != nil {
+ actualTeams[teamProto.GetTargetName()] = *teamProto.TrendyTeamId
+ } else {
+ actualTeams[teamProto.GetTargetName()] = ""
+ }
+ if teamProto.GetTestOnly() {
+ actualTests = append(actualTests, teamProto.GetTargetName())
+ }
+ if teamProto.GetTopLevelTarget() {
+ actualTopLevelTests = append(actualTopLevelTests, teamProto.GetTargetName())
+ }
}
- expectedTeams := map[string]*string{
- "main_test": proto.String("cool_team"),
- "tool": proto.String("22222"),
- "noteam": nil,
+ expectedTeams := map[string]string{
+ "main_test": "cool_team",
+ "tool": "22222",
+ "test-and-team-and-top1": "22222",
+ "test-and-team-and-top2": "22222",
+ "test-and-team-and-top3": "22222",
+ "test-and-team-and-top4": "22222",
+ "noteam": "",
}
+ expectedTests := []string{
+ "noteam",
+ "test-and-team-and-top1",
+ "test-and-team-and-top2",
+ "test-and-team-and-top3",
+ // There should be no test-and-team-top4 as we skip writing all variants
+ // test-only for all variants
+ }
AssertDeepEquals(t, "compare maps", expectedTeams, actualTeams)
+ AssertDeepEquals(t, "test matchup", expectedTests, actualTests)
}
func getTeamProtoOutput(t *testing.T, ctx *TestResult) *team_proto.AllTeams {
@@ -171,10 +229,9 @@
} `
ctx := GroupFixturePreparers(
- PrepareForTestWithTeamBuildComponents,
+ prepareForTestWithTeamAndFakes,
PrepareForTestWithPackageModule,
FixtureRegisterWithContext(func(ctx RegistrationContext) {
- ctx.RegisterModuleType("fake", fakeModuleFactory)
ctx.RegisterParallelSingletonType("all_teams", AllTeamsFactory)
}),
FixtureAddTextFile("Android.bp", rootBp),
@@ -206,3 +263,37 @@
}
AssertDeepEquals(t, "compare maps", expectedTeams, actualTeams)
}
+
+type fakeForTests struct {
+ ModuleBase
+
+ sourceProperties SourceProperties
+ props struct {
+ // If true, don't write test-only value in provider
+ Skip bool `android:"arch_variant"`
+ }
+}
+
+func fakeFactory() Module {
+ module := &fakeForTests{}
+ module.AddProperties(&module.sourceProperties, &module.props)
+ InitAndroidArchModule(module, HostAndDeviceSupported, MultilibBoth)
+
+ return module
+}
+
+var prepareForTestWithTeamAndFakes = GroupFixturePreparers(
+ FixtureRegisterWithContext(RegisterTeamBuildComponents),
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.RegisterModuleType("fake", fakeFactory)
+ }),
+)
+
+func (f *fakeForTests) GenerateAndroidBuildActions(ctx ModuleContext) {
+ if Bool(f.sourceProperties.Test_only) {
+ SetProvider(ctx, TestOnlyProviderKey, TestModuleInformation{
+ TestOnly: Bool(f.sourceProperties.Test_only) && !f.props.Skip,
+ TopLevelTarget: false,
+ })
+ }
+}
diff --git a/android/apex.go b/android/apex.go
index 8759905..dc0aeed 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "slices"
"sort"
"strconv"
"strings"
@@ -89,7 +90,13 @@
TestApexes []string
}
-var ApexInfoProvider = blueprint.NewMutatorProvider[ApexInfo]("apex")
+// AllApexInfo holds the ApexInfo of all apexes that include this module.
+type AllApexInfo struct {
+ ApexInfos []ApexInfo
+}
+
+var ApexInfoProvider = blueprint.NewMutatorProvider[ApexInfo]("apex_mutate")
+var AllApexInfoProvider = blueprint.NewMutatorProvider[*AllApexInfo]("apex_info")
func (i ApexInfo) AddJSONData(d *map[string]interface{}) {
(*d)["Apex"] = map[string]interface{}{
@@ -108,7 +115,7 @@
// are configured to have the same alias variation named apex29. Whether platform APIs is allowed
// or not also matters; if two APEXes don't have the same allowance, they get different names and
// thus wouldn't be merged.
-func (i ApexInfo) mergedName(ctx PathContext) string {
+func (i ApexInfo) mergedName() string {
name := "apex" + strconv.Itoa(i.MinSdkVersion.FinalOrFutureInt())
return name
}
@@ -543,17 +550,10 @@
return true
}
-type byApexName []ApexInfo
-
-func (a byApexName) Len() int { return len(a) }
-func (a byApexName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-func (a byApexName) Less(i, j int) bool { return a[i].ApexVariationName < a[j].ApexVariationName }
-
// mergeApexVariations deduplicates apex variations that would build identically into a common
// variation. It returns the reduced list of variations and a list of aliases from the original
// variation names to the new variation names.
-func mergeApexVariations(ctx PathContext, apexInfos []ApexInfo) (merged []ApexInfo, aliases [][2]string) {
- sort.Sort(byApexName(apexInfos))
+func mergeApexVariations(apexInfos []ApexInfo) (merged []ApexInfo, aliases [][2]string) {
seen := make(map[string]int)
for _, apexInfo := range apexInfos {
// If this is for a prebuilt apex then use the actual name of the apex variation to prevent this
@@ -567,7 +567,7 @@
// this one into it, otherwise create a new merged ApexInfo from this one and save it away so
// other ApexInfo instances can be merged into it.
variantName := apexInfo.ApexVariationName
- mergedName := apexInfo.mergedName(ctx)
+ mergedName := apexInfo.mergedName()
if index, exists := seen[mergedName]; exists {
// Variants having the same mergedName are deduped
merged[index].InApexVariants = append(merged[index].InApexVariants, variantName)
@@ -592,73 +592,131 @@
return merged, aliases
}
-// CreateApexVariations mutates a given module into multiple apex variants each of which is for an
-// apexBundle (and/or the platform) where the module is part of.
-func CreateApexVariations(mctx BottomUpMutatorContext, module ApexModule) []Module {
+// IncomingApexTransition is called by apexTransitionMutator.IncomingTransition on modules that can be in apexes.
+// The incomingVariation can be either the name of an apex if the dependency is coming directly from an apex
+// module, or it can be the name of an apex variation (e.g. apex10000) if it is coming from another module that
+// is in the apex.
+func IncomingApexTransition(ctx IncomingTransitionContext, incomingVariation string) string {
+ module := ctx.Module().(ApexModule)
base := module.apexModuleBase()
+ var apexInfos []ApexInfo
+ if allApexInfos, ok := ModuleProvider(ctx, AllApexInfoProvider); ok {
+ apexInfos = allApexInfos.ApexInfos
+ }
+
+ // Dependencies from platform variations go to the platform variation.
+ if incomingVariation == "" {
+ return ""
+ }
+
+ // If this module has no apex variations the use the platform variation.
+ if len(apexInfos) == 0 {
+ return ""
+ }
+
+ // Convert the list of apex infos into from the AllApexInfoProvider into the merged list
+ // of apex variations and the aliases from apex names to apex variations.
+ var aliases [][2]string
+ if !module.UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps {
+ apexInfos, aliases = mergeApexVariations(apexInfos)
+ }
+
+ // Check if the incoming variation matches an apex name, and if so use the corresponding
+ // apex variation.
+ aliasIndex := slices.IndexFunc(aliases, func(alias [2]string) bool {
+ return alias[0] == incomingVariation
+ })
+ if aliasIndex >= 0 {
+ return aliases[aliasIndex][1]
+ }
+
+ // Check if the incoming variation matches an apex variation.
+ apexIndex := slices.IndexFunc(apexInfos, func(info ApexInfo) bool {
+ return info.ApexVariationName == incomingVariation
+ })
+ if apexIndex >= 0 {
+ return incomingVariation
+ }
+
+ return ""
+}
+
+func MutateApexTransition(ctx BaseModuleContext, variation string) {
+ module := ctx.Module().(ApexModule)
+ base := module.apexModuleBase()
+ platformVariation := variation == ""
+
+ var apexInfos []ApexInfo
+ if allApexInfos, ok := ModuleProvider(ctx, AllApexInfoProvider); ok {
+ apexInfos = allApexInfos.ApexInfos
+ }
+
// Shortcut
- if len(base.apexInfos) == 0 {
- return nil
+ if len(apexInfos) == 0 {
+ return
}
// Do some validity checks.
// TODO(jiyong): is this the right place?
- base.checkApexAvailableProperty(mctx)
+ base.checkApexAvailableProperty(ctx)
- var apexInfos []ApexInfo
- var aliases [][2]string
- if !mctx.Module().(ApexModule).UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps {
- apexInfos, aliases = mergeApexVariations(mctx, base.apexInfos)
- } else {
- apexInfos = base.apexInfos
+ if !module.UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps {
+ apexInfos, _ = mergeApexVariations(apexInfos)
}
- // base.apexInfos is only needed to propagate the list of apexes from apexInfoMutator to
- // apexMutator. It is no longer accurate after mergeApexVariations, and won't be copied to
- // all but the first created variant. Clear it so it doesn't accidentally get used later.
- base.apexInfos = nil
- sort.Sort(byApexName(apexInfos))
var inApex ApexMembership
for _, a := range apexInfos {
for _, apexContents := range a.ApexContents {
- inApex = inApex.merge(apexContents.contents[mctx.ModuleName()])
+ inApex = inApex.merge(apexContents.contents[ctx.ModuleName()])
}
}
base.ApexProperties.InAnyApex = true
base.ApexProperties.DirectlyInAnyApex = inApex == directlyInApex
- defaultVariation := ""
- mctx.SetDefaultDependencyVariation(&defaultVariation)
+ if platformVariation && !ctx.Host() && !module.AvailableFor(AvailableToPlatform) {
+ // Do not install the module for platform, but still allow it to output
+ // uninstallable AndroidMk entries in certain cases when they have side
+ // effects. TODO(jiyong): move this routine to somewhere else
+ module.MakeUninstallable()
+ }
+ if !platformVariation {
+ var thisApexInfo ApexInfo
- variations := []string{defaultVariation}
- testApexes := []string{}
+ apexIndex := slices.IndexFunc(apexInfos, func(info ApexInfo) bool {
+ return info.ApexVariationName == variation
+ })
+ if apexIndex >= 0 {
+ thisApexInfo = apexInfos[apexIndex]
+ } else {
+ panic(fmt.Errorf("failed to find apexInfo for incoming variation %q", variation))
+ }
+
+ SetProvider(ctx, ApexInfoProvider, thisApexInfo)
+ }
+
+ // Set the value of TestApexes in every single apex variant.
+ // This allows each apex variant to be aware of the test apexes in the user provided apex_available.
+ var testApexes []string
for _, a := range apexInfos {
- variations = append(variations, a.ApexVariationName)
testApexes = append(testApexes, a.TestApexes...)
}
- modules := mctx.CreateVariations(variations...)
- for i, mod := range modules {
- platformVariation := i == 0
- if platformVariation && !mctx.Host() && !mod.(ApexModule).AvailableFor(AvailableToPlatform) {
- // Do not install the module for platform, but still allow it to output
- // uninstallable AndroidMk entries in certain cases when they have side
- // effects. TODO(jiyong): move this routine to somewhere else
- mod.MakeUninstallable()
- }
- if !platformVariation {
- mctx.SetVariationProvider(mod, ApexInfoProvider, apexInfos[i-1])
- }
- // Set the value of TestApexes in every single apex variant.
- // This allows each apex variant to be aware of the test apexes in the user provided apex_available.
- mod.(ApexModule).apexModuleBase().ApexProperties.TestApexes = testApexes
- }
+ base.ApexProperties.TestApexes = testApexes
- for _, alias := range aliases {
- mctx.CreateAliasVariation(alias[0], alias[1])
- }
+}
- return modules
+func ApexInfoMutator(ctx TopDownMutatorContext, module ApexModule) {
+ base := module.apexModuleBase()
+ if len(base.apexInfos) > 0 {
+ apexInfos := slices.Clone(base.apexInfos)
+ slices.SortFunc(apexInfos, func(a, b ApexInfo) int {
+ return strings.Compare(a.ApexVariationName, b.ApexVariationName)
+ })
+ SetProvider(ctx, AllApexInfoProvider, &AllApexInfo{apexInfos})
+ // base.apexInfos is only needed to propagate the list of apexes from the apex module to its
+ // contents within apexInfoMutator. Clear it so it doesn't accidentally get used later.
+ base.apexInfos = nil
+ }
}
// UpdateUniqueApexVariationsForDeps sets UniqueApexVariationsForDeps if any dependencies that are
@@ -669,13 +727,16 @@
// InApexVariants list in common. It is used instead of DepIsInSameApex because it needs to
// determine if the dep is in the same APEX due to being directly included, not only if it
// is included _because_ it is a dependency.
- anyInSameApex := func(a, b []ApexInfo) bool {
- collectApexes := func(infos []ApexInfo) []string {
- var ret []string
- for _, info := range infos {
- ret = append(ret, info.InApexVariants...)
+ anyInSameApex := func(a, b ApexModule) bool {
+ collectApexes := func(m ApexModule) []string {
+ if allApexInfo, ok := OtherModuleProvider(mctx, m, AllApexInfoProvider); ok {
+ var ret []string
+ for _, info := range allApexInfo.ApexInfos {
+ ret = append(ret, info.InApexVariants...)
+ }
+ return ret
}
- return ret
+ return nil
}
aApexes := collectApexes(a)
@@ -693,7 +754,7 @@
// If any of the dependencies requires unique apex variations, so does this module.
mctx.VisitDirectDeps(func(dep Module) {
if depApexModule, ok := dep.(ApexModule); ok {
- if anyInSameApex(depApexModule.apexModuleBase().apexInfos, am.apexModuleBase().apexInfos) &&
+ if anyInSameApex(depApexModule, am) &&
(depApexModule.UniqueApexVariations() ||
depApexModule.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps) {
am.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps = true
diff --git a/android/apex_contributions.go b/android/apex_contributions.go
index c76d9c2..dd09fbf 100644
--- a/android/apex_contributions.go
+++ b/android/apex_contributions.go
@@ -115,10 +115,6 @@
func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) {
addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
for _, content := range m.Contents() {
- // Skip any apexes that have been added to the product specific ignore list
- if InList(content, ctx.Config().BuildIgnoreApexContributionContents()) {
- continue
- }
// Coverage builds for TARGET_RELEASE=foo should always build from source,
// even if TARGET_RELEASE=foo uses prebuilt mainline modules.
// This is necessary because the checked-in prebuilts were generated with
@@ -141,13 +137,19 @@
}
p := PrebuiltSelectionInfoMap{}
- ctx.VisitDirectDepsWithTag(acDepTag, func(child Module) {
- if m, ok := child.(*apexContributions); ok {
- addContentsToProvider(&p, m)
- } else {
- ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
- }
- })
+ // Skip apex_contributions if BuildApexContributionContents is true
+ // This product config var allows some products in the same family to use mainline modules from source
+ // (e.g. shiba and shiba_fullmte)
+ // Eventually these product variants will have their own release config maps.
+ if !proptools.Bool(ctx.Config().BuildIgnoreApexContributionContents()) {
+ ctx.VisitDirectDepsWithTag(acDepTag, func(child Module) {
+ if m, ok := child.(*apexContributions); ok {
+ addContentsToProvider(&p, m)
+ } else {
+ ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
+ }
+ })
+ }
SetProvider(ctx, PrebuiltSelectionInfoProvider, p)
}
diff --git a/android/apex_test.go b/android/apex_test.go
index ddc730d..347bf7d 100644
--- a/android/apex_test.go
+++ b/android/apex_test.go
@@ -33,10 +33,22 @@
{
name: "single",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantAliases: [][2]string{
{"foo", "apex10000"},
@@ -45,98 +57,231 @@
{
name: "merge",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
- {"bar", FutureApiLevel, false, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "bar",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, false, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, false, nil}},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo", "bar"},
+ InApexModules: []string{"foo", "bar"},
+ }},
wantAliases: [][2]string{
- {"bar", "apex10000"},
{"foo", "apex10000"},
+ {"bar", "apex10000"},
},
},
{
name: "don't merge version",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
- {"bar", uncheckedFinalApiLevel(30), false, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "bar",
+ MinSdkVersion: uncheckedFinalApiLevel(30),
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex30", uncheckedFinalApiLevel(30), false, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
- {"apex10000", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "apex30",
+ MinSdkVersion: uncheckedFinalApiLevel(30),
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantAliases: [][2]string{
- {"bar", "apex30"},
{"foo", "apex10000"},
+ {"bar", "apex30"},
},
},
{
name: "merge updatable",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
- {"bar", FutureApiLevel, true, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "bar",
+ MinSdkVersion: FutureApiLevel,
+ Updatable: true,
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, true, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ Updatable: true,
+ InApexVariants: []string{"foo", "bar"},
+ InApexModules: []string{"foo", "bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantAliases: [][2]string{
- {"bar", "apex10000"},
{"foo", "apex10000"},
+ {"bar", "apex10000"},
},
},
{
name: "don't merge when for prebuilt_apex",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
- {"bar", FutureApiLevel, true, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "bar",
+ MinSdkVersion: FutureApiLevel,
+ Updatable: true,
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
// This one should not be merged in with the others because it is for
// a prebuilt_apex.
- {"baz", FutureApiLevel, true, false, []string{"baz"}, []string{"baz"}, nil, ForPrebuiltApex, nil},
+ {
+ ApexVariationName: "baz",
+ MinSdkVersion: FutureApiLevel,
+ Updatable: true,
+ InApexVariants: []string{"baz"},
+ InApexModules: []string{"baz"},
+ ForPrebuiltApex: ForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, true, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex, nil},
- {"baz", FutureApiLevel, true, false, []string{"baz"}, []string{"baz"}, nil, ForPrebuiltApex, nil},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ Updatable: true,
+ InApexVariants: []string{"foo", "bar"},
+ InApexModules: []string{"foo", "bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "baz",
+ MinSdkVersion: FutureApiLevel,
+ Updatable: true,
+ InApexVariants: []string{"baz"},
+ InApexModules: []string{"baz"},
+ ForPrebuiltApex: ForPrebuiltApex,
+ },
},
wantAliases: [][2]string{
- {"bar", "apex10000"},
{"foo", "apex10000"},
+ {"bar", "apex10000"},
},
},
{
name: "merge different UsePlatformApis but don't allow using platform api",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
- {"bar", FutureApiLevel, false, true, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "bar",
+ MinSdkVersion: FutureApiLevel,
+ UsePlatformApis: true,
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, false, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo", "bar"},
+ InApexModules: []string{"foo", "bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantAliases: [][2]string{
- {"bar", "apex10000"},
{"foo", "apex10000"},
+ {"bar", "apex10000"},
},
},
{
name: "merge same UsePlatformApis and allow using platform api",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, true, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
- {"bar", FutureApiLevel, false, true, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ UsePlatformApis: true,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "bar",
+ MinSdkVersion: FutureApiLevel,
+ UsePlatformApis: true,
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, false, true, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ UsePlatformApis: true,
+ InApexVariants: []string{"foo", "bar"},
+ InApexModules: []string{"foo", "bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantAliases: [][2]string{
- {"bar", "apex10000"},
{"foo", "apex10000"},
+ {"bar", "apex10000"},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- config := TestConfig(t.TempDir(), nil, "", nil)
- ctx := &configErrorWrapper{config: config}
- gotMerged, gotAliases := mergeApexVariations(ctx, tt.in)
+ gotMerged, gotAliases := mergeApexVariations(tt.in)
if !reflect.DeepEqual(gotMerged, tt.wantMerged) {
t.Errorf("mergeApexVariations() gotMerged = %v, want %v", gotMerged, tt.wantMerged)
}
diff --git a/android/arch.go b/android/arch.go
index f430364..3224c3a 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -975,7 +975,7 @@
panic(fmt.Errorf("unexpected tag format %q", field.Tag))
}
// these tags don't need to be present in the runtime generated struct type.
- values = RemoveListFromList(values, []string{"arch_variant", "variant_prepend", "path"})
+ values = RemoveListFromList(values, []string{"arch_variant", "variant_prepend", "path", "replace_instead_of_append"})
if len(values) > 0 {
panic(fmt.Errorf("unknown tags %q in field %q", values, prefix+field.Name))
}
diff --git a/android/base_module_context.go b/android/base_module_context.go
index 3367b06..c5fe585 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -20,7 +20,7 @@
"strings"
"github.com/google/blueprint"
- "github.com/google/blueprint/parser"
+ "github.com/google/blueprint/proptools"
)
// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
@@ -219,7 +219,7 @@
// EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context
// can be used to evaluate the final value of Configurable properties.
- EvaluateConfiguration(parser.SelectType, string) (string, bool)
+ EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue
}
type baseModuleContext struct {
@@ -577,38 +577,6 @@
return sb.String()
}
-func (m *baseModuleContext) EvaluateConfiguration(ty parser.SelectType, condition string) (string, bool) {
- switch ty {
- case parser.SelectTypeReleaseVariable:
- if v, ok := m.Config().productVariables.BuildFlags[condition]; ok {
- return v, true
- }
- return "", false
- case parser.SelectTypeProductVariable:
- // TODO(b/323382414): Might add these on a case-by-case basis
- m.ModuleErrorf("TODO(b/323382414): Product variables are not yet supported in selects")
- return "", false
- case parser.SelectTypeSoongConfigVariable:
- parts := strings.Split(condition, ":")
- namespace := parts[0]
- variable := parts[1]
- if n, ok := m.Config().productVariables.VendorVars[namespace]; ok {
- if v, ok := n[variable]; ok {
- return v, true
- }
- }
- return "", false
- case parser.SelectTypeVariant:
- if condition == "arch" {
- if !m.ArchReady() {
- m.ModuleErrorf("A select on arch was attempted before the arch mutator ran")
- return "", false
- }
- return m.Arch().ArchType.Name, true
- }
- m.ModuleErrorf("Unknown variant " + condition)
- return "", false
- default:
- panic("Should be unreachable")
- }
+func (m *baseModuleContext) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
+ return m.Module().ConfigurableEvaluator(m).EvaluateConfiguration(condition, property)
}
diff --git a/android/config.go b/android/config.go
index 18f89fb..75d135f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -872,7 +872,7 @@
// require them to run and get the current build thumbprint. This ensures they
// don't rebuild on every incremental build when the build thumbprint changes.
func (c *config) BuildThumbprintFile(ctx PathContext) Path {
- return PathForOutput(ctx, String(c.productVariables.BuildThumbprintFile))
+ return PathForArbitraryOutput(ctx, "target", "product", c.DeviceName(), String(c.productVariables.BuildThumbprintFile))
}
// DeviceName returns the name of the current device target.
@@ -949,7 +949,11 @@
}
func (c *config) PlatformMinSupportedTargetSdkVersion() string {
- return String(c.productVariables.Platform_min_supported_target_sdk_version)
+ var val, ok = c.productVariables.BuildFlags["RELEASE_PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION"]
+ if !ok {
+ return ""
+ }
+ return val
}
func (c *config) PlatformBaseOS() string {
@@ -1409,6 +1413,11 @@
return strconv.Itoa(vendorApiLevel - 100)
}
+func IsTrunkStableVendorApiLevel(level string) bool {
+ levelInt, err := strconv.Atoi(level)
+ return err == nil && levelInt >= 202404
+}
+
func (c *config) VendorApiLevelFrozen() bool {
return c.productVariables.GetBuildFlagBool("RELEASE_BOARD_API_LEVEL_FROZEN")
}
@@ -1436,10 +1445,6 @@
return "vendor"
}
-func (c *deviceConfig) VndkVersion() string {
- return String(c.config.productVariables.DeviceVndkVersion)
-}
-
func (c *deviceConfig) RecoverySnapshotVersion() string {
return String(c.config.productVariables.RecoverySnapshotVersion)
}
@@ -1448,10 +1453,6 @@
return StringDefault(c.config.productVariables.DeviceCurrentApiLevelForVendorModules, "current")
}
-func (c *deviceConfig) PlatformVndkVersion() string {
- return String(c.config.productVariables.Platform_vndk_version)
-}
-
func (c *deviceConfig) ExtraVndkVersions() []string {
return c.config.productVariables.ExtraVndkVersions
}
@@ -2126,7 +2127,7 @@
return ret
}
-func (c *config) BuildIgnoreApexContributionContents() []string {
+func (c *config) BuildIgnoreApexContributionContents() *bool {
return c.productVariables.BuildIgnoreApexContributionContents
}
diff --git a/android/config_bp2build.go b/android/config_bp2build.go
deleted file mode 100644
index 4c2fb5e..0000000
--- a/android/config_bp2build.go
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2021 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
-
-import (
- "strings"
-
- "github.com/google/blueprint"
-)
-
-// ExportedVariables is a collection of interdependent configuration variables
-type ExportedVariables struct {
- // Maps containing toolchain variables that are independent of the
- // environment variables of the build.
- exportedStringVars ExportedStringVariables
- exportedStringListVars ExportedStringListVariables
- exportedStringListDictVars ExportedStringListDictVariables
-
- exportedVariableReferenceDictVars ExportedVariableReferenceDictVariables
-
- /// Maps containing variables that are dependent on the build config.
- exportedConfigDependingVars ExportedConfigDependingVariables
-
- pctx PackageContext
-}
-
-// NewExportedVariables creats an empty ExportedVariables struct with non-nil maps
-func NewExportedVariables(pctx PackageContext) ExportedVariables {
- return ExportedVariables{
- exportedStringVars: ExportedStringVariables{},
- exportedStringListVars: ExportedStringListVariables{},
- exportedStringListDictVars: ExportedStringListDictVariables{},
- exportedVariableReferenceDictVars: ExportedVariableReferenceDictVariables{},
- exportedConfigDependingVars: ExportedConfigDependingVariables{},
- pctx: pctx,
- }
-}
-
-// ExportStringStaticVariable declares a static string variable and exports it to
-// Bazel's toolchain.
-func (ev ExportedVariables) ExportStringStaticVariable(name string, value string) {
- ev.pctx.StaticVariable(name, value)
- ev.exportedStringVars.set(name, value)
-}
-
-// ExportStringListStaticVariable declares a static variable and exports it to
-// Bazel's toolchain.
-func (ev ExportedVariables) ExportStringListStaticVariable(name string, value []string) {
- ev.pctx.StaticVariable(name, strings.Join(value, " "))
- ev.exportedStringListVars.set(name, value)
-}
-
-// ExportVariableConfigMethod declares a variable whose value is evaluated at
-// runtime via a function with access to the Config and exports it to Bazel's
-// toolchain.
-func (ev ExportedVariables) ExportVariableConfigMethod(name string, method interface{}) blueprint.Variable {
- ev.exportedConfigDependingVars.set(name, method)
- return ev.pctx.VariableConfigMethod(name, method)
-}
-
-// ExportSourcePathVariable declares a static "source path" variable and exports
-// it to Bazel's toolchain.
-func (ev ExportedVariables) ExportSourcePathVariable(name string, value string) {
- ev.pctx.SourcePathVariable(name, value)
- ev.exportedStringVars.set(name, value)
-}
-
-// ExportVariableFuncVariable declares a variable whose value is evaluated at
-// runtime via a function and exports it to Bazel's toolchain.
-func (ev ExportedVariables) ExportVariableFuncVariable(name string, f func() string) {
- ev.exportedConfigDependingVars.set(name, func(config Config) string {
- return f()
- })
- ev.pctx.VariableFunc(name, func(PackageVarContext) string {
- return f()
- })
-}
-
-// ExportString only exports a variable to Bazel, but does not declare it in Soong
-func (ev ExportedVariables) ExportString(name string, value string) {
- ev.exportedStringVars.set(name, value)
-}
-
-// ExportStringList only exports a variable to Bazel, but does not declare it in Soong
-func (ev ExportedVariables) ExportStringList(name string, value []string) {
- ev.exportedStringListVars.set(name, value)
-}
-
-// ExportStringListDict only exports a variable to Bazel, but does not declare it in Soong
-func (ev ExportedVariables) ExportStringListDict(name string, value map[string][]string) {
- ev.exportedStringListDictVars.set(name, value)
-}
-
-// ExportVariableReferenceDict only exports a variable to Bazel, but does not declare it in Soong
-func (ev ExportedVariables) ExportVariableReferenceDict(name string, value map[string]string) {
- ev.exportedVariableReferenceDictVars.set(name, value)
-}
-
-// ExportedConfigDependingVariables is a mapping of variable names to functions
-// of type func(config Config) string which return the runtime-evaluated string
-// value of a particular variable
-type ExportedConfigDependingVariables map[string]interface{}
-
-func (m ExportedConfigDependingVariables) set(k string, v interface{}) {
- m[k] = v
-}
-
-// ExportedStringVariables is a mapping of variable names to string values
-type ExportedStringVariables map[string]string
-
-func (m ExportedStringVariables) set(k string, v string) {
- m[k] = v
-}
-
-// ExportedStringListVariables is a mapping of variable names to a list of strings
-type ExportedStringListVariables map[string][]string
-
-func (m ExportedStringListVariables) set(k string, v []string) {
- m[k] = v
-}
-
-// ExportedStringListDictVariables is a mapping from variable names to a
-// dictionary which maps keys to lists of strings
-type ExportedStringListDictVariables map[string]map[string][]string
-
-func (m ExportedStringListDictVariables) set(k string, v map[string][]string) {
- m[k] = v
-}
-
-// ExportedVariableReferenceDictVariables is a mapping from variable names to a
-// dictionary which references previously defined variables. This is used to
-// create a Starlark output such as:
-//
-// string_var1 = "string1
-// var_ref_dict_var1 = {
-// "key1": string_var1
-// }
-//
-// This type of variable collection must be expanded last so that it recognizes
-// previously defined variables.
-type ExportedVariableReferenceDictVariables map[string]map[string]string
-
-func (m ExportedVariableReferenceDictVariables) set(k string, v map[string]string) {
- m[k] = v
-}
diff --git a/android/defs.go b/android/defs.go
index dab012d..78cdea2 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -20,8 +20,7 @@
)
var (
- pctx = NewPackageContext("android/soong/android")
- exportedVars = NewExportedVariables(pctx)
+ pctx = NewPackageContext("android/soong/android")
cpPreserveSymlinks = pctx.VariableConfigMethod("cpPreserveSymlinks",
Config.CpPreserveSymlinksFlags)
@@ -104,16 +103,6 @@
Description: "concatenate files to $out",
})
- // ubuntu 14.04 offcially use dash for /bin/sh, and its builtin echo command
- // doesn't support -e option. Therefore we force to use /bin/bash when writing out
- // content to file.
- writeFile = pctx.AndroidStaticRule("writeFile",
- blueprint.RuleParams{
- Command: `rm -f $out && /bin/bash -c 'echo -e -n "$$0" > $out' $content`,
- Description: "writing file $out",
- },
- "content")
-
// Used only when USE_GOMA=true is set, to restrict non-goma jobs to the local parallelism value
localPool = blueprint.NewBuiltinPool("local_pool")
@@ -130,9 +119,6 @@
pctx.VariableFunc("RBEWrapper", func(ctx PackageVarContext) string {
return ctx.Config().RBEWrapper()
})
-
- exportedVars.ExportStringList("NeverAllowNotInIncludeDir", neverallowNotInIncludeDir)
- exportedVars.ExportStringList("NeverAllowNoUseIncludeDir", neverallowNoUseIncludeDir)
}
// GlobToListFileRule creates a rule that writes a list of files matching a pattern to a file.
diff --git a/android/early_module_context.go b/android/early_module_context.go
index 8f75773..cf1b5fc 100644
--- a/android/early_module_context.go
+++ b/android/early_module_context.go
@@ -15,9 +15,10 @@
package android
import (
- "github.com/google/blueprint"
"os"
"text/scanner"
+
+ "github.com/google/blueprint"
)
// EarlyModuleContext provides methods that can be called early, as soon as the properties have
@@ -54,6 +55,9 @@
// PropertyErrorf reports an error at the line number of a property in the module definition.
PropertyErrorf(property, fmt string, args ...interface{})
+ // OtherModulePropertyErrorf reports an error at the line number of a property in the given module definition.
+ OtherModulePropertyErrorf(module Module, property, fmt string, args ...interface{})
+
// Failed returns true if any errors have been reported. In most cases the module can continue with generating
// build rules after an error, allowing it to report additional errors in a single run, but in cases where the error
// has prevented the module from creating necessary data it can return early when Failed returns true.
@@ -167,3 +171,7 @@
func (e *earlyModuleContext) Namespace() *Namespace {
return e.EarlyModuleContext.Namespace().(*Namespace)
}
+
+func (e *earlyModuleContext) OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) {
+ e.EarlyModuleContext.OtherModulePropertyErrorf(module, property, fmt, args)
+}
diff --git a/android/module.go b/android/module.go
index c0597fa..5fe379c 100644
--- a/android/module.go
+++ b/android/module.go
@@ -123,6 +123,8 @@
// TransitivePackagingSpecs returns the PackagingSpecs for this module and any transitive
// dependencies with dependency tags for which IsInstallDepNeeded() returns true.
TransitivePackagingSpecs() []PackagingSpec
+
+ ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator
}
// Qualified id for a module
@@ -1040,12 +1042,12 @@
pv := ctx.Config().productVariables
fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
if fullManifest {
- m.addRequiredDeps(ctx)
+ addRequiredDeps(ctx)
}
}
// addRequiredDeps adds required, target_required, and host_required as dependencies.
-func (m *ModuleBase) addRequiredDeps(ctx BottomUpMutatorContext) {
+func addRequiredDeps(ctx BottomUpMutatorContext) {
addDep := func(target Target, depName string) {
if !ctx.OtherModuleExists(depName) {
if ctx.Config().AllowMissingDependencies() {
@@ -1058,9 +1060,9 @@
// in build/make/core/main.mk.
// TODO(jiyong): the Make-side does this only when the required module is a shared
// library or a native test.
- bothInAndroid := m.Device() && target.Os.Class == Device
- nativeArch := m.Arch().ArchType.Multilib != string(MultilibCommon)
- sameBitness := m.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
+ bothInAndroid := ctx.Device() && target.Os.Class == Device
+ nativeArch := InList(ctx.Arch().ArchType.Multilib, []string{"lib32", "lib64"})
+ sameBitness := ctx.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
if bothInAndroid && nativeArch && !sameBitness {
return
}
@@ -1071,32 +1073,40 @@
}
}
- if m.Device() {
- for _, depName := range m.RequiredModuleNames() {
- for _, target := range ctx.Config().Targets[Android] {
+ var deviceTargets []Target
+ deviceTargets = append(deviceTargets, ctx.Config().Targets[Android]...)
+ deviceTargets = append(deviceTargets, ctx.Config().AndroidCommonTarget)
+
+ var hostTargets []Target
+ hostTargets = append(hostTargets, ctx.Config().Targets[ctx.Config().BuildOS]...)
+ hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget)
+
+ if ctx.Device() {
+ for _, depName := range ctx.Module().RequiredModuleNames() {
+ for _, target := range deviceTargets {
addDep(target, depName)
}
}
- for _, depName := range m.HostRequiredModuleNames() {
- for _, target := range ctx.Config().Targets[ctx.Config().BuildOS] {
+ for _, depName := range ctx.Module().HostRequiredModuleNames() {
+ for _, target := range hostTargets {
addDep(target, depName)
}
}
}
- if m.Host() {
- for _, depName := range m.RequiredModuleNames() {
- for _, target := range ctx.Config().Targets[ctx.Config().BuildOS] {
+ if ctx.Host() {
+ for _, depName := range ctx.Module().RequiredModuleNames() {
+ for _, target := range hostTargets {
// When a host module requires another host module, don't make a
// dependency if they have different OSes (i.e. hostcross).
- if m.Target().HostCross != target.HostCross {
+ if ctx.Target().HostCross != target.HostCross {
continue
}
addDep(target, depName)
}
}
- for _, depName := range m.TargetRequiredModuleNames() {
- for _, target := range ctx.Config().Targets[Android] {
+ for _, depName := range ctx.Module().TargetRequiredModuleNames() {
+ for _, target := range deviceTargets {
addDep(target, depName)
}
}
@@ -1230,6 +1240,10 @@
return distFiles
}
+func (m *ModuleBase) ArchReady() bool {
+ return m.commonProperties.ArchReady
+}
+
func (m *ModuleBase) Target() Target {
return m.commonProperties.CompileTarget
}
@@ -2104,6 +2118,106 @@
return proptools.Bool(m.commonProperties.Native_bridge_supported)
}
+type ConfigAndErrorContext interface {
+ Config() Config
+ OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
+}
+
+type configurationEvalutor struct {
+ ctx ConfigAndErrorContext
+ m Module
+}
+
+func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator {
+ return configurationEvalutor{
+ ctx: ctx,
+ m: m.module,
+ }
+}
+
+func (e configurationEvalutor) PropertyErrorf(property string, fmt string, args ...interface{}) {
+ e.ctx.OtherModulePropertyErrorf(e.m, property, fmt, args)
+}
+
+func (e configurationEvalutor) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
+ ctx := e.ctx
+ m := e.m
+ switch condition.FunctionName {
+ case "release_variable":
+ if len(condition.Args) != 1 {
+ ctx.OtherModulePropertyErrorf(m, property, "release_variable requires 1 argument, found %d", len(condition.Args))
+ return proptools.ConfigurableValueUndefined()
+ }
+ if v, ok := ctx.Config().productVariables.BuildFlags[condition.Args[0]]; ok {
+ return proptools.ConfigurableValueString(v)
+ }
+ return proptools.ConfigurableValueUndefined()
+ case "product_variable":
+ // TODO(b/323382414): Might add these on a case-by-case basis
+ ctx.OtherModulePropertyErrorf(m, property, "TODO(b/323382414): Product variables are not yet supported in selects")
+ return proptools.ConfigurableValueUndefined()
+ case "soong_config_variable":
+ if len(condition.Args) != 2 {
+ ctx.OtherModulePropertyErrorf(m, property, "soong_config_variable requires 2 arguments, found %d", len(condition.Args))
+ return proptools.ConfigurableValueUndefined()
+ }
+ namespace := condition.Args[0]
+ variable := condition.Args[1]
+ if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
+ if v, ok := n[variable]; ok {
+ return proptools.ConfigurableValueString(v)
+ }
+ }
+ return proptools.ConfigurableValueUndefined()
+ case "arch":
+ if len(condition.Args) != 0 {
+ ctx.OtherModulePropertyErrorf(m, property, "arch requires no arguments, found %d", len(condition.Args))
+ return proptools.ConfigurableValueUndefined()
+ }
+ if !m.base().ArchReady() {
+ ctx.OtherModulePropertyErrorf(m, property, "A select on arch was attempted before the arch mutator ran")
+ return proptools.ConfigurableValueUndefined()
+ }
+ return proptools.ConfigurableValueString(m.base().Arch().ArchType.Name)
+ case "os":
+ if len(condition.Args) != 0 {
+ ctx.OtherModulePropertyErrorf(m, property, "os requires no arguments, found %d", len(condition.Args))
+ return proptools.ConfigurableValueUndefined()
+ }
+ // the arch mutator runs after the os mutator, we can just use this to enforce that os is ready.
+ if !m.base().ArchReady() {
+ ctx.OtherModulePropertyErrorf(m, property, "A select on os was attempted before the arch mutator ran (arch runs after os, we use it to lazily detect that os is ready)")
+ return proptools.ConfigurableValueUndefined()
+ }
+ return proptools.ConfigurableValueString(m.base().Os().Name)
+ case "boolean_var_for_testing":
+ // We currently don't have any other boolean variables (we should add support for typing
+ // the soong config variables), so add this fake one for testing the boolean select
+ // functionality.
+ if len(condition.Args) != 0 {
+ ctx.OtherModulePropertyErrorf(m, property, "boolean_var_for_testing requires 0 arguments, found %d", len(condition.Args))
+ return proptools.ConfigurableValueUndefined()
+ }
+
+ if n, ok := ctx.Config().productVariables.VendorVars["boolean_var"]; ok {
+ if v, ok := n["for_testing"]; ok {
+ switch v {
+ case "true":
+ return proptools.ConfigurableValueBool(true)
+ case "false":
+ return proptools.ConfigurableValueBool(false)
+ default:
+ ctx.OtherModulePropertyErrorf(m, property, "testing:my_boolean_var can only be true or false, found %q", v)
+ }
+ }
+ }
+ return proptools.ConfigurableValueUndefined()
+ default:
+ ctx.OtherModulePropertyErrorf(m, property, "Unknown select condition %s", condition.FunctionName)
+ return proptools.ConfigurableValueUndefined()
+ }
+}
+
// ModuleNameWithPossibleOverride returns the name of the OverrideModule that overrides the current
// variant of this OverridableModule, or ctx.ModuleName() if this module is not an OverridableModule
// or if this variant is not overridden.
diff --git a/android/module_context.go b/android/module_context.go
index 1cab630..d3e2770 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -234,6 +234,8 @@
variables map[string]string
}
+var _ ModuleContext = &moduleContext{}
+
func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) {
return pctx, BuildParams{
Rule: ErrorRule,
diff --git a/android/mutator.go b/android/mutator.go
index 0ff4f48..75ba650 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -391,6 +391,7 @@
type IncomingTransitionContext interface {
ArchModuleContext
+ ModuleProviderContext
// Module returns the target of the dependency edge for which the transition
// is being computed
@@ -404,6 +405,7 @@
type OutgoingTransitionContext interface {
ArchModuleContext
+ ModuleProviderContext
// Module returns the target of the dependency edge for which the transition
// is being computed
@@ -505,6 +507,7 @@
type androidTransitionMutator struct {
finalPhase bool
mutator TransitionMutator
+ name string
}
func (a *androidTransitionMutator) Split(ctx blueprint.BaseModuleContext) []string {
@@ -537,6 +540,10 @@
return DeviceConfig{c.bp.Config().(Config).deviceConfig}
}
+func (c *outgoingTransitionContextImpl) provider(provider blueprint.AnyProviderKey) (any, bool) {
+ return c.bp.Provider(provider)
+}
+
func (a *androidTransitionMutator) OutgoingTransition(bpctx blueprint.OutgoingTransitionContext, sourceVariation string) string {
if m, ok := bpctx.Module().(Module); ok {
ctx := outgoingTransitionContextPool.Get().(*outgoingTransitionContextImpl)
@@ -568,6 +575,10 @@
return DeviceConfig{c.bp.Config().(Config).deviceConfig}
}
+func (c *incomingTransitionContextImpl) provider(provider blueprint.AnyProviderKey) (any, bool) {
+ return c.bp.Provider(provider)
+}
+
func (a *androidTransitionMutator) IncomingTransition(bpctx blueprint.IncomingTransitionContext, incomingVariation string) string {
if m, ok := bpctx.Module().(Module); ok {
ctx := incomingTransitionContextPool.Get().(*incomingTransitionContextImpl)
@@ -586,6 +597,9 @@
if am, ok := ctx.Module().(Module); ok {
mctx := bottomUpMutatorContextFactory(ctx, am, a.finalPhase)
defer bottomUpMutatorContextPool.Put(mctx)
+ base := am.base()
+ base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, a.name)
+ base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variation)
a.mutator.Mutate(mctx, variation)
}
}
@@ -594,6 +608,7 @@
atm := &androidTransitionMutator{
finalPhase: x.finalPhase,
mutator: m,
+ name: name,
}
mutator := &mutator{
name: name,
diff --git a/android/path_properties.go b/android/path_properties.go
index ea92565..6210aee 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -109,9 +109,9 @@
case reflect.Struct:
intf := sv.Interface()
if configurable, ok := intf.(proptools.Configurable[string]); ok {
- ret = append(ret, proptools.String(configurable.Evaluate(ctx)))
+ ret = append(ret, configurable.GetOrDefault(ctx, ""))
} else if configurable, ok := intf.(proptools.Configurable[[]string]); ok {
- ret = append(ret, proptools.Slice(configurable.Evaluate(ctx))...)
+ ret = append(ret, configurable.GetOrDefault(ctx, nil)...)
} else {
panic(fmt.Errorf(`field %s in type %s has tag android:"path" but is not a string or slice of strings, it is a %s`,
v.Type().FieldByIndex(i).Name, v.Type(), sv.Type()))
diff --git a/android/paths.go b/android/paths.go
index 61c1258..2b33f67 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -673,7 +673,8 @@
expandedSrcFiles = append(expandedSrcFiles, srcFiles...)
}
- return expandedSrcFiles, append(missingDeps, missingExcludeDeps...)
+ // TODO: b/334169722 - Replace with an error instead of implicitly removing duplicates.
+ return FirstUniquePaths(expandedSrcFiles), append(missingDeps, missingExcludeDeps...)
}
type missingDependencyError struct {
@@ -1831,17 +1832,13 @@
return base.Join(ctx, pathComponents...)
}
-func pathForNdkOrSdkInstall(ctx PathContext, prefix string, paths []string) InstallPath {
- base := pathForPartitionInstallDir(ctx, "", prefix, false)
- return base.Join(ctx, paths...)
-}
-
-func PathForNdkInstall(ctx PathContext, paths ...string) InstallPath {
- return pathForNdkOrSdkInstall(ctx, "ndk", paths)
+func PathForNdkInstall(ctx PathContext, paths ...string) OutputPath {
+ return PathForOutput(ctx, append([]string{"ndk"}, paths...)...)
}
func PathForMainlineSdksInstall(ctx PathContext, paths ...string) InstallPath {
- return pathForNdkOrSdkInstall(ctx, "mainline-sdks", paths)
+ base := pathForPartitionInstallDir(ctx, "", "mainline-sdks", false)
+ return base.Join(ctx, paths...)
}
func InstallPathToOnDevicePath(ctx PathContext, path InstallPath) string {
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 5a94a0f..2b7b55b 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -71,6 +71,9 @@
//
// If specified then the prefer property is ignored in favor of the value of the Soong config
// variable.
+ //
+ // DEPRECATED: This property is being deprecated b/308188211.
+ // Use RELEASE_APEX_CONTRIBUTIONS build flags to select prebuilts of mainline modules.
Use_source_config_var *ConfigVarProperties
}
@@ -703,11 +706,6 @@
return true
}
- // If the use_source_config_var property is set then it overrides the prefer property setting.
- if configVar := p.properties.Use_source_config_var; configVar != nil {
- return !ctx.Config().VendorConfig(proptools.String(configVar.Config_namespace)).Bool(proptools.String(configVar.Var_name))
- }
-
// TODO: use p.Properties.Name and ctx.ModuleDir to override preference
return Bool(p.properties.Prefer)
}
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 2241b08..2574ed4 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -295,158 +295,6 @@
}`,
prebuilt: []OsType{Android, buildOS},
},
- {
- name: "prebuilt use_source_config_var={acme, use_source} - no var specified",
- modules: `
- source {
- name: "bar",
- }
-
- prebuilt {
- name: "bar",
- use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
- srcs: ["prebuilt_file"],
- }`,
- // When use_source_env is specified then it will use the prebuilt by default if the environment
- // variable is not set.
- prebuilt: []OsType{Android, buildOS},
- },
- {
- name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=false",
- modules: `
- source {
- name: "bar",
- }
-
- prebuilt {
- name: "bar",
- use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
- srcs: ["prebuilt_file"],
- }`,
- preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
- variables.VendorVars = map[string]map[string]string{
- "acme": {
- "use_source": "false",
- },
- }
- }),
- // Setting the environment variable named in use_source_env to false will cause the prebuilt to
- // be used.
- prebuilt: []OsType{Android, buildOS},
- },
- {
- name: "apex_contributions supersedes any source preferred via use_source_config_var",
- modules: `
- source {
- name: "bar",
- }
-
- prebuilt {
- name: "bar",
- use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
- srcs: ["prebuilt_file"],
- }
- apex_contributions {
- name: "my_mainline_module_contribution",
- api_domain: "apexfoo",
- // this metadata module contains prebuilt
- contents: ["prebuilt_bar"],
- }
- all_apex_contributions {
- name: "all_apex_contributions",
- }
- `,
- preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
- variables.VendorVars = map[string]map[string]string{
- "acme": {
- "use_source": "true",
- },
- }
- variables.BuildFlags = map[string]string{
- "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contribution",
- }
- }),
- // use_source_config_var indicates that source should be used
- // but this is superseded by `my_mainline_module_contribution`
- prebuilt: []OsType{Android, buildOS},
- },
- {
- name: "apex_contributions supersedes any prebuilt preferred via use_source_config_var",
- modules: `
- source {
- name: "bar",
- }
-
- prebuilt {
- name: "bar",
- use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
- srcs: ["prebuilt_file"],
- }
- apex_contributions {
- name: "my_mainline_module_contribution",
- api_domain: "apexfoo",
- // this metadata module contains source
- contents: ["bar"],
- }
- all_apex_contributions {
- name: "all_apex_contributions",
- }
- `,
- preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
- variables.VendorVars = map[string]map[string]string{
- "acme": {
- "use_source": "false",
- },
- }
- variables.BuildFlags = map[string]string{
- "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contribution",
- }
- }),
- // use_source_config_var indicates that prebuilt should be used
- // but this is superseded by `my_mainline_module_contribution`
- prebuilt: nil,
- },
- {
- name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true",
- modules: `
- source {
- name: "bar",
- }
-
- prebuilt {
- name: "bar",
- use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
- srcs: ["prebuilt_file"],
- }`,
- preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
- variables.VendorVars = map[string]map[string]string{
- "acme": {
- "use_source": "true",
- },
- }
- }),
- // Setting the environment variable named in use_source_env to true will cause the source to be
- // used.
- prebuilt: nil,
- },
- {
- name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true, no source",
- modules: `
- prebuilt {
- name: "bar",
- use_source_config_var: {config_namespace: "acme", var_name: "use_source"},
- srcs: ["prebuilt_file"],
- }`,
- preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) {
- variables.VendorVars = map[string]map[string]string{
- "acme": {
- "use_source": "true",
- },
- }
- }),
- // Although the environment variable says to use source there is no source available.
- prebuilt: []OsType{Android, buildOS},
- },
}
fs := MockFS{
diff --git a/android/selects_test.go b/android/selects_test.go
index b4e226f..f912ce6 100644
--- a/android/selects_test.go
+++ b/android/selects_test.go
@@ -39,7 +39,7 @@
my_string_list: select(soong_config_variable("my_namespace", "my_variable"), {
"a": ["a.cpp"],
"b": ["b.cpp"],
- _: ["c.cpp"],
+ default: ["c.cpp"],
}),
}
`,
@@ -55,7 +55,7 @@
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
"a": "a.cpp",
"b": "b.cpp",
- _: "c.cpp",
+ default: "c.cpp",
}),
}
`,
@@ -71,7 +71,7 @@
my_bool: select(soong_config_variable("my_namespace", "my_variable"), {
"a": true,
"b": false,
- _: true,
+ default: true,
}),
}
`,
@@ -87,7 +87,7 @@
my_paths: select(soong_config_variable("my_namespace", "my_variable"), {
"a": ["foo.txt"],
"b": ["bar.txt"],
- _: ["baz.txt"],
+ default: ["baz.txt"],
}),
}
`,
@@ -103,7 +103,7 @@
my_paths: select(soong_config_variable("my_namespace", "my_variable"), {
"a": [":a"],
"b": [":b"],
- _: [":c"],
+ default: [":c"],
}),
}
`,
@@ -117,11 +117,25 @@
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
"a": "a.cpp",
"b": true,
- _: "c.cpp",
+ default: "c.cpp",
}),
}
`,
- expectedError: `can't assign bool value to string property "my_string\[1\]"`,
+ expectedError: `Android.bp:8:5: Found select statement with differing types "string" and "bool" in its cases`,
+ },
+ {
+ name: "Select type doesn't match property type",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": false,
+ "b": true,
+ default: true,
+ }),
+ }
+ `,
+ expectedError: `can't assign bool value to string property "my_string\[0\]"`,
},
{
name: "String list non-default",
@@ -131,7 +145,7 @@
my_string_list: select(soong_config_variable("my_namespace", "my_variable"), {
"a": ["a.cpp"],
"b": ["b.cpp"],
- _: ["c.cpp"],
+ default: ["c.cpp"],
}),
}
`,
@@ -152,11 +166,11 @@
my_string_list: select(soong_config_variable("my_namespace", "my_variable"), {
"a": ["a.cpp"],
"b": ["b.cpp"],
- _: ["c.cpp"],
+ default: ["c.cpp"],
}) + select(soong_config_variable("my_namespace", "my_variable_2"), {
"a2": ["a2.cpp"],
"b2": ["b2.cpp"],
- _: ["c2.cpp"],
+ default: ["c2.cpp"],
}),
}
`,
@@ -177,7 +191,7 @@
my_string_list: ["literal.cpp"] + select(soong_config_variable("my_namespace", "my_variable"), {
"a2": ["a2.cpp"],
"b2": ["b2.cpp"],
- _: ["c2.cpp"],
+ default: ["c2.cpp"],
}),
}
`,
@@ -193,7 +207,7 @@
my_string_list: select(soong_config_variable("my_namespace", "my_variable"), {
"a2": ["a2.cpp"],
"b2": ["b2.cpp"],
- _: ["c2.cpp"],
+ default: ["c2.cpp"],
}) + ["literal.cpp"],
}
`,
@@ -202,18 +216,41 @@
},
},
{
- name: "Can't append bools",
+ name: "true + false = true",
bp: `
my_module_type {
name: "foo",
my_bool: select(soong_config_variable("my_namespace", "my_variable"), {
"a": true,
"b": false,
- _: true,
+ default: true,
}) + false,
}
`,
- expectedError: "my_bool: Cannot append bools",
+ provider: selectsTestProvider{
+ my_bool: proptools.BoolPtr(true),
+ },
+ },
+ {
+ name: "false + false = false",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_bool: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": true,
+ "b": false,
+ default: true,
+ }) + false,
+ }
+ `,
+ vendorVars: map[string]map[string]string{
+ "my_namespace": {
+ "my_variable": "b",
+ },
+ },
+ provider: selectsTestProvider{
+ my_bool: proptools.BoolPtr(false),
+ },
},
{
name: "Append string",
@@ -223,7 +260,7 @@
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
"a": "a",
"b": "b",
- _: "c",
+ default: "c",
}) + ".cpp",
}
`,
@@ -232,16 +269,16 @@
},
},
{
- name: "Select on variant",
+ name: "Select on arch",
bp: `
my_module_type {
name: "foo",
- my_string: select(variant("arch"), {
+ my_string: select(arch(), {
"x86": "my_x86",
"x86_64": "my_x86_64",
"arm": "my_arm",
"arm64": "my_arm64",
- _: "my_default",
+ default: "my_default",
}),
}
`,
@@ -249,14 +286,326 @@
my_string: proptools.StringPtr("my_arm64"),
},
},
+ {
+ name: "Select on os",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(os(), {
+ "android": "my_android",
+ "linux": "my_linux",
+ default: "my_default",
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("my_android"),
+ },
+ },
+ {
+ name: "Unset value",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": unset,
+ "b": "b",
+ default: "c",
+ })
+ }
+ `,
+ vendorVars: map[string]map[string]string{
+ "my_namespace": {
+ "my_variable": "a",
+ },
+ },
+ provider: selectsTestProvider{},
+ },
+ {
+ name: "Unset value on different branch",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": unset,
+ "b": "b",
+ default: "c",
+ })
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("c"),
+ },
+ },
+ {
+ name: "unset + unset = unset",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(soong_config_variable("my_namespace", "my_variable"), {
+ "foo": "bar",
+ default: unset,
+ }) + select(soong_config_variable("my_namespace", "my_variable2"), {
+ "baz": "qux",
+ default: unset,
+ })
+ }
+ `,
+ provider: selectsTestProvider{},
+ },
+ {
+ name: "unset + string = string",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(soong_config_variable("my_namespace", "my_variable"), {
+ "foo": "bar",
+ default: unset,
+ }) + select(soong_config_variable("my_namespace", "my_variable2"), {
+ default: "a",
+ })
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("a"),
+ },
+ },
+ {
+ name: "unset + bool = bool",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_bool: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": true,
+ default: unset,
+ }) + select(soong_config_variable("my_namespace", "my_variable2"), {
+ default: true,
+ })
+ }
+ `,
+ provider: selectsTestProvider{
+ my_bool: proptools.BoolPtr(true),
+ },
+ },
+ {
+ name: "defaults with lists are appended",
+ bp: `
+ my_module_type {
+ name: "foo",
+ defaults: ["bar"],
+ my_string_list: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": ["a1"],
+ default: ["b1"],
+ }),
+ }
+ my_defaults {
+ name: "bar",
+ my_string_list: select(soong_config_variable("my_namespace", "my_variable2"), {
+ "a": ["a2"],
+ default: ["b2"],
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string_list: &[]string{"b2", "b1"},
+ },
+ },
+ {
+ name: "Replacing string list",
+ bp: `
+ my_module_type {
+ name: "foo",
+ defaults: ["bar"],
+ replacing_string_list: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": ["a1"],
+ default: ["b1"],
+ }),
+ }
+ my_defaults {
+ name: "bar",
+ replacing_string_list: select(soong_config_variable("my_namespace", "my_variable2"), {
+ "a": ["a2"],
+ default: ["b2"],
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ replacing_string_list: &[]string{"b1"},
+ },
+ },
+ {
+ name: "Multi-condition string 1",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select((
+ soong_config_variable("my_namespace", "my_variable"),
+ soong_config_variable("my_namespace", "my_variable2"),
+ ), {
+ ("a", "b"): "a+b",
+ ("a", default): "a+default",
+ (default, default): "default",
+ }),
+ }
+ `,
+ vendorVars: map[string]map[string]string{
+ "my_namespace": {
+ "my_variable": "a",
+ "my_variable2": "b",
+ },
+ },
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("a+b"),
+ },
+ },
+ {
+ name: "Multi-condition string 2",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select((
+ soong_config_variable("my_namespace", "my_variable"),
+ soong_config_variable("my_namespace", "my_variable2"),
+ ), {
+ ("a", "b"): "a+b",
+ ("a", default): "a+default",
+ (default, default): "default",
+ }),
+ }
+ `,
+ vendorVars: map[string]map[string]string{
+ "my_namespace": {
+ "my_variable": "a",
+ "my_variable2": "c",
+ },
+ },
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("a+default"),
+ },
+ },
+ {
+ name: "Multi-condition string 3",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select((
+ soong_config_variable("my_namespace", "my_variable"),
+ soong_config_variable("my_namespace", "my_variable2"),
+ ), {
+ ("a", "b"): "a+b",
+ ("a", default): "a+default",
+ (default, default): "default",
+ }),
+ }
+ `,
+ vendorVars: map[string]map[string]string{
+ "my_namespace": {
+ "my_variable": "c",
+ "my_variable2": "b",
+ },
+ },
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("default"),
+ },
+ },
+ {
+ name: "Select on boolean",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(boolean_var_for_testing(), {
+ true: "t",
+ false: "f",
+ }),
+ }
+ `,
+ vendorVars: map[string]map[string]string{
+ "boolean_var": {
+ "for_testing": "true",
+ },
+ },
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("t"),
+ },
+ },
+ {
+ name: "Select on boolean false",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(boolean_var_for_testing(), {
+ true: "t",
+ false: "f",
+ }),
+ }
+ `,
+ vendorVars: map[string]map[string]string{
+ "boolean_var": {
+ "for_testing": "false",
+ },
+ },
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("f"),
+ },
+ },
+ {
+ name: "Select on boolean undefined",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(boolean_var_for_testing(), {
+ true: "t",
+ false: "f",
+ }),
+ }
+ `,
+ expectedError: "foo",
+ },
+ {
+ name: "Select on boolean undefined with default",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(boolean_var_for_testing(), {
+ true: "t",
+ false: "f",
+ default: "default",
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("default"),
+ },
+ },
+ {
+ name: "Mismatched condition types",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(boolean_var_for_testing(), {
+ "true": "t",
+ "false": "f",
+ default: "default",
+ }),
+ }
+ `,
+ vendorVars: map[string]map[string]string{
+ "boolean_var": {
+ "for_testing": "false",
+ },
+ },
+ expectedError: "Expected all branches of a select on condition boolean_var_for_testing\\(\\) to have type bool, found string",
+ },
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
fixtures := GroupFixturePreparers(
+ PrepareForTestWithDefaults,
PrepareForTestWithArchMutator,
FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.RegisterModuleType("my_module_type", newSelectsMockModule)
+ ctx.RegisterModuleType("my_defaults", newSelectsMockModuleDefaults)
}),
FixtureModifyProductVariables(func(variables FixtureProductVariables) {
variables.VendorVars = tc.vendorVars
@@ -279,10 +628,11 @@
}
type selectsTestProvider struct {
- my_bool *bool
- my_string *string
- my_string_list *[]string
- my_paths *[]string
+ my_bool *bool
+ my_string *string
+ my_string_list *[]string
+ my_paths *[]string
+ replacing_string_list *[]string
}
func (p *selectsTestProvider) String() string {
@@ -299,16 +649,18 @@
my_string: %s,
my_string_list: %s,
my_paths: %s,
-}`, myBoolStr, myStringStr, p.my_string_list, p.my_paths)
+ replacing_string_list %s,
+}`, myBoolStr, myStringStr, p.my_string_list, p.my_paths, p.replacing_string_list)
}
var selectsTestProviderKey = blueprint.NewProvider[selectsTestProvider]()
type selectsMockModuleProperties struct {
- My_bool proptools.Configurable[bool]
- My_string proptools.Configurable[string]
- My_string_list proptools.Configurable[[]string]
- My_paths proptools.Configurable[[]string] `android:"path"`
+ My_bool proptools.Configurable[bool]
+ My_string proptools.Configurable[string]
+ My_string_list proptools.Configurable[[]string]
+ My_paths proptools.Configurable[[]string] `android:"path"`
+ Replacing_string_list proptools.Configurable[[]string] `android:"replace_instead_of_append,arch_variant"`
}
type selectsMockModule struct {
@@ -319,10 +671,11 @@
func (p *selectsMockModule) GenerateAndroidBuildActions(ctx ModuleContext) {
SetProvider(ctx, selectsTestProviderKey, selectsTestProvider{
- my_bool: p.properties.My_bool.Evaluate(ctx),
- my_string: p.properties.My_string.Evaluate(ctx),
- my_string_list: p.properties.My_string_list.Evaluate(ctx),
- my_paths: p.properties.My_paths.Evaluate(ctx),
+ my_bool: p.properties.My_bool.Get(ctx),
+ my_string: p.properties.My_string.Get(ctx),
+ my_string_list: p.properties.My_string_list.Get(ctx),
+ my_paths: p.properties.My_paths.Get(ctx),
+ replacing_string_list: p.properties.Replacing_string_list.Get(ctx),
})
}
@@ -333,3 +686,23 @@
InitDefaultableModule(m)
return m
}
+
+type selectsMockModuleDefaults struct {
+ ModuleBase
+ DefaultsModuleBase
+}
+
+func (d *selectsMockModuleDefaults) GenerateAndroidBuildActions(ctx ModuleContext) {
+}
+
+func newSelectsMockModuleDefaults() Module {
+ module := &selectsMockModuleDefaults{}
+
+ module.AddProperties(
+ &selectsMockModuleProperties{},
+ )
+
+ InitDefaultsModule(module)
+
+ return module
+}
diff --git a/android/shared_properties.go b/android/shared_properties.go
new file mode 100644
index 0000000..84d68fa
--- /dev/null
+++ b/android/shared_properties.go
@@ -0,0 +1,26 @@
+// Copyright 2024 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
+
+// For storing user-supplied properties about source code on a module to be queried later.
+type SourceProperties struct {
+ // Indicates that the module and its source code are only used in tests, not
+ // production code. Used by coverage reports and potentially other tools.
+ Test_only *bool
+ // Used internally to write if this is a top level test target.
+ // i.e. something that can be run directly or through tradefed as a test.
+ // `java_library` would be false, `java_test` would be true.
+ Top_level_test_target bool `blueprint:"mutated"`
+}
diff --git a/android/singleton.go b/android/singleton.go
index 5f93996..76df1eb 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -87,6 +87,9 @@
// builder whenever a file matching the pattern as added or removed, without rerunning if a
// file that does not match the pattern is added to a searched directory.
GlobWithDeps(pattern string, excludes []string) ([]string, error)
+
+ // OtherModulePropertyErrorf reports an error on the line number of the given property of the given module
+ OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{})
}
type singletonAdaptor struct {
@@ -279,3 +282,7 @@
func (s *singletonContextAdaptor) moduleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) {
return s.SingletonContext.ModuleProvider(module, provider)
}
+
+func (s *singletonContextAdaptor) OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{}) {
+ s.blueprintSingletonContext().OtherModulePropertyErrorf(module, property, format, args)
+}
diff --git a/android/team.go b/android/team.go
index df61f40..c273dc6 100644
--- a/android/team.go
+++ b/android/team.go
@@ -14,6 +14,8 @@
package android
+import "github.com/google/blueprint"
+
func init() {
RegisterTeamBuildComponents(InitRegistrationContext)
}
@@ -37,6 +39,13 @@
properties teamProperties
}
+type TestModuleInformation struct {
+ TestOnly bool
+ TopLevelTarget bool
+}
+
+var TestOnlyProviderKey = blueprint.NewProvider[TestModuleInformation]()
+
// Real work is done for the module that depends on us.
// If needed, the team can serialize the config to json/proto file as well.
func (t *teamModule) GenerateAndroidBuildActions(ctx ModuleContext) {}
diff --git a/android/team_proto/team.pb.go b/android/team_proto/team.pb.go
index 61260cf..8414d17 100644
--- a/android/team_proto/team.pb.go
+++ b/android/team_proto/team.pb.go
@@ -46,6 +46,13 @@
TrendyTeamId *string `protobuf:"bytes,3,opt,name=trendy_team_id,json=trendyTeamId" json:"trendy_team_id,omitempty"`
// OPTIONAL: Files directly owned by this module.
File []string `protobuf:"bytes,4,rep,name=file" json:"file,omitempty"`
+ // OPTIONAL: Is this a test-only module.
+ TestOnly *bool `protobuf:"varint,5,opt,name=test_only,json=testOnly" json:"test_only,omitempty"`
+ // OPTIONAL: Is this intended to be run as a test target.
+ // This target can be run directly as a test or passed to tradefed.
+ TopLevelTarget *bool `protobuf:"varint,6,opt,name=top_level_target,json=topLevelTarget" json:"top_level_target,omitempty"`
+ // OPTIONAL: Name of module kind, i.e. java_library
+ Kind *string `protobuf:"bytes,7,opt,name=kind" json:"kind,omitempty"`
}
func (x *Team) Reset() {
@@ -108,6 +115,27 @@
return nil
}
+func (x *Team) GetTestOnly() bool {
+ if x != nil && x.TestOnly != nil {
+ return *x.TestOnly
+ }
+ return false
+}
+
+func (x *Team) GetTopLevelTarget() bool {
+ if x != nil && x.TopLevelTarget != nil {
+ return *x.TopLevelTarget
+ }
+ return false
+}
+
+func (x *Team) GetKind() string {
+ if x != nil && x.Kind != nil {
+ return *x.Kind
+ }
+ return ""
+}
+
type AllTeams struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -159,20 +187,26 @@
var file_team_proto_rawDesc = []byte{
0x0a, 0x0a, 0x74, 0x65, 0x61, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x74, 0x65,
- 0x61, 0x6d, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x75, 0x0a, 0x04, 0x54, 0x65, 0x61, 0x6d,
- 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4e, 0x61, 0x6d,
- 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
- 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x72, 0x65, 0x6e, 0x64, 0x79, 0x5f,
- 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74,
- 0x72, 0x65, 0x6e, 0x64, 0x79, 0x54, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x66,
- 0x69, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x22,
- 0x32, 0x0a, 0x08, 0x41, 0x6c, 0x6c, 0x54, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x26, 0x0a, 0x05, 0x74,
- 0x65, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x65, 0x61,
- 0x6d, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x65, 0x61, 0x6d, 0x52, 0x05, 0x74, 0x65,
- 0x61, 0x6d, 0x73, 0x42, 0x22, 0x5a, 0x20, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73,
- 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x74, 0x65, 0x61,
- 0x6d, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x61, 0x6d, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd0, 0x01, 0x0a, 0x04, 0x54, 0x65, 0x61,
+ 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4e, 0x61,
+ 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x72, 0x65, 0x6e, 0x64, 0x79,
+ 0x5f, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
+ 0x74, 0x72, 0x65, 0x6e, 0x64, 0x79, 0x54, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04,
+ 0x66, 0x69, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65,
+ 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x05, 0x20,
+ 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x65, 0x73, 0x74, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x28, 0x0a,
+ 0x10, 0x74, 0x6f, 0x70, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65,
+ 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x74, 0x6f, 0x70, 0x4c, 0x65, 0x76, 0x65,
+ 0x6c, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18,
+ 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0x32, 0x0a, 0x08, 0x41,
+ 0x6c, 0x6c, 0x54, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x26, 0x0a, 0x05, 0x74, 0x65, 0x61, 0x6d, 0x73,
+ 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x65, 0x61, 0x6d, 0x52, 0x05, 0x74, 0x65, 0x61, 0x6d, 0x73, 0x42,
+ 0x22, 0x5a, 0x20, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67,
+ 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f,
}
var (
diff --git a/android/team_proto/team.proto b/android/team_proto/team.proto
index 401eccc..69ebf43 100644
--- a/android/team_proto/team.proto
+++ b/android/team_proto/team.proto
@@ -27,6 +27,16 @@
// OPTIONAL: Files directly owned by this module.
repeated string file = 4;
+
+ // OPTIONAL: Is this a test-only module.
+ optional bool test_only = 5;
+
+ // OPTIONAL: Is this intended to be run as a test target.
+ // This target can be run directly as a test or passed to tradefed.
+ optional bool top_level_target = 6;
+
+ // OPTIONAL: Name of module kind, i.e. java_library
+ optional string kind = 7;
}
message AllTeams {
diff --git a/android/team_test.go b/android/team_test.go
index 75b3e9f..ccfcaaa 100644
--- a/android/team_test.go
+++ b/android/team_test.go
@@ -27,16 +27,19 @@
return module
}
+var prepareForTestWithTeamAndFakeBuildComponents = GroupFixturePreparers(
+ FixtureRegisterWithContext(RegisterTeamBuildComponents),
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.RegisterModuleType("fake", fakeModuleFactory)
+ }),
+)
+
func (*fakeModuleForTests) GenerateAndroidBuildActions(ModuleContext) {}
func TestTeam(t *testing.T) {
t.Parallel()
- ctx := GroupFixturePreparers(
- PrepareForTestWithTeamBuildComponents,
- FixtureRegisterWithContext(func(ctx RegistrationContext) {
- ctx.RegisterModuleType("fake", fakeModuleFactory)
- }),
- ).RunTestWithBp(t, `
+ ctx := prepareForTestWithTeamAndFakeBuildComponents.
+ RunTestWithBp(t, `
fake {
name: "main_test",
team: "someteam",
@@ -66,12 +69,7 @@
func TestMissingTeamFails(t *testing.T) {
t.Parallel()
- GroupFixturePreparers(
- PrepareForTestWithTeamBuildComponents,
- FixtureRegisterWithContext(func(ctx RegistrationContext) {
- ctx.RegisterModuleType("fake", fakeModuleFactory)
- }),
- ).
+ prepareForTestWithTeamAndFakeBuildComponents.
ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern("depends on undefined module \"ring-bearer")).
RunTestWithBp(t, `
fake {
@@ -86,9 +84,6 @@
GroupFixturePreparers(
PrepareForTestWithTeamBuildComponents,
PrepareForTestWithPackageModule,
- FixtureRegisterWithContext(func(ctx RegistrationContext) {
- ctx.RegisterModuleType("fake", fakeModuleFactory)
- }),
).
ExtendWithErrorHandler(FixtureExpectsAtLeastOneErrorMatchingPattern("depends on undefined module \"ring-bearer")).
RunTestWithBp(t, `
diff --git a/android/util.go b/android/util.go
index 363b31c..698a856 100644
--- a/android/util.go
+++ b/android/util.go
@@ -524,22 +524,27 @@
return root, suffix, ext
}
-// ShardPaths takes a Paths, and returns a slice of Paths where each one has at most shardSize paths.
-func ShardPaths(paths Paths, shardSize int) []Paths {
- if len(paths) == 0 {
+func shard[T ~[]E, E any](toShard T, shardSize int) []T {
+ if len(toShard) == 0 {
return nil
}
- ret := make([]Paths, 0, (len(paths)+shardSize-1)/shardSize)
- for len(paths) > shardSize {
- ret = append(ret, paths[0:shardSize])
- paths = paths[shardSize:]
+
+ ret := make([]T, 0, (len(toShard)+shardSize-1)/shardSize)
+ for len(toShard) > shardSize {
+ ret = append(ret, toShard[0:shardSize])
+ toShard = toShard[shardSize:]
}
- if len(paths) > 0 {
- ret = append(ret, paths)
+ if len(toShard) > 0 {
+ ret = append(ret, toShard)
}
return ret
}
+// ShardPaths takes a Paths, and returns a slice of Paths where each one has at most shardSize paths.
+func ShardPaths(paths Paths, shardSize int) []Paths {
+ return shard(paths, shardSize)
+}
+
// ShardString takes a string and returns a slice of strings where the length of each one is
// at most shardSize.
func ShardString(s string, shardSize int) []string {
@@ -560,18 +565,7 @@
// ShardStrings takes a slice of strings, and returns a slice of slices of strings where each one has at most shardSize
// elements.
func ShardStrings(s []string, shardSize int) [][]string {
- if len(s) == 0 {
- return nil
- }
- ret := make([][]string, 0, (len(s)+shardSize-1)/shardSize)
- for len(s) > shardSize {
- ret = append(ret, s[0:shardSize])
- s = s[shardSize:]
- }
- if len(s) > 0 {
- ret = append(ret, s)
- }
- return ret
+ return shard(s, shardSize)
}
// CheckDuplicate checks if there are duplicates in given string list.
diff --git a/android/variable.go b/android/variable.go
index 583c950..599f88e 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -137,6 +137,8 @@
Srcs []string
Exclude_srcs []string
Cmd *string
+
+ Deps []string
}
// eng is true for -eng builds, and can be used to turn on additional heavyweight debugging
@@ -197,24 +199,22 @@
BuildThumbprintFile *string `json:",omitempty"`
DisplayBuildNumber *bool `json:",omitempty"`
- Platform_display_version_name *string `json:",omitempty"`
- Platform_version_name *string `json:",omitempty"`
- Platform_sdk_version *int `json:",omitempty"`
- Platform_sdk_codename *string `json:",omitempty"`
- Platform_sdk_version_or_codename *string `json:",omitempty"`
- Platform_sdk_final *bool `json:",omitempty"`
- Platform_sdk_extension_version *int `json:",omitempty"`
- Platform_base_sdk_extension_version *int `json:",omitempty"`
- Platform_version_active_codenames []string `json:",omitempty"`
- Platform_version_all_preview_codenames []string `json:",omitempty"`
- Platform_vndk_version *string `json:",omitempty"`
- Platform_systemsdk_versions []string `json:",omitempty"`
- Platform_security_patch *string `json:",omitempty"`
- Platform_preview_sdk_version *string `json:",omitempty"`
- Platform_min_supported_target_sdk_version *string `json:",omitempty"`
- Platform_base_os *string `json:",omitempty"`
- Platform_version_last_stable *string `json:",omitempty"`
- Platform_version_known_codenames *string `json:",omitempty"`
+ Platform_display_version_name *string `json:",omitempty"`
+ Platform_version_name *string `json:",omitempty"`
+ Platform_sdk_version *int `json:",omitempty"`
+ Platform_sdk_codename *string `json:",omitempty"`
+ Platform_sdk_version_or_codename *string `json:",omitempty"`
+ Platform_sdk_final *bool `json:",omitempty"`
+ Platform_sdk_extension_version *int `json:",omitempty"`
+ Platform_base_sdk_extension_version *int `json:",omitempty"`
+ Platform_version_active_codenames []string `json:",omitempty"`
+ Platform_version_all_preview_codenames []string `json:",omitempty"`
+ Platform_systemsdk_versions []string `json:",omitempty"`
+ Platform_security_patch *string `json:",omitempty"`
+ Platform_preview_sdk_version *string `json:",omitempty"`
+ Platform_base_os *string `json:",omitempty"`
+ Platform_version_last_stable *string `json:",omitempty"`
+ Platform_version_known_codenames *string `json:",omitempty"`
DeviceName *string `json:",omitempty"`
DeviceProduct *string `json:",omitempty"`
@@ -494,7 +494,7 @@
BuildFromSourceStub *bool `json:",omitempty"`
- BuildIgnoreApexContributionContents []string `json:",omitempty"`
+ BuildIgnoreApexContributionContents *bool `json:",omitempty"`
HiddenapiExportableStubs *bool `json:",omitempty"`
@@ -591,7 +591,6 @@
Platform_sdk_final: boolPtr(false),
Platform_version_active_codenames: []string{"S"},
Platform_version_all_preview_codenames: []string{"S"},
- Platform_vndk_version: stringPtr("S"),
HostArch: stringPtr("x86_64"),
HostSecondaryArch: stringPtr("x86"),
diff --git a/apex/Android.bp b/apex/Android.bp
index 27017ae..abae9e2 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -40,7 +40,6 @@
"dexpreopt_bootjars_test.go",
"platform_bootclasspath_test.go",
"systemserver_classpath_fragment_test.go",
- "vndk_test.go",
],
pluginFor: ["soong_build"],
}
diff --git a/apex/aconfig_test.go b/apex/aconfig_test.go
index a179dbf..3e44f0b 100644
--- a/apex/aconfig_test.go
+++ b/apex/aconfig_test.go
@@ -217,6 +217,24 @@
srcs: ["src/lib.rs"],
apex_available: ["myapex"],
}
+ rust_library {
+ name: "libaconfig_storage_read_api", // test mock
+ crate_name: "aconfig_storage_read_api",
+ srcs: ["src/lib.rs"],
+ apex_available: ["myapex"],
+ }
+ rust_library {
+ name: "liblogger", // test mock
+ crate_name: "logger",
+ srcs: ["src/lib.rs"],
+ apex_available: ["myapex"],
+ }
+ rust_library {
+ name: "liblog_rust", // test mock
+ crate_name: "log_rust",
+ srcs: ["src/lib.rs"],
+ apex_available: ["myapex"],
+ }
rust_ffi_shared {
name: "libmy_rust_library",
srcs: ["src/lib.rs"],
@@ -480,6 +498,24 @@
srcs: ["src/lib.rs"],
apex_available: ["myapex"],
}
+ rust_library {
+ name: "libaconfig_storage_read_api", // test mock
+ crate_name: "aconfig_storage_read_api",
+ srcs: ["src/lib.rs"],
+ apex_available: ["myapex"],
+ }
+ rust_library {
+ name: "liblogger", // test mock
+ crate_name: "logger",
+ srcs: ["src/lib.rs"],
+ apex_available: ["myapex"],
+ }
+ rust_library {
+ name: "liblog_rust", // test mock
+ crate_name: "log_rust",
+ srcs: ["src/lib.rs"],
+ apex_available: ["myapex"],
+ }
rust_ffi_shared {
name: "libmy_rust_library",
srcs: ["src/lib.rs"],
@@ -524,6 +560,24 @@
srcs: ["src/lib.rs"],
apex_available: ["myapex"],
}
+ rust_library {
+ name: "libaconfig_storage_read_api", // test mock
+ crate_name: "aconfig_storage_read_api",
+ srcs: ["src/lib.rs"],
+ apex_available: ["myapex"],
+ }
+ rust_library {
+ name: "liblogger", // test mock
+ crate_name: "logger",
+ srcs: ["src/lib.rs"],
+ apex_available: ["myapex"],
+ }
+ rust_library {
+ name: "liblog_rust", // test mock
+ crate_name: "log_rust",
+ srcs: ["src/lib.rs"],
+ apex_available: ["myapex"],
+ }
rust_binary {
name: "my_rust_binary",
srcs: ["foo/bar/MyClass.rs"],
diff --git a/apex/apex.go b/apex/apex.go
index bc91407..ef57d7e 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -73,7 +73,7 @@
// Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether
// it should create a platform variant.
ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
- ctx.BottomUp("apex", apexMutator).Parallel()
+ ctx.Transition("apex", &apexTransitionMutator{})
ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel()
// Register after apex_info mutator so that it can use ApexVariationName
@@ -358,6 +358,8 @@
// be removed from PRODUCT_PACKAGES.
Overrides []string
+ Multilib apexMultilibProperties
+
// Logging parent value.
Logging_parent string
@@ -735,39 +737,25 @@
// suffix indicates the vndk version for vendor/product if vndk is enabled.
// getImageVariation can simply join the result of this function to get the
// image variation name.
-func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
+func (a *apexBundle) getImageVariationPair() (string, string) {
if a.vndkApex {
- return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
+ return cc.VendorVariationPrefix, a.vndkVersion()
}
prefix := android.CoreVariation
- vndkVersion := ""
- if deviceConfig.VndkVersion() != "" {
- if a.SocSpecific() || a.DeviceSpecific() {
- prefix = cc.VendorVariationPrefix
- vndkVersion = deviceConfig.VndkVersion()
- } else if a.ProductSpecific() {
- prefix = cc.ProductVariationPrefix
- vndkVersion = deviceConfig.PlatformVndkVersion()
- }
- } else {
- if a.SocSpecific() || a.DeviceSpecific() {
- prefix = cc.VendorVariation
- } else if a.ProductSpecific() {
- prefix = cc.ProductVariation
- }
- }
- if vndkVersion == "current" {
- vndkVersion = deviceConfig.PlatformVndkVersion()
+ if a.SocSpecific() || a.DeviceSpecific() {
+ prefix = cc.VendorVariation
+ } else if a.ProductSpecific() {
+ prefix = cc.ProductVariation
}
- return prefix, vndkVersion
+ return prefix, ""
}
// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
-func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
- prefix, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig())
+func (a *apexBundle) getImageVariation() string {
+ prefix, vndkVersion := a.getImageVariationPair()
return prefix + vndkVersion
}
@@ -777,7 +765,7 @@
// each target os/architectures, appropriate dependencies are selected by their
// target.<os>.multilib.<type> groups and are added as (direct) dependencies.
targets := ctx.MultiTargets()
- imageVariation := a.getImageVariation(ctx)
+ imageVariation := a.getImageVariation()
a.combineProperties(ctx)
@@ -1096,6 +1084,10 @@
if a, ok := mctx.Module().(ApexInfoMutator); ok {
a.ApexInfoMutator(mctx)
}
+
+ if am, ok := mctx.Module().(android.ApexModule); ok {
+ android.ApexInfoMutator(mctx, am)
+ }
enforceAppUpdatability(mctx)
}
@@ -1296,44 +1288,41 @@
}
}
-// apexMutator visits each module and creates apex variations if the module was marked in the
-// previous run of apexInfoMutator.
-func apexMutator(mctx android.BottomUpMutatorContext) {
- if !mctx.Module().Enabled() {
- return
- }
+type apexTransitionMutator struct{}
- // This is the usual path.
- if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
- android.CreateApexVariations(mctx, am)
- return
- }
-
+func (a *apexTransitionMutator) Split(ctx android.BaseModuleContext) []string {
// apexBundle itself is mutated so that it and its dependencies have the same apex variant.
- if ai, ok := mctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
- apexBundleName := ai.ApexVariationName()
- mctx.CreateVariations(apexBundleName)
- if strings.HasPrefix(apexBundleName, "com.android.art") {
- // Create an alias from the platform variant. This is done to make
- // test_for dependencies work for modules that are split by the APEX
- // mutator, since test_for dependencies always go to the platform variant.
- // This doesn't happen for normal APEXes that are disjunct, so only do
- // this for the overlapping ART APEXes.
- // TODO(b/183882457): Remove this if the test_for functionality is
- // refactored to depend on the proper APEX variants instead of platform.
- mctx.CreateAliasVariation("", apexBundleName)
- }
- } else if o, ok := mctx.Module().(*OverrideApex); ok {
+ if ai, ok := ctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) {
+ return []string{ai.ApexVariationName()}
+ } else if o, ok := ctx.Module().(*OverrideApex); ok {
apexBundleName := o.GetOverriddenModuleName()
if apexBundleName == "" {
- mctx.ModuleErrorf("base property is not set")
- return
+ ctx.ModuleErrorf("base property is not set")
}
- mctx.CreateVariations(apexBundleName)
- if strings.HasPrefix(apexBundleName, "com.android.art") {
- // TODO(b/183882457): See note for CreateAliasVariation above.
- mctx.CreateAliasVariation("", apexBundleName)
- }
+ return []string{apexBundleName}
+ }
+ return []string{""}
+}
+
+func (a *apexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+ return sourceVariation
+}
+
+func (a *apexTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
+ if am, ok := ctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
+ return android.IncomingApexTransition(ctx, incomingVariation)
+ } else if ai, ok := ctx.Module().(ApexInfoMutator); ok {
+ return ai.ApexVariationName()
+ } else if o, ok := ctx.Module().(*OverrideApex); ok {
+ return o.GetOverriddenModuleName()
+ }
+
+ return ""
+}
+
+func (a *apexTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
+ if am, ok := ctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
+ android.MutateApexTransition(ctx, variation)
}
}
@@ -1538,7 +1527,7 @@
// TODO(jiyong): move this info (the sanitizer name, the lib name, etc.) to cc/sanitize.go
// Keep only the mechanism here.
if sanitizerName == "hwaddress" && strings.HasPrefix(a.Name(), "com.android.runtime") {
- imageVariation := a.getImageVariation(ctx)
+ imageVariation := a.getImageVariation()
for _, target := range ctx.MultiTargets() {
if target.Arch.ArchType.Multilib == "lib64" {
addDependenciesForNativeModules(ctx, ApexNativeDependencies{
diff --git a/apex/apex_test.go b/apex/apex_test.go
index b7362b2..2441b02 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -218,7 +218,6 @@
),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = proptools.StringPtr("current")
variables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test")
variables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"}
variables.Platform_sdk_codename = proptools.StringPtr("Q")
@@ -226,7 +225,6 @@
// "Tiramisu" needs to be in the next line for compatibility with soong code,
// not because of these tests specifically (it's not used by the tests)
variables.Platform_version_active_codenames = []string{"Q", "Tiramisu"}
- variables.Platform_vndk_version = proptools.StringPtr("29")
variables.BuildId = proptools.StringPtr("TEST.BUILD_ID")
}),
)
@@ -2062,9 +2060,9 @@
}
`)
- vendorVariant := "android_vendor.29_arm64_armv8-a"
+ vendorVariant := "android_vendor_arm64_armv8-a"
- mylib := ctx.ModuleForTests("mylib", vendorVariant+"_shared_myapex")
+ mylib := ctx.ModuleForTests("mylib", vendorVariant+"_shared_apex29")
// Ensure that mylib links with "current" LLNDK
libFlags := names(mylib.Rule("ld").Args["libFlags"])
@@ -3025,158 +3023,6 @@
ensureListNotContains(t, requireNativeLibs, ":vndk")
}
-func TestVendorApex_use_vndk_as_stable_TryingToIncludeVNDKLib(t *testing.T) {
- testApexError(t, `Trying to include a VNDK library`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libc++"], // libc++ is a VNDK lib
- vendor: true,
- use_vndk_as_stable: true,
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }`)
-}
-
-func TestVendorApex_use_vndk_as_stable(t *testing.T) {
- // myapex myapex2
- // | |
- // mybin ------. mybin2
- // \ \ / |
- // (stable) .---\--------` |
- // \ / \ |
- // \ / \ /
- // libvndk libvendor
- // (vndk)
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- binaries: ["mybin"],
- vendor: true,
- use_vndk_as_stable: true,
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_binary {
- name: "mybin",
- vendor: true,
- shared_libs: ["libvndk", "libvendor"],
- }
- cc_library {
- name: "libvndk",
- vndk: {
- enabled: true,
- },
- vendor_available: true,
- product_available: true,
- }
- cc_library {
- name: "libvendor",
- vendor: true,
- stl: "none",
- }
- apex {
- name: "myapex2",
- key: "myapex.key",
- binaries: ["mybin2"],
- vendor: true,
- use_vndk_as_stable: false,
- updatable: false,
- }
- cc_binary {
- name: "mybin2",
- vendor: true,
- shared_libs: ["libvndk", "libvendor"],
- }
- `,
- android.FixtureModifyConfig(func(config android.Config) {
- config.TestProductVariables.KeepVndk = proptools.BoolPtr(true)
- }),
- )
-
- vendorVariant := "android_vendor.29_arm64_armv8-a"
-
- for _, tc := range []struct {
- name string
- apexName string
- moduleName string
- moduleVariant string
- libs []string
- contents []string
- requireVndkNamespace bool
- }{
- {
- name: "use_vndk_as_stable",
- apexName: "myapex",
- moduleName: "mybin",
- moduleVariant: vendorVariant + "_apex10000",
- libs: []string{
- // should link with vendor variants of VNDK libs(libvndk/libc++)
- "out/soong/.intermediates/libvndk/" + vendorVariant + "_shared/libvndk.so",
- "out/soong/.intermediates/" + cc.DefaultCcCommonTestModulesDir + "libc++/" + vendorVariant + "_shared/libc++.so",
- // unstable Vendor libs as APEX variant
- "out/soong/.intermediates/libvendor/" + vendorVariant + "_shared_apex10000/libvendor.so",
- },
- contents: []string{
- "bin/mybin",
- "lib64/libvendor.so",
- // VNDK libs (libvndk/libc++) are not included
- },
- requireVndkNamespace: true,
- },
- {
- name: "!use_vndk_as_stable",
- apexName: "myapex2",
- moduleName: "mybin2",
- moduleVariant: vendorVariant + "_myapex2",
- libs: []string{
- // should link with "unique" APEX(myapex2) variant of VNDK libs(libvndk/libc++)
- "out/soong/.intermediates/libvndk/" + vendorVariant + "_shared_myapex2/libvndk.so",
- "out/soong/.intermediates/" + cc.DefaultCcCommonTestModulesDir + "libc++/" + vendorVariant + "_shared_myapex2/libc++.so",
- // unstable vendor libs have "merged" APEX variants
- "out/soong/.intermediates/libvendor/" + vendorVariant + "_shared_apex10000/libvendor.so",
- },
- contents: []string{
- "bin/mybin2",
- "lib64/libvendor.so",
- // VNDK libs are included as well
- "lib64/libvndk.so",
- "lib64/libc++.so",
- },
- requireVndkNamespace: false,
- },
- } {
- t.Run(tc.name, func(t *testing.T) {
- // Check linked libs
- ldRule := ctx.ModuleForTests(tc.moduleName, tc.moduleVariant).Rule("ld")
- libs := names(ldRule.Args["libFlags"])
- for _, lib := range tc.libs {
- ensureListContains(t, libs, lib)
- }
- // Check apex contents
- ensureExactContents(t, ctx, tc.apexName, "android_common_"+tc.apexName, tc.contents)
-
- // Check "requireNativeLibs"
- apexManifestRule := ctx.ModuleForTests(tc.apexName, "android_common_"+tc.apexName).Rule("apexManifestRule")
- requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"])
- if tc.requireVndkNamespace {
- ensureListContains(t, requireNativeLibs, ":vndk")
- } else {
- ensureListNotContains(t, requireNativeLibs, ":vndk")
- }
- })
- }
-}
-
func TestProductVariant(t *testing.T) {
ctx := testApex(t, `
apex {
@@ -3202,7 +3048,7 @@
`)
cflags := strings.Fields(
- ctx.ModuleForTests("foo", "android_product.29_arm64_armv8-a_myapex").Rule("cc").Args["cFlags"])
+ ctx.ModuleForTests("foo", "android_product_arm64_armv8-a_apex10000").Rule("cc").Args["cFlags"])
ensureListContains(t, cflags, "-D__ANDROID_VNDK__")
ensureListContains(t, cflags, "-D__ANDROID_APEX__")
ensureListContains(t, cflags, "-D__ANDROID_PRODUCT__")
@@ -3823,166 +3669,6 @@
assertFileListEquals(t, files, actualFiles)
}
-func TestVndkApexCurrent(t *testing.T) {
- commonFiles := []string{
- "lib/libc++.so",
- "lib64/libc++.so",
- "etc/llndk.libraries.29.txt",
- "etc/vndkcore.libraries.29.txt",
- "etc/vndksp.libraries.29.txt",
- "etc/vndkprivate.libraries.29.txt",
- "etc/vndkproduct.libraries.29.txt",
- }
- testCases := []struct {
- vndkVersion string
- expectedFiles []string
- }{
- {
- vndkVersion: "current",
- expectedFiles: append(commonFiles,
- "lib/libvndk.so",
- "lib/libvndksp.so",
- "lib64/libvndk.so",
- "lib64/libvndksp.so"),
- },
- }
- for _, tc := range testCases {
- t.Run("VNDK.current with DeviceVndkVersion="+tc.vndkVersion, func(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "com.android.vndk.current.key",
- updatable: false,
- }
-
- apex_key {
- name: "com.android.vndk.current.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "libvndk",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
-
- cc_library {
- name: "libvndksp",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
-
- // VNDK-Ext should not cause any problems
-
- cc_library {
- name: "libvndk.ext",
- srcs: ["mylib2.cpp"],
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- system_shared_libs: [],
- stl: "none",
- }
-
- cc_library {
- name: "libvndksp.ext",
- srcs: ["mylib2.cpp"],
- vendor: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- extends: "libvndksp",
- },
- system_shared_libs: [],
- stl: "none",
- }
- `+vndkLibrariesTxtFiles("current"), android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = proptools.StringPtr(tc.vndkVersion)
- variables.KeepVndk = proptools.BoolPtr(true)
- }))
- ensureExactContents(t, ctx, "com.android.vndk.current", "android_common", tc.expectedFiles)
- })
- }
-}
-
-func TestVndkApexWithPrebuilt(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "com.android.vndk.current.key",
- updatable: false,
- }
-
- apex_key {
- name: "com.android.vndk.current.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_prebuilt_library_shared {
- name: "libvndk",
- srcs: ["libvndk.so"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
-
- cc_prebuilt_library_shared {
- name: "libvndk.arm",
- srcs: ["libvndk.arm.so"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- enabled: false,
- arch: {
- arm: {
- enabled: true,
- },
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
- `+vndkLibrariesTxtFiles("current"),
- withFiles(map[string][]byte{
- "libvndk.so": nil,
- "libvndk.arm.so": nil,
- }))
- ensureExactContents(t, ctx, "com.android.vndk.current", "android_common", []string{
- "lib/libvndk.so",
- "lib/libvndk.arm.so",
- "lib64/libvndk.so",
- "lib/libc++.so",
- "lib64/libc++.so",
- "etc/*",
- })
-}
-
func vndkLibrariesTxtFiles(vers ...string) (result string) {
for _, v := range vers {
if v == "current" {
@@ -4090,9 +3776,10 @@
func TestVndkApexNameRule(t *testing.T) {
ctx := testApex(t, `
apex_vndk {
- name: "com.android.vndk.current",
+ name: "com.android.vndk.v29",
key: "myapex.key",
file_contexts: ":myapex-file_contexts",
+ vndk_version: "29",
updatable: false,
}
apex_vndk {
@@ -4106,7 +3793,7 @@
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
- }`+vndkLibrariesTxtFiles("28", "current"))
+ }`+vndkLibrariesTxtFiles("28", "29"))
assertApexName := func(expected, moduleName string) {
module := ctx.ModuleForTests(moduleName, "android_common")
@@ -4114,51 +3801,10 @@
ensureContains(t, apexManifestRule.Args["opt"], "-v name "+expected)
}
- assertApexName("com.android.vndk.v29", "com.android.vndk.current")
+ assertApexName("com.android.vndk.v29", "com.android.vndk.v29")
assertApexName("com.android.vndk.v28", "com.android.vndk.v28")
}
-func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "com.android.vndk.current.key",
- file_contexts: ":myapex-file_contexts",
- updatable: false,
- }
-
- apex_key {
- name: "com.android.vndk.current.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "libvndk",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- native_bridge_supported: true,
- host_supported: true,
- vndk: {
- enabled: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
- `+vndkLibrariesTxtFiles("current"),
- withNativeBridgeEnabled)
-
- ensureExactContents(t, ctx, "com.android.vndk.current", "android_common", []string{
- "lib/libvndk.so",
- "lib64/libvndk.so",
- "lib/libc++.so",
- "lib64/libc++.so",
- "etc/*",
- })
-}
-
func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) {
testApexError(t, `module "com.android.vndk.current" .*: native_bridge_supported: .* doesn't support native bridge binary`, `
apex_vndk {
@@ -4259,215 +3905,6 @@
})
}
-func TestVndkApexShouldNotProvideNativeLibs(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "com.android.vndk.current.key",
- file_contexts: ":myapex-file_contexts",
- updatable: false,
- }
-
- apex_key {
- name: "com.android.vndk.current.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "libz",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- stubs: {
- symbol_file: "libz.map.txt",
- versions: ["30"],
- }
- }
- `+vndkLibrariesTxtFiles("current"), withFiles(map[string][]byte{
- "libz.map.txt": nil,
- }))
-
- apexManifestRule := ctx.ModuleForTests("com.android.vndk.current", "android_common").Rule("apexManifestRule")
- provideNativeLibs := names(apexManifestRule.Args["provideNativeLibs"])
- ensureListEmpty(t, provideNativeLibs)
- ensureExactContents(t, ctx, "com.android.vndk.current", "android_common", []string{
- "out/soong/.intermediates/libz/android_vendor.29_arm64_armv8-a_shared/libz.so:lib64/libz.so",
- "out/soong/.intermediates/libz/android_vendor.29_arm_armv7-a-neon_shared/libz.so:lib/libz.so",
- "*/*",
- })
-}
-
-func TestVendorApexWithVndkPrebuilts(t *testing.T) {
- ctx := testApex(t, "",
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = proptools.StringPtr("27")
- }),
- android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
- cc.RegisterVendorSnapshotModules(ctx)
- }),
- withFiles(map[string][]byte{
- "vendor/foo/Android.bp": []byte(`
- apex {
- name: "myapex",
- binaries: ["foo"],
- key: "myapex.key",
- min_sdk_version: "27",
- vendor: true,
- }
-
- cc_binary {
- name: "foo",
- vendor: true,
- srcs: ["abc.cpp"],
- shared_libs: [
- "libllndk",
- "libvndk",
- ],
- nocrt: true,
- system_shared_libs: [],
- min_sdk_version: "27",
- }
-
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `),
- // Simulate VNDK prebuilts with vendor_snapshot
- "prebuilts/vndk/Android.bp": []byte(`
- vndk_prebuilt_shared {
- name: "libllndk",
- version: "27",
- vendor_available: true,
- product_available: true,
- target_arch: "arm64",
- arch: {
- arm64: {
- srcs: ["libllndk.so"],
- },
- },
- }
-
- vndk_prebuilt_shared {
- name: "libvndk",
- version: "27",
- vendor_available: true,
- product_available: true,
- target_arch: "arm64",
- arch: {
- arm64: {
- srcs: ["libvndk.so"],
- },
- },
- vndk: {
- enabled: true,
- },
- min_sdk_version: "27",
- }
-
- vndk_prebuilt_shared {
- name: "libc++",
- version: "27",
- target_arch: "arm64",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- arch: {
- arm64: {
- srcs: ["libc++.so"],
- },
- },
- min_sdk_version: "apex_inherit",
- }
-
- vendor_snapshot {
- name: "vendor_snapshot",
- version: "27",
- arch: {
- arm64: {
- vndk_libs: [
- "libc++",
- "libllndk",
- "libvndk",
- ],
- static_libs: [
- "libc++demangle",
- "libclang_rt.builtins",
- "libunwind",
- ],
- },
- }
- }
-
- vendor_snapshot_static {
- name: "libclang_rt.builtins",
- version: "27",
- target_arch: "arm64",
- vendor: true,
- arch: {
- arm64: {
- src: "libclang_rt.builtins-aarch64-android.a",
- },
- },
- }
-
- vendor_snapshot_static {
- name: "libc++demangle",
- version: "27",
- target_arch: "arm64",
- compile_multilib: "64",
- vendor: true,
- arch: {
- arm64: {
- src: "libc++demangle.a",
- },
- },
- min_sdk_version: "apex_inherit",
- }
-
- vendor_snapshot_static {
- name: "libunwind",
- version: "27",
- target_arch: "arm64",
- compile_multilib: "64",
- vendor: true,
- arch: {
- arm64: {
- src: "libunwind.a",
- },
- },
- min_sdk_version: "apex_inherit",
- }
- `),
- }))
-
- // Should embed the prebuilt VNDK libraries in the apex
- ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{
- "bin/foo",
- "prebuilts/vndk/libc++.so:lib64/libc++.so",
- "prebuilts/vndk/libvndk.so:lib64/libvndk.so",
- })
-
- // Should link foo with prebuilt libraries (shared/static)
- ldRule := ctx.ModuleForTests("foo", "android_vendor.27_arm64_armv8-a_myapex").Rule("ld")
- android.AssertStringDoesContain(t, "should link to prebuilt llndk", ldRule.Args["libFlags"], "prebuilts/vndk/libllndk.so")
- android.AssertStringDoesContain(t, "should link to prebuilt vndk", ldRule.Args["libFlags"], "prebuilts/vndk/libvndk.so")
- android.AssertStringDoesContain(t, "should link to prebuilt libc++demangle", ldRule.Args["libFlags"], "prebuilts/vndk/libc++demangle.a")
- android.AssertStringDoesContain(t, "should link to prebuilt libunwind", ldRule.Args["libFlags"], "prebuilts/vndk/libunwind.a")
-
- // Should declare the LLNDK library as a "required" external dependency
- manifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
- requireNativeLibs := names(manifestRule.Args["requireNativeLibs"])
- ensureListContains(t, requireNativeLibs, "libllndk.so")
-}
-
func TestDependenciesInApexManifest(t *testing.T) {
ctx := testApex(t, `
apex {
@@ -7334,6 +6771,15 @@
bpfs: ["overrideBpf"],
prebuilts: ["override_myetc"],
overrides: ["unknownapex"],
+ compile_multilib: "first",
+ multilib: {
+ lib32: {
+ native_shared_libs: ["mylib32"],
+ },
+ lib64: {
+ native_shared_libs: ["mylib64"],
+ },
+ },
logging_parent: "com.foo.bar",
package_name: "test.overridden.package",
key: "mynewapex.key",
@@ -7391,6 +6837,16 @@
name: "override_myetc",
src: "override_myprebuilt",
}
+
+ cc_library {
+ name: "mylib32",
+ apex_available: [ "myapex" ],
+ }
+
+ cc_library {
+ name: "mylib64",
+ apex_available: [ "myapex" ],
+ }
`, withManifestPackageNameOverrides([]string{"myapex:com.android.myapex"}))
originalVariant := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(android.OverridableModule)
@@ -7658,8 +7114,9 @@
"etc/permissions/foo.xml",
})
// Permission XML should point to the activated path of impl jar of java_sdk_library
- sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_myapex").Rule("java_sdk_xml")
- ensureMatches(t, sdkLibrary.RuleParams.Command, `<library\\n\s+name=\\\"foo\\\"\\n\s+file=\\\"/apex/myapex/javalib/foo.jar\\\"`)
+ sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_myapex").Output("foo.xml")
+ contents := android.ContentFromFileRuleForTests(t, ctx, sdkLibrary)
+ ensureMatches(t, contents, "<library\\n\\s+name=\\\"foo\\\"\\n\\s+file=\\\"/apex/myapex/javalib/foo.jar\\\"")
}
func TestJavaSDKLibrary_WithinApex(t *testing.T) {
@@ -7710,7 +7167,7 @@
// The bar library should depend on the implementation jar.
barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
- if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.impl\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
t.Errorf("expected %q, found %#q", expected, actual)
}
}
@@ -11296,6 +10753,33 @@
],
}
+ rust_library {
+ name: "libaconfig_storage_read_api", // test mock
+ crate_name: "aconfig_storage_read_api",
+ srcs: ["src/lib.rs"],
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ rust_library {
+ name: "liblogger", // test mock
+ crate_name: "logger",
+ srcs: ["src/lib.rs"],
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ rust_library {
+ name: "liblog_rust", // test mock
+ crate_name: "log_rust",
+ srcs: ["src/lib.rs"],
+ apex_available: [
+ "myapex",
+ ],
+ }
+
rust_ffi_shared {
name: "libmy_rust_library",
srcs: ["src/lib.rs"],
@@ -11380,14 +10864,14 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 26 {
- t.Fatalf("Expected 26 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 32 {
+ t.Fatalf("Expected 28 commands, got %d in:\n%s", len(copyCmds), s)
}
- ensureMatches(t, copyCmds[22], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$")
- ensureMatches(t, copyCmds[23], "^cp -f .*/package.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[24], "^cp -f .*/flag.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[25], "^cp -f .*/flag.val .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[28], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[29], "^cp -f .*/package.map .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[30], "^cp -f .*/flag.map .*/image.apex/etc$")
+ ensureMatches(t, copyCmds[31], "^cp -f .*/flag.val .*/image.apex/etc$")
inputs := []string{
"my_aconfig_declarations_foo/intermediate.pb",
@@ -11921,3 +11405,121 @@
checkHideFromMake(t, ctx, tc.expectedVisibleModuleName, tc.expectedHiddenModuleNames)
}
}
+
+func TestAconfifDeclarationsValidation(t *testing.T) {
+ aconfigDeclarationLibraryString := func(moduleNames []string) (ret string) {
+ for _, moduleName := range moduleNames {
+ ret += fmt.Sprintf(`
+ aconfig_declarations {
+ name: "%[1]s",
+ package: "com.example.package",
+ srcs: [
+ "%[1]s.aconfig",
+ ],
+ }
+ java_aconfig_library {
+ name: "%[1]s-lib",
+ aconfig_declarations: "%[1]s",
+ }
+ `, moduleName)
+ }
+ return ret
+ }
+
+ result := android.GroupFixturePreparers(
+ prepareForApexTest,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureWithLastReleaseApis("foo"),
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.SetApiLibraries([]string{"foo"})
+ }),
+ ).RunTestWithBp(t, `
+ java_library {
+ name: "baz-java-lib",
+ static_libs: [
+ "baz-lib",
+ ],
+ }
+ filegroup {
+ name: "qux-filegroup",
+ srcs: [
+ ":qux-lib{.generated_srcjars}",
+ ],
+ }
+ filegroup {
+ name: "qux-another-filegroup",
+ srcs: [
+ ":qux-filegroup",
+ ],
+ }
+ java_library {
+ name: "quux-java-lib",
+ srcs: [
+ "a.java",
+ ],
+ libs: [
+ "quux-lib",
+ ],
+ }
+ java_sdk_library {
+ name: "foo",
+ srcs: [
+ ":qux-another-filegroup",
+ ],
+ api_packages: ["foo"],
+ system: {
+ enabled: true,
+ },
+ module_lib: {
+ enabled: true,
+ },
+ test: {
+ enabled: true,
+ },
+ static_libs: [
+ "bar-lib",
+ ],
+ libs: [
+ "baz-java-lib",
+ "quux-java-lib",
+ ],
+ aconfig_declarations: [
+ "bar",
+ ],
+ }
+ `+aconfigDeclarationLibraryString([]string{"bar", "baz", "qux", "quux"}))
+
+ m := result.ModuleForTests("foo.stubs.source", "android_common")
+ outDir := "out/soong/.intermediates"
+
+ // Arguments passed to aconfig to retrieve the state of the flags defined in the
+ // textproto files
+ aconfigFlagArgs := m.Output("released-flagged-apis-exportable.txt").Args["flags_path"]
+
+ // "bar-lib" is a static_lib of "foo" and is passed to metalava as classpath. Thus the
+ // cache file provided by the associated aconfig_declarations module "bar" should be passed
+ // to aconfig.
+ android.AssertStringDoesContain(t, "cache file of a java_aconfig_library static_lib "+
+ "passed as an input",
+ aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "bar"))
+
+ // "baz-java-lib", which statically depends on "baz-lib", is a lib of "foo" and is passed
+ // to metalava as classpath. Thus the cache file provided by the associated
+ // aconfig_declarations module "baz" should be passed to aconfig.
+ android.AssertStringDoesContain(t, "cache file of a lib that statically depends on "+
+ "java_aconfig_library passed as an input",
+ aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "baz"))
+
+ // "qux-lib" is passed to metalava as src via the filegroup, thus the cache file provided by
+ // the associated aconfig_declarations module "qux" should be passed to aconfig.
+ android.AssertStringDoesContain(t, "cache file of srcs java_aconfig_library passed as an "+
+ "input",
+ aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "qux"))
+
+ // "quux-java-lib" is a lib of "foo" and is passed to metalava as classpath, but does not
+ // statically depend on "quux-lib". Therefore, the cache file provided by the associated
+ // aconfig_declarations module "quux" should not be passed to aconfig.
+ android.AssertStringDoesNotContain(t, "cache file of a lib that does not statically "+
+ "depend on java_aconfig_library not passed as an input",
+ aconfigFlagArgs, fmt.Sprintf("%s/%s/intermediate.pb", outDir, "quux"))
+}
diff --git a/apex/builder.go b/apex/builder.go
index 6ad282a..763ce4d 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -277,7 +277,7 @@
// VNDK APEX name is determined at runtime, so update "name" in apex_manifest
optCommands := []string{}
if a.vndkApex {
- apexName := vndkApexNamePrefix + a.vndkVersion(ctx.DeviceConfig())
+ apexName := vndkApexNamePrefix + a.vndkVersion()
optCommands = append(optCommands, "-v name "+apexName)
}
@@ -293,7 +293,7 @@
}
if android.InList(":vndk", requireNativeLibs) {
- if _, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig()); vndkVersion != "" {
+ if _, vndkVersion := a.getImageVariationPair(); vndkVersion != "" {
optCommands = append(optCommands, "-v vndkVersion "+vndkVersion)
}
}
@@ -485,7 +485,7 @@
}
func isVintfFragment(fi apexFile) bool {
- isVintfFragment, _ := path.Match("etc/vintf/*.xml", fi.path())
+ isVintfFragment, _ := path.Match("etc/vintf/*", fi.path())
return isVintfFragment
}
@@ -1043,7 +1043,7 @@
if a.vndkApex {
overrideName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(vndkApexName)
if overridden {
- return overrideName + ".v" + a.vndkVersion(ctx.DeviceConfig())
+ return overrideName + ".v" + a.vndkVersion()
}
return ""
}
diff --git a/apex/vndk.go b/apex/vndk.go
index 377c1c0..781aa3c 100644
--- a/apex/vndk.go
+++ b/apex/vndk.go
@@ -45,16 +45,12 @@
return bundle
}
-func (a *apexBundle) vndkVersion(config android.DeviceConfig) string {
- vndkVersion := proptools.StringDefault(a.vndkProperties.Vndk_version, "current")
- if vndkVersion == "current" {
- vndkVersion = config.PlatformVndkVersion()
- }
- return vndkVersion
+func (a *apexBundle) vndkVersion() string {
+ return proptools.StringDefault(a.vndkProperties.Vndk_version, "current")
}
type apexVndkProperties struct {
- // Indicates VNDK version of which this VNDK APEX bundles VNDK libs. Default is Platform VNDK Version.
+ // Indicates VNDK version of which this VNDK APEX bundles VNDK libs.
Vndk_version *string
}
@@ -64,7 +60,7 @@
mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType())
}
- vndkVersion := ab.vndkVersion(mctx.DeviceConfig())
+ vndkVersion := ab.vndkVersion()
if vndkVersion != "" {
apiLevel, err := android.ApiLevelFromUser(mctx, vndkVersion)
if err != nil {
@@ -73,17 +69,9 @@
}
targets := mctx.MultiTargets()
- if len(targets) > 0 && apiLevel.LessThan(cc.MinApiForArch(mctx, targets[0].Arch.ArchType)) &&
- vndkVersion != mctx.DeviceConfig().PlatformVndkVersion() {
+ if len(targets) > 0 && apiLevel.LessThan(cc.MinApiForArch(mctx, targets[0].Arch.ArchType)) {
// Disable VNDK APEXes for VNDK versions less than the minimum supported API
- // level for the primary architecture. This validation is skipped if the VNDK
- // version matches the platform VNDK version, which can occur when the device
- // config targets the 'current' VNDK (see `vndkVersion`).
- ab.Disable()
- }
- if proptools.String(ab.vndkProperties.Vndk_version) != "" &&
- mctx.DeviceConfig().PlatformVndkVersion() != "" &&
- apiLevel.GreaterThanOrEqualTo(android.ApiLevelOrPanic(mctx, mctx.DeviceConfig().PlatformVndkVersion())) {
+ // level for the primary architecture.
ab.Disable()
}
}
@@ -93,20 +81,11 @@
func apexVndkDepsMutator(mctx android.BottomUpMutatorContext) {
if m, ok := mctx.Module().(*cc.Module); ok && cc.IsForVndkApex(mctx, m) {
vndkVersion := m.VndkVersion()
- // For VNDK-Lite device, we gather core-variants of VNDK-Sp libraries, which doesn't have VNDK version defined
- if vndkVersion == "" {
- vndkVersion = mctx.DeviceConfig().PlatformVndkVersion()
- }
if vndkVersion == "" {
return
}
-
- if vndkVersion == mctx.DeviceConfig().PlatformVndkVersion() {
- vndkVersion = "current"
- } else {
- vndkVersion = "v" + vndkVersion
- }
+ vndkVersion = "v" + vndkVersion
vndkApexName := "com.android.vndk." + vndkVersion
diff --git a/apex/vndk_test.go b/apex/vndk_test.go
deleted file mode 100644
index 894aece..0000000
--- a/apex/vndk_test.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package apex
-
-import (
- "testing"
-
- "github.com/google/blueprint/proptools"
-
- "android/soong/android"
-)
-
-func TestVndkApexUsesVendorVariant(t *testing.T) {
- bp := `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "mykey",
- updatable: false,
- }
- apex_key {
- name: "mykey",
- }
- cc_library {
- name: "libfoo",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- system_shared_libs: [],
- stl: "none",
- }
- ` + vndkLibrariesTxtFiles("current")
-
- ensureFileSrc := func(t *testing.T, files []fileInApex, path, src string) {
- t.Helper()
- for _, f := range files {
- if f.path == path {
- ensureContains(t, f.src, src)
- return
- }
- }
- t.Errorf("expected path %q not found", path)
- }
-
- t.Run("VNDK lib doesn't have an apex variant", func(t *testing.T) {
- ctx := testApex(t, bp)
-
- // libfoo doesn't have apex variants
- for _, variant := range ctx.ModuleVariantsForTests("libfoo") {
- ensureNotContains(t, variant, "_myapex")
- }
-
- // VNDK APEX doesn't create apex variant
- files := getFiles(t, ctx, "com.android.vndk.current", "android_common")
- ensureFileSrc(t, files, "lib/libfoo.so", "libfoo/android_vendor.29_arm_armv7-a-neon_shared/libfoo.so")
- })
-
- t.Run("VNDK APEX gathers only vendor variants even if product variants are available", func(t *testing.T) {
- ctx := testApex(t, bp)
-
- files := getFiles(t, ctx, "com.android.vndk.current", "android_common")
- ensureFileSrc(t, files, "lib/libfoo.so", "libfoo/android_vendor.29_arm_armv7-a-neon_shared/libfoo.so")
- })
-
- t.Run("VNDK APEX supports coverage variants", func(t *testing.T) {
- ctx := testApex(t, bp,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.GcovCoverage = proptools.BoolPtr(true)
- variables.Native_coverage = proptools.BoolPtr(true)
- }),
- )
-
- files := getFiles(t, ctx, "com.android.vndk.current", "android_common")
- ensureFileSrc(t, files, "lib/libfoo.so", "libfoo/android_vendor.29_arm_armv7-a-neon_shared/libfoo.so")
-
- files = getFiles(t, ctx, "com.android.vndk.current", "android_common_cov")
- ensureFileSrc(t, files, "lib/libfoo.so", "libfoo/android_vendor.29_arm_armv7-a-neon_shared_cov/libfoo.so")
- })
-}
diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go
index 672e852..b5b49b1 100644
--- a/bpfix/bpfix/bpfix_test.go
+++ b/bpfix/bpfix/bpfix_test.go
@@ -19,6 +19,7 @@
import (
"bytes"
"fmt"
+ "os"
"reflect"
"strings"
"testing"
@@ -2215,3 +2216,9 @@
})
}
}
+
+func TestMain(m *testing.M) {
+ // Skip checking Android.mk path with cleaning "ANDROID_BUILD_TOP"
+ os.Setenv("ANDROID_BUILD_TOP", "")
+ os.Exit(m.Run())
+}
diff --git a/cc/Android.bp b/cc/Android.bp
index 9e4b763..5ba9427 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -17,7 +17,6 @@
"soong-fuzz",
"soong-genrule",
"soong-multitree",
- "soong-snapshot",
"soong-testing",
"soong-tradefed",
],
@@ -45,12 +44,10 @@
"sabi.go",
"sdk.go",
"snapshot_prebuilt.go",
- "snapshot_utils.go",
"stl.go",
"strip.go",
"tidy.go",
"util.go",
- "vendor_snapshot.go",
"vndk.go",
"vndk_prebuilt.go",
@@ -94,6 +91,7 @@
"afdo_test.go",
"binary_test.go",
"cc_test.go",
+ "cc_test_only_property_test.go",
"compiler_test.go",
"gen_test.go",
"genrule_test.go",
@@ -111,7 +109,6 @@
"test_data_test.go",
"tidy_test.go",
"vendor_public_library_test.go",
- "vendor_snapshot_test.go",
],
pluginFor: ["soong_build"],
}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 20673e8..ef26366 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -15,8 +15,6 @@
package cc
import (
- "github.com/google/blueprint/proptools"
-
"fmt"
"io"
"path/filepath"
@@ -448,6 +446,7 @@
if c.parsedCoverageXmlPath.String() != "" {
entries.SetString("SOONG_NDK_API_XML", "$(SOONG_NDK_API_XML) "+c.parsedCoverageXmlPath.String())
}
+ entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) // Stubs should not be installed
})
}
@@ -477,79 +476,6 @@
})
}
-func (c *snapshotLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
- // Each vendor snapshot is exported to androidMk only when BOARD_VNDK_VERSION != current
- // and the version of the prebuilt is same as BOARD_VNDK_VERSION.
- if c.shared() {
- entries.Class = "SHARED_LIBRARIES"
- } else if c.static() {
- entries.Class = "STATIC_LIBRARIES"
- } else if c.header() {
- entries.Class = "HEADER_LIBRARIES"
- }
-
- entries.SubName = ""
-
- if c.IsSanitizerEnabled(cfi) {
- entries.SubName += ".cfi"
- } else if c.IsSanitizerEnabled(Hwasan) {
- entries.SubName += ".hwasan"
- }
-
- entries.SubName += c.baseProperties.Androidmk_suffix
-
- entries.ExtraEntries = append(entries.ExtraEntries, func(_ android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- c.libraryDecorator.androidMkWriteExportedFlags(entries)
-
- if c.shared() || c.static() {
- src := c.path.String()
- // For static libraries which aren't installed, directly use Src to extract filename.
- // This is safe: generated snapshot modules have a real path as Src, not a module
- if c.static() {
- src = proptools.String(c.properties.Src)
- }
- path, file := filepath.Split(src)
- stem, suffix, ext := android.SplitFileExt(file)
- entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
- entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
- entries.SetString("LOCAL_MODULE_STEM", stem)
- if c.shared() {
- entries.SetString("LOCAL_MODULE_PATH", path)
- }
- if c.tocFile.Valid() {
- entries.SetString("LOCAL_SOONG_TOC", c.tocFile.String())
- }
-
- if c.shared() && len(c.Properties.Overrides) > 0 {
- entries.SetString("LOCAL_OVERRIDES_MODULES", strings.Join(makeOverrideModuleNames(ctx, c.Properties.Overrides), " "))
- }
- }
-
- if !c.shared() { // static or header
- entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
- }
- })
-}
-
-func (c *snapshotBinaryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
- entries.Class = "EXECUTABLES"
- entries.SubName = c.baseProperties.Androidmk_suffix
-}
-
-func (c *snapshotObjectLinker) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
- entries.Class = "STATIC_LIBRARIES"
- entries.SubName = c.baseProperties.Androidmk_suffix
-
- entries.ExtraFooters = append(entries.ExtraFooters,
- func(w io.Writer, name, prefix, moduleDir string) {
- out := entries.OutputFile.Path()
- varname := fmt.Sprintf("SOONG_%sOBJECT_%s%s", prefix, name, entries.SubName)
-
- fmt.Fprintf(w, "\n%s := %s\n", varname, out.String())
- fmt.Fprintln(w, ".KATI_READONLY: "+varname)
- })
-}
-
func (c *ndkPrebuiltStlLinker) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
entries.Class = "SHARED_LIBRARIES"
}
diff --git a/cc/builder.go b/cc/builder.go
index e4d5be2..845176e 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -375,13 +375,14 @@
localCppFlags string
localLdFlags string
- libFlags string // Flags to add to the linker directly after specifying libraries to link.
- extraLibFlags string // Flags to add to the linker last.
- tidyFlags string // Flags that apply to clang-tidy
- sAbiFlags string // Flags that apply to header-abi-dumps
- aidlFlags string // Flags that apply to aidl source files
- rsFlags string // Flags that apply to renderscript source files
- toolchain config.Toolchain
+ noOverrideFlags string // Flags appended at the end so they are not overridden.
+ libFlags string // Flags to add to the linker directly after specifying libraries to link.
+ extraLibFlags string // Flags to add to the linker last.
+ tidyFlags string // Flags that apply to clang-tidy
+ sAbiFlags string // Flags that apply to header-abi-dumps
+ aidlFlags string // Flags that apply to aidl source files
+ rsFlags string // Flags that apply to renderscript source files
+ toolchain config.Toolchain
// True if these extra features are enabled.
tidy bool
@@ -485,7 +486,8 @@
flags.localCommonFlags + " " +
flags.localToolingCFlags + " " +
flags.localConlyFlags + " " +
- flags.systemIncludeFlags
+ flags.systemIncludeFlags + " " +
+ flags.noOverrideFlags
cflags := flags.globalCommonFlags + " " +
flags.globalCFlags + " " +
@@ -493,7 +495,8 @@
flags.localCommonFlags + " " +
flags.localCFlags + " " +
flags.localConlyFlags + " " +
- flags.systemIncludeFlags
+ flags.systemIncludeFlags + " " +
+ flags.noOverrideFlags
toolingCppflags := flags.globalCommonFlags + " " +
flags.globalToolingCFlags + " " +
@@ -501,7 +504,8 @@
flags.localCommonFlags + " " +
flags.localToolingCFlags + " " +
flags.localToolingCppFlags + " " +
- flags.systemIncludeFlags
+ flags.systemIncludeFlags + " " +
+ flags.noOverrideFlags
cppflags := flags.globalCommonFlags + " " +
flags.globalCFlags + " " +
@@ -509,7 +513,8 @@
flags.localCommonFlags + " " +
flags.localCFlags + " " +
flags.localCppFlags + " " +
- flags.systemIncludeFlags
+ flags.systemIncludeFlags + " " +
+ flags.noOverrideFlags
asflags := flags.globalCommonFlags + " " +
flags.globalAsFlags + " " +
@@ -522,26 +527,6 @@
sAbiDumpFiles = make(android.Paths, 0, len(srcFiles))
}
- cflags += " ${config.NoOverrideGlobalCflags}"
- toolingCflags += " ${config.NoOverrideGlobalCflags}"
- cppflags += " ${config.NoOverrideGlobalCflags}"
- toolingCppflags += " ${config.NoOverrideGlobalCflags}"
-
- if flags.toolchain.Is64Bit() {
- cflags += " ${config.NoOverride64GlobalCflags}"
- toolingCflags += " ${config.NoOverride64GlobalCflags}"
- cppflags += " ${config.NoOverride64GlobalCflags}"
- toolingCppflags += " ${config.NoOverride64GlobalCflags}"
- }
-
- modulePath := ctx.ModuleDir()
- if android.IsThirdPartyPath(modulePath) {
- cflags += " ${config.NoOverrideExternalGlobalCflags}"
- toolingCflags += " ${config.NoOverrideExternalGlobalCflags}"
- cppflags += " ${config.NoOverrideExternalGlobalCflags}"
- toolingCppflags += " ${config.NoOverrideExternalGlobalCflags}"
- }
-
// Multiple source files have build rules usually share the same cFlags or tidyFlags.
// Define only one version in this module and share it in multiple build rules.
// To simplify the code, the shared variables are all named as $flags<nnn>.
@@ -869,14 +854,15 @@
// Generate a rule to combine .dump sAbi dump files from multiple source files
// into a single .ldump sAbi dump file
func transformDumpToLinkedDump(ctx android.ModuleContext, sAbiDumps android.Paths, soFile android.Path,
- baseName, exportedHeaderFlags string, symbolFile android.OptionalPath,
+ baseName string, exportedIncludeDirs []string, symbolFile android.OptionalPath,
excludedSymbolVersions, excludedSymbolTags []string,
- api string) android.OptionalPath {
+ api string) android.Path {
outputFile := android.PathForModuleOut(ctx, baseName+".lsdump")
implicits := android.Paths{soFile}
symbolFilterStr := "-so " + soFile.String()
+ exportedHeaderFlags := android.JoinWithPrefix(exportedIncludeDirs, "-I")
if symbolFile.Valid() {
implicits = append(implicits, symbolFile.Path())
@@ -901,13 +887,7 @@
}
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ABI_LINKER") {
rule = sAbiLinkRE
- rbeImplicits := implicits.Strings()
- for _, p := range strings.Split(exportedHeaderFlags, " ") {
- if len(p) > 2 {
- // Exclude the -I prefix.
- rbeImplicits = append(rbeImplicits, p[2:])
- }
- }
+ rbeImplicits := append(implicits.Strings(), exportedIncludeDirs...)
args["implicitInputs"] = strings.Join(rbeImplicits, ",")
}
ctx.Build(pctx, android.BuildParams{
@@ -918,7 +898,7 @@
Implicits: implicits,
Args: args,
})
- return android.OptionalPathForPath(outputFile)
+ return outputFile
}
func transformAbiDumpToAbiDiff(ctx android.ModuleContext, inputDump, referenceDump android.Path,
diff --git a/cc/cc.go b/cc/cc.go
index 90185ea..e3954d7 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -35,7 +35,6 @@
"android/soong/fuzz"
"android/soong/genrule"
"android/soong/multitree"
- "android/soong/snapshot"
)
func init() {
@@ -137,6 +136,12 @@
ExcludeLibsForApex []string
// List of libs that need to be excluded for non-APEX variant
ExcludeLibsForNonApex []string
+
+ // LLNDK headers for the ABI checker to check LLNDK implementation library.
+ // An LLNDK implementation is the core variant. LLNDK header libs are reexported by the vendor variant.
+ // The core variant cannot depend on the vendor variant because of the order of CreateVariations.
+ // Instead, the LLNDK implementation depends on the LLNDK header libs.
+ LlndkHeaderLibs []string
}
// PathDeps is a struct containing file paths to dependencies of a module.
@@ -192,6 +197,10 @@
// Paths to direct srcs and transitive include dirs from direct aidl_library deps
AidlLibraryInfos []aidl_library.AidlLibraryInfo
+
+ // LLNDK headers for the ABI checker to check LLNDK implementation library.
+ LlndkIncludeDirs android.Paths
+ LlndkSystemIncludeDirs android.Paths
}
// LocalOrGlobalFlags contains flags that need to have values set globally by the build system or locally by the module
@@ -215,7 +224,8 @@
// Local flags (which individual modules are responsible for). These may override global flags.
Local LocalOrGlobalFlags
// Global flags (which build system or toolchain is responsible for).
- Global LocalOrGlobalFlags
+ Global LocalOrGlobalFlags
+ NoOverrideFlags []string // Flags applied to the end of list of flags so they are not overridden
aidlFlags []string // Flags that apply to aidl source files
rsFlags []string // Flags that apply to renderscript source files
@@ -346,11 +356,6 @@
// see soong/cc/config/vndk.go
MustUseVendorVariant bool `blueprint:"mutated"`
- // Used by vendor snapshot to record dependencies from snapshot modules.
- SnapshotSharedLibs []string `blueprint:"mutated"`
- SnapshotStaticLibs []string `blueprint:"mutated"`
- SnapshotRuntimeLibs []string `blueprint:"mutated"`
-
Installable *bool `android:"arch_variant"`
// Set by factories of module types that can only be referenced from variants compiled against
@@ -363,20 +368,6 @@
// variant to have a ".sdk" suffix.
SdkAndPlatformVariantVisibleToMake bool `blueprint:"mutated"`
- // Normally Soong uses the directory structure to decide which modules
- // should be included (framework) or excluded (non-framework) from the
- // different snapshots (vendor, recovery, etc.), but this property
- // allows a partner to exclude a module normally thought of as a
- // framework module from the vendor snapshot.
- Exclude_from_vendor_snapshot *bool
-
- // Normally Soong uses the directory structure to decide which modules
- // should be included (framework) or excluded (non-framework) from the
- // different snapshots (vendor, recovery, etc.), but this property
- // allows a partner to exclude a module normally thought of as a
- // framework module from the recovery snapshot.
- Exclude_from_recovery_snapshot *bool
-
// List of APEXes that this module has private access to for testing purpose. The module
// can depend on libraries that are not exported by the APEXes and use private symbols
// from the exported libraries.
@@ -808,6 +799,7 @@
JniFuzzLibTag = dependencyTag{name: "jni_fuzz_lib_tag"}
FdoProfileTag = dependencyTag{name: "fdo_profile"}
aidlLibraryTag = dependencyTag{name: "aidl_library"}
+ llndkHeaderLibTag = dependencyTag{name: "llndk_header_lib"}
)
func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
@@ -853,6 +845,7 @@
VendorProperties VendorProperties
Properties BaseProperties
+ sourceProperties android.SourceProperties
// initialize before calling Init
hod android.HostOrDeviceSupported
@@ -959,8 +952,6 @@
"IsVndkSp": c.IsVndkSp(),
"IsLlndk": c.IsLlndk(),
"IsLlndkPublic": c.IsLlndkPublic(),
- "IsSnapshotLibrary": c.IsSnapshotLibrary(),
- "IsSnapshotPrebuilt": c.IsSnapshotPrebuilt(),
"IsVendorPublicLibrary": c.IsVendorPublicLibrary(),
"ApexSdkVersion": c.apexSdkVersion,
"TestFor": c.TestFor(),
@@ -1272,6 +1263,10 @@
for _, feature := range c.features {
c.AddProperties(feature.props()...)
}
+ // Allow test-only on libraries that are not cc_test_library
+ if c.library != nil && !c.testLibrary() {
+ c.AddProperties(&c.sourceProperties)
+ }
android.InitAndroidArchModule(c, c.hod, c.multilib)
android.InitApexModule(c)
@@ -1512,14 +1507,6 @@
return false
}
-func (c *Module) ExcludeFromVendorSnapshot() bool {
- return Bool(c.Properties.Exclude_from_vendor_snapshot)
-}
-
-func (c *Module) ExcludeFromRecoverySnapshot() bool {
- return Bool(c.Properties.Exclude_from_recovery_snapshot)
-}
-
func isBionic(name string) bool {
switch name {
case "libc", "libm", "libdl", "libdl_android", "linker":
@@ -1883,7 +1870,6 @@
func getNameSuffixWithVndkVersion(ctx android.ModuleContext, c LinkableInterface) string {
// Returns the name suffix for product and vendor variants. If the VNDK version is not
// "current", it will append the VNDK version to the name suffix.
- var vndkVersion string
var nameSuffix string
if c.InProduct() {
if c.ProductSpecific() {
@@ -1893,13 +1879,9 @@
}
return ProductSuffix
} else {
- vndkVersion = ctx.DeviceConfig().VndkVersion()
nameSuffix = VendorSuffix
}
- if vndkVersion == "current" {
- vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
- }
- if c.VndkVersion() != vndkVersion && c.VndkVersion() != "" {
+ if c.VndkVersion() != "" {
// add version suffix only if the module is using different vndk version than the
// version in product or vendor partition.
nameSuffix += "." + c.VndkVersion()
@@ -2013,6 +1995,20 @@
}
func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
+ ctx := moduleContextFromAndroidModuleContext(actx, c)
+
+ // If Test_only is set on a module in bp file, respect the setting, otherwise
+ // see if is a known test module type.
+ testOnly := c.testModule || c.testLibrary()
+ if c.sourceProperties.Test_only != nil {
+ testOnly = Bool(c.sourceProperties.Test_only)
+ }
+ // Keep before any early returns.
+ android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
+ TestOnly: testOnly,
+ TopLevelTarget: c.testModule,
+ })
+
// Handle the case of a test module split by `test_per_src` mutator.
//
// The `test_per_src` mutator adds an extra variation named "", depending on all the other
@@ -2031,8 +2027,6 @@
c.makeLinkType = GetMakeLinkType(actx, c)
- ctx := moduleContextFromAndroidModuleContext(actx, c)
-
deps := c.depsToPaths(ctx)
if ctx.Failed() {
return
@@ -2154,18 +2148,11 @@
c.outputFile = android.OptionalPathForPath(outputFile)
c.maybeUnhideFromMake()
-
- // glob exported headers for snapshot, if BOARD_VNDK_VERSION is current or
- // RECOVERY_SNAPSHOT_VERSION is current.
- if i, ok := c.linker.(snapshotLibraryInterface); ok {
- if ShouldCollectHeadersForSnapshot(ctx, c, apexInfo) {
- i.collectHeadersForSnapshot(ctx)
- }
- }
}
if c.testModule {
android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
}
+
android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: deps.GeneratedSources.Strings()})
android.CollectDependencyAconfigFiles(ctx, &c.mergedAconfigFiles)
@@ -2318,6 +2305,7 @@
deps.LateSharedLibs = android.LastUniqueStrings(deps.LateSharedLibs)
deps.HeaderLibs = android.LastUniqueStrings(deps.HeaderLibs)
deps.RuntimeLibs = android.LastUniqueStrings(deps.RuntimeLibs)
+ deps.LlndkHeaderLibs = android.LastUniqueStrings(deps.LlndkHeaderLibs)
for _, lib := range deps.ReexportSharedLibHeaders {
if !inList(lib, deps.SharedLibs) {
@@ -2440,31 +2428,6 @@
return apiImportInfo
}
-func GetSnapshot(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android.BottomUpMutatorContext) SnapshotInfo {
- // Only device modules with BOARD_VNDK_VERSION uses snapshot. Others use the zero value of
- // SnapshotInfo, which provides no mappings.
- if *snapshotInfo == nil && c.Device() {
- // Only retrieve the snapshot on demand in order to avoid circular dependencies
- // between the modules in the snapshot and the snapshot itself.
- var snapshotModule []blueprint.Module
- if c.InVendor() && c.VndkVersion() == actx.DeviceConfig().VndkVersion() && actx.OtherModuleExists("vendor_snapshot") {
- snapshotModule = actx.AddVariationDependencies(nil, nil, "vendor_snapshot")
- } else if recoverySnapshotVersion := actx.DeviceConfig().RecoverySnapshotVersion(); recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" && c.InRecovery() && actx.OtherModuleExists("recovery_snapshot") {
- snapshotModule = actx.AddVariationDependencies(nil, nil, "recovery_snapshot")
- }
- if len(snapshotModule) > 0 && snapshotModule[0] != nil {
- snapshot, _ := android.OtherModuleProvider(actx, snapshotModule[0], SnapshotInfoProvider)
- *snapshotInfo = &snapshot
- // republish the snapshot for use in later mutators on this module
- android.SetProvider(actx, SnapshotInfoProvider, snapshot)
- }
- }
- if *snapshotInfo == nil {
- *snapshotInfo = &SnapshotInfo{}
- }
- return **snapshotInfo
-}
-
func GetReplaceModuleName(lib string, replaceMap map[string]string) string {
if snapshot, ok := replaceMap[lib]; ok {
return snapshot
@@ -2473,44 +2436,35 @@
return lib
}
-// RewriteLibs takes a list of names of shared libraries and scans it for three types
+// FilterNdkLibs takes a list of names of shared libraries and scans it for two types
// of names:
//
-// 1. Name of an NDK library that refers to a prebuilt module.
-//
-// For each of these, it adds the name of the prebuilt module (which will be in
-// prebuilts/ndk) to the list of nonvariant libs.
-//
-// 2. Name of an NDK library that refers to an ndk_library module.
+// 1. Name of an NDK library that refers to an ndk_library module.
//
// For each of these, it adds the name of the ndk_library module to the list of
// variant libs.
//
-// 3. Anything else (so anything that isn't an NDK library).
+// 2. Anything else (so anything that isn't an NDK library).
//
// It adds these to the nonvariantLibs list.
//
// The caller can then know to add the variantLibs dependencies differently from the
// nonvariantLibs
-func RewriteLibs(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android.BottomUpMutatorContext, config android.Config, list []string) (nonvariantLibs []string, variantLibs []string) {
+func FilterNdkLibs(c LinkableInterface, config android.Config, list []string) (nonvariantLibs []string, variantLibs []string) {
variantLibs = []string{}
nonvariantLibs = []string{}
for _, entry := range list {
// strip #version suffix out
name, _ := StubsLibNameAndVersion(entry)
- if c.InRecovery() {
- nonvariantLibs = append(nonvariantLibs, GetReplaceModuleName(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs))
- } else if c.UseSdk() && inList(name, *getNDKKnownLibs(config)) {
+ if c.UseSdk() && inList(name, *getNDKKnownLibs(config)) {
variantLibs = append(variantLibs, name+ndkLibrarySuffix)
- } else if c.UseVndk() {
- nonvariantLibs = append(nonvariantLibs, GetReplaceModuleName(entry, GetSnapshot(c, snapshotInfo, actx).SharedLibs))
} else {
- // put name#version back
nonvariantLibs = append(nonvariantLibs, entry)
}
}
return nonvariantLibs, variantLibs
+
}
func rewriteLibsForApiImports(c LinkableInterface, libs []string, replaceList map[string]string, config android.Config) ([]string, []string) {
@@ -2582,18 +2536,12 @@
c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs
- var snapshotInfo *SnapshotInfo
-
variantNdkLibs := []string{}
variantLateNdkLibs := []string{}
if ctx.Os() == android.Android {
- deps.SharedLibs, variantNdkLibs = RewriteLibs(c, &snapshotInfo, actx, ctx.Config(), deps.SharedLibs)
- deps.LateSharedLibs, variantLateNdkLibs = RewriteLibs(c, &snapshotInfo, actx, ctx.Config(), deps.LateSharedLibs)
- deps.ReexportSharedLibHeaders, _ = RewriteLibs(c, &snapshotInfo, actx, ctx.Config(), deps.ReexportSharedLibHeaders)
-
- for idx, lib := range deps.RuntimeLibs {
- deps.RuntimeLibs[idx] = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).SharedLibs)
- }
+ deps.SharedLibs, variantNdkLibs = FilterNdkLibs(c, ctx.Config(), deps.SharedLibs)
+ deps.LateSharedLibs, variantLateNdkLibs = FilterNdkLibs(c, ctx.Config(), deps.LateSharedLibs)
+ deps.ReexportSharedLibHeaders, _ = FilterNdkLibs(c, ctx.Config(), deps.ReexportSharedLibHeaders)
}
for _, lib := range deps.HeaderLibs {
@@ -2606,7 +2554,6 @@
if c.shouldUseApiSurface() {
lib = GetReplaceModuleName(lib, apiImportInfo.HeaderLibs)
}
- lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs)
if c.isNDKStubLibrary() {
// ndk_headers do not have any variations
@@ -2629,11 +2576,18 @@
), stubImplementation, c.BaseModuleName())
}
+ // If this module is an LLNDK implementation library, let it depend on LlndkHeaderLibs.
+ if c.ImageVariation().Variation == android.CoreVariation && c.Device() &&
+ c.Target().NativeBridge == android.NativeBridgeDisabled {
+ actx.AddVariationDependencies(
+ []blueprint.Variation{{Mutator: "image", Variation: VendorVariation}},
+ llndkHeaderLibTag,
+ deps.LlndkHeaderLibs...)
+ }
+
for _, lib := range deps.WholeStaticLibs {
depTag := libraryDependencyTag{Kind: staticLibraryDependency, wholeStatic: true, reexportFlags: true}
- lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)
-
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
}, depTag, lib)
@@ -2648,8 +2602,6 @@
depTag.excludeInApex = true
}
- lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs)
-
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
}, depTag, lib)
@@ -2662,7 +2614,7 @@
depTag := libraryDependencyTag{Kind: staticLibraryDependency, staticUnwinder: true}
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
- }, depTag, GetReplaceModuleName(staticUnwinder(actx), GetSnapshot(c, &snapshotInfo, actx).StaticLibs))
+ }, depTag, staticUnwinder(actx))
}
// shared lib names without the #version suffix
@@ -2703,14 +2655,14 @@
depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency}
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
- }, depTag, GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs))
+ }, depTag, lib)
}
for _, lib := range deps.UnexportedStaticLibs {
depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency, unexportedSymbols: true}
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
- }, depTag, GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).StaticLibs))
+ }, depTag, lib)
}
for _, lib := range deps.LateSharedLibs {
@@ -2751,11 +2703,11 @@
actx.AddVariationDependencies(crtVariations, objDepTag, deps.ObjFiles...)
for _, crt := range deps.CrtBegin {
actx.AddVariationDependencies(crtVariations, CrtBeginDepTag,
- GetReplaceModuleName(crt, GetSnapshot(c, &snapshotInfo, actx).Objects))
+ crt)
}
for _, crt := range deps.CrtEnd {
actx.AddVariationDependencies(crtVariations, CrtEndDepTag,
- GetReplaceModuleName(crt, GetSnapshot(c, &snapshotInfo, actx).Objects))
+ crt)
}
if deps.DynamicLinker != "" {
actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker)
@@ -2788,7 +2740,7 @@
actx.AddVariationDependencies([]blueprint.Variation{
c.ImageVariation(),
{Mutator: "link", Variation: "shared"},
- }, vndkExtDepTag, GetReplaceModuleName(vndkdep.getVndkExtendsModuleName(), GetSnapshot(c, &snapshotInfo, actx).SharedLibs))
+ }, vndkExtDepTag, vndkdep.getVndkExtendsModuleName())
}
}
@@ -3189,6 +3141,12 @@
return
}
+ if depTag == llndkHeaderLibTag {
+ depExporterInfo, _ := android.OtherModuleProvider(ctx, dep, FlagExporterInfoProvider)
+ depPaths.LlndkIncludeDirs = append(depPaths.LlndkIncludeDirs, depExporterInfo.IncludeDirs...)
+ depPaths.LlndkSystemIncludeDirs = append(depPaths.LlndkSystemIncludeDirs, depExporterInfo.SystemIncludeDirs...)
+ }
+
linkFile := ccDep.OutputFile()
if libDepTag, ok := depTag.(libraryDependencyTag); ok {
@@ -3368,10 +3326,10 @@
// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
// Re-exported shared library headers must be included as well since they can help us with type information
// about template instantiations (instantiated from their headers).
- // -isystem headers are not included since for bionic libraries, abi-filtering is taken care of by version
- // scripts.
c.sabi.Properties.ReexportedIncludes = append(
c.sabi.Properties.ReexportedIncludes, depExporterInfo.IncludeDirs.Strings()...)
+ c.sabi.Properties.ReexportedSystemIncludes = append(
+ c.sabi.Properties.ReexportedSystemIncludes, depExporterInfo.SystemIncludeDirs.Strings()...)
}
makeLibName := MakeLibName(ctx, c, ccDep, ccDep.BaseModuleName()) + libDepTag.makeSuffix
@@ -3396,8 +3354,6 @@
// they merely serve as Make dependencies and do not affect this lib itself.
c.Properties.AndroidMkSharedLibs = append(
c.Properties.AndroidMkSharedLibs, makeLibName)
- // Record BaseLibName for snapshots.
- c.Properties.SnapshotSharedLibs = append(c.Properties.SnapshotSharedLibs, BaseLibName(depName))
case libDepTag.static():
if libDepTag.wholeStatic {
c.Properties.AndroidMkWholeStaticLibs = append(
@@ -3406,8 +3362,6 @@
c.Properties.AndroidMkStaticLibs = append(
c.Properties.AndroidMkStaticLibs, makeLibName)
}
- // Record BaseLibName for snapshots.
- c.Properties.SnapshotStaticLibs = append(c.Properties.SnapshotStaticLibs, BaseLibName(depName))
}
} else if !c.IsStubs() {
// Stubs lib doesn't link to the runtime lib, object, crt, etc. dependencies.
@@ -3416,8 +3370,6 @@
case runtimeDepTag:
c.Properties.AndroidMkRuntimeLibs = append(
c.Properties.AndroidMkRuntimeLibs, MakeLibName(ctx, c, ccDep, ccDep.BaseModuleName())+libDepTag.makeSuffix)
- // Record BaseLibName for snapshots.
- c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, BaseLibName(depName))
case objDepTag:
depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path())
case CrtBeginDepTag:
@@ -3448,6 +3400,7 @@
if c.sabi != nil {
c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes)
+ c.sabi.Properties.ReexportedSystemIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedSystemIncludes)
}
return depPaths
@@ -3801,6 +3754,14 @@
return false
}
+func (m *Module) Dylib() bool {
+ return false
+}
+
+func (m *Module) Rlib() bool {
+ return false
+}
+
func GetMakeLinkType(actx android.ModuleContext, c LinkableInterface) string {
if c.InVendorOrProduct() {
if c.IsLlndk() {
@@ -4032,8 +3993,6 @@
return nil
}
-var _ snapshot.RelativeInstallPath = (*Module)(nil)
-
type moduleType int
const (
diff --git a/cc/cc_test.go b/cc/cc_test.go
index d1b728e..3d75bf5 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -17,7 +17,6 @@
import (
"fmt"
"os"
- "path/filepath"
"reflect"
"regexp"
"runtime"
@@ -39,17 +38,6 @@
}
var prepareForCcTest = android.GroupFixturePreparers(
- PrepareForTestWithCcIncludeVndk,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.VendorApiLevel = StringPtr("202404")
- variables.DeviceVndkVersion = StringPtr("current")
- variables.KeepVndk = BoolPtr(true)
- variables.Platform_vndk_version = StringPtr("29")
- }),
-)
-
-// TODO(b/316829758) Update prepareForCcTest with this configuration and remove prepareForCcTestWithoutVndk
-var prepareForCcTestWithoutVndk = android.GroupFixturePreparers(
PrepareForIntegrationTestWithCc,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.VendorApiLevel = StringPtr("202404")
@@ -123,30 +111,14 @@
func testCcError(t *testing.T, pattern string, bp string) {
t.Helper()
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- testCcErrorWithConfig(t, pattern, config)
- return
-}
-
-// testCcErrorProductVndk runs tests using the prepareForCcTest
-//
-// See testCc for an explanation as to how to stop using this deprecated method.
-//
-// deprecated
-func testCcErrorProductVndk(t *testing.T, pattern string, bp string) {
- t.Helper()
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
testCcErrorWithConfig(t, pattern, config)
return
}
const (
coreVariant = "android_arm64_armv8-a_shared"
- vendorVariant = "android_vendor.29_arm64_armv8-a_shared"
- productVariant = "android_product.29_arm64_armv8-a_shared"
+ vendorVariant = "android_vendor_arm64_armv8-a_shared"
+ productVariant = "android_product_arm64_armv8-a_shared"
recoveryVariant = "android_recovery_arm64_armv8-a_shared"
)
@@ -302,44 +274,6 @@
checkInstallPartition(t, ctx, "libproduct_odmavailable", vendorVariant, "odm")
}
-func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
- isVndkSp bool, extends string, variant string) {
-
- t.Helper()
-
- mod := ctx.ModuleForTests(name, variant).Module().(*Module)
-
- // Check library properties.
- lib, ok := mod.compiler.(*libraryDecorator)
- if !ok {
- t.Errorf("%q must have libraryDecorator", name)
- } else if lib.baseInstaller.subDir != subDir {
- t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
- lib.baseInstaller.subDir)
- }
-
- // Check VNDK properties.
- if mod.vndkdep == nil {
- t.Fatalf("%q must have `vndkdep`", name)
- }
- if !mod.IsVndk() {
- t.Errorf("%q IsVndk() must equal to true", name)
- }
- if mod.IsVndkSp() != isVndkSp {
- t.Errorf("%q IsVndkSp() must equal to %t", name, isVndkSp)
- }
-
- // Check VNDK extension properties.
- isVndkExt := extends != ""
- if mod.IsVndkExt() != isVndkExt {
- t.Errorf("%q IsVndkExt() must equal to %t", name, isVndkExt)
- }
-
- if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
- t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
- }
-}
-
func checkWriteFileOutput(t *testing.T, ctx *android.TestContext, params android.TestingBuildParams, expected []string) {
t.Helper()
content := android.ContentFromFileRuleForTests(t, ctx, params)
@@ -347,344 +281,6 @@
assertArrayString(t, actual, expected)
}
-func checkVndkOutput(t *testing.T, ctx *android.TestContext, output string, expected []string) {
- t.Helper()
- vndkSnapshot := ctx.SingletonForTests("vndk-snapshot")
- checkWriteFileOutput(t, ctx, vndkSnapshot.Output(output), expected)
-}
-
-func checkVndkLibrariesOutput(t *testing.T, ctx *android.TestContext, module string, expected []string) {
- t.Helper()
- got := ctx.ModuleForTests(module, "android_common").Module().(*vndkLibrariesTxt).fileNames
- assertArrayString(t, got, expected)
-}
-
-func TestVndk(t *testing.T) {
- t.Parallel()
- bp := `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_private",
- vendor_available: true,
- vndk: {
- enabled: true,
- private: true,
- },
- nocrt: true,
- stem: "libvndk-private",
- }
-
- cc_library {
- name: "libvndk_product",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- target: {
- vendor: {
- cflags: ["-DTEST"],
- },
- product: {
- cflags: ["-DTEST"],
- },
- },
- }
-
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- nocrt: true,
- suffix: "-x",
- }
-
- cc_library {
- name: "libvndk_sp_private",
- vendor_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- private: true,
- },
- nocrt: true,
- target: {
- vendor: {
- suffix: "-x",
- },
- },
- }
-
- cc_library {
- name: "libvndk_sp_product_private",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- private: true,
- },
- nocrt: true,
- target: {
- vendor: {
- suffix: "-x",
- },
- product: {
- suffix: "-x",
- },
- },
- }
-
- cc_library {
- name: "libllndk",
- llndk: {
- symbol_file: "libllndk.map.txt",
- export_llndk_headers: ["libllndk_headers"],
- }
- }
-
- cc_library {
- name: "libclang_rt.hwasan-llndk",
- llndk: {
- symbol_file: "libclang_rt.hwasan.map.txt",
- }
- }
-
- cc_library_headers {
- name: "libllndk_headers",
- llndk: {
- llndk_headers: true,
- },
- export_include_dirs: ["include"],
- }
-
- llndk_libraries_txt {
- name: "llndk.libraries.txt",
- }
- vndkcore_libraries_txt {
- name: "vndkcore.libraries.txt",
- }
- vndksp_libraries_txt {
- name: "vndksp.libraries.txt",
- }
- vndkprivate_libraries_txt {
- name: "vndkprivate.libraries.txt",
- }
- vndkproduct_libraries_txt {
- name: "vndkproduct.libraries.txt",
- }
- vndkcorevariant_libraries_txt {
- name: "vndkcorevariant.libraries.txt",
- insert_vndk_version: false,
- }
- `
-
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
-
- ctx := testCcWithConfig(t, config)
-
- // subdir == "" because VNDK libs are not supposed to be installed separately.
- // They are installed as part of VNDK APEX instead.
- checkVndkModule(t, ctx, "libvndk", "", false, "", vendorVariant)
- checkVndkModule(t, ctx, "libvndk_private", "", false, "", vendorVariant)
- checkVndkModule(t, ctx, "libvndk_product", "", false, "", vendorVariant)
- checkVndkModule(t, ctx, "libvndk_sp", "", true, "", vendorVariant)
- checkVndkModule(t, ctx, "libvndk_sp_private", "", true, "", vendorVariant)
- checkVndkModule(t, ctx, "libvndk_sp_product_private", "", true, "", vendorVariant)
-
- checkVndkModule(t, ctx, "libvndk_product", "", false, "", productVariant)
- checkVndkModule(t, ctx, "libvndk_sp_product_private", "", true, "", productVariant)
-
- // Check VNDK snapshot output.
- snapshotDir := "vndk-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
-
- vndkLibPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
- "arm64", "armv8-a"))
- vndkLib2ndPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
- "arm", "armv7-a-neon"))
-
- vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core")
- vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp")
- llndkLibPath := filepath.Join(vndkLibPath, "shared", "llndk-stub")
-
- vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
- vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
- llndkLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "llndk-stub")
-
- variant := "android_vendor.29_arm64_armv8-a_shared"
- variant2nd := "android_vendor.29_arm_armv7-a-neon_shared"
-
- snapshotSingleton := ctx.SingletonForTests("vndk-snapshot")
-
- CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLibPath, variant)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLib2ndPath, variant2nd)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLibPath, variant)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLib2ndPath, variant2nd)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLibPath, variant)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLib2ndPath, variant2nd)
- CheckSnapshot(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", llndkLibPath, variant)
- CheckSnapshot(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", llndkLib2ndPath, variant2nd)
-
- snapshotConfigsPath := filepath.Join(snapshotVariantPath, "configs")
- CheckSnapshot(t, ctx, snapshotSingleton, "llndk.libraries.txt", "llndk.libraries.txt", snapshotConfigsPath, "android_common")
- CheckSnapshot(t, ctx, snapshotSingleton, "vndkcore.libraries.txt", "vndkcore.libraries.txt", snapshotConfigsPath, "android_common")
- CheckSnapshot(t, ctx, snapshotSingleton, "vndksp.libraries.txt", "vndksp.libraries.txt", snapshotConfigsPath, "android_common")
- CheckSnapshot(t, ctx, snapshotSingleton, "vndkprivate.libraries.txt", "vndkprivate.libraries.txt", snapshotConfigsPath, "android_common")
- CheckSnapshot(t, ctx, snapshotSingleton, "vndkproduct.libraries.txt", "vndkproduct.libraries.txt", snapshotConfigsPath, "android_common")
-
- checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
- "LLNDK: libc.so",
- "LLNDK: libdl.so",
- "LLNDK: libft2.so",
- "LLNDK: libllndk.so",
- "LLNDK: libm.so",
- "VNDK-SP: libc++.so",
- "VNDK-SP: libvndk_sp-x.so",
- "VNDK-SP: libvndk_sp_private-x.so",
- "VNDK-SP: libvndk_sp_product_private-x.so",
- "VNDK-core: libvndk-private.so",
- "VNDK-core: libvndk.so",
- "VNDK-core: libvndk_product.so",
- "VNDK-private: libft2.so",
- "VNDK-private: libvndk-private.so",
- "VNDK-private: libvndk_sp_private-x.so",
- "VNDK-private: libvndk_sp_product_private-x.so",
- "VNDK-product: libc++.so",
- "VNDK-product: libvndk_product.so",
- "VNDK-product: libvndk_sp_product_private-x.so",
- })
- checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt", []string{"libc.so", "libclang_rt.hwasan-llndk.so", "libdl.so", "libft2.so", "libllndk.so", "libm.so"})
- checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk-private.so", "libvndk.so", "libvndk_product.so"})
- checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so", "libvndk_sp_product_private-x.so"})
- checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt", []string{"libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so", "libvndk_sp_product_private-x.so"})
- checkVndkLibrariesOutput(t, ctx, "vndkproduct.libraries.txt", []string{"libc++.so", "libvndk_product.so", "libvndk_sp_product_private-x.so"})
- checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", nil)
-}
-
-func TestVndkWithHostSupported(t *testing.T) {
- t.Parallel()
- ctx := testCc(t, `
- cc_library {
- name: "libvndk_host_supported",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- host_supported: true,
- }
-
- cc_library {
- name: "libvndk_host_supported_but_disabled_on_device",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- host_supported: true,
- enabled: false,
- target: {
- host: {
- enabled: true,
- }
- }
- }
-
- vndkcore_libraries_txt {
- name: "vndkcore.libraries.txt",
- }
- `)
-
- checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk_host_supported.so"})
-}
-
-func TestVndkLibrariesTxtAndroidMk(t *testing.T) {
- t.Parallel()
- bp := `
- llndk_libraries_txt {
- name: "llndk.libraries.txt",
- insert_vndk_version: true,
- }`
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- config.TestProductVariables.KeepVndk = BoolPtr(true)
- ctx := testCcWithConfig(t, config)
-
- module := ctx.ModuleForTests("llndk.libraries.txt", "android_common")
- entries := android.AndroidMkEntriesForTest(t, ctx, module.Module())[0]
- assertArrayString(t, entries.EntryMap["LOCAL_MODULE_STEM"], []string{"llndk.libraries.29.txt"})
-}
-
-func TestVndkUsingCoreVariant(t *testing.T) {
- t.Parallel()
- bp := `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk2",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- private: true,
- },
- nocrt: true,
- }
-
- vndkcorevariant_libraries_txt {
- name: "vndkcorevariant.libraries.txt",
- insert_vndk_version: false,
- }
- `
-
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
- config.TestProductVariables.KeepVndk = BoolPtr(true)
-
- setVndkMustUseVendorVariantListForTest(config, []string{"libvndk"})
-
- ctx := testCcWithConfig(t, config)
-
- checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", []string{"libc++.so", "libvndk2.so", "libvndk_sp.so"})
-}
-
func TestDataLibs(t *testing.T) {
t.Parallel()
bp := `
@@ -702,9 +298,6 @@
`
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
ctx := testCcWithConfig(t, config)
module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
@@ -761,9 +354,6 @@
`
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
ctx := testCcWithConfig(t, config)
module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
@@ -859,247 +449,9 @@
}
}
-func TestVndkModuleError(t *testing.T) {
- t.Parallel()
- // Check the error message for vendor_available and product_available properties.
- testCcErrorProductVndk(t, "vndk: vendor_available must be set to true when `vndk: {enabled: true}`", `
- cc_library {
- name: "libvndk",
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
- `)
-
- testCcErrorProductVndk(t, "vndk: vendor_available must be set to true when `vndk: {enabled: true}`", `
- cc_library {
- name: "libvndk",
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
- `)
-
- testCcErrorProductVndk(t, "product properties must have the same values with the vendor properties for VNDK modules", `
- cc_library {
- name: "libvndkprop",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- target: {
- vendor: {
- cflags: ["-DTEST",],
- },
- },
- }
- `)
-}
-
-func TestVndkDepError(t *testing.T) {
- t.Parallel()
- // Check whether an error is emitted when a VNDK lib depends on a system lib.
- testCcError(t, "dependency \".*\" of \".*\" missing variant", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- shared_libs: ["libfwk"], // Cause error
- nocrt: true,
- }
-
- cc_library {
- name: "libfwk",
- nocrt: true,
- }
- `)
-
- // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
- testCcError(t, "dependency \".*\" of \".*\" missing variant", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- shared_libs: ["libvendor"], // Cause error
- nocrt: true,
- }
-
- cc_library {
- name: "libvendor",
- vendor: true,
- nocrt: true,
- }
- `)
-
- // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
- testCcError(t, "dependency \".*\" of \".*\" missing variant", `
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- shared_libs: ["libfwk"], // Cause error
- nocrt: true,
- }
-
- cc_library {
- name: "libfwk",
- nocrt: true,
- }
- `)
-
- // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
- testCcError(t, "dependency \".*\" of \".*\" missing variant", `
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- shared_libs: ["libvendor"], // Cause error
- nocrt: true,
- }
-
- cc_library {
- name: "libvendor",
- vendor: true,
- nocrt: true,
- }
- `)
-
- // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
- testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- shared_libs: ["libvndk"], // Cause error
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
- `)
-
- // Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib.
- testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- shared_libs: ["libnonvndk"],
- nocrt: true,
- }
-
- cc_library {
- name: "libnonvndk",
- vendor_available: true,
- product_available: true,
- nocrt: true,
- }
- `)
-
- // Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib.
- testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
- cc_library {
- name: "libvndkprivate",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- private: true,
- },
- shared_libs: ["libnonvndk"],
- nocrt: true,
- }
-
- cc_library {
- name: "libnonvndk",
- vendor_available: true,
- product_available: true,
- nocrt: true,
- }
- `)
-
- // Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib.
- testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
- cc_library {
- name: "libvndksp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- shared_libs: ["libnonvndk"],
- nocrt: true,
- }
-
- cc_library {
- name: "libnonvndk",
- vendor_available: true,
- product_available: true,
- nocrt: true,
- }
- `)
-
- // Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib.
- testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
- cc_library {
- name: "libvndkspprivate",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- private: true,
- },
- shared_libs: ["libnonvndk"],
- nocrt: true,
- }
-
- cc_library {
- name: "libnonvndk",
- vendor_available: true,
- product_available: true,
- nocrt: true,
- }
- `)
-}
-
func TestDoubleLoadbleDep(t *testing.T) {
t.Parallel()
- // okay to link : LLNDK -> double_loadable VNDK
+ // okay to link : LLNDK -> double_loadable
testCc(t, `
cc_library {
name: "libllndk",
@@ -1113,32 +465,9 @@
name: "libdoubleloadable",
vendor_available: true,
product_available: true,
- vndk: {
- enabled: true,
- },
double_loadable: true,
}
`)
- // okay to link : LLNDK -> VNDK-SP
- testCc(t, `
- cc_library {
- name: "libllndk",
- shared_libs: ["libvndksp"],
- llndk: {
- symbol_file: "libllndk.map.txt",
- }
- }
-
- cc_library {
- name: "libvndksp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- }
- `)
// okay to link : double_loadable -> double_loadable
testCc(t, `
cc_library {
@@ -1154,15 +483,12 @@
double_loadable: true,
}
`)
- // okay to link : double_loadable VNDK -> double_loadable VNDK private
+ // okay to link : double_loadable -> double_loadable
testCc(t, `
cc_library {
name: "libdoubleloadable",
vendor_available: true,
product_available: true,
- vndk: {
- enabled: true,
- },
double_loadable: true,
shared_libs: ["libnondoubleloadable"],
}
@@ -1171,10 +497,6 @@
name: "libnondoubleloadable",
vendor_available: true,
product_available: true,
- vndk: {
- enabled: true,
- private: true,
- },
double_loadable: true,
}
`)
@@ -1204,7 +526,7 @@
func TestDoubleLoadableDepError(t *testing.T) {
t.Parallel()
- // Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
+ // Check whether an error is emitted when a LLNDK depends on a non-double_loadable lib.
testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
cc_library {
name: "libllndk",
@@ -1218,9 +540,6 @@
name: "libnondoubleloadable",
vendor_available: true,
product_available: true,
- vndk: {
- enabled: true,
- },
}
`)
@@ -1285,999 +604,13 @@
`)
}
-func TestCheckVndkMembershipBeforeDoubleLoadable(t *testing.T) {
- t.Parallel()
- testCcError(t, "module \"libvndksp\" variant .*: .*: VNDK-SP must only depend on VNDK-SP", `
- cc_library {
- name: "libvndksp",
- shared_libs: ["libanothervndksp"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- }
- }
-
- cc_library {
- name: "libllndk",
- shared_libs: ["libanothervndksp"],
- }
-
- cc_library {
- name: "libanothervndksp",
- vendor_available: true,
- product_available: true,
- }
- `)
-}
-
-func TestVndkExt(t *testing.T) {
- t.Parallel()
- // This test checks the VNDK-Ext properties.
- bp := `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
- cc_library {
- name: "libvndk2",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- target: {
- vendor: {
- suffix: "-suffix",
- },
- product: {
- suffix: "-suffix",
- },
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk2_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk2",
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext_product",
- product_specific: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk2_ext_product",
- product_specific: true,
- vndk: {
- enabled: true,
- extends: "libvndk2",
- },
- nocrt: true,
- }
- `
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
-
- ctx := testCcWithConfig(t, config)
-
- checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk", vendorVariant)
- checkVndkModule(t, ctx, "libvndk_ext_product", "vndk", false, "libvndk", productVariant)
-
- mod_vendor := ctx.ModuleForTests("libvndk2_ext", vendorVariant).Module().(*Module)
- assertString(t, mod_vendor.outputFile.Path().Base(), "libvndk2-suffix.so")
-
- mod_product := ctx.ModuleForTests("libvndk2_ext_product", productVariant).Module().(*Module)
- assertString(t, mod_product.outputFile.Path().Base(), "libvndk2-suffix.so")
-}
-
-func TestVndkExtError(t *testing.T) {
- t.Parallel()
- // This test ensures an error is emitted in ill-formed vndk-ext definition.
- testCcError(t, "must set `vendor: true` or `product_specific: true` to set `extends: \".*\"`", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext",
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
- `)
-
- testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext",
- vendor: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
- `)
-
- testCcErrorProductVndk(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext_product",
- product_specific: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
- `)
-
- testCcErrorProductVndk(t, "must not set at the same time as `vndk: {extends: \"\\.\\.\\.\"}`", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext_product",
- product_specific: true,
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
- `)
-}
-
-func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
- t.Parallel()
- // This test ensures an error is emitted for inconsistent support_system_process.
- testCcError(t, "module \".*\" with mismatched support_system_process", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- support_system_process: true,
- },
- nocrt: true,
- }
- `)
-
- testCcError(t, "module \".*\" with mismatched support_system_process", `
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk_sp",
- },
- nocrt: true,
- }
- `)
-}
-
-func TestVndkExtVendorAvailableFalseError(t *testing.T) {
- t.Parallel()
- // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
- // with `private: true`.
- testCcError(t, "`extends` refers module \".*\" which has `private: true`", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- private: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
- `)
-
- testCcErrorProductVndk(t, "`extends` refers module \".*\" which has `private: true`", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- private: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext_product",
- product_specific: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
- `)
-}
-
-func TestVendorModuleUseVndkExt(t *testing.T) {
- t.Parallel()
- // This test ensures a vendor module can depend on a VNDK-Ext library.
- testCc(t, `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk_sp",
- support_system_process: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvendor",
- vendor: true,
- shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
- nocrt: true,
- }
- `)
-}
-
-func TestVndkExtUseVendorLib(t *testing.T) {
- t.Parallel()
- // This test ensures a VNDK-Ext library can depend on a vendor library.
- testCc(t, `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- shared_libs: ["libvendor"],
- nocrt: true,
- }
-
- cc_library {
- name: "libvendor",
- vendor: true,
- nocrt: true,
- }
- `)
-
- // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
- testCc(t, `
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk_sp",
- support_system_process: true,
- },
- shared_libs: ["libvendor"], // Cause an error
- nocrt: true,
- }
-
- cc_library {
- name: "libvendor",
- vendor: true,
- nocrt: true,
- }
- `)
-}
-
-func TestProductVndkExtDependency(t *testing.T) {
- t.Parallel()
- bp := `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext_product",
- product_specific: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- shared_libs: ["libproduct_for_vndklibs"],
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp_ext_product",
- product_specific: true,
- vndk: {
- enabled: true,
- extends: "libvndk_sp",
- support_system_process: true,
- },
- shared_libs: ["libproduct_for_vndklibs"],
- nocrt: true,
- }
-
- cc_library {
- name: "libproduct",
- product_specific: true,
- shared_libs: ["libvndk_ext_product", "libvndk_sp_ext_product"],
- nocrt: true,
- }
-
- cc_library {
- name: "libproduct_for_vndklibs",
- product_specific: true,
- nocrt: true,
- }
- `
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
-
- testCcWithConfig(t, config)
-}
-
-func TestVndkSpExtUseVndkError(t *testing.T) {
- t.Parallel()
- // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
- // library.
- testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk_sp",
- support_system_process: true,
- },
- shared_libs: ["libvndk"], // Cause an error
- nocrt: true,
- }
- `)
-
- // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
- // library.
- testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk_sp",
- support_system_process: true,
- },
- shared_libs: ["libvndk_ext"], // Cause an error
- nocrt: true,
- }
- `)
-}
-
-func TestVndkUseVndkExtError(t *testing.T) {
- t.Parallel()
- // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
- // VNDK-Ext/VNDK-SP-Ext library.
- testCcError(t, "dependency \".*\" of \".*\" missing variant", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk2",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- shared_libs: ["libvndk_ext"],
- nocrt: true,
- }
- `)
-
- testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk2",
- vendor_available: true,
- vndk: {
- enabled: true,
- },
- target: {
- vendor: {
- shared_libs: ["libvndk_ext"],
- },
- },
- nocrt: true,
- }
- `)
-
- testCcError(t, "dependency \".*\" of \".*\" missing variant", `
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk_sp",
- support_system_process: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp_2",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- shared_libs: ["libvndk_sp_ext"],
- nocrt: true,
- }
- `)
-
- testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk_sp",
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_sp2",
- vendor_available: true,
- vndk: {
- enabled: true,
- },
- target: {
- vendor: {
- shared_libs: ["libvndk_sp_ext"],
- },
- },
- nocrt: true,
- }
- `)
-}
-
-func TestEnforceProductVndkVersion(t *testing.T) {
- t.Parallel()
- bp := `
- cc_library {
- name: "libllndk",
- llndk: {
- symbol_file: "libllndk.map.txt",
- }
- }
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
- cc_library {
- name: "libvndk_sp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- nocrt: true,
- }
- cc_library {
- name: "libva",
- vendor_available: true,
- nocrt: true,
- }
- cc_library {
- name: "libpa",
- product_available: true,
- nocrt: true,
- }
- cc_library {
- name: "libboth_available",
- vendor_available: true,
- product_available: true,
- nocrt: true,
- srcs: ["foo.c"],
- target: {
- vendor: {
- suffix: "-vendor",
- },
- product: {
- suffix: "-product",
- },
- }
- }
- cc_library {
- name: "libproduct_va",
- product_specific: true,
- vendor_available: true,
- nocrt: true,
- }
- cc_library {
- name: "libprod",
- product_specific: true,
- shared_libs: [
- "libllndk",
- "libvndk",
- "libvndk_sp",
- "libpa",
- "libboth_available",
- "libproduct_va",
- ],
- nocrt: true,
- }
- cc_library {
- name: "libvendor",
- vendor: true,
- shared_libs: [
- "libllndk",
- "libvndk",
- "libvndk_sp",
- "libva",
- "libboth_available",
- "libproduct_va",
- ],
- nocrt: true,
- }
- `
-
- ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
-
- checkVndkModule(t, ctx, "libvndk", "", false, "", productVariant)
- checkVndkModule(t, ctx, "libvndk_sp", "", true, "", productVariant)
-
- mod_vendor := ctx.ModuleForTests("libboth_available", vendorVariant).Module().(*Module)
- assertString(t, mod_vendor.outputFile.Path().Base(), "libboth_available-vendor.so")
-
- mod_product := ctx.ModuleForTests("libboth_available", productVariant).Module().(*Module)
- assertString(t, mod_product.outputFile.Path().Base(), "libboth_available-product.so")
-
- ensureStringContains := func(t *testing.T, str string, substr string) {
- t.Helper()
- if !strings.Contains(str, substr) {
- t.Errorf("%q is not found in %v", substr, str)
- }
- }
- ensureStringNotContains := func(t *testing.T, str string, substr string) {
- t.Helper()
- if strings.Contains(str, substr) {
- t.Errorf("%q is found in %v", substr, str)
- }
- }
-
- // _static variant is used since _shared reuses *.o from the static variant
- vendor_static := ctx.ModuleForTests("libboth_available", strings.Replace(vendorVariant, "_shared", "_static", 1))
- product_static := ctx.ModuleForTests("libboth_available", strings.Replace(productVariant, "_shared", "_static", 1))
-
- vendor_cflags := vendor_static.Rule("cc").Args["cFlags"]
- ensureStringContains(t, vendor_cflags, "-D__ANDROID_VNDK__")
- ensureStringContains(t, vendor_cflags, "-D__ANDROID_VENDOR__")
- ensureStringNotContains(t, vendor_cflags, "-D__ANDROID_PRODUCT__")
- ensureStringContains(t, vendor_cflags, "-D__ANDROID_VENDOR_API__=202404")
-
- product_cflags := product_static.Rule("cc").Args["cFlags"]
- ensureStringContains(t, product_cflags, "-D__ANDROID_VNDK__")
- ensureStringContains(t, product_cflags, "-D__ANDROID_PRODUCT__")
- ensureStringNotContains(t, product_cflags, "-D__ANDROID_VENDOR__")
- ensureStringNotContains(t, product_cflags, "-D__ANDROID_VENDOR_API__=202404")
-}
-
-func TestEnforceProductVndkVersionErrors(t *testing.T) {
- t.Parallel()
- testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
- cc_library {
- name: "libprod",
- product_specific: true,
- shared_libs: [
- "libvendor",
- ],
- nocrt: true,
- }
- cc_library {
- name: "libvendor",
- vendor: true,
- nocrt: true,
- }
- `)
- testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
- cc_library {
- name: "libprod",
- product_specific: true,
- shared_libs: [
- "libsystem",
- ],
- nocrt: true,
- }
- cc_library {
- name: "libsystem",
- nocrt: true,
- }
- `)
- testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
- cc_library {
- name: "libprod",
- product_specific: true,
- shared_libs: [
- "libva",
- ],
- nocrt: true,
- }
- cc_library {
- name: "libva",
- vendor_available: true,
- nocrt: true,
- }
- `)
- testCcErrorProductVndk(t, "non-VNDK module should not link to \".*\" which has `private: true`", `
- cc_library {
- name: "libprod",
- product_specific: true,
- shared_libs: [
- "libvndk_private",
- ],
- nocrt: true,
- }
- cc_library {
- name: "libvndk_private",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- private: true,
- },
- nocrt: true,
- }
- `)
- testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
- cc_library {
- name: "libprod",
- product_specific: true,
- shared_libs: [
- "libsystem_ext",
- ],
- nocrt: true,
- }
- cc_library {
- name: "libsystem_ext",
- system_ext_specific: true,
- nocrt: true,
- }
- `)
- testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:", `
- cc_library {
- name: "libsystem",
- shared_libs: [
- "libproduct_va",
- ],
- nocrt: true,
- }
- cc_library {
- name: "libproduct_va",
- product_specific: true,
- vendor_available: true,
- nocrt: true,
- }
- `)
-}
-
func TestMakeLinkType(t *testing.T) {
t.Parallel()
bp := `
cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- }
- cc_library {
- name: "libvndksp",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- }
- cc_library {
- name: "libvndkprivate",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- private: true,
- },
- }
- cc_library {
name: "libvendor",
vendor: true,
}
- cc_library {
- name: "libvndkext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- }
vndk_prebuilt_shared {
name: "prevndk",
version: "27",
@@ -2307,40 +640,15 @@
private: true,
}
}
-
llndk_libraries_txt {
name: "llndk.libraries.txt",
}
- vndkcore_libraries_txt {
- name: "vndkcore.libraries.txt",
- }
- vndksp_libraries_txt {
- name: "vndksp.libraries.txt",
- }
- vndkprivate_libraries_txt {
- name: "vndkprivate.libraries.txt",
- }
- vndkcorevariant_libraries_txt {
- name: "vndkcorevariant.libraries.txt",
- insert_vndk_version: false,
- }
`
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
// native:vndk
ctx := testCcWithConfig(t, config)
- checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt",
- []string{"libvndk.so", "libvndkprivate.so"})
- checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt",
- []string{"libc++.so", "libvndksp.so"})
- checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt",
- []string{"libc.so", "libdl.so", "libft2.so", "libllndk.so", "libllndkprivate.so", "libm.so"})
- checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt",
- []string{"libft2.so", "libllndkprivate.so", "libvndkprivate.so"})
-
vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared"
tests := []struct {
@@ -2348,15 +656,9 @@
name string
expected string
}{
- {vendorVariant, "libvndk", "native:vndk"},
- {vendorVariant, "libvndksp", "native:vndk"},
- {vendorVariant, "libvndkprivate", "native:vndk_private"},
{vendorVariant, "libvendor", "native:vendor"},
- {vendorVariant, "libvndkext", "native:vendor"},
{vendorVariant, "libllndk", "native:vndk"},
{vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
- {coreVariant, "libvndk", "native:platform"},
- {coreVariant, "libvndkprivate", "native:platform"},
{coreVariant, "libllndk", "native:platform"},
}
for _, test := range tests {
@@ -2656,6 +958,7 @@
cc_library_headers {
name: "libexternal_llndk_headers",
export_include_dirs: ["include_llndk"],
+ export_system_include_dirs: ["include_system_llndk"],
llndk: {
symbol_file: "libllndk.map.txt",
},
@@ -2671,37 +974,74 @@
},
export_include_dirs: ["include"],
}
+
+ cc_library {
+ name: "libllndk_with_system_headers",
+ llndk: {
+ symbol_file: "libllndk.map.txt",
+ export_llndk_headers: ["libexternal_llndk_headers"],
+ export_headers_as_system: true,
+ },
+ export_include_dirs: ["include"],
+ export_system_include_dirs: ["include_system"],
+ }
`)
actual := result.ModuleVariantsForTests("libllndk")
for i := 0; i < len(actual); i++ {
- if !strings.HasPrefix(actual[i], "android_vendor.29_") {
+ if !strings.HasPrefix(actual[i], "android_vendor_") {
actual = append(actual[:i], actual[i+1:]...)
i--
}
}
expected := []string{
- "android_vendor.29_arm64_armv8-a_shared",
- "android_vendor.29_arm_armv7-a-neon_shared",
+ "android_vendor_arm64_armv8-a_shared",
+ "android_vendor_arm_armv7-a-neon_shared",
}
android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
- params := result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared").Description("generate stub")
+ params := result.ModuleForTests("libllndk", "android_vendor_arm_armv7-a-neon_shared").Description("generate stub")
android.AssertSame(t, "use Vendor API level for default stubs", "202404", params.Args["apiLevel"])
- checkExportedIncludeDirs := func(module, variant string, expectedDirs ...string) {
+ checkExportedIncludeDirs := func(module, variant string, expectedSystemDirs []string, expectedDirs ...string) {
t.Helper()
m := result.ModuleForTests(module, variant).Module()
f, _ := android.SingletonModuleProvider(result, m, FlagExporterInfoProvider)
android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
expectedDirs, f.IncludeDirs)
+ android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
+ expectedSystemDirs, f.SystemIncludeDirs)
}
- checkExportedIncludeDirs("libllndk", "android_arm64_armv8-a_shared", "include")
- checkExportedIncludeDirs("libllndk", "android_vendor.29_arm64_armv8-a_shared", "include")
- checkExportedIncludeDirs("libllndk_with_external_headers", "android_arm64_armv8-a_shared", "include")
- checkExportedIncludeDirs("libllndk_with_external_headers", "android_vendor.29_arm64_armv8-a_shared", "include_llndk")
- checkExportedIncludeDirs("libllndk_with_override_headers", "android_arm64_armv8-a_shared", "include")
- checkExportedIncludeDirs("libllndk_with_override_headers", "android_vendor.29_arm64_armv8-a_shared", "include_llndk")
+ checkExportedIncludeDirs("libllndk", coreVariant, nil, "include")
+ checkExportedIncludeDirs("libllndk", vendorVariant, nil, "include")
+ checkExportedIncludeDirs("libllndk_with_external_headers", coreVariant, nil, "include")
+ checkExportedIncludeDirs("libllndk_with_external_headers", vendorVariant,
+ []string{"include_system_llndk"}, "include_llndk")
+ checkExportedIncludeDirs("libllndk_with_override_headers", coreVariant, nil, "include")
+ checkExportedIncludeDirs("libllndk_with_override_headers", vendorVariant, nil, "include_llndk")
+ checkExportedIncludeDirs("libllndk_with_system_headers", coreVariant, []string{"include_system"}, "include")
+ checkExportedIncludeDirs("libllndk_with_system_headers", vendorVariant,
+ []string{"include_system", "include", "include_system_llndk"}, "include_llndk")
+
+ checkAbiLinkerIncludeDirs := func(module string) {
+ t.Helper()
+ coreModule := result.ModuleForTests(module, coreVariant)
+ abiCheckFlags := ""
+ for _, output := range coreModule.AllOutputs() {
+ if strings.HasSuffix(output, ".so.llndk.lsdump") {
+ abiCheckFlags = coreModule.Output(output).Args["exportedHeaderFlags"]
+ }
+ }
+ vendorModule := result.ModuleForTests(module, vendorVariant).Module()
+ vendorInfo, _ := android.SingletonModuleProvider(result, vendorModule, FlagExporterInfoProvider)
+ vendorDirs := android.Concat(vendorInfo.IncludeDirs, vendorInfo.SystemIncludeDirs)
+ android.AssertStringEquals(t, module+" has different exported include dirs for vendor variant and ABI check",
+ android.JoinPathsWithPrefix(vendorDirs, "-I"), abiCheckFlags)
+ }
+ checkAbiLinkerIncludeDirs("libllndk")
+ checkAbiLinkerIncludeDirs("libllndk_with_override_headers")
+ checkAbiLinkerIncludeDirs("libllndk_with_external_headers")
+ checkAbiLinkerIncludeDirs("libllndk_with_system_headers")
}
func TestLlndkHeaders(t *testing.T) {
@@ -2733,7 +1073,7 @@
`)
// _static variant is used since _shared reuses *.o from the static variant
- cc := ctx.ModuleForTests("libvendor", "android_vendor.29_arm_armv7-a-neon_static").Rule("cc")
+ cc := ctx.ModuleForTests("libvendor", "android_vendor_arm_armv7-a-neon_static").Rule("cc")
cflags := cc.Args["cFlags"]
if !strings.Contains(cflags, "-Imy_include") {
t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
@@ -2855,7 +1195,7 @@
// runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
// and vendor variants.
- variant = "android_vendor.29_arm64_armv8-a_shared"
+ variant = "android_vendor_arm64_armv8-a_shared"
module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
checkRuntimeLibs(t, []string{"liball_available.vendor"}, module)
@@ -2865,7 +1205,7 @@
// runtime_libs for product variants have '.product' suffixes if the modules have both core
// and product variants.
- variant = "android_product.29_arm64_armv8-a_shared"
+ variant = "android_product_arm64_armv8-a_shared"
module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
checkRuntimeLibs(t, []string{"liball_available.product"}, module)
@@ -2882,7 +1222,7 @@
module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
checkRuntimeLibs(t, []string{"liball_available"}, module)
- variant = "android_vendor.29_arm64_armv8-a_shared"
+ variant = "android_vendor_arm64_armv8-a_shared"
module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
checkRuntimeLibs(t, nil, module)
}
@@ -3065,9 +1405,6 @@
`
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
ctx := testCcWithConfig(t, config)
module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
@@ -4795,8 +3132,7 @@
}
}
-// TODO(b/316829758) Remove this test and do not set VNDK version from other tests
-func TestImageVariantsWithoutVndk(t *testing.T) {
+func TestImageVariants(t *testing.T) {
t.Parallel()
bp := `
@@ -4815,7 +3151,7 @@
}
`
- ctx := prepareForCcTestWithoutVndk.RunTestWithBp(t, bp)
+ ctx := prepareForCcTest.RunTestWithBp(t, bp)
hasDep := func(m android.Module, wantDep android.Module) bool {
t.Helper()
@@ -4843,7 +3179,7 @@
testDepWithVariant("product")
}
-func TestVendorSdkVersionWithoutVndk(t *testing.T) {
+func TestVendorSdkVersion(t *testing.T) {
t.Parallel()
bp := `
@@ -4861,7 +3197,7 @@
}
`
- ctx := prepareForCcTestWithoutVndk.RunTestWithBp(t, bp)
+ ctx := prepareForCcTest.RunTestWithBp(t, bp)
testSdkVersionFlag := func(module, version string) {
flags := ctx.ModuleForTests(module, "android_vendor_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
android.AssertStringDoesContain(t, "min sdk version", flags, "-target aarch64-linux-android"+version)
@@ -4871,7 +3207,7 @@
testSdkVersionFlag("libbar", "29")
ctx = android.GroupFixturePreparers(
- prepareForCcTestWithoutVndk,
+ prepareForCcTest,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
if variables.BuildFlags == nil {
variables.BuildFlags = make(map[string]string)
diff --git a/cc/cc_test_only_property_test.go b/cc/cc_test_only_property_test.go
new file mode 100644
index 0000000..c14f34e
--- /dev/null
+++ b/cc/cc_test_only_property_test.go
@@ -0,0 +1,219 @@
+// Copyright 2024 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 cc
+
+import (
+ "android/soong/android"
+ "android/soong/android/team_proto"
+ "log"
+ "strings"
+ "testing"
+
+ "github.com/google/blueprint"
+ "google.golang.org/protobuf/proto"
+)
+
+func TestTestOnlyProvider(t *testing.T) {
+ t.Parallel()
+ ctx := android.GroupFixturePreparers(
+ prepareForCcTest,
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("cc_test_host", TestHostFactory)
+ }),
+ ).RunTestWithBp(t, `
+ // These should be test-only
+ cc_fuzz { name: "cc-fuzz" }
+ cc_test { name: "cc-test", gtest:false }
+ cc_benchmark { name: "cc-benchmark" }
+ cc_library { name: "cc-library-forced",
+ test_only: true }
+ cc_test_library {name: "cc-test-library", gtest: false}
+ cc_test_host {name: "cc-test-host", gtest: false}
+
+ // These should not be.
+ cc_genrule { name: "cc_genrule", cmd: "echo foo", out: ["out"] }
+ cc_library { name: "cc_library" }
+ cc_library { name: "cc_library_false", test_only: false }
+ cc_library_static { name: "cc_static" }
+ cc_library_shared { name: "cc_library_shared" }
+
+ cc_object { name: "cc-object" }
+ `)
+
+ // Visit all modules and ensure only the ones that should
+ // marked as test-only are marked as test-only.
+
+ actualTestOnly := []string{}
+ ctx.VisitAllModules(func(m blueprint.Module) {
+ if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, android.TestOnlyProviderKey); ok {
+ if provider.TestOnly {
+ actualTestOnly = append(actualTestOnly, m.Name())
+ }
+ }
+ })
+ expectedTestOnlyModules := []string{
+ "cc-test",
+ "cc-library-forced",
+ "cc-fuzz",
+ "cc-benchmark",
+ "cc-test-library",
+ "cc-test-host",
+ }
+
+ notEqual, left, right := android.ListSetDifference(expectedTestOnlyModules, actualTestOnly)
+ if notEqual {
+ t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right)
+ }
+}
+
+func TestTestOnlyValueWithTestPerSrcProp(t *testing.T) {
+ t.Parallel()
+ ctx := android.GroupFixturePreparers(
+ prepareForCcTest,
+ ).RunTestWithBp(t, `
+ // These should be test-only
+ cc_test { name: "cc-test",
+ gtest: false,
+ test_per_src: true,
+ srcs: ["foo_test.cpp"],
+ test_options: { unit_test: false, },
+ }
+ `)
+
+ // Ensure all variation of test-per-src tests are marked test-only.
+ ctx.VisitAllModules(func(m blueprint.Module) {
+ testOnly := false
+ if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, android.TestOnlyProviderKey); ok {
+ if provider.TestOnly {
+ testOnly = true
+ }
+ }
+ if module, ok := m.(*Module); ok {
+ if testModule, ok := module.installer.(*testBinary); ok {
+ if !testOnly && *testModule.Properties.Test_per_src {
+ t.Errorf("%v is not test-only but should be", m)
+ }
+ }
+ }
+ })
+}
+
+func TestTestOnlyInTeamsProto(t *testing.T) {
+ t.Parallel()
+ ctx := android.GroupFixturePreparers(
+ android.PrepareForTestWithTeamBuildComponents,
+ prepareForCcTest,
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ ctx.RegisterParallelSingletonType("all_teams", android.AllTeamsFactory)
+ ctx.RegisterModuleType("cc_test_host", TestHostFactory)
+
+ }),
+ ).RunTestWithBp(t, `
+ package { default_team: "someteam"}
+
+ // These should be test-only
+ cc_fuzz { name: "cc-fuzz" }
+ cc_test { name: "cc-test", gtest:false }
+ cc_benchmark { name: "cc-benchmark" }
+ cc_library { name: "cc-library-forced",
+ test_only: true }
+ cc_test_library {name: "cc-test-library", gtest: false}
+ cc_test_host {name: "cc-test-host", gtest: false}
+
+ // These should not be.
+ cc_genrule { name: "cc_genrule", cmd: "echo foo", out: ["out"] }
+ cc_library { name: "cc_library" }
+ cc_library_static { name: "cc_static" }
+ cc_library_shared { name: "cc_library_shared" }
+
+ cc_object { name: "cc-object" }
+ team {
+ name: "someteam",
+ trendy_team_id: "cool_team",
+ }
+ `)
+
+ var teams *team_proto.AllTeams
+ teams = getTeamProtoOutput(t, ctx)
+
+ // map of module name -> trendy team name.
+ actualTrueModules := []string{}
+ for _, teamProto := range teams.Teams {
+ if Bool(teamProto.TestOnly) {
+ actualTrueModules = append(actualTrueModules, teamProto.GetTargetName())
+ }
+ }
+ expectedTestOnlyModules := []string{
+ "cc-test",
+ "cc-library-forced",
+ "cc-fuzz",
+ "cc-benchmark",
+ "cc-test-library",
+ "cc-test-host",
+ }
+
+ notEqual, left, right := android.ListSetDifference(expectedTestOnlyModules, actualTrueModules)
+ if notEqual {
+ t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right)
+ }
+}
+
+// Don't allow setting test-only on things that are always tests or never tests.
+func TestInvalidTestOnlyTargets(t *testing.T) {
+ testCases := []string{
+ ` cc_test { name: "cc-test", test_only: true, gtest: false, srcs: ["foo.cc"], } `,
+ ` cc_binary { name: "cc-binary", test_only: true, srcs: ["foo.cc"], } `,
+ ` cc_test_library {name: "cc-test-library", test_only: true, gtest: false} `,
+ ` cc_test_host {name: "cc-test-host", test_only: true, gtest: false} `,
+ ` cc_defaults {name: "cc-defaults", test_only: true} `,
+ }
+
+ for i, bp := range testCases {
+ ctx := android.GroupFixturePreparers(
+ prepareForCcTest,
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("cc_test_host", TestHostFactory)
+ })).
+ ExtendWithErrorHandler(android.FixtureIgnoreErrors).
+ RunTestWithBp(t, bp)
+ if len(ctx.Errs) == 0 {
+ t.Errorf("Expected err setting test_only in testcase #%d", i)
+ }
+ if len(ctx.Errs) > 1 {
+ t.Errorf("Too many errs: [%s] %v", bp, ctx.Errs)
+ }
+
+ if len(ctx.Errs) == 1 {
+ if !strings.Contains(ctx.Errs[0].Error(), "unrecognized property \"test_only\"") {
+ t.Errorf("ERR: %s bad bp: %s", ctx.Errs[0], bp)
+ }
+ }
+ }
+}
+
+func getTeamProtoOutput(t *testing.T, ctx *android.TestResult) *team_proto.AllTeams {
+ teams := new(team_proto.AllTeams)
+ config := ctx.SingletonForTests("all_teams")
+ allOutputs := config.AllOutputs()
+
+ protoPath := allOutputs[0]
+
+ out := config.MaybeOutput(protoPath)
+ outProto := []byte(android.ContentFromFileRuleForTests(t, ctx.TestContext, out))
+ if err := proto.Unmarshal(outProto, teams); err != nil {
+ log.Fatalln("Failed to parse teams proto:", err)
+ }
+ return teams
+}
diff --git a/cc/compdb.go b/cc/compdb.go
index 617be1a..da28183 100644
--- a/cc/compdb.go
+++ b/cc/compdb.go
@@ -164,6 +164,7 @@
args = append(args, expandAllVars(ctx, ccModule.flags.Local.ConlyFlags)...)
}
args = append(args, expandAllVars(ctx, ccModule.flags.SystemIncludeFlags)...)
+ args = append(args, expandAllVars(ctx, ccModule.flags.NoOverrideFlags)...)
args = append(args, src.String())
return args
}
diff --git a/cc/compiler.go b/cc/compiler.go
index de1ae71..9a961cf 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -539,7 +539,6 @@
flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainCflags())
}
-
cStd := parseCStd(compiler.Properties.C_std)
cppStd := parseCppStd(compiler.Properties.Cpp_std)
@@ -671,6 +670,16 @@
flags.Local.CFlags = append(flags.Local.CFlags, "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES")
}
+ flags.NoOverrideFlags = append(flags.NoOverrideFlags, "${config.NoOverrideGlobalCflags}")
+
+ if flags.Toolchain.Is64Bit() {
+ flags.NoOverrideFlags = append(flags.NoOverrideFlags, "${config.NoOverride64GlobalCflags}")
+ }
+
+ if android.IsThirdPartyPath(ctx.ModuleDir()) {
+ flags.NoOverrideFlags = append(flags.NoOverrideFlags, "${config.NoOverrideExternalGlobalCflags}")
+ }
+
return flags
}
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index 10342a3..beb68e1 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -91,43 +91,39 @@
)
func init() {
- exportedVars.ExportStringListStaticVariable("Arm64Ldflags", arm64Ldflags)
+ pctx.StaticVariable("Arm64Ldflags", strings.Join(arm64Ldflags, " "))
- exportedVars.ExportStringList("Arm64Lldflags", arm64Lldflags)
pctx.VariableFunc("Arm64Lldflags", func(ctx android.PackageVarContext) string {
maxPageSizeFlag := "-Wl,-z,max-page-size=" + ctx.Config().MaxPageSizeSupported()
flags := append(arm64Lldflags, maxPageSizeFlag)
return strings.Join(flags, " ")
})
- exportedVars.ExportStringList("Arm64Cflags", arm64Cflags)
pctx.VariableFunc("Arm64Cflags", func(ctx android.PackageVarContext) string {
flags := arm64Cflags
if ctx.Config().NoBionicPageSizeMacro() {
flags = append(flags, "-D__BIONIC_NO_PAGE_SIZE_MACRO")
+ } else {
+ flags = append(flags, "-D__BIONIC_DEPRECATED_PAGE_SIZE_MACRO")
}
return strings.Join(flags, " ")
})
- exportedVars.ExportStringListStaticVariable("Arm64Cppflags", arm64Cppflags)
+ pctx.StaticVariable("Arm64Cppflags", strings.Join(arm64Cppflags, " "))
- exportedVars.ExportVariableReferenceDict("Arm64ArchVariantCflags", arm64ArchVariantCflagsVar)
- exportedVars.ExportVariableReferenceDict("Arm64CpuVariantCflags", arm64CpuVariantCflagsVar)
- exportedVars.ExportVariableReferenceDict("Arm64CpuVariantLdflags", arm64CpuVariantLdflags)
+ pctx.StaticVariable("Arm64Armv8ACflags", strings.Join(arm64ArchVariantCflags["armv8-a"], " "))
+ pctx.StaticVariable("Arm64Armv8ABranchProtCflags", strings.Join(arm64ArchVariantCflags["armv8-a-branchprot"], " "))
+ pctx.StaticVariable("Arm64Armv82ACflags", strings.Join(arm64ArchVariantCflags["armv8-2a"], " "))
+ pctx.StaticVariable("Arm64Armv82ADotprodCflags", strings.Join(arm64ArchVariantCflags["armv8-2a-dotprod"], " "))
+ pctx.StaticVariable("Arm64Armv9ACflags", strings.Join(arm64ArchVariantCflags["armv9-a"], " "))
- exportedVars.ExportStringListStaticVariable("Arm64Armv8ACflags", arm64ArchVariantCflags["armv8-a"])
- exportedVars.ExportStringListStaticVariable("Arm64Armv8ABranchProtCflags", arm64ArchVariantCflags["armv8-a-branchprot"])
- exportedVars.ExportStringListStaticVariable("Arm64Armv82ACflags", arm64ArchVariantCflags["armv8-2a"])
- exportedVars.ExportStringListStaticVariable("Arm64Armv82ADotprodCflags", arm64ArchVariantCflags["armv8-2a-dotprod"])
- exportedVars.ExportStringListStaticVariable("Arm64Armv9ACflags", arm64ArchVariantCflags["armv9-a"])
+ pctx.StaticVariable("Arm64CortexA53Cflags", strings.Join(arm64CpuVariantCflags["cortex-a53"], " "))
+ pctx.StaticVariable("Arm64CortexA55Cflags", strings.Join(arm64CpuVariantCflags["cortex-a55"], " "))
+ pctx.StaticVariable("Arm64KryoCflags", strings.Join(arm64CpuVariantCflags["kryo"], " "))
+ pctx.StaticVariable("Arm64ExynosM1Cflags", strings.Join(arm64CpuVariantCflags["exynos-m1"], " "))
+ pctx.StaticVariable("Arm64ExynosM2Cflags", strings.Join(arm64CpuVariantCflags["exynos-m2"], " "))
- exportedVars.ExportStringListStaticVariable("Arm64CortexA53Cflags", arm64CpuVariantCflags["cortex-a53"])
- exportedVars.ExportStringListStaticVariable("Arm64CortexA55Cflags", arm64CpuVariantCflags["cortex-a55"])
- exportedVars.ExportStringListStaticVariable("Arm64KryoCflags", arm64CpuVariantCflags["kryo"])
- exportedVars.ExportStringListStaticVariable("Arm64ExynosM1Cflags", arm64CpuVariantCflags["exynos-m1"])
- exportedVars.ExportStringListStaticVariable("Arm64ExynosM2Cflags", arm64CpuVariantCflags["exynos-m2"])
-
- exportedVars.ExportStringListStaticVariable("Arm64FixCortexA53Ldflags", []string{"-Wl,--fix-cortex-a53-843419"})
+ pctx.StaticVariable("Arm64FixCortexA53Ldflags", "-Wl,--fix-cortex-a53-843419")
}
var (
diff --git a/cc/config/arm64_linux_host.go b/cc/config/arm64_linux_host.go
index f7d190b..438e0e6 100644
--- a/cc/config/arm64_linux_host.go
+++ b/cc/config/arm64_linux_host.go
@@ -61,9 +61,9 @@
)
func init() {
- exportedVars.ExportStringListStaticVariable("LinuxBionicArm64Cflags", linuxCrossCflags)
- exportedVars.ExportStringListStaticVariable("LinuxBionicArm64Ldflags", linuxCrossLdflags)
- exportedVars.ExportStringListStaticVariable("LinuxBionicArm64Lldflags", linuxCrossLldflags)
+ pctx.StaticVariable("LinuxBionicArm64Cflags", strings.Join(linuxCrossCflags, " "))
+ pctx.StaticVariable("LinuxBionicArm64Ldflags", strings.Join(linuxCrossLdflags, " "))
+ pctx.StaticVariable("LinuxBionicArm64Lldflags", strings.Join(linuxCrossLldflags, " "))
}
// toolchain config for ARM64 Linux CrossHost. Almost everything is the same as the ARM64 Android
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index 3284e4b..3cb1909 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -35,7 +35,7 @@
armCppflags = []string{
// Revert this after b/322359235 is fixed
"-mllvm", "-enable-shrink-wrap=false",
- }
+ }
armLdflags = []string{
"-Wl,-m,armelf",
@@ -185,43 +185,37 @@
)
func init() {
- // Just exported. Not created as a Ninja static variable.
- exportedVars.ExportString("ArmClangTriple", clangTriple)
+ pctx.StaticVariable("ArmLdflags", strings.Join(armLdflags, " "))
+ pctx.StaticVariable("ArmLldflags", strings.Join(armLldflags, " "))
- exportedVars.ExportStringListStaticVariable("ArmLdflags", armLdflags)
- exportedVars.ExportStringListStaticVariable("ArmLldflags", armLldflags)
-
- exportedVars.ExportStringListStaticVariable("ArmFixCortexA8LdFlags", armFixCortexA8LdFlags)
- exportedVars.ExportStringListStaticVariable("ArmNoFixCortexA8LdFlags", armNoFixCortexA8LdFlags)
+ pctx.StaticVariable("ArmFixCortexA8LdFlags", strings.Join(armFixCortexA8LdFlags, " "))
+ pctx.StaticVariable("ArmNoFixCortexA8LdFlags", strings.Join(armNoFixCortexA8LdFlags, " "))
// Clang cflags
- exportedVars.ExportStringListStaticVariable("ArmToolchainCflags", armToolchainCflags)
- exportedVars.ExportStringListStaticVariable("ArmCflags", armCflags)
- exportedVars.ExportStringListStaticVariable("ArmCppflags", armCppflags)
+ pctx.StaticVariable("ArmToolchainCflags", strings.Join(armToolchainCflags, " "))
+ pctx.StaticVariable("ArmCflags", strings.Join(armCflags, " "))
+ pctx.StaticVariable("ArmCppflags", strings.Join(armCppflags, " "))
// Clang ARM vs. Thumb instruction set cflags
- exportedVars.ExportStringListStaticVariable("ArmArmCflags", armArmCflags)
- exportedVars.ExportStringListStaticVariable("ArmThumbCflags", armThumbCflags)
-
- exportedVars.ExportVariableReferenceDict("ArmArchVariantCflags", armArchVariantCflagsVar)
- exportedVars.ExportVariableReferenceDict("ArmCpuVariantCflags", armCpuVariantCflagsVar)
+ pctx.StaticVariable("ArmArmCflags", strings.Join(armArmCflags, " "))
+ pctx.StaticVariable("ArmThumbCflags", strings.Join(armThumbCflags, " "))
// Clang arch variant cflags
- exportedVars.ExportStringListStaticVariable("ArmArmv7ACflags", armArchVariantCflags["armv7-a"])
- exportedVars.ExportStringListStaticVariable("ArmArmv7ANeonCflags", armArchVariantCflags["armv7-a-neon"])
- exportedVars.ExportStringListStaticVariable("ArmArmv8ACflags", armArchVariantCflags["armv8-a"])
- exportedVars.ExportStringListStaticVariable("ArmArmv82ACflags", armArchVariantCflags["armv8-2a"])
+ pctx.StaticVariable("ArmArmv7ACflags", strings.Join(armArchVariantCflags["armv7-a"], " "))
+ pctx.StaticVariable("ArmArmv7ANeonCflags", strings.Join(armArchVariantCflags["armv7-a-neon"], " "))
+ pctx.StaticVariable("ArmArmv8ACflags", strings.Join(armArchVariantCflags["armv8-a"], " "))
+ pctx.StaticVariable("ArmArmv82ACflags", strings.Join(armArchVariantCflags["armv8-2a"], " "))
// Clang cpu variant cflags
- exportedVars.ExportStringListStaticVariable("ArmGenericCflags", armCpuVariantCflags[""])
- exportedVars.ExportStringListStaticVariable("ArmCortexA7Cflags", armCpuVariantCflags["cortex-a7"])
- exportedVars.ExportStringListStaticVariable("ArmCortexA8Cflags", armCpuVariantCflags["cortex-a8"])
- exportedVars.ExportStringListStaticVariable("ArmCortexA15Cflags", armCpuVariantCflags["cortex-a15"])
- exportedVars.ExportStringListStaticVariable("ArmCortexA32Cflags", armCpuVariantCflags["cortex-a32"])
- exportedVars.ExportStringListStaticVariable("ArmCortexA53Cflags", armCpuVariantCflags["cortex-a53"])
- exportedVars.ExportStringListStaticVariable("ArmCortexA55Cflags", armCpuVariantCflags["cortex-a55"])
- exportedVars.ExportStringListStaticVariable("ArmKraitCflags", armCpuVariantCflags["krait"])
- exportedVars.ExportStringListStaticVariable("ArmKryoCflags", armCpuVariantCflags["kryo"])
+ pctx.StaticVariable("ArmGenericCflags", strings.Join(armCpuVariantCflags[""], " "))
+ pctx.StaticVariable("ArmCortexA7Cflags", strings.Join(armCpuVariantCflags["cortex-a7"], " "))
+ pctx.StaticVariable("ArmCortexA8Cflags", strings.Join(armCpuVariantCflags["cortex-a8"], " "))
+ pctx.StaticVariable("ArmCortexA15Cflags", strings.Join(armCpuVariantCflags["cortex-a15"], " "))
+ pctx.StaticVariable("ArmCortexA32Cflags", strings.Join(armCpuVariantCflags["cortex-a32"], " "))
+ pctx.StaticVariable("ArmCortexA53Cflags", strings.Join(armCpuVariantCflags["cortex-a53"], " "))
+ pctx.StaticVariable("ArmCortexA55Cflags", strings.Join(armCpuVariantCflags["cortex-a55"], " "))
+ pctx.StaticVariable("ArmKraitCflags", strings.Join(armCpuVariantCflags["krait"], " "))
+ pctx.StaticVariable("ArmKryoCflags", strings.Join(armCpuVariantCflags["kryo"], " "))
}
var (
diff --git a/cc/config/arm_linux_host.go b/cc/config/arm_linux_host.go
index e21c60d..e7c7bc4 100644
--- a/cc/config/arm_linux_host.go
+++ b/cc/config/arm_linux_host.go
@@ -14,7 +14,10 @@
package config
-import "android/soong/android"
+import (
+ "android/soong/android"
+ "strings"
+)
var (
linuxArmCflags = []string{
@@ -39,15 +42,15 @@
)
func init() {
- exportedVars.ExportStringListStaticVariable("LinuxArmCflags", linuxArmCflags)
- exportedVars.ExportStringListStaticVariable("LinuxArm64Cflags", linuxArm64Cflags)
- exportedVars.ExportStringListStaticVariable("LinuxArmLdflags", linuxArmLdflags)
- exportedVars.ExportStringListStaticVariable("LinuxArmLldflags", linuxArmLldflags)
- exportedVars.ExportStringListStaticVariable("LinuxArm64Ldflags", linuxArm64Ldflags)
- exportedVars.ExportStringListStaticVariable("LinuxArm64Lldflags", linuxArm64Lldflags)
+ pctx.StaticVariable("LinuxArmCflags", strings.Join(linuxArmCflags, " "))
+ pctx.StaticVariable("LinuxArm64Cflags", strings.Join(linuxArm64Cflags, " "))
+ pctx.StaticVariable("LinuxArmLdflags", strings.Join(linuxArmLdflags, " "))
+ pctx.StaticVariable("LinuxArmLldflags", strings.Join(linuxArmLldflags, " "))
+ pctx.StaticVariable("LinuxArm64Ldflags", strings.Join(linuxArm64Ldflags, " "))
+ pctx.StaticVariable("LinuxArm64Lldflags", strings.Join(linuxArm64Lldflags, " "))
- exportedVars.ExportStringListStaticVariable("LinuxArmYasmFlags", []string{"-f elf32 -m arm"})
- exportedVars.ExportStringListStaticVariable("LinuxArm64YasmFlags", []string{"-f elf64 -m aarch64"})
+ pctx.StaticVariable("LinuxArmYasmFlags", "-f elf32 -m arm")
+ pctx.StaticVariable("LinuxArm64YasmFlags", "-f elf64 -m aarch64")
}
diff --git a/cc/config/global.go b/cc/config/global.go
index b21d56c..ffd6d7e 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -24,8 +24,7 @@
)
var (
- pctx = android.NewPackageContext("android/soong/cc/config")
- exportedVars = android.NewExportedVariables(pctx)
+ pctx = android.NewPackageContext("android/soong/cc/config")
// Flags used by lots of devices. Putting them in package static variables
// will save bytes in build.ninja so they aren't repeated for every file
@@ -145,6 +144,9 @@
// Make paths in deps files relative.
"-no-canonical-prefixes",
+
+ // http://b/315250603 temporarily disabled
+ "-Wno-error=format",
}
commonGlobalConlyflags = []string{}
@@ -255,8 +257,6 @@
"-Werror=fortify-source",
// http://b/315246135 temporarily disabled
"-Wno-unused-variable",
- // http://b/315250603 temporarily disabled
- "-Wno-error=format",
// Disabled because it produces many false positives. http://b/323050926
"-Wno-missing-field-initializers",
// http://b/323050889
@@ -295,6 +295,9 @@
// New warnings to be fixed after clang-r475365
"-Wno-error=single-bit-bitfield-constant-conversion", // http://b/243965903
"-Wno-error=enum-constexpr-conversion", // http://b/243964282
+ // New warnings to be fixed after clang-r522817
+ "-Wno-error=invalid-offsetof",
+ "-Wno-error=thread-safety-reference-return",
// Irrelevant on Android because _we_ don't use exceptions, but causes
// lots of build noise because libcxx/libcxxabi do. This can probably
@@ -302,6 +305,9 @@
// until then because it causes warnings in the _callers_, not the
// project itself.
"-Wno-deprecated-dynamic-exception-spec",
+
+ // Allow using VLA CXX extension.
+ "-Wno-vla-cxx-extension",
}
noOverride64GlobalCflags = []string{}
@@ -386,7 +392,7 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r510928"
+ ClangDefaultVersion = "clang-r522817"
ClangDefaultShortVersion = "18"
// Directories with warnings from Android.bp files.
@@ -401,26 +407,19 @@
VisibilityDefaultFlag = "-fvisibility=default"
)
-func ExportStringList(name string, value []string) {
- exportedVars.ExportStringList(name, value)
-}
-
func init() {
if runtime.GOOS == "linux" {
commonGlobalCflags = append(commonGlobalCflags, "-fdebug-prefix-map=/proc/self/cwd=")
}
- exportedVars.ExportStringListStaticVariable("CommonGlobalConlyflags", commonGlobalConlyflags)
- exportedVars.ExportStringListStaticVariable("CommonGlobalAsflags", commonGlobalAsflags)
- exportedVars.ExportStringListStaticVariable("DeviceGlobalCppflags", deviceGlobalCppflags)
- exportedVars.ExportStringListStaticVariable("DeviceGlobalLdflags", deviceGlobalLdflags)
- exportedVars.ExportStringListStaticVariable("DeviceGlobalLldflags", deviceGlobalLldflags)
- exportedVars.ExportStringListStaticVariable("HostGlobalCppflags", hostGlobalCppflags)
- exportedVars.ExportStringListStaticVariable("HostGlobalLdflags", hostGlobalLdflags)
- exportedVars.ExportStringListStaticVariable("HostGlobalLldflags", hostGlobalLldflags)
-
- // Export the static default CommonGlobalCflags to Bazel.
- exportedVars.ExportStringList("CommonGlobalCflags", commonGlobalCflags)
+ pctx.StaticVariable("CommonGlobalConlyflags", strings.Join(commonGlobalConlyflags, " "))
+ pctx.StaticVariable("CommonGlobalAsflags", strings.Join(commonGlobalAsflags, " "))
+ pctx.StaticVariable("DeviceGlobalCppflags", strings.Join(deviceGlobalCppflags, " "))
+ pctx.StaticVariable("DeviceGlobalLdflags", strings.Join(deviceGlobalLdflags, " "))
+ pctx.StaticVariable("DeviceGlobalLldflags", strings.Join(deviceGlobalLldflags, " "))
+ pctx.StaticVariable("HostGlobalCppflags", strings.Join(hostGlobalCppflags, " "))
+ pctx.StaticVariable("HostGlobalLdflags", strings.Join(hostGlobalLdflags, " "))
+ pctx.StaticVariable("HostGlobalLldflags", strings.Join(hostGlobalLldflags, " "))
pctx.VariableFunc("CommonGlobalCflags", func(ctx android.PackageVarContext) string {
flags := slices.Clone(commonGlobalCflags)
@@ -467,16 +466,10 @@
return strings.Join(flags, " ")
})
- // Export the static default DeviceGlobalCflags to Bazel.
- // TODO(187086342): handle cflags that are set in VariableFuncs.
- exportedVars.ExportStringList("DeviceGlobalCflags", deviceGlobalCflags)
-
pctx.VariableFunc("DeviceGlobalCflags", func(ctx android.PackageVarContext) string {
return strings.Join(deviceGlobalCflags, " ")
})
- // Export the static default NoOverrideGlobalCflags to Bazel.
- exportedVars.ExportStringList("NoOverrideGlobalCflags", noOverrideGlobalCflags)
pctx.VariableFunc("NoOverrideGlobalCflags", func(ctx android.PackageVarContext) string {
flags := noOverrideGlobalCflags
if ctx.Config().IsEnvTrue("LLVM_NEXT") {
@@ -486,21 +479,11 @@
return strings.Join(flags, " ")
})
- exportedVars.ExportStringListStaticVariable("NoOverride64GlobalCflags", noOverride64GlobalCflags)
- exportedVars.ExportStringListStaticVariable("HostGlobalCflags", hostGlobalCflags)
- exportedVars.ExportStringListStaticVariable("NoOverrideExternalGlobalCflags", noOverrideExternalGlobalCflags)
- exportedVars.ExportStringListStaticVariable("CommonGlobalCppflags", commonGlobalCppflags)
- exportedVars.ExportStringListStaticVariable("ExternalCflags", extraExternalCflags)
-
- exportedVars.ExportString("CStdVersion", CStdVersion)
- exportedVars.ExportString("CppStdVersion", CppStdVersion)
- exportedVars.ExportString("ExperimentalCStdVersion", ExperimentalCStdVersion)
- exportedVars.ExportString("ExperimentalCppStdVersion", ExperimentalCppStdVersion)
-
- exportedVars.ExportString("VersionScriptFlagPrefix", VersionScriptFlagPrefix)
-
- exportedVars.ExportString("VisibilityHiddenFlag", VisibilityHiddenFlag)
- exportedVars.ExportString("VisibilityDefaultFlag", VisibilityDefaultFlag)
+ pctx.StaticVariable("NoOverride64GlobalCflags", strings.Join(noOverride64GlobalCflags, " "))
+ pctx.StaticVariable("HostGlobalCflags", strings.Join(hostGlobalCflags, " "))
+ pctx.StaticVariable("NoOverrideExternalGlobalCflags", strings.Join(noOverrideExternalGlobalCflags, " "))
+ pctx.StaticVariable("CommonGlobalCppflags", strings.Join(commonGlobalCppflags, " "))
+ pctx.StaticVariable("ExternalCflags", strings.Join(extraExternalCflags, " "))
// Everything in these lists is a crime against abstraction and dependency tracking.
// Do not add anything to this list.
@@ -515,11 +498,10 @@
"frameworks/native/opengl/include",
"frameworks/av/include",
}
- exportedVars.ExportStringList("CommonGlobalIncludes", commonGlobalIncludes)
pctx.PrefixedExistentPathsForSourcesVariable("CommonGlobalIncludes", "-I", commonGlobalIncludes)
- exportedVars.ExportStringStaticVariable("CLANG_DEFAULT_VERSION", ClangDefaultVersion)
- exportedVars.ExportStringStaticVariable("CLANG_DEFAULT_SHORT_VERSION", ClangDefaultShortVersion)
+ pctx.StaticVariable("CLANG_DEFAULT_VERSION", ClangDefaultVersion)
+ pctx.StaticVariable("CLANG_DEFAULT_SHORT_VERSION", ClangDefaultShortVersion)
pctx.StaticVariableWithEnvOverride("ClangBase", "LLVM_PREBUILTS_BASE", ClangDefaultBase)
pctx.StaticVariableWithEnvOverride("ClangVersion", "LLVM_PREBUILTS_VERSION", ClangDefaultVersion)
@@ -529,7 +511,7 @@
pctx.StaticVariableWithEnvOverride("ClangShortVersion", "LLVM_RELEASE_VERSION", ClangDefaultShortVersion)
pctx.StaticVariable("ClangAsanLibDir", "${ClangBase}/linux-x86/${ClangVersion}/lib/clang/${ClangShortVersion}/lib/linux")
- exportedVars.ExportStringListStaticVariable("WarningAllowedProjects", WarningAllowedProjects)
+ pctx.StaticVariable("WarningAllowedProjects", strings.Join(WarningAllowedProjects, " "))
// These are tied to the version of LLVM directly in external/llvm, so they might trail the host prebuilts
// being used for the rest of the build process.
@@ -544,7 +526,6 @@
"frameworks/rs/script_api/include",
}
pctx.PrefixedExistentPathsForSourcesVariable("RsGlobalIncludes", "-I", rsGlobalIncludes)
- exportedVars.ExportStringList("RsGlobalIncludes", rsGlobalIncludes)
pctx.VariableFunc("CcWrapper", func(ctx android.PackageVarContext) string {
if override := ctx.Config().Getenv("CC_WRAPPER"); override != "" {
@@ -562,7 +543,7 @@
pctx.StaticVariableWithEnvOverride("REAbiLinkerExecStrategy", "RBE_ABI_LINKER_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
}
-var HostPrebuiltTag = exportedVars.ExportVariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
+var HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
func ClangPath(ctx android.PathContext, file string) android.SourcePath {
type clangToolKey string
diff --git a/cc/config/riscv64_device.go b/cc/config/riscv64_device.go
index 47f0de1..724676a 100644
--- a/cc/config/riscv64_device.go
+++ b/cc/config/riscv64_device.go
@@ -62,15 +62,11 @@
func init() {
- exportedVars.ExportStringListStaticVariable("Riscv64Ldflags", riscv64Ldflags)
- exportedVars.ExportStringListStaticVariable("Riscv64Lldflags", riscv64Lldflags)
+ pctx.StaticVariable("Riscv64Ldflags", strings.Join(riscv64Ldflags, " "))
+ pctx.StaticVariable("Riscv64Lldflags", strings.Join(riscv64Lldflags, " "))
- exportedVars.ExportStringListStaticVariable("Riscv64Cflags", riscv64Cflags)
- exportedVars.ExportStringListStaticVariable("Riscv64Cppflags", riscv64Cppflags)
-
- exportedVars.ExportVariableReferenceDict("Riscv64ArchVariantCflags", riscv64ArchVariantCflagsVar)
- exportedVars.ExportVariableReferenceDict("Riscv64CpuVariantCflags", riscv64CpuVariantCflagsVar)
- exportedVars.ExportVariableReferenceDict("Riscv64CpuVariantLdflags", riscv64CpuVariantLdflags)
+ pctx.StaticVariable("Riscv64Cflags", strings.Join(riscv64Cflags, " "))
+ pctx.StaticVariable("Riscv64Cppflags", strings.Join(riscv64Cppflags, " "))
}
var (
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index b40557a..46d5d90 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -87,7 +87,7 @@
// The global default tidy checks should include clang-tidy
// default checks and tested groups, but exclude known noisy checks.
// See https://clang.llvm.org/extra/clang-tidy/checks/list.html
- exportedVars.ExportVariableConfigMethod("TidyDefaultGlobalChecks", func(config android.Config) string {
+ pctx.VariableConfigMethod("TidyDefaultGlobalChecks", func(config android.Config) string {
if override := config.Getenv("DEFAULT_GLOBAL_TIDY_CHECKS"); override != "" {
return override
}
@@ -149,7 +149,7 @@
// There are too many clang-tidy warnings in external and vendor projects, so we only
// enable some google checks for these projects. Users can add more checks locally with the
// "tidy_checks" list in .bp files, or the "Checks" list in .clang-tidy config files.
- exportedVars.ExportVariableConfigMethod("TidyExternalVendorChecks", func(config android.Config) string {
+ pctx.VariableConfigMethod("TidyExternalVendorChecks", func(config android.Config) string {
if override := config.Getenv("DEFAULT_EXTERNAL_VENDOR_TIDY_CHECKS"); override != "" {
return override
}
@@ -163,25 +163,21 @@
}, ",")
})
- exportedVars.ExportVariableFuncVariable("TidyGlobalNoChecks", func() string {
- return strings.Join(globalNoCheckList, ",")
- })
+ pctx.StaticVariable("TidyGlobalNoChecks", strings.Join(globalNoCheckList, ","))
- exportedVars.ExportVariableFuncVariable("TidyGlobalNoErrorChecks", func() string {
- return strings.Join(globalNoErrorCheckList, ",")
- })
+ pctx.StaticVariable("TidyGlobalNoErrorChecks", strings.Join(globalNoErrorCheckList, ","))
- exportedVars.ExportStringListStaticVariable("TidyExtraArgFlags", extraArgFlags)
+ pctx.StaticVariable("TidyExtraArgFlags", strings.Join(extraArgFlags, " "))
// To reduce duplicate warnings from the same header files,
// header-filter will contain only the module directory and
// those specified by DEFAULT_TIDY_HEADER_DIRS.
- exportedVars.ExportVariableConfigMethod("TidyDefaultHeaderDirs", func(config android.Config) string {
+ pctx.VariableConfigMethod("TidyDefaultHeaderDirs", func(config android.Config) string {
return config.Getenv("DEFAULT_TIDY_HEADER_DIRS")
})
// Use WTIH_TIDY_FLAGS to pass extra global default clang-tidy flags.
- exportedVars.ExportVariableConfigMethod("TidyWithTidyFlags", func(config android.Config) string {
+ pctx.VariableConfigMethod("TidyWithTidyFlags", func(config android.Config) string {
return config.Getenv("WITH_TIDY_FLAGS")
})
}
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index 71e98fe..7dc990b 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -16,14 +16,15 @@
import (
"fmt"
+ "strings"
"android/soong/android"
)
func init() {
- exportedVars.ExportStringListStaticVariable("DarwinAvailableLibraries", darwinAvailableLibraries)
- exportedVars.ExportStringListStaticVariable("LinuxAvailableLibraries", linuxAvailableLibraries)
- exportedVars.ExportStringListStaticVariable("WindowsAvailableLibraries", windowsAvailableLibraries)
+ pctx.StaticVariable("DarwinAvailableLibraries", strings.Join(darwinAvailableLibraries, " "))
+ pctx.StaticVariable("LinuxAvailableLibraries", strings.Join(linuxAvailableLibraries, " "))
+ pctx.StaticVariable("WindowsAvailableLibraries", strings.Join(windowsAvailableLibraries, " "))
}
type toolchainFactory func(arch android.Arch) Toolchain
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index ca2c2b7..5aa2a7e 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -97,11 +97,10 @@
)
func init() {
- exportedVars.ExportStringListStaticVariable("X86_64ToolchainCflags", []string{"-m64"})
- exportedVars.ExportStringListStaticVariable("X86_64ToolchainLdflags", []string{"-m64"})
+ pctx.StaticVariable("X86_64ToolchainCflags", "-m64")
+ pctx.StaticVariable("X86_64ToolchainLdflags", "-m64")
- exportedVars.ExportStringListStaticVariable("X86_64Ldflags", x86_64Ldflags)
- exportedVars.ExportStringList("X86_64Lldflags", X86_64Lldflags)
+ pctx.StaticVariable("X86_64Ldflags", strings.Join(x86_64Ldflags, " "))
pctx.VariableFunc("X86_64Lldflags", func(ctx android.PackageVarContext) string {
maxPageSizeFlag := "-Wl,-z,max-page-size=" + ctx.Config().MaxPageSizeSupported()
flags := append(X86_64Lldflags, maxPageSizeFlag)
@@ -109,27 +108,20 @@
})
// Clang cflags
- exportedVars.ExportStringList("X86_64Cflags", x86_64Cflags)
pctx.VariableFunc("X86_64Cflags", func(ctx android.PackageVarContext) string {
flags := x86_64Cflags
if ctx.Config().NoBionicPageSizeMacro() {
flags = append(flags, "-D__BIONIC_NO_PAGE_SIZE_MACRO")
+ } else {
+ flags = append(flags, "-D__BIONIC_DEPRECATED_PAGE_SIZE_MACRO")
}
return strings.Join(flags, " ")
})
- exportedVars.ExportStringListStaticVariable("X86_64Cppflags", x86_64Cppflags)
+ pctx.StaticVariable("X86_64Cppflags", strings.Join(x86_64Cppflags, " "))
// Yasm flags
- exportedVars.ExportStringListStaticVariable("X86_64YasmFlags", []string{
- "-f elf64",
- "-m amd64",
- })
-
- // Extended cflags
-
- exportedVars.ExportStringListDict("X86_64ArchVariantCflags", x86_64ArchVariantCflags)
- exportedVars.ExportStringListDict("X86_64ArchFeatureCflags", x86_64ArchFeatureCflags)
+ pctx.StaticVariable("X86_64YasmFlags", "-f elf64 -m amd64")
// Architecture variant cflags
for variant, cflags := range x86_64ArchVariantCflags {
diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go
index 60b8339..4b0041c 100644
--- a/cc/config/x86_device.go
+++ b/cc/config/x86_device.go
@@ -101,25 +101,18 @@
)
func init() {
- exportedVars.ExportStringListStaticVariable("X86ToolchainCflags", []string{"-m32"})
- exportedVars.ExportStringListStaticVariable("X86ToolchainLdflags", []string{"-m32"})
+ pctx.StaticVariable("X86ToolchainCflags", "-m32")
+ pctx.StaticVariable("X86ToolchainLdflags", "-m32")
- exportedVars.ExportStringListStaticVariable("X86Ldflags", x86Ldflags)
- exportedVars.ExportStringListStaticVariable("X86Lldflags", x86Ldflags)
+ pctx.StaticVariable("X86Ldflags", strings.Join(x86Ldflags, " "))
+ pctx.StaticVariable("X86Lldflags", strings.Join(x86Ldflags, " "))
// Clang cflags
- exportedVars.ExportStringListStaticVariable("X86Cflags", x86Cflags)
- exportedVars.ExportStringListStaticVariable("X86Cppflags", x86Cppflags)
+ pctx.StaticVariable("X86Cflags", strings.Join(x86Cflags, " "))
+ pctx.StaticVariable("X86Cppflags", strings.Join(x86Cppflags, " "))
// Yasm flags
- exportedVars.ExportStringListStaticVariable("X86YasmFlags", []string{
- "-f elf32",
- "-m x86",
- })
-
- // Extended cflags
- exportedVars.ExportStringListDict("X86ArchVariantCflags", x86ArchVariantCflags)
- exportedVars.ExportStringListDict("X86ArchFeatureCflags", x86ArchFeatureCflags)
+ pctx.StaticVariable("X86YasmFlags", "-f elf32 -m x86")
// Architecture variant cflags
for variant, cflags := range x86ArchVariantCflags {
diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go
index 99d4ebb..515cb21 100644
--- a/cc/config/x86_linux_bionic_host.go
+++ b/cc/config/x86_linux_bionic_host.go
@@ -16,6 +16,7 @@
import (
"android/soong/android"
+ "strings"
)
var (
@@ -72,13 +73,13 @@
)
func init() {
- exportedVars.ExportStringListStaticVariable("LinuxBionicCflags", linuxBionicCflags)
- exportedVars.ExportStringListStaticVariable("LinuxBionicLdflags", linuxBionicLdflags)
- exportedVars.ExportStringListStaticVariable("LinuxBionicLldflags", linuxBionicLldflags)
+ pctx.StaticVariable("LinuxBionicCflags", strings.Join(linuxBionicCflags, " "))
+ pctx.StaticVariable("LinuxBionicLdflags", strings.Join(linuxBionicLdflags, " "))
+ pctx.StaticVariable("LinuxBionicLldflags", strings.Join(linuxBionicLldflags, " "))
// Use the device gcc toolchain for now
- exportedVars.ExportStringStaticVariable("LinuxBionicGccVersion", x86_64GccVersion)
- exportedVars.ExportSourcePathVariable("LinuxBionicGccRoot",
+ pctx.StaticVariable("LinuxBionicGccVersion", x86_64GccVersion)
+ pctx.SourcePathVariable("LinuxBionicGccRoot",
"prebuilts/gcc/${HostPrebuiltTag}/x86/x86_64-linux-android-${LinuxBionicGccVersion}")
}
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index 9bc54d6..7f22377 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -120,40 +120,40 @@
)
func init() {
- exportedVars.ExportStringStaticVariable("LinuxGccVersion", linuxGccVersion)
- exportedVars.ExportStringStaticVariable("LinuxGlibcVersion", linuxGlibcVersion)
+ pctx.StaticVariable("LinuxGccVersion", linuxGccVersion)
+ pctx.StaticVariable("LinuxGlibcVersion", linuxGlibcVersion)
// Most places use the full GCC version. A few only use up to the first two numbers.
if p := strings.Split(linuxGccVersion, "."); len(p) > 2 {
- exportedVars.ExportStringStaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], "."))
+ pctx.StaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], "."))
} else {
- exportedVars.ExportStringStaticVariable("ShortLinuxGccVersion", linuxGccVersion)
+ pctx.StaticVariable("ShortLinuxGccVersion", linuxGccVersion)
}
- exportedVars.ExportSourcePathVariable("LinuxGccRoot",
+ pctx.SourcePathVariable("LinuxGccRoot",
"prebuilts/gcc/linux-x86/host/x86_64-linux-glibc${LinuxGlibcVersion}-${ShortLinuxGccVersion}")
- exportedVars.ExportStringListStaticVariable("LinuxGccTriple", []string{"x86_64-linux"})
+ pctx.StaticVariable("LinuxGccTriple", "x86_64-linux")
- exportedVars.ExportStringListStaticVariable("LinuxCflags", linuxCflags)
- exportedVars.ExportStringListStaticVariable("LinuxLdflags", linuxLdflags)
- exportedVars.ExportStringListStaticVariable("LinuxLldflags", linuxLldflags)
- exportedVars.ExportStringListStaticVariable("LinuxGlibcCflags", linuxGlibcCflags)
- exportedVars.ExportStringListStaticVariable("LinuxGlibcLdflags", linuxGlibcLdflags)
- exportedVars.ExportStringListStaticVariable("LinuxGlibcLldflags", linuxGlibcLdflags)
- exportedVars.ExportStringListStaticVariable("LinuxMuslCflags", linuxMuslCflags)
- exportedVars.ExportStringListStaticVariable("LinuxMuslLdflags", linuxMuslLdflags)
- exportedVars.ExportStringListStaticVariable("LinuxMuslLldflags", linuxMuslLdflags)
+ pctx.StaticVariable("LinuxCflags", strings.Join(linuxCflags, " "))
+ pctx.StaticVariable("LinuxLdflags", strings.Join(linuxLdflags, " "))
+ pctx.StaticVariable("LinuxLldflags", strings.Join(linuxLldflags, " "))
+ pctx.StaticVariable("LinuxGlibcCflags", strings.Join(linuxGlibcCflags, " "))
+ pctx.StaticVariable("LinuxGlibcLdflags", strings.Join(linuxGlibcLdflags, " "))
+ pctx.StaticVariable("LinuxGlibcLldflags", strings.Join(linuxGlibcLdflags, " "))
+ pctx.StaticVariable("LinuxMuslCflags", strings.Join(linuxMuslCflags, " "))
+ pctx.StaticVariable("LinuxMuslLdflags", strings.Join(linuxMuslLdflags, " "))
+ pctx.StaticVariable("LinuxMuslLldflags", strings.Join(linuxMuslLdflags, " "))
- exportedVars.ExportStringListStaticVariable("LinuxX86Cflags", linuxX86Cflags)
- exportedVars.ExportStringListStaticVariable("LinuxX8664Cflags", linuxX8664Cflags)
- exportedVars.ExportStringListStaticVariable("LinuxX86Ldflags", linuxX86Ldflags)
- exportedVars.ExportStringListStaticVariable("LinuxX86Lldflags", linuxX86Ldflags)
- exportedVars.ExportStringListStaticVariable("LinuxX8664Ldflags", linuxX8664Ldflags)
- exportedVars.ExportStringListStaticVariable("LinuxX8664Lldflags", linuxX8664Ldflags)
+ pctx.StaticVariable("LinuxX86Cflags", strings.Join(linuxX86Cflags, " "))
+ pctx.StaticVariable("LinuxX8664Cflags", strings.Join(linuxX8664Cflags, " "))
+ pctx.StaticVariable("LinuxX86Ldflags", strings.Join(linuxX86Ldflags, " "))
+ pctx.StaticVariable("LinuxX86Lldflags", strings.Join(linuxX86Ldflags, " "))
+ pctx.StaticVariable("LinuxX8664Ldflags", strings.Join(linuxX8664Ldflags, " "))
+ pctx.StaticVariable("LinuxX8664Lldflags", strings.Join(linuxX8664Ldflags, " "))
// Yasm flags
- exportedVars.ExportStringListStaticVariable("LinuxX86YasmFlags", []string{"-f elf32 -m x86"})
- exportedVars.ExportStringListStaticVariable("LinuxX8664YasmFlags", []string{"-f elf64 -m amd64"})
+ pctx.StaticVariable("LinuxX86YasmFlags", "-f elf32 -m x86")
+ pctx.StaticVariable("LinuxX8664YasmFlags", "-f elf64 -m amd64")
}
type toolchainLinux struct {
diff --git a/cc/genrule.go b/cc/genrule.go
index 0fb3e2d..431a01c 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -19,7 +19,6 @@
"android/soong/android"
"android/soong/genrule"
- "android/soong/snapshot"
)
func init() {
@@ -97,43 +96,19 @@
func (g *GenruleExtraProperties) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
// If the build is using a snapshot, the recovery variant under AOSP directories
// is not needed.
- recoverySnapshotVersion := ctx.DeviceConfig().RecoverySnapshotVersion()
- if recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" &&
- !snapshot.IsRecoveryProprietaryModule(ctx) {
- return false
- } else {
- return Bool(g.Recovery_available)
- }
+ return Bool(g.Recovery_available)
}
func (g *GenruleExtraProperties) ExtraImageVariations(ctx android.BaseModuleContext) []string {
var variants []string
- vndkVersion := ctx.DeviceConfig().VndkVersion()
vendorVariantRequired := Bool(g.Vendor_available) || Bool(g.Odm_available) || ctx.SocSpecific() || ctx.DeviceSpecific()
productVariantRequired := Bool(g.Product_available) || ctx.ProductSpecific()
- if vndkVersion == "" {
- if vendorVariantRequired {
- variants = append(variants, VendorVariation)
- }
- if productVariantRequired {
- variants = append(variants, ProductVariation)
- }
- } else {
- if vendorVariantRequired {
- // If vndkVersion is current, we can always use PlatformVndkVersion.
- // If not, we assume modules under proprietary paths are compatible for
- // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, that is
- // PLATFORM_VNDK_VERSION.
- if vndkVersion == "current" || !snapshot.IsVendorProprietaryModule(ctx) {
- variants = append(variants, VendorVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion())
- } else {
- variants = append(variants, VendorVariationPrefix+vndkVersion)
- }
- }
- if productVariantRequired {
- variants = append(variants, ProductVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion())
- }
+ if vendorVariantRequired {
+ variants = append(variants, VendorVariation)
+ }
+ if productVariantRequired {
+ variants = append(variants, ProductVariation)
}
return variants
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
index 0896206..b3d5116 100644
--- a/cc/genrule_test.go
+++ b/cc/genrule_test.go
@@ -200,7 +200,7 @@
}
`
t.Helper()
- ctx := PrepareForTestWithCcIncludeVndk.RunTestWithBp(t, bp)
+ ctx := PrepareForIntegrationTestWithCc.RunTestWithBp(t, bp)
variants := ctx.ModuleVariantsForTests("gen")
if !slices.Contains(variants, "android_vendor_arm64_armv8-a") {
diff --git a/cc/image.go b/cc/image.go
index d02a2f3..f8c5ca5 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -22,7 +22,6 @@
"strings"
"android/soong/android"
- "android/soong/snapshot"
"github.com/google/blueprint/proptools"
)
@@ -429,43 +428,26 @@
var vendorVariants []string
var productVariants []string
- platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
- boardVndkVersion := mctx.DeviceConfig().VndkVersion()
- recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion()
- usingRecoverySnapshot := recoverySnapshotVersion != "current" &&
- recoverySnapshotVersion != ""
needVndkVersionVendorVariantForLlndk := false
- if boardVndkVersion != "" {
- boardVndkApiLevel, err := android.ApiLevelFromUser(mctx, boardVndkVersion)
- if err == nil && !boardVndkApiLevel.IsPreview() {
- // VNDK snapshot newer than v30 has LLNDK stub libraries.
- // Only the VNDK version less than or equal to v30 requires generating the vendor
- // variant of the VNDK version from the source tree.
- needVndkVersionVendorVariantForLlndk = boardVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, "30"))
- }
- }
- if boardVndkVersion == "current" {
- boardVndkVersion = platformVndkVersion
- }
if m.NeedsLlndkVariants() {
// This is an LLNDK library. The implementation of the library will be on /system,
// and vendor and product variants will be created with LLNDK stubs.
// The LLNDK libraries need vendor variants even if there is no VNDK.
coreVariantNeeded = true
- vendorVariants = append(vendorVariants, platformVndkVersion)
- productVariants = append(productVariants, platformVndkVersion)
+ vendorVariants = append(vendorVariants, "")
+ productVariants = append(productVariants, "")
// Generate vendor variants for boardVndkVersion only if the VNDK snapshot does not
// provide the LLNDK stub libraries.
if needVndkVersionVendorVariantForLlndk {
- vendorVariants = append(vendorVariants, boardVndkVersion)
+ vendorVariants = append(vendorVariants, "")
}
} else if m.NeedsVendorPublicLibraryVariants() {
// A vendor public library has the implementation on /vendor, with stub variants
// for system and product.
coreVariantNeeded = true
- vendorVariants = append(vendorVariants, boardVndkVersion)
- productVariants = append(productVariants, platformVndkVersion)
+ vendorVariants = append(vendorVariants, "")
+ productVariants = append(productVariants, "")
} else if m.IsSnapshotPrebuilt() {
// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
// PRODUCT_EXTRA_VNDK_VERSIONS.
@@ -483,36 +465,16 @@
// BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
// PLATFORM_VNDK_VERSION.
if m.HasVendorVariant() {
- if snapshot.IsVendorProprietaryModule(mctx) {
- vendorVariants = append(vendorVariants, boardVndkVersion)
- } else {
- vendorVariants = append(vendorVariants, platformVndkVersion)
- }
+ vendorVariants = append(vendorVariants, "")
}
// product_available modules are available to /product.
if m.HasProductVariant() {
- productVariants = append(productVariants, platformVndkVersion)
+ productVariants = append(productVariants, "")
}
} else if vendorSpecific && m.SdkVersion() == "" {
// This will be available in /vendor (or /odm) only
-
- // kernel_headers is a special module type whose exported headers
- // are coming from DeviceKernelHeaders() which is always vendor
- // dependent. They'll always have both vendor variants.
- // For other modules, we assume that modules under proprietary
- // paths are compatible for BOARD_VNDK_VERSION. The other modules
- // are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
- if m.KernelHeadersDecorator() {
- vendorVariants = append(vendorVariants,
- platformVndkVersion,
- boardVndkVersion,
- )
- } else if snapshot.IsVendorProprietaryModule(mctx) {
- vendorVariants = append(vendorVariants, boardVndkVersion)
- } else {
- vendorVariants = append(vendorVariants, platformVndkVersion)
- }
+ vendorVariants = append(vendorVariants, "")
} else {
// This is either in /system (or similar: /data), or is a
// module built with the NDK. Modules built with the NDK
@@ -523,7 +485,7 @@
if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
// The module has "product_specific: true" that does not create core variant.
coreVariantNeeded = false
- productVariants = append(productVariants, platformVndkVersion)
+ productVariants = append(productVariants, "")
}
if m.RamdiskAvailable() {
@@ -553,15 +515,6 @@
coreVariantNeeded = false
}
- // If using a snapshot, the recovery variant under AOSP directories is not needed,
- // except for kernel headers, which needs all variants.
- if !m.KernelHeadersDecorator() &&
- !m.IsSnapshotPrebuilt() &&
- usingRecoverySnapshot &&
- !snapshot.IsRecoveryProprietaryModule(mctx) {
- recoveryVariantNeeded = false
- }
-
for _, variant := range android.FirstUniqueStrings(vendorVariants) {
if variant == "" {
m.AppendExtraVariant(VendorVariation)
@@ -693,14 +646,6 @@
m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
}
squashVendorSrcs(m)
-
- // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
- // Hide other vendor variants to avoid collision.
- vndkVersion := ctx.DeviceConfig().VndkVersion()
- if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
- m.Properties.HideFromMake = true
- m.HideFromMake()
- }
} else if strings.HasPrefix(variant, ProductVariation) {
m.Properties.ImageVariation = ProductVariation
if strings.HasPrefix(variant, ProductVariationPrefix) {
diff --git a/cc/library.go b/cc/library.go
index 5607632..5b24809 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -17,7 +17,6 @@
import (
"fmt"
"io"
- "log"
"path/filepath"
"regexp"
"strconv"
@@ -295,6 +294,10 @@
return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
}
+func (f *flagExporter) exportedSystemIncludes(ctx ModuleContext) android.Paths {
+ return android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)
+}
+
// exportIncludes registers the include directories and system include directories to be exported
// transitively to modules depending on this module.
func (f *flagExporter) exportIncludes(ctx ModuleContext) {
@@ -390,9 +393,6 @@
// Output archive of gcno coverage information files
coverageOutputFile android.OptionalPath
- // linked Source Abi Dump
- sAbiOutputFile android.OptionalPath
-
// Source Abi Diff
sAbiDiff android.Paths
@@ -424,126 +424,9 @@
*baseLinker
*baseInstaller
- collectedSnapshotHeaders android.Paths
-
apiListCoverageXmlPath android.ModuleOutPath
}
-func GlobHeadersForSnapshot(ctx android.ModuleContext, paths android.Paths) android.Paths {
- ret := android.Paths{}
-
- // Headers in the source tree should be globbed. On the contrast, generated headers
- // can't be globbed, and they should be manually collected.
- // So, we first filter out intermediate directories (which contains generated headers)
- // from exported directories, and then glob headers under remaining directories.
- for _, path := range paths {
- dir := path.String()
- // Skip if dir is for generated headers
- if strings.HasPrefix(dir, ctx.Config().OutDir()) {
- continue
- }
-
- // libeigen wrongly exports the root directory "external/eigen". But only two
- // subdirectories "Eigen" and "unsupported" contain exported header files. Even worse
- // some of them have no extension. So we need special treatment for libeigen in order
- // to glob correctly.
- if dir == "external/eigen" {
- // Only these two directories contains exported headers.
- for _, subdir := range []string{"Eigen", "unsupported/Eigen"} {
- globDir := "external/eigen/" + subdir + "/**/*"
- glob, err := ctx.GlobWithDeps(globDir, nil)
- if err != nil {
- ctx.ModuleErrorf("glob of %q failed: %s", globDir, err)
- return nil
- }
- for _, header := range glob {
- if strings.HasSuffix(header, "/") {
- continue
- }
- ext := filepath.Ext(header)
- if ext != "" && ext != ".h" {
- continue
- }
- ret = append(ret, android.PathForSource(ctx, header))
- }
- }
- continue
- }
- globDir := dir + "/**/*"
- glob, err := ctx.GlobWithDeps(globDir, nil)
- if err != nil {
- ctx.ModuleErrorf("glob of %q failed: %s", globDir, err)
- return nil
- }
- isLibcxx := strings.HasPrefix(dir, "external/libcxx/include")
- for _, header := range glob {
- if isLibcxx {
- // Glob all files under this special directory, because of C++ headers with no
- // extension.
- if strings.HasSuffix(header, "/") {
- continue
- }
- } else {
- // Filter out only the files with extensions that are headers.
- found := false
- for _, ext := range HeaderExts {
- if strings.HasSuffix(header, ext) {
- found = true
- break
- }
- }
- if !found {
- continue
- }
- }
- ret = append(ret, android.PathForSource(ctx, header))
- }
- }
- return ret
-}
-
-func GlobGeneratedHeadersForSnapshot(_ android.ModuleContext, paths android.Paths) android.Paths {
- ret := android.Paths{}
- for _, header := range paths {
- // TODO(b/148123511): remove exportedDeps after cleaning up genrule
- if strings.HasSuffix(header.Base(), "-phony") {
- continue
- }
- ret = append(ret, header)
- }
- return ret
-}
-
-// collectHeadersForSnapshot collects all exported headers from library.
-// It globs header files in the source tree for exported include directories,
-// and tracks generated header files separately.
-//
-// This is to be called from GenerateAndroidBuildActions, and then collected
-// header files can be retrieved by snapshotHeaders().
-func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext) {
- ret := android.Paths{}
-
- // Headers in the source tree should be globbed. On the contrast, generated headers
- // can't be globbed, and they should be manually collected.
- // So, we first filter out intermediate directories (which contains generated headers)
- // from exported directories, and then glob headers under remaining directories.
- ret = append(ret, GlobHeadersForSnapshot(ctx, append(android.CopyOfPaths(l.flagExporter.dirs), l.flagExporter.systemDirs...))...)
-
- // Collect generated headers
- ret = append(ret, GlobGeneratedHeadersForSnapshot(ctx, append(android.CopyOfPaths(l.flagExporter.headers), l.flagExporter.deps...))...)
-
- l.collectedSnapshotHeaders = ret
-}
-
-// This returns all exported header files, both generated ones and headers from source tree.
-// collectHeadersForSnapshot() must be called before calling this.
-func (l *libraryDecorator) snapshotHeaders() android.Paths {
- if l.collectedSnapshotHeaders == nil {
- panic("snapshotHeaders() must be called after collectHeadersForSnapshot()")
- }
- return l.collectedSnapshotHeaders
-}
-
// linkerProps returns the list of properties structs relevant for this library. (For example, if
// the library is cc_shared_library, then static-library properties are omitted.)
func (library *libraryDecorator) linkerProps() []interface{} {
@@ -756,15 +639,11 @@
return Objects{}
}
if library.sabi.shouldCreateSourceAbiDump() {
- exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
- var SourceAbiFlags []string
- for _, dir := range exportIncludeDirs.Strings() {
- SourceAbiFlags = append(SourceAbiFlags, "-I"+dir)
+ dirs := library.exportedIncludeDirsForAbiCheck(ctx)
+ flags.SAbiFlags = make([]string, 0, len(dirs))
+ for _, dir := range dirs {
+ flags.SAbiFlags = append(flags.SAbiFlags, "-I"+dir)
}
- for _, reexportedInclude := range library.sabi.Properties.ReexportedIncludes {
- SourceAbiFlags = append(SourceAbiFlags, "-I"+reexportedInclude)
- }
- flags.SAbiFlags = SourceAbiFlags
totalLength := len(library.baseCompiler.Properties.Srcs) + len(deps.GeneratedSources) +
len(library.SharedProperties.Shared.Srcs) + len(library.StaticProperties.Static.Srcs)
if totalLength > 0 {
@@ -870,20 +749,6 @@
func (library *libraryDecorator) getLibName(ctx BaseModuleContext) string {
name := library.getLibNameHelper(ctx.baseModuleName(), ctx.inVendor(), ctx.inProduct())
- // Replace name with VNDK ext as original lib only when VNDK is enabled
- if ctx.IsVndkExt() {
- if ctx.DeviceConfig().VndkVersion() != "" {
- // vndk-ext lib should have the same name with original lib
- ctx.VisitDirectDepsWithTag(vndkExtDepTag, func(module android.Module) {
- originalName := module.(*Module).outputFile.Path()
- name = strings.TrimSuffix(originalName.Base(), originalName.Ext())
- })
- } else {
- // TODO(b/320208784) : Suggest a solution for former VNDK-ext libraries before VNDK deprecation.
- log.Printf("VNDK Extension on module %s will not be available once VNDK is deprecated", ctx.baseModuleName())
- }
- }
-
if ctx.Host() && Bool(library.Properties.Unique_host_soname) {
if !strings.HasSuffix(name, "-host") {
name = name + "-host"
@@ -983,6 +848,8 @@
deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.SharedProperties.Shared.Export_shared_lib_headers...)
deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.SharedProperties.Shared.Export_static_lib_headers...)
+
+ deps.LlndkHeaderLibs = append(deps.LlndkHeaderLibs, library.Properties.Llndk.Export_llndk_headers...)
}
if ctx.inVendor() {
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
@@ -1275,7 +1142,7 @@
objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...)
library.coverageOutputFile = transformCoverageFilesToZip(ctx, objs, library.getLibName(ctx))
- library.linkSAbiDumpFiles(ctx, objs, fileName, unstrippedOutputFile)
+ library.linkSAbiDumpFiles(ctx, deps, objs, fileName, unstrippedOutputFile)
var transitiveStaticLibrariesForOrdering *android.DepSet[android.Path]
if static := ctx.GetDirectDepsWithTag(staticVariantTag); len(static) > 0 {
@@ -1338,6 +1205,62 @@
return library.coverageOutputFile
}
+func (library *libraryDecorator) exportedIncludeDirsForAbiCheck(ctx ModuleContext) []string {
+ exportIncludeDirs := library.flagExporter.exportedIncludes(ctx).Strings()
+ exportIncludeDirs = append(exportIncludeDirs, library.sabi.Properties.ReexportedIncludes...)
+ exportSystemIncludeDirs := library.flagExporter.exportedSystemIncludes(ctx).Strings()
+ exportSystemIncludeDirs = append(exportSystemIncludeDirs, library.sabi.Properties.ReexportedSystemIncludes...)
+ // The ABI checker does not distinguish normal and system headers.
+ return append(exportIncludeDirs, exportSystemIncludeDirs...)
+}
+
+func (library *libraryDecorator) llndkIncludeDirsForAbiCheck(ctx ModuleContext, deps PathDeps) []string {
+ var includeDirs, systemIncludeDirs []string
+
+ // The ABI checker does not need the preprocess which adds macro guards to function declarations.
+ preprocessedDirs := android.PathsForModuleSrc(ctx, library.Properties.Llndk.Export_preprocessed_headers).Strings()
+ if Bool(library.Properties.Llndk.Export_headers_as_system) {
+ systemIncludeDirs = append(systemIncludeDirs, preprocessedDirs...)
+ } else {
+ includeDirs = append(includeDirs, preprocessedDirs...)
+ }
+
+ if library.Properties.Llndk.Override_export_include_dirs != nil {
+ includeDirs = append(includeDirs, android.PathsForModuleSrc(
+ ctx, library.Properties.Llndk.Override_export_include_dirs).Strings()...)
+ } else {
+ includeDirs = append(includeDirs, library.flagExporter.exportedIncludes(ctx).Strings()...)
+ // Ignore library.sabi.Properties.ReexportedIncludes because
+ // LLNDK does not reexport the implementation's dependencies, such as export_header_libs.
+ }
+
+ systemIncludeDirs = append(systemIncludeDirs,
+ library.flagExporter.exportedSystemIncludes(ctx).Strings()...)
+ if Bool(library.Properties.Llndk.Export_headers_as_system) {
+ systemIncludeDirs = append(systemIncludeDirs, includeDirs...)
+ includeDirs = nil
+ }
+ // Header libs.
+ includeDirs = append(includeDirs, deps.LlndkIncludeDirs.Strings()...)
+ systemIncludeDirs = append(systemIncludeDirs, deps.LlndkSystemIncludeDirs.Strings()...)
+ // The ABI checker does not distinguish normal and system headers.
+ return append(includeDirs, systemIncludeDirs...)
+}
+
+func (library *libraryDecorator) linkLlndkSAbiDumpFiles(ctx ModuleContext,
+ deps PathDeps, sAbiDumpFiles android.Paths, soFile android.Path, libFileName string,
+ excludeSymbolVersions, excludeSymbolTags []string) android.Path {
+ // NDK symbols in version 34 are LLNDK symbols. Those in version 35 are not.
+ // TODO(b/314010764): Add parameters to read LLNDK symbols from the symbol file.
+ return transformDumpToLinkedDump(ctx,
+ sAbiDumpFiles, soFile, libFileName+".llndk",
+ library.llndkIncludeDirsForAbiCheck(ctx, deps),
+ android.OptionalPathForModuleSrc(ctx, library.Properties.Llndk.Symbol_file),
+ append([]string{"*_PLATFORM", "*_PRIVATE"}, excludeSymbolVersions...),
+ append([]string{"platform-only"}, excludeSymbolTags...),
+ "34")
+}
+
func getRefAbiDumpFile(ctx android.ModuleInstallPathContext,
versionedDumpDir, fileName string) android.OptionalPath {
@@ -1384,12 +1307,11 @@
}
// sourceAbiDiff registers a build statement to compare linked sAbi dump files (.lsdump).
-func (library *libraryDecorator) sourceAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
+func (library *libraryDecorator) sourceAbiDiff(ctx android.ModuleContext,
+ sourceDump, referenceDump android.Path,
baseName, nameExt string, isLlndkOrNdk, allowExtensions bool,
sourceVersion, errorMessage string) {
- sourceDump := library.sAbiOutputFile.Path()
-
extraFlags := []string{"-target-version", sourceVersion}
headerAbiChecker := library.getHeaderAbiCheckerProperties(ctx)
if Bool(headerAbiChecker.Check_all_apis) {
@@ -1413,26 +1335,29 @@
baseName, nameExt, extraFlags, errorMessage))
}
-func (library *libraryDecorator) crossVersionAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
+func (library *libraryDecorator) crossVersionAbiDiff(ctx android.ModuleContext,
+ sourceDump, referenceDump android.Path,
baseName string, isLlndkOrNdk bool, sourceVersion, prevVersion string) {
errorMessage := "error: Please follow https://android.googlesource.com/platform/development/+/main/vndk/tools/header-checker/README.md#configure-cross_version-abi-check to resolve the ABI difference between your source code and version " + prevVersion + "."
- library.sourceAbiDiff(ctx, referenceDump, baseName, prevVersion,
+ library.sourceAbiDiff(ctx, sourceDump, referenceDump, baseName, prevVersion,
isLlndkOrNdk, true /* allowExtensions */, sourceVersion, errorMessage)
}
-func (library *libraryDecorator) sameVersionAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
+func (library *libraryDecorator) sameVersionAbiDiff(ctx android.ModuleContext,
+ sourceDump, referenceDump android.Path,
baseName, nameExt string, isLlndkOrNdk bool) {
libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l " + libName
- library.sourceAbiDiff(ctx, referenceDump, baseName, nameExt,
+ library.sourceAbiDiff(ctx, sourceDump, referenceDump, baseName, nameExt,
isLlndkOrNdk, false /* allowExtensions */, "current", errorMessage)
}
-func (library *libraryDecorator) optInAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
+func (library *libraryDecorator) optInAbiDiff(ctx android.ModuleContext,
+ sourceDump, referenceDump android.Path,
baseName, nameExt string, refDumpDir string) {
libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
@@ -1442,33 +1367,45 @@
errorMessage += " -products " + ctx.Config().DeviceProduct()
}
- library.sourceAbiDiff(ctx, referenceDump, baseName, nameExt,
+ library.sourceAbiDiff(ctx, sourceDump, referenceDump, baseName, nameExt,
false /* isLlndkOrNdk */, false /* allowExtensions */, "current", errorMessage)
}
-func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
+func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, deps PathDeps, objs Objects, fileName string, soFile android.Path) {
if library.sabi.shouldCreateSourceAbiDump() {
- exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
- var SourceAbiFlags []string
- for _, dir := range exportIncludeDirs.Strings() {
- SourceAbiFlags = append(SourceAbiFlags, "-I"+dir)
- }
- for _, reexportedInclude := range library.sabi.Properties.ReexportedIncludes {
- SourceAbiFlags = append(SourceAbiFlags, "-I"+reexportedInclude)
- }
- exportedHeaderFlags := strings.Join(SourceAbiFlags, " ")
+ exportedIncludeDirs := library.exportedIncludeDirsForAbiCheck(ctx)
headerAbiChecker := library.getHeaderAbiCheckerProperties(ctx)
currSdkVersion := currRefAbiDumpSdkVersion(ctx)
currVendorVersion := ctx.Config().VendorApiLevel()
- library.sAbiOutputFile = transformDumpToLinkedDump(ctx, objs.sAbiDumpFiles, soFile, fileName, exportedHeaderFlags,
+
+ // Generate source dumps.
+ implDump := transformDumpToLinkedDump(ctx,
+ objs.sAbiDumpFiles, soFile, fileName,
+ exportedIncludeDirs,
android.OptionalPathForModuleSrc(ctx, library.symbolFileForAbiCheck(ctx)),
headerAbiChecker.Exclude_symbol_versions,
headerAbiChecker.Exclude_symbol_tags,
currSdkVersion)
- for _, tag := range classifySourceAbiDump(ctx) {
- addLsdumpPath(string(tag) + ":" + library.sAbiOutputFile.String())
+ var llndkDump android.Path
+ tags := classifySourceAbiDump(ctx)
+ for _, tag := range tags {
+ if tag == llndkLsdumpTag {
+ if llndkDump == nil {
+ // TODO(b/323447559): Evaluate if replacing sAbiDumpFiles with implDump is faster
+ llndkDump = library.linkLlndkSAbiDumpFiles(ctx,
+ deps, objs.sAbiDumpFiles, soFile, fileName,
+ headerAbiChecker.Exclude_symbol_versions,
+ headerAbiChecker.Exclude_symbol_tags)
+ }
+ addLsdumpPath(string(tag) + ":" + llndkDump.String())
+ } else {
+ addLsdumpPath(string(tag) + ":" + implDump.String())
+ }
+ }
+ // Diff source dumps and reference dumps.
+ for _, tag := range tags {
dumpDirName := tag.dirName()
if dumpDirName == "" {
continue
@@ -1483,29 +1420,38 @@
}
// Check against the previous version.
var prevVersion, currVersion string
+ sourceDump := implDump
// If this release config does not define VendorApiLevel, fall back to the old policy.
if isLlndk && currVendorVersion != "" {
prevVersion = ctx.Config().PrevVendorApiLevel()
currVersion = currVendorVersion
+ // LLNDK dumps are generated by different rules after trunk stable.
+ if android.IsTrunkStableVendorApiLevel(prevVersion) {
+ sourceDump = llndkDump
+ }
} else {
prevVersion, currVersion = crossVersionAbiDiffSdkVersions(ctx, dumpDir)
}
prevDumpDir := filepath.Join(dumpDir, prevVersion, binderBitness)
prevDumpFile := getRefAbiDumpFile(ctx, prevDumpDir, fileName)
if prevDumpFile.Valid() {
- library.crossVersionAbiDiff(ctx, prevDumpFile.Path(),
+ library.crossVersionAbiDiff(ctx, sourceDump, prevDumpFile.Path(),
fileName, isLlndk || isNdk, currVersion, nameExt+prevVersion)
}
// Check against the current version.
+ sourceDump = implDump
if isLlndk && currVendorVersion != "" {
currVersion = currVendorVersion
+ if android.IsTrunkStableVendorApiLevel(currVersion) {
+ sourceDump = llndkDump
+ }
} else {
currVersion = currSdkVersion
}
currDumpDir := filepath.Join(dumpDir, currVersion, binderBitness)
currDumpFile := getRefAbiDumpFile(ctx, currDumpDir, fileName)
if currDumpFile.Valid() {
- library.sameVersionAbiDiff(ctx, currDumpFile.Path(),
+ library.sameVersionAbiDiff(ctx, sourceDump, currDumpFile.Path(),
fileName, nameExt, isLlndk || isNdk)
}
}
@@ -1518,7 +1464,8 @@
if !optInDumpFile.Valid() {
continue
}
- library.optInAbiDiff(ctx, optInDumpFile.Path(),
+ library.optInAbiDiff(ctx,
+ implDump, optInDumpFile.Path(),
fileName, "opt"+strconv.Itoa(i), optInDumpDirPath.String())
}
}
@@ -1885,9 +1832,6 @@
if props := library.getHeaderAbiCheckerProperties(ctx); props.Symbol_file != nil {
return props.Symbol_file
}
- if ctx.Module().(*Module).IsLlndk() {
- return library.Properties.Llndk.Symbol_file
- }
if library.hasStubsVariants() && library.Properties.Stubs.Symbol_file != nil {
return library.Properties.Stubs.Symbol_file
}
diff --git a/cc/library_stub.go b/cc/library_stub.go
index aab6664..cddb1b5 100644
--- a/cc/library_stub.go
+++ b/cc/library_stub.go
@@ -496,11 +496,10 @@
func (v *CcApiVariant) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { return false }
func (v *CcApiVariant) ExtraImageVariations(ctx android.BaseModuleContext) []string {
var variations []string
- platformVndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
if String(v.properties.Variant) == "llndk" {
- variations = append(variations, VendorVariationPrefix+platformVndkVersion)
- variations = append(variations, ProductVariationPrefix+platformVndkVersion)
+ variations = append(variations, VendorVariation)
+ variations = append(variations, ProductVariation)
}
return variations
diff --git a/cc/library_stub_test.go b/cc/library_stub_test.go
index 528577a..4df0a41 100644
--- a/cc/library_stub_test.go
+++ b/cc/library_stub_test.go
@@ -71,8 +71,8 @@
android.AssertBoolEquals(t, "original library should be linked with non-stub variant", true, hasDirectDependency(t, ctx, libfoo, libbar))
android.AssertBoolEquals(t, "Stub library from API surface should be not linked with non-stub variant", false, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
- libfooVendor := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
- libbarApiImportVendor := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
+ libfooVendor := ctx.ModuleForTests("libfoo", "android_vendor_arm64_armv8-a_shared").Module()
+ libbarApiImportVendor := ctx.ModuleForTests("libbar.apiimport", "android_vendor_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, "original library should not be linked", false, hasDirectDependency(t, ctx, libfooVendor, libbar))
android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfooVendor, libbarApiImportVendor))
@@ -102,8 +102,8 @@
ctx := prepareForCcTest.RunTestWithBp(t, bp)
- libfoo := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
- libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
+ libfoo := ctx.ModuleForTests("libfoo", "android_vendor_arm64_armv8-a_shared").Module()
+ libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
}
@@ -135,9 +135,9 @@
ctx := prepareForCcTest.RunTestWithBp(t, bp)
- libfoo := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
- libbar := ctx.ModuleForTests("libbar", "android_vendor.29_arm64_armv8-a_shared").Module()
- libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
+ libfoo := ctx.ModuleForTests("libfoo", "android_vendor_arm64_armv8-a_shared").Module()
+ libbar := ctx.ModuleForTests("libbar", "android_vendor_arm64_armv8-a_shared").Module()
+ libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, "original library should be linked", true, hasDirectDependency(t, ctx, libfoo, libbar))
android.AssertBoolEquals(t, "Stub library from API surface should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
@@ -174,13 +174,13 @@
}
`
ctx := prepareForCcTest.RunTestWithBp(t, bp)
- vendorCFlags := ctx.ModuleForTests("vendorbin", "android_vendor.29_arm64_armv8-a").Rule("cc").Args["cFlags"]
+ vendorCFlags := ctx.ModuleForTests("vendorbin", "android_vendor_arm64_armv8-a").Rule("cc").Args["cFlags"]
android.AssertStringDoesContain(t, "Vendor binary should compile using headers provided by stub", vendorCFlags, "-Istub_include_dir")
android.AssertStringDoesNotContain(t, "Vendor binary should not compile using headers of source", vendorCFlags, "-Isource_include_dir")
android.AssertStringDoesContain(t, "Vendor binary should compile using system headers provided by stub", vendorCFlags, "-isystem stub_system_include_dir")
android.AssertStringDoesNotContain(t, "Vendor binary should not compile using system headers of source", vendorCFlags, "-isystem source_system_include_dir")
- vendorImplicits := ctx.ModuleForTests("vendorbin", "android_vendor.29_arm64_armv8-a").Rule("cc").OrderOnly.Strings()
+ vendorImplicits := ctx.ModuleForTests("vendorbin", "android_vendor_arm64_armv8-a").Rule("cc").OrderOnly.Strings()
// Building the stub.so file first assembles its .h files in multi-tree out.
// These header files are required for compiling the other API domain (vendor in this case)
android.AssertStringListContains(t, "Vendor binary compilation should have an implicit dep on the stub .so file", vendorImplicits, "libfoo.so")
@@ -223,17 +223,17 @@
ctx := prepareForCcTest.RunTestWithBp(t, bp)
- binfoo := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Module()
- libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
- libbarApiVariant := ctx.ModuleForTests("libbar.llndk.apiimport", "android_vendor.29_arm64_armv8-a").Module()
+ binfoo := ctx.ModuleForTests("binfoo", "android_vendor_arm64_armv8-a").Module()
+ libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor_arm64_armv8-a_shared").Module()
+ libbarApiVariant := ctx.ModuleForTests("libbar.llndk.apiimport", "android_vendor_arm64_armv8-a").Module()
android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, binfoo, libbarApiImport))
android.AssertBoolEquals(t, "Stub library variant from API surface should be linked", true, hasDirectDependency(t, ctx, libbarApiImport, libbarApiVariant))
- binFooLibFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("ld").Args["libFlags"]
+ binFooLibFlags := ctx.ModuleForTests("binfoo", "android_vendor_arm64_armv8-a").Rule("ld").Args["libFlags"]
android.AssertStringDoesContain(t, "Vendor binary should be linked with LLNDK variant source", binFooLibFlags, "libbar.llndk.apiimport.so")
- binFooCFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("cc").Args["cFlags"]
+ binFooCFlags := ctx.ModuleForTests("binfoo", "android_vendor_arm64_armv8-a").Rule("cc").Args["cFlags"]
android.AssertStringDoesContain(t, "Vendor binary should include headers from the LLNDK variant source", binFooCFlags, "-Ilibbar_llndk_include")
}
@@ -446,12 +446,12 @@
binfoo := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Module()
libbarApiImportv29 := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_sdk_shared_29").Module()
- libbarApiImportLlndk := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
+ libbarApiImportLlndk := ctx.ModuleForTests("libbar.apiimport", "android_vendor_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, "Binary using SDK should be linked with API library from NDK variant", true, hasDirectDependency(t, ctx, binfoo, libbarApiImportv29))
android.AssertBoolEquals(t, "Binary using SDK should not be linked with API library from LLNDK variant", false, hasDirectDependency(t, ctx, binfoo, libbarApiImportLlndk))
- binbaz := ctx.ModuleForTests("binbaz", "android_vendor.29_arm64_armv8-a").Module()
+ binbaz := ctx.ModuleForTests("binbaz", "android_vendor_arm64_armv8-a").Module()
android.AssertBoolEquals(t, "Vendor binary should be linked with API library from LLNDK variant", true, hasDirectDependency(t, ctx, binbaz, libbarApiImportLlndk))
android.AssertBoolEquals(t, "Vendor binary should not be linked with API library from NDK variant", false, hasDirectDependency(t, ctx, binbaz, libbarApiImportv29))
diff --git a/cc/linkable.go b/cc/linkable.go
index 6f22091..10cc38f 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -3,7 +3,6 @@
import (
"android/soong/android"
"android/soong/fuzz"
- "android/soong/snapshot"
"github.com/google/blueprint"
)
@@ -63,55 +62,9 @@
// implementation should handle tags from both.
type SantizableDependencyTagChecker func(tag blueprint.DependencyTag) bool
-// Snapshottable defines those functions necessary for handling module snapshots.
-type Snapshottable interface {
- snapshot.VendorSnapshotModuleInterface
- snapshot.RecoverySnapshotModuleInterface
-
- // SnapshotHeaders returns a list of header paths provided by this module.
- SnapshotHeaders() android.Paths
-
- // SnapshotLibrary returns true if this module is a snapshot library.
- IsSnapshotLibrary() bool
-
- // EffectiveLicenseFiles returns the list of License files for this module.
- EffectiveLicenseFiles() android.Paths
-
- // SnapshotRuntimeLibs returns a list of libraries needed by this module at runtime but which aren't build dependencies.
- SnapshotRuntimeLibs() []string
-
- // SnapshotSharedLibs returns the list of shared library dependencies for this module.
- SnapshotSharedLibs() []string
-
- // SnapshotStaticLibs returns the list of static library dependencies for this module.
- SnapshotStaticLibs() []string
-
- // SnapshotDylibs returns the list of dylib library dependencies for this module.
- SnapshotDylibs() []string
-
- // SnapshotRlibs returns the list of rlib library dependencies for this module.
- SnapshotRlibs() []string
-
- // IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
- IsSnapshotPrebuilt() bool
-
- // IsSnapshotSanitizer returns true if this snapshot module implements SnapshotSanitizer.
- IsSnapshotSanitizer() bool
-
- // IsSnapshotSanitizerAvailable returns true if this snapshot module has a sanitizer source available (cfi, hwasan).
- IsSnapshotSanitizerAvailable(t SanitizerType) bool
-
- // SetSnapshotSanitizerVariation sets the sanitizer variation type for this snapshot module.
- SetSnapshotSanitizerVariation(t SanitizerType, enabled bool)
-
- // IsSnapshotUnsanitizedVariant returns true if this is the unsanitized snapshot module variant.
- IsSnapshotUnsanitizedVariant() bool
-}
-
// LinkableInterface is an interface for a type of module that is linkable in a C++ library.
type LinkableInterface interface {
android.Module
- Snapshottable
Module() android.Module
CcLibrary() bool
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index c307410..9e727a1 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -14,6 +14,11 @@
package cc
+import (
+ "android/soong/android"
+ "strings"
+)
+
var (
llndkLibrarySuffix = ".llndk"
llndkHeadersSuffix = ".llndk"
@@ -55,3 +60,21 @@
// llndk.symbol_file.
Llndk_headers *bool
}
+
+func makeLlndkVars(ctx android.MakeVarsContext) {
+ // Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to avoid installing libraries on /system if
+ // they been moved to an apex.
+ movedToApexLlndkLibraries := make(map[string]bool)
+ ctx.VisitAllModules(func(module android.Module) {
+ if library := moduleLibraryInterface(module); library != nil && library.hasLLNDKStubs() {
+ // Skip bionic libs, they are handled in different manner
+ name := library.implementationModuleName(module.(*Module).BaseModuleName())
+ if module.(android.ApexModule).DirectlyInAnyApex() && !isBionic(name) {
+ movedToApexLlndkLibraries[name] = true
+ }
+ }
+ })
+
+ ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES",
+ strings.Join(android.SortedKeys(movedToApexLlndkLibraries), " "))
+}
diff --git a/cc/makevars.go b/cc/makevars.go
index 70fdd57..9251d6a 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -97,9 +97,6 @@
ctx.Strict("GLOBAL_CLANG_CPPFLAGS_NO_OVERRIDE", "")
ctx.Strict("GLOBAL_CLANG_EXTERNAL_CFLAGS_NO_OVERRIDE", "${config.NoOverrideExternalGlobalCflags}")
- ctx.Strict("BOARD_VNDK_VERSION", ctx.DeviceConfig().VndkVersion())
- ctx.Strict("RECOVERY_SNAPSHOT_VERSION", ctx.DeviceConfig().RecoverySnapshotVersion())
-
// Filter vendor_public_library that are exported to make
exportedVendorPublicLibraries := []string{}
ctx.VisitAllModules(func(module android.Module) {
@@ -123,12 +120,12 @@
ctx.Strict("SOONG_MODULES_USING_WNO_ERROR", makeStringOfKeys(ctx, modulesUsingWnoErrorKey))
ctx.Strict("SOONG_MODULES_MISSING_PGO_PROFILE_FILE", makeStringOfKeys(ctx, modulesMissingProfileFileKey))
- ctx.Strict("CLANG_COVERAGE_CONFIG_CFLAGS", strings.Join(clangCoverageCFlags, " "))
- ctx.Strict("CLANG_COVERAGE_CONFIG_COMMFLAGS", strings.Join(clangCoverageCommonFlags, " "))
- ctx.Strict("CLANG_COVERAGE_HOST_LDFLAGS", strings.Join(clangCoverageHostLdFlags, " "))
- ctx.Strict("CLANG_COVERAGE_INSTR_PROFILE", profileInstrFlag)
- ctx.Strict("CLANG_COVERAGE_CONTINUOUS_FLAGS", strings.Join(clangContinuousCoverageFlags, " "))
- ctx.Strict("CLANG_COVERAGE_HWASAN_FLAGS", strings.Join(clangCoverageHWASanFlags, " "))
+ ctx.Strict("CLANG_COVERAGE_CONFIG_CFLAGS", strings.Join(clangCoverageCFlags, " "))
+ ctx.Strict("CLANG_COVERAGE_CONFIG_COMMFLAGS", strings.Join(clangCoverageCommonFlags, " "))
+ ctx.Strict("CLANG_COVERAGE_HOST_LDFLAGS", strings.Join(clangCoverageHostLdFlags, " "))
+ ctx.Strict("CLANG_COVERAGE_INSTR_PROFILE", profileInstrFlag)
+ ctx.Strict("CLANG_COVERAGE_CONTINUOUS_FLAGS", strings.Join(clangContinuousCoverageFlags, " "))
+ ctx.Strict("CLANG_COVERAGE_HWASAN_FLAGS", strings.Join(clangCoverageHWASanFlags, " "))
ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS", strings.Join(asanCflags, " "))
ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS", strings.Join(asanLdflags, " "))
@@ -184,6 +181,8 @@
if len(deviceTargets) > 1 {
makeVarsToolchain(ctx, "2ND_", deviceTargets[1])
}
+
+ makeLlndkVars(ctx)
}
func makeVarsToolchain(ctx android.MakeVarsContext, secondPrefix string,
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index 567cb7c..57a3b3a 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -15,7 +15,6 @@
package cc
import (
- "fmt"
"path/filepath"
"android/soong/android"
@@ -45,7 +44,7 @@
}
// Returns the NDK base include path for use with sdk_version current. Usable with -I.
-func getCurrentIncludePath(ctx android.ModuleContext) android.InstallPath {
+func getCurrentIncludePath(ctx android.ModuleContext) android.OutputPath {
return getNdkSysrootBase(ctx).Join(ctx, "usr/include")
}
@@ -87,7 +86,7 @@
}
func getHeaderInstallDir(ctx android.ModuleContext, header android.Path, from string,
- to string) android.InstallPath {
+ to string) android.OutputPath {
// Output path is the sysroot base + "usr/include" + to directory + directory component
// of the file without the leading from directory stripped.
//
@@ -129,13 +128,12 @@
for _, header := range m.srcPaths {
installDir := getHeaderInstallDir(ctx, header, String(m.properties.From),
String(m.properties.To))
- installedPath := ctx.InstallFile(installDir, header.Base(), header)
installPath := installDir.Join(ctx, header.Base())
- if installPath != installedPath {
- panic(fmt.Sprintf(
- "expected header install path (%q) not equal to actual install path %q",
- installPath, installedPath))
- }
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: header,
+ Output: installPath,
+ })
m.installPaths = append(m.installPaths, installPath)
}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 183e818..25231fd 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -225,7 +225,7 @@
}
func init() {
- config.ExportStringList("StubLibraryCompilerFlags", stubLibraryCompilerFlags)
+ pctx.StaticVariable("StubLibraryCompilerFlags", strings.Join(stubLibraryCompilerFlags, " "))
}
func addStubLibraryCompilerFlags(flags Flags) Flags {
@@ -325,13 +325,6 @@
if runtime.GOOS == "darwin" {
return false
}
- // abidw doesn't currently handle top-byte-ignore correctly. Disable ABI
- // dumping for those configs while we wait for a fix. We'll still have ABI
- // checking coverage from non-hwasan builds.
- // http://b/190554910
- if android.InList("hwaddress", config.SanitizeDevice()) {
- return false
- }
// http://b/156513478
return config.ReleaseNdkAbiMonitored()
}
@@ -525,19 +518,25 @@
// Returns the install path for unversioned NDK libraries (currently only static
// libraries).
-func getUnversionedLibraryInstallPath(ctx ModuleContext) android.InstallPath {
+func getUnversionedLibraryInstallPath(ctx ModuleContext) android.OutputPath {
return getNdkSysrootBase(ctx).Join(ctx, "usr/lib", config.NDKTriple(ctx.toolchain()))
}
// Returns the install path for versioned NDK libraries. These are most often
// stubs, but the same paths are used for CRT objects.
-func getVersionedLibraryInstallPath(ctx ModuleContext, apiLevel android.ApiLevel) android.InstallPath {
+func getVersionedLibraryInstallPath(ctx ModuleContext, apiLevel android.ApiLevel) android.OutputPath {
return getUnversionedLibraryInstallPath(ctx).Join(ctx, apiLevel.String())
}
func (stub *stubDecorator) install(ctx ModuleContext, path android.Path) {
installDir := getVersionedLibraryInstallPath(ctx, stub.apiLevel)
- stub.installPath = ctx.InstallFile(installDir, path.Base(), path)
+ out := installDir.Join(ctx, path.Base())
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: path,
+ Output: out,
+ })
+ stub.installPath = out
}
func newStubLibrary() *Module {
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index 483d23b..e815172 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -69,12 +69,12 @@
ctx.RegisterParallelSingletonType("ndk", NdkSingleton)
}
-func getNdkInstallBase(ctx android.PathContext) android.InstallPath {
+func getNdkInstallBase(ctx android.PathContext) android.OutputPath {
return android.PathForNdkInstall(ctx)
}
// Returns the main install directory for the NDK sysroot. Usable with --sysroot.
-func getNdkSysrootBase(ctx android.PathContext) android.InstallPath {
+func getNdkSysrootBase(ctx android.PathContext) android.OutputPath {
return getNdkInstallBase(ctx).Join(ctx, "sysroot")
}
diff --git a/cc/object_test.go b/cc/object_test.go
index c0d1331..004dfd3 100644
--- a/cc/object_test.go
+++ b/cc/object_test.go
@@ -41,7 +41,7 @@
{"android_arm64_armv8-a_sdk_29", "29"},
{"android_arm64_armv8-a_sdk_30", "30"},
{"android_arm64_armv8-a_sdk_current", "10000"},
- {"android_vendor.29_arm64_armv8-a", "29"},
+ {"android_vendor_arm64_armv8-a", "10000"},
}
ctx := prepareForCcTest.RunTestWithBp(t, bp)
@@ -50,7 +50,7 @@
expected := "-target aarch64-linux-android" + v.num + " "
android.AssertStringDoesContain(t, "cflag", cflags, expected)
}
- ctx = prepareForCcTestWithoutVndk.RunTestWithBp(t, bp)
+ ctx = prepareForCcTest.RunTestWithBp(t, bp)
android.AssertStringDoesContain(t, "cflag",
ctx.ModuleForTests("crt_foo", "android_vendor_arm64_armv8-a").Rule("cc").Args["cFlags"],
"-target aarch64-linux-android10000 ")
diff --git a/cc/sabi.go b/cc/sabi.go
index af26726..ef43c8d 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -92,7 +92,8 @@
// Include directories that may contain ABI information exported by a library.
// These directories are passed to the header-abi-dumper.
- ReexportedIncludes []string `blueprint:"mutated"`
+ ReexportedIncludes []string `blueprint:"mutated"`
+ ReexportedSystemIncludes []string `blueprint:"mutated"`
}
type sabi struct {
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 52b5be9..db046ec 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -25,7 +25,6 @@
"android/soong/android"
"android/soong/cc/config"
- "android/soong/snapshot"
)
var (
@@ -403,30 +402,8 @@
var _ android.SkipApexAllowedDependenciesCheck = (*libraryDependencyTag)(nil)
-var exportedVars = android.NewExportedVariables(pctx)
-
func init() {
- exportedVars.ExportStringListStaticVariable("HostOnlySanitizeFlags", hostOnlySanitizeFlags)
- exportedVars.ExportStringList("DeviceOnlySanitizeFlags", deviceOnlySanitizeFlags)
-
- exportedVars.ExportStringList("MinimalRuntimeFlags", minimalRuntimeFlags)
-
- // Leave out "-flto" from the slices exported to bazel, as we will use the
- // dedicated LTO feature for this. For C Flags and Linker Flags, also leave
- // out the cross DSO flag which will be added separately under the correct conditions.
- exportedVars.ExportStringList("CfiCFlags", append(cfiCflags[2:], cfiEnableFlag))
- exportedVars.ExportStringList("CfiLdFlags", cfiLdflags[2:])
- exportedVars.ExportStringList("CfiAsFlags", cfiAsflags[1:])
-
- exportedVars.ExportString("SanitizeIgnorelistPrefix", sanitizeIgnorelistPrefix)
- exportedVars.ExportString("CfiCrossDsoFlag", cfiCrossDsoFlag)
- exportedVars.ExportString("CfiBlocklistPath", cfiBlocklistPath)
- exportedVars.ExportString("CfiBlocklistFilename", cfiBlocklistFilename)
- exportedVars.ExportString("CfiExportsMapPath", cfiExportsMapPath)
- exportedVars.ExportString("CfiExportsMapFilename", cfiExportsMapFilename)
- exportedVars.ExportString("CfiAssemblySupportFlag", cfiAssemblySupportFlag)
-
- exportedVars.ExportString("NoSanitizeLinkRuntimeFlag", noSanitizeLinkRuntimeFlag)
+ pctx.StaticVariable("HostOnlySanitizeFlags", strings.Join(hostOnlySanitizeFlags, " "))
android.RegisterMakeVarsProvider(pctx, cfiMakeVarsProvider)
android.RegisterMakeVarsProvider(pctx, hwasanMakeVarsProvider)
@@ -881,6 +858,7 @@
flags.Local.CFlags = append(flags.Local.CFlags, cfiCflags...)
flags.Local.AsFlags = append(flags.Local.AsFlags, cfiAsflags...)
+ flags.CFlagsDeps = append(flags.CFlagsDeps, android.PathForSource(ctx, cfiBlocklistPath + "/" + cfiBlocklistFilename))
if Bool(s.Properties.Sanitize.Config.Cfi_assembly_support) {
flags.Local.CFlags = append(flags.Local.CFlags, cfiAssemblySupportFlag)
}
@@ -1141,42 +1119,6 @@
return IsSanitizableDependencyTag
}
-// Determines if the current module is a static library going to be captured
-// as vendor snapshot. Such modules must create both cfi and non-cfi variants,
-// except for ones which explicitly disable cfi.
-func needsCfiForVendorSnapshot(mctx android.BaseModuleContext) bool {
- if inList("hwaddress", mctx.Config().SanitizeDevice()) {
- // cfi will not be built if SANITIZE_TARGET=hwaddress is set
- return false
- }
-
- if snapshot.IsVendorProprietaryModule(mctx) {
- return false
- }
-
- c := mctx.Module().(PlatformSanitizeable)
-
- if !c.InVendor() {
- return false
- }
-
- if !c.StaticallyLinked() {
- return false
- }
-
- if c.IsPrebuilt() {
- return false
- }
-
- if !c.SanitizerSupported(cfi) {
- return false
- }
-
- return c.SanitizePropDefined() &&
- !c.SanitizeNever() &&
- !c.IsSanitizerExplicitlyDisabled(cfi)
-}
-
type sanitizerSplitMutator struct {
sanitizer SanitizerType
}
@@ -1201,10 +1143,6 @@
func (s *sanitizerSplitMutator) Split(ctx android.BaseModuleContext) []string {
if c, ok := ctx.Module().(PlatformSanitizeable); ok && c.SanitizePropDefined() {
- if s.sanitizer == cfi && needsCfiForVendorSnapshot(ctx) {
- return []string{"", s.sanitizer.variationName()}
- }
-
// If the given sanitizer is not requested in the .bp file for a module, it
// won't automatically build the sanitized variation.
if !c.IsSanitizerEnabled(s.sanitizer) {
@@ -1242,17 +1180,6 @@
}
}
- if c, ok := ctx.Module().(LinkableInterface); ok {
- // Check if it's a snapshot module supporting sanitizer
- if c.IsSnapshotSanitizer() {
- if c.IsSnapshotSanitizerAvailable(s.sanitizer) {
- return []string{"", s.sanitizer.variationName()}
- } else {
- return []string{""}
- }
- }
- }
-
return []string{""}
}
@@ -1277,12 +1204,6 @@
func (s *sanitizerSplitMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
if d, ok := ctx.Module().(PlatformSanitizeable); ok {
- if dm, ok := ctx.Module().(LinkableInterface); ok {
- if dm.IsSnapshotSanitizerAvailable(s.sanitizer) {
- return incomingVariation
- }
- }
-
if !d.SanitizePropDefined() ||
d.SanitizeNever() ||
d.IsSanitizerExplicitlyDisabled(s.sanitizer) ||
@@ -1393,59 +1314,9 @@
if sanitizerVariation {
sanitizeable.AddSanitizerDependencies(mctx, s.sanitizer.name())
}
- } else if c, ok := mctx.Module().(LinkableInterface); ok {
- if c.IsSnapshotSanitizerAvailable(s.sanitizer) {
- if !c.IsSnapshotUnsanitizedVariant() {
- // Snapshot sanitizer may have only one variantion.
- // Skip exporting the module if it already has a sanitizer variation.
- c.SetPreventInstall()
- c.SetHideFromMake()
- return
- }
- c.SetSnapshotSanitizerVariation(s.sanitizer, sanitizerVariation)
-
- // Export the static lib name to make
- if c.Static() && c.ExportedToMake() {
- // use BaseModuleName which is the name for Make.
- if s.sanitizer == cfi {
- cfiStaticLibs(mctx.Config()).add(c, c.BaseModuleName())
- } else if s.sanitizer == Hwasan {
- hwasanStaticLibs(mctx.Config()).add(c, c.BaseModuleName())
- }
- }
- }
}
}
-func (c *Module) IsSnapshotSanitizer() bool {
- if _, ok := c.linker.(SnapshotSanitizer); ok {
- return true
- }
- return false
-}
-
-func (c *Module) IsSnapshotSanitizerAvailable(t SanitizerType) bool {
- if ss, ok := c.linker.(SnapshotSanitizer); ok {
- return ss.IsSanitizerAvailable(t)
- }
- return false
-}
-
-func (c *Module) SetSnapshotSanitizerVariation(t SanitizerType, enabled bool) {
- if ss, ok := c.linker.(SnapshotSanitizer); ok {
- ss.SetSanitizerVariation(t, enabled)
- } else {
- panic(fmt.Errorf("Calling SetSnapshotSanitizerVariation on a non-snapshotLibraryDecorator: %s", c.Name()))
- }
-}
-
-func (c *Module) IsSnapshotUnsanitizedVariant() bool {
- if ss, ok := c.linker.(SnapshotSanitizer); ok {
- return ss.IsUnsanitizedVariant()
- }
- return false
-}
-
func (c *Module) SanitizeNever() bool {
return Bool(c.sanitize.Properties.SanitizeMutated.Never)
}
@@ -1492,15 +1363,6 @@
return true
}
- if p, ok := d.linker.(*snapshotLibraryDecorator); ok {
- if Bool(p.properties.Sanitize_minimal_dep) {
- c.sanitize.Properties.MinimalRuntimeDep = true
- }
- if Bool(p.properties.Sanitize_ubsan_dep) {
- c.sanitize.Properties.UbsanRuntimeDep = true
- }
- }
-
return false
})
}
@@ -1626,12 +1488,6 @@
}
addStaticDeps := func(dep string, hideSymbols bool) {
- // If we're using snapshots, redirect to snapshot whenever possible
- snapshot, _ := android.ModuleProvider(mctx, SnapshotInfoProvider)
- if lib, ok := snapshot.StaticLibs[dep]; ok {
- dep = lib
- }
-
// static executable gets static runtime libs
depTag := libraryDependencyTag{Kind: staticLibraryDependency, unexportedSymbols: hideSymbols}
variations := append(mctx.Target().Variations(),
@@ -1713,12 +1569,6 @@
// the best.
addStaticDeps(runtimeSharedLibrary, true)
} else if !c.static() && !c.Header() {
- // If we're using snapshots, redirect to snapshot whenever possible
- snapshot, _ := android.ModuleProvider(mctx, SnapshotInfoProvider)
- if lib, ok := snapshot.SharedLibs[runtimeSharedLibrary]; ok {
- runtimeSharedLibrary = lib
- }
-
// Skip apex dependency check for sharedLibraryDependency
// when sanitizer diags are enabled. Skipping the check will allow
// building with diag libraries without having to list the
diff --git a/cc/sdk.go b/cc/sdk.go
index 6341926..736a958 100644
--- a/cc/sdk.go
+++ b/cc/sdk.go
@@ -106,8 +106,6 @@
}
ctx.AliasVariation("")
}
- case *snapshotModule:
- ctx.CreateVariations("")
case *CcApiVariant:
ccApiVariant, _ := ctx.Module().(*CcApiVariant)
if String(ccApiVariant.properties.Variant) == "ndk" {
diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go
index e769fe9..f4a3d88 100644
--- a/cc/snapshot_prebuilt.go
+++ b/cc/snapshot_prebuilt.go
@@ -18,818 +18,9 @@
// snapshot mutators and snapshot information maps which are also defined in this file.
import (
- "fmt"
- "strings"
-
"android/soong/android"
- "android/soong/snapshot"
-
- "github.com/google/blueprint"
)
-// This interface overrides snapshot.SnapshotImage to implement cc module specific functions
-type SnapshotImage interface {
- snapshot.SnapshotImage
-
- // The image variant name for this snapshot image.
- // For example, recovery snapshot image will return "recovery", and vendor snapshot image will
- // return "vendor." + version.
- imageVariantName(cfg android.DeviceConfig) string
-
- // The variant suffix for snapshot modules. For example, vendor snapshot modules will have
- // ".vendor" as their suffix.
- moduleNameSuffix() string
-}
-
-type vendorSnapshotImage struct {
- *snapshot.VendorSnapshotImage
-}
-
-type recoverySnapshotImage struct {
- *snapshot.RecoverySnapshotImage
-}
-
-func (vendorSnapshotImage) imageVariantName(cfg android.DeviceConfig) string {
- return VendorVariationPrefix + cfg.VndkVersion()
-}
-
-func (vendorSnapshotImage) moduleNameSuffix() string {
- return VendorSuffix
-}
-
-func (recoverySnapshotImage) imageVariantName(cfg android.DeviceConfig) string {
- return android.RecoveryVariation
-}
-
-func (recoverySnapshotImage) moduleNameSuffix() string {
- return RecoverySuffix
-}
-
-// Override existing vendor and recovery snapshot for cc module specific extra functions
-var VendorSnapshotImageSingleton vendorSnapshotImage = vendorSnapshotImage{&snapshot.VendorSnapshotImageSingleton}
-var RecoverySnapshotImageSingleton recoverySnapshotImage = recoverySnapshotImage{&snapshot.RecoverySnapshotImageSingleton}
-
-func RegisterVendorSnapshotModules(ctx android.RegistrationContext) {
- ctx.RegisterModuleType("vendor_snapshot", vendorSnapshotFactory)
- ctx.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory)
- ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory)
- ctx.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory)
- ctx.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory)
- ctx.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory)
-}
-
-func RegisterRecoverySnapshotModules(ctx android.RegistrationContext) {
- ctx.RegisterModuleType("recovery_snapshot", recoverySnapshotFactory)
- ctx.RegisterModuleType("recovery_snapshot_shared", RecoverySnapshotSharedFactory)
- ctx.RegisterModuleType("recovery_snapshot_static", RecoverySnapshotStaticFactory)
- ctx.RegisterModuleType("recovery_snapshot_header", RecoverySnapshotHeaderFactory)
- ctx.RegisterModuleType("recovery_snapshot_binary", RecoverySnapshotBinaryFactory)
- ctx.RegisterModuleType("recovery_snapshot_object", RecoverySnapshotObjectFactory)
-}
-
-func init() {
- RegisterVendorSnapshotModules(android.InitRegistrationContext)
- RegisterRecoverySnapshotModules(android.InitRegistrationContext)
- android.RegisterMakeVarsProvider(pctx, snapshotMakeVarsProvider)
-}
-
-const (
- snapshotHeaderSuffix = "_header."
- SnapshotSharedSuffix = "_shared."
- SnapshotStaticSuffix = "_static."
- snapshotBinarySuffix = "_binary."
- snapshotObjectSuffix = "_object."
- SnapshotRlibSuffix = "_rlib."
- SnapshotDylibSuffix = "_dylib."
-)
-
-type SnapshotProperties struct {
- Header_libs []string `android:"arch_variant"`
- Static_libs []string `android:"arch_variant"`
- Shared_libs []string `android:"arch_variant"`
- Rlibs []string `android:"arch_variant"`
- Dylibs []string `android:"arch_variant"`
- Vndk_libs []string `android:"arch_variant"`
- Binaries []string `android:"arch_variant"`
- Objects []string `android:"arch_variant"`
-}
-type snapshotModule struct {
- android.ModuleBase
-
- properties SnapshotProperties
-
- baseSnapshot BaseSnapshotDecorator
-
- image SnapshotImage
-}
-
-func (s *snapshotModule) ImageMutatorBegin(ctx android.BaseModuleContext) {
- cfg := ctx.DeviceConfig()
- if !s.image.IsUsingSnapshot(cfg) || s.image.TargetSnapshotVersion(cfg) != s.baseSnapshot.Version() {
- s.Disable()
- }
-}
-
-func (s *snapshotModule) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
- return false
-}
-
-func (s *snapshotModule) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return false
-}
-
-func (s *snapshotModule) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return false
-}
-
-func (s *snapshotModule) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return false
-}
-
-func (s *snapshotModule) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
- return false
-}
-
-func (s *snapshotModule) ExtraImageVariations(ctx android.BaseModuleContext) []string {
- return []string{s.image.imageVariantName(ctx.DeviceConfig())}
-}
-
-func (s *snapshotModule) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
-}
-
-func (s *snapshotModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- // Nothing, the snapshot module is only used to forward dependency information in DepsMutator.
-}
-
-func getSnapshotNameSuffix(moduleSuffix, version, arch string) string {
- versionSuffix := version
- if arch != "" {
- versionSuffix += "." + arch
- }
- return moduleSuffix + versionSuffix
-}
-
-func (s *snapshotModule) DepsMutator(ctx android.BottomUpMutatorContext) {
- collectSnapshotMap := func(names []string, snapshotSuffix, moduleSuffix string) map[string]string {
- snapshotMap := make(map[string]string)
- for _, name := range names {
- snapshotMap[name] = name +
- getSnapshotNameSuffix(snapshotSuffix+moduleSuffix,
- s.baseSnapshot.Version(),
- ctx.DeviceConfig().Arches()[0].ArchType.String())
- }
- return snapshotMap
- }
-
- snapshotSuffix := s.image.moduleNameSuffix()
- headers := collectSnapshotMap(s.properties.Header_libs, snapshotSuffix, snapshotHeaderSuffix)
- binaries := collectSnapshotMap(s.properties.Binaries, snapshotSuffix, snapshotBinarySuffix)
- objects := collectSnapshotMap(s.properties.Objects, snapshotSuffix, snapshotObjectSuffix)
- staticLibs := collectSnapshotMap(s.properties.Static_libs, snapshotSuffix, SnapshotStaticSuffix)
- sharedLibs := collectSnapshotMap(s.properties.Shared_libs, snapshotSuffix, SnapshotSharedSuffix)
- rlibs := collectSnapshotMap(s.properties.Rlibs, snapshotSuffix, SnapshotRlibSuffix)
- dylibs := collectSnapshotMap(s.properties.Dylibs, snapshotSuffix, SnapshotDylibSuffix)
- vndkLibs := collectSnapshotMap(s.properties.Vndk_libs, "", vndkSuffix)
- for k, v := range vndkLibs {
- sharedLibs[k] = v
- }
-
- android.SetProvider(ctx, SnapshotInfoProvider, SnapshotInfo{
- HeaderLibs: headers,
- Binaries: binaries,
- Objects: objects,
- StaticLibs: staticLibs,
- SharedLibs: sharedLibs,
- Rlibs: rlibs,
- Dylibs: dylibs,
- })
-}
-
-type SnapshotInfo struct {
- HeaderLibs, Binaries, Objects, StaticLibs, SharedLibs, Rlibs, Dylibs map[string]string
-}
-
-var SnapshotInfoProvider = blueprint.NewMutatorProvider[SnapshotInfo]("deps")
-
-var _ android.ImageInterface = (*snapshotModule)(nil)
-
-func snapshotMakeVarsProvider(ctx android.MakeVarsContext) {
- snapshotSet := map[string]struct{}{}
- ctx.VisitAllModules(func(m android.Module) {
- if s, ok := m.(*snapshotModule); ok {
- if _, ok := snapshotSet[s.Name()]; ok {
- // arch variant generates duplicated modules
- // skip this as we only need to know the path of the module.
- return
- }
- snapshotSet[s.Name()] = struct{}{}
- imageNameVersion := strings.Split(s.image.imageVariantName(ctx.DeviceConfig()), ".")
- ctx.Strict(
- strings.Join([]string{strings.ToUpper(imageNameVersion[0]), s.baseSnapshot.Version(), "SNAPSHOT_DIR"}, "_"),
- ctx.ModuleDir(s))
- }
- })
-}
-
-func vendorSnapshotFactory() android.Module {
- return snapshotFactory(VendorSnapshotImageSingleton)
-}
-
-func recoverySnapshotFactory() android.Module {
- return snapshotFactory(RecoverySnapshotImageSingleton)
-}
-
-func snapshotFactory(image SnapshotImage) android.Module {
- snapshotModule := &snapshotModule{}
- snapshotModule.image = image
- snapshotModule.AddProperties(
- &snapshotModule.properties,
- &snapshotModule.baseSnapshot.baseProperties)
- android.InitAndroidArchModule(snapshotModule, android.DeviceSupported, android.MultilibBoth)
- return snapshotModule
-}
-
-type BaseSnapshotDecoratorProperties struct {
- // snapshot version.
- Version string
-
- // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64')
- Target_arch string
-
- // Suffix to be added to the module name when exporting to Android.mk, e.g. ".vendor".
- Androidmk_suffix string `blueprint:"mutated"`
-
- // Suffix to be added to the module name, e.g., vendor_shared,
- // recovery_shared, etc.
- ModuleSuffix string `blueprint:"mutated"`
-}
-
-// BaseSnapshotDecorator provides common basic functions for all snapshot modules, such as snapshot
-// version, snapshot arch, etc. It also adds a special suffix to Soong module name, so it doesn't
-// collide with source modules. e.g. the following example module,
-//
-// vendor_snapshot_static {
-// name: "libbase",
-// arch: "arm64",
-// version: 30,
-// ...
-// }
-//
-// will be seen as "libbase.vendor_static.30.arm64" by Soong.
-type BaseSnapshotDecorator struct {
- baseProperties BaseSnapshotDecoratorProperties
- Image SnapshotImage
-}
-
-func (p *BaseSnapshotDecorator) Name(name string) string {
- return name + p.NameSuffix()
-}
-
-func (p *BaseSnapshotDecorator) NameSuffix() string {
- return getSnapshotNameSuffix(p.moduleSuffix(), p.Version(), p.Arch())
-}
-
-func (p *BaseSnapshotDecorator) Version() string {
- return p.baseProperties.Version
-}
-
-func (p *BaseSnapshotDecorator) Arch() string {
- return p.baseProperties.Target_arch
-}
-
-func (p *BaseSnapshotDecorator) moduleSuffix() string {
- return p.baseProperties.ModuleSuffix
-}
-
-func (p *BaseSnapshotDecorator) IsSnapshotPrebuilt() bool {
- return true
-}
-
-func (p *BaseSnapshotDecorator) SnapshotAndroidMkSuffix() string {
- return p.baseProperties.Androidmk_suffix
-}
-
-func (p *BaseSnapshotDecorator) SetSnapshotAndroidMkSuffix(ctx android.ModuleContext, variant string) {
- // If there are any 2 or more variations among {core, product, vendor, recovery}
- // we have to add the androidmk suffix to avoid duplicate modules with the same
- // name.
- variations := append(ctx.Target().Variations(), blueprint.Variation{
- Mutator: "image",
- Variation: android.CoreVariation})
-
- if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(LinkableInterface).BaseModuleName()) {
- p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix()
- return
- }
-
- variations = append(ctx.Target().Variations(), blueprint.Variation{
- Mutator: "image",
- Variation: ProductVariationPrefix + ctx.DeviceConfig().PlatformVndkVersion()})
-
- if ctx.OtherModuleFarDependencyVariantExists(variations, ctx.Module().(LinkableInterface).BaseModuleName()) {
- p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix()
- return
- }
-
- images := []SnapshotImage{VendorSnapshotImageSingleton, RecoverySnapshotImageSingleton}
-
- for _, image := range images {
- if p.Image == image {
- continue
- }
- variations = append(ctx.Target().Variations(), blueprint.Variation{
- Mutator: "image",
- Variation: image.imageVariantName(ctx.DeviceConfig())})
-
- if ctx.OtherModuleFarDependencyVariantExists(variations,
- ctx.Module().(LinkableInterface).BaseModuleName()+
- getSnapshotNameSuffix(
- image.moduleNameSuffix()+variant,
- p.Version(),
- ctx.DeviceConfig().Arches()[0].ArchType.String())) {
- p.baseProperties.Androidmk_suffix = p.Image.moduleNameSuffix()
- return
- }
- }
-
- p.baseProperties.Androidmk_suffix = ""
-}
-
-// Call this with a module suffix after creating a snapshot module, such as
-// vendorSnapshotSharedSuffix, recoverySnapshotBinarySuffix, etc.
-func (p *BaseSnapshotDecorator) Init(m LinkableInterface, image SnapshotImage, moduleSuffix string) {
- p.Image = image
- p.baseProperties.ModuleSuffix = image.moduleNameSuffix() + moduleSuffix
- m.AddProperties(&p.baseProperties)
- android.AddLoadHook(m, func(ctx android.LoadHookContext) {
- vendorSnapshotLoadHook(ctx, p)
- })
-}
-
-// vendorSnapshotLoadHook disables snapshots if it's not BOARD_VNDK_VERSION.
-// As vendor snapshot is only for vendor, such modules won't be used at all.
-func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *BaseSnapshotDecorator) {
- if p.Version() != ctx.DeviceConfig().VndkVersion() {
- ctx.Module().Disable()
- return
- }
-}
-
-// Module definitions for snapshots of libraries (shared, static, header).
-//
-// Modules (vendor|recovery)_snapshot_(shared|static|header) are defined here. Shared libraries and
-// static libraries have their prebuilt library files (.so for shared, .a for static) as their src,
-// which can be installed or linked against. Also they export flags needed when linked, such as
-// include directories, c flags, sanitize dependency information, etc.
-//
-// These modules are auto-generated by development/vendor_snapshot/update.py.
-type SnapshotLibraryProperties struct {
- // Prebuilt file for each arch.
- Src *string `android:"arch_variant"`
-
- // list of directories that will be added to the include path (using -I).
- Export_include_dirs []string `android:"arch_variant"`
-
- // list of directories that will be added to the system path (using -isystem).
- Export_system_include_dirs []string `android:"arch_variant"`
-
- // list of flags that will be used for any module that links against this module.
- Export_flags []string `android:"arch_variant"`
-
- // Whether this prebuilt needs to depend on sanitize ubsan runtime or not.
- Sanitize_ubsan_dep *bool `android:"arch_variant"`
-
- // Whether this prebuilt needs to depend on sanitize minimal runtime or not.
- Sanitize_minimal_dep *bool `android:"arch_variant"`
-}
-
-type SnapshotSanitizer interface {
- IsSanitizerAvailable(t SanitizerType) bool
- SetSanitizerVariation(t SanitizerType, enabled bool)
- IsSanitizerEnabled(t SanitizerType) bool
- IsUnsanitizedVariant() bool
-}
-
-type snapshotLibraryDecorator struct {
- BaseSnapshotDecorator
- *libraryDecorator
- properties SnapshotLibraryProperties
- sanitizerProperties struct {
- SanitizerVariation SanitizerType `blueprint:"mutated"`
-
- // Library flags for cfi variant.
- Cfi SnapshotLibraryProperties `android:"arch_variant"`
-
- // Library flags for hwasan variant.
- Hwasan SnapshotLibraryProperties `android:"arch_variant"`
- }
-}
-
-func (p *snapshotLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
- p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix())
- return p.libraryDecorator.linkerFlags(ctx, flags)
-}
-
-func (p *snapshotLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
- arches := config.Arches()
- if len(arches) == 0 || arches[0].ArchType.String() != p.Arch() {
- return false
- }
- if !p.header() && p.properties.Src == nil {
- return false
- }
- return true
-}
-
-// cc modules' link functions are to link compiled objects into final binaries.
-// As snapshots are prebuilts, this just returns the prebuilt binary after doing things which are
-// done by normal library decorator, e.g. exporting flags.
-func (p *snapshotLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
- var variant string
- if p.shared() {
- variant = SnapshotSharedSuffix
- } else if p.static() {
- variant = SnapshotStaticSuffix
- } else {
- variant = snapshotHeaderSuffix
- }
-
- p.SetSnapshotAndroidMkSuffix(ctx, variant)
-
- if p.header() {
- return p.libraryDecorator.link(ctx, flags, deps, objs)
- }
-
- if p.IsSanitizerEnabled(cfi) {
- p.properties = p.sanitizerProperties.Cfi
- } else if p.IsSanitizerEnabled(Hwasan) {
- p.properties = p.sanitizerProperties.Hwasan
- }
-
- if !p.MatchesWithDevice(ctx.DeviceConfig()) {
- return nil
- }
-
- // Flags specified directly to this module.
- p.libraryDecorator.reexportDirs(android.PathsForModuleSrc(ctx, p.properties.Export_include_dirs)...)
- p.libraryDecorator.reexportSystemDirs(android.PathsForModuleSrc(ctx, p.properties.Export_system_include_dirs)...)
- p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
-
- // Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
- p.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
- p.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
- p.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
- p.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
- p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
-
- in := android.PathForModuleSrc(ctx, *p.properties.Src)
- p.unstrippedOutputFile = in
-
- if p.shared() {
- libName := in.Base()
-
- // Optimize out relinking against shared libraries whose interface hasn't changed by
- // depending on a table of contents file instead of the library itself.
- tocFile := android.PathForModuleOut(ctx, libName+".toc")
- p.tocFile = android.OptionalPathForPath(tocFile)
- TransformSharedObjectToToc(ctx, in, tocFile)
-
- android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{
- SharedLibrary: in,
- Target: ctx.Target(),
-
- TableOfContents: p.tocFile,
- })
- }
-
- if p.static() {
- depSet := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(in).Build()
- android.SetProvider(ctx, StaticLibraryInfoProvider, StaticLibraryInfo{
- StaticLibrary: in,
-
- TransitiveStaticLibrariesForOrdering: depSet,
- })
- }
-
- p.libraryDecorator.flagExporter.setProvider(ctx)
-
- return in
-}
-
-func (p *snapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) {
- if p.MatchesWithDevice(ctx.DeviceConfig()) && p.shared() {
- p.baseInstaller.install(ctx, file)
- }
-}
-
-func (p *snapshotLibraryDecorator) nativeCoverage() bool {
- return false
-}
-
-var _ SnapshotSanitizer = (*snapshotLibraryDecorator)(nil)
-
-func (p *snapshotLibraryDecorator) IsSanitizerAvailable(t SanitizerType) bool {
- switch t {
- case cfi:
- return p.sanitizerProperties.Cfi.Src != nil
- case Hwasan:
- return p.sanitizerProperties.Hwasan.Src != nil
- default:
- return false
- }
-}
-
-func (p *snapshotLibraryDecorator) SetSanitizerVariation(t SanitizerType, enabled bool) {
- if !enabled || p.IsSanitizerEnabled(t) {
- return
- }
- if !p.IsUnsanitizedVariant() {
- panic(fmt.Errorf("snapshot Sanitizer must be one of Cfi or Hwasan but not both"))
- }
- p.sanitizerProperties.SanitizerVariation = t
-}
-
-func (p *snapshotLibraryDecorator) IsSanitizerEnabled(t SanitizerType) bool {
- return p.sanitizerProperties.SanitizerVariation == t
-}
-
-func (p *snapshotLibraryDecorator) IsUnsanitizedVariant() bool {
- return !p.IsSanitizerEnabled(Asan) &&
- !p.IsSanitizerEnabled(Hwasan)
-}
-
-func snapshotLibraryFactory(image SnapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
- module, library := NewLibrary(android.DeviceSupported)
-
- module.stl = nil
- module.sanitize = nil
- library.disableStripping()
-
- prebuilt := &snapshotLibraryDecorator{
- libraryDecorator: library,
- }
-
- prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true)
- prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true)
-
- // Prevent default system libs (libc, libm, and libdl) from being linked
- if prebuilt.baseLinker.Properties.System_shared_libs == nil {
- prebuilt.baseLinker.Properties.System_shared_libs = []string{}
- }
-
- module.compiler = nil
- module.linker = prebuilt
- module.installer = prebuilt
-
- prebuilt.Init(module, image, moduleSuffix)
- module.AddProperties(
- &prebuilt.properties,
- &prebuilt.sanitizerProperties,
- )
-
- return module, prebuilt
-}
-
-// vendor_snapshot_shared is a special prebuilt shared library which is auto-generated by
-// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_shared
-// overrides the vendor variant of the cc shared library with the same name, if BOARD_VNDK_VERSION
-// is set.
-func VendorSnapshotSharedFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(VendorSnapshotImageSingleton, SnapshotSharedSuffix)
- prebuilt.libraryDecorator.BuildOnlyShared()
- return module.Init()
-}
-
-// recovery_snapshot_shared is a special prebuilt shared library which is auto-generated by
-// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_shared
-// overrides the recovery variant of the cc shared library with the same name, if BOARD_VNDK_VERSION
-// is set.
-func RecoverySnapshotSharedFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(RecoverySnapshotImageSingleton, SnapshotSharedSuffix)
- prebuilt.libraryDecorator.BuildOnlyShared()
- return module.Init()
-}
-
-// vendor_snapshot_static is a special prebuilt static library which is auto-generated by
-// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_static
-// overrides the vendor variant of the cc static library with the same name, if BOARD_VNDK_VERSION
-// is set.
-func VendorSnapshotStaticFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(VendorSnapshotImageSingleton, SnapshotStaticSuffix)
- prebuilt.libraryDecorator.BuildOnlyStatic()
- return module.Init()
-}
-
-// recovery_snapshot_static is a special prebuilt static library which is auto-generated by
-// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_static
-// overrides the recovery variant of the cc static library with the same name, if BOARD_VNDK_VERSION
-// is set.
-func RecoverySnapshotStaticFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(RecoverySnapshotImageSingleton, SnapshotStaticSuffix)
- prebuilt.libraryDecorator.BuildOnlyStatic()
- return module.Init()
-}
-
-// vendor_snapshot_header is a special header library which is auto-generated by
-// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_header
-// overrides the vendor variant of the cc header library with the same name, if BOARD_VNDK_VERSION
-// is set.
-func VendorSnapshotHeaderFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(VendorSnapshotImageSingleton, snapshotHeaderSuffix)
- prebuilt.libraryDecorator.HeaderOnly()
- return module.Init()
-}
-
-// recovery_snapshot_header is a special header library which is auto-generated by
-// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_header
-// overrides the recovery variant of the cc header library with the same name, if BOARD_VNDK_VERSION
-// is set.
-func RecoverySnapshotHeaderFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(RecoverySnapshotImageSingleton, snapshotHeaderSuffix)
- prebuilt.libraryDecorator.HeaderOnly()
- return module.Init()
-}
-
-// Module definitions for snapshots of executable binaries.
-//
-// Modules (vendor|recovery)_snapshot_binary are defined here. They have their prebuilt executable
-// binaries (e.g. toybox, sh) as their src, which can be installed.
-//
-// These modules are auto-generated by development/vendor_snapshot/update.py.
-type snapshotBinaryProperties struct {
- // Prebuilt file for each arch.
- Src *string `android:"arch_variant"`
-}
-
-type snapshotBinaryDecorator struct {
- BaseSnapshotDecorator
- *binaryDecorator
- properties snapshotBinaryProperties
-}
-
-func (p *snapshotBinaryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
- if config.DeviceArch() != p.Arch() {
- return false
- }
- if p.properties.Src == nil {
- return false
- }
- return true
-}
-
-// cc modules' link functions are to link compiled objects into final binaries.
-// As snapshots are prebuilts, this just returns the prebuilt binary
-func (p *snapshotBinaryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
- p.SetSnapshotAndroidMkSuffix(ctx, snapshotBinarySuffix)
-
- if !p.MatchesWithDevice(ctx.DeviceConfig()) {
- return nil
- }
-
- in := android.PathForModuleSrc(ctx, *p.properties.Src)
- p.unstrippedOutputFile = in
- binName := in.Base()
-
- // use cpExecutable to make it executable
- outputFile := android.PathForModuleOut(ctx, binName)
- ctx.Build(pctx, android.BuildParams{
- Rule: android.CpExecutable,
- Description: "prebuilt",
- Output: outputFile,
- Input: in,
- })
-
- // binary snapshots need symlinking
- p.setSymlinkList(ctx)
-
- return outputFile
-}
-
-func (p *snapshotBinaryDecorator) nativeCoverage() bool {
- return false
-}
-
-// vendor_snapshot_binary is a special prebuilt executable binary which is auto-generated by
-// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_binary
-// overrides the vendor variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set.
-func VendorSnapshotBinaryFactory() android.Module {
- return snapshotBinaryFactory(VendorSnapshotImageSingleton, snapshotBinarySuffix)
-}
-
-// recovery_snapshot_binary is a special prebuilt executable binary which is auto-generated by
-// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_binary
-// overrides the recovery variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set.
-func RecoverySnapshotBinaryFactory() android.Module {
- return snapshotBinaryFactory(RecoverySnapshotImageSingleton, snapshotBinarySuffix)
-}
-
-func snapshotBinaryFactory(image SnapshotImage, moduleSuffix string) android.Module {
- module, binary := NewBinary(android.DeviceSupported)
- binary.baseLinker.Properties.No_libcrt = BoolPtr(true)
- binary.baseLinker.Properties.Nocrt = BoolPtr(true)
-
- // Prevent default system libs (libc, libm, and libdl) from being linked
- if binary.baseLinker.Properties.System_shared_libs == nil {
- binary.baseLinker.Properties.System_shared_libs = []string{}
- }
-
- prebuilt := &snapshotBinaryDecorator{
- binaryDecorator: binary,
- }
-
- module.compiler = nil
- module.sanitize = nil
- module.stl = nil
- module.linker = prebuilt
-
- prebuilt.Init(module, image, moduleSuffix)
- module.AddProperties(&prebuilt.properties)
- return module.Init()
-}
-
-// Module definitions for snapshots of object files (*.o).
-//
-// Modules (vendor|recovery)_snapshot_object are defined here. They have their prebuilt object
-// files (*.o) as their src.
-//
-// These modules are auto-generated by development/vendor_snapshot/update.py.
-type vendorSnapshotObjectProperties struct {
- // Prebuilt file for each arch.
- Src *string `android:"arch_variant"`
-}
-
-type snapshotObjectLinker struct {
- BaseSnapshotDecorator
- objectLinker
- properties vendorSnapshotObjectProperties
-}
-
-func (p *snapshotObjectLinker) MatchesWithDevice(config android.DeviceConfig) bool {
- if config.DeviceArch() != p.Arch() {
- return false
- }
- if p.properties.Src == nil {
- return false
- }
- return true
-}
-
-// cc modules' link functions are to link compiled objects into final binaries.
-// As snapshots are prebuilts, this just returns the prebuilt binary
-func (p *snapshotObjectLinker) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path {
- p.SetSnapshotAndroidMkSuffix(ctx, snapshotObjectSuffix)
-
- if !p.MatchesWithDevice(ctx.DeviceConfig()) {
- return nil
- }
-
- return android.PathForModuleSrc(ctx, *p.properties.Src)
-}
-
-func (p *snapshotObjectLinker) nativeCoverage() bool {
- return false
-}
-
-// vendor_snapshot_object is a special prebuilt compiled object file which is auto-generated by
-// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_object
-// overrides the vendor variant of the cc object with the same name, if BOARD_VNDK_VERSION is set.
-func VendorSnapshotObjectFactory() android.Module {
- module := newObject(android.DeviceSupported)
-
- prebuilt := &snapshotObjectLinker{
- objectLinker: objectLinker{
- baseLinker: NewBaseLinker(nil),
- },
- }
- module.linker = prebuilt
-
- prebuilt.Init(module, VendorSnapshotImageSingleton, snapshotObjectSuffix)
- module.AddProperties(&prebuilt.properties)
-
- // vendor_snapshot_object module does not provide sanitizer variants
- module.sanitize.Properties.Sanitize.Never = BoolPtr(true)
-
- return module.Init()
-}
-
-// recovery_snapshot_object is a special prebuilt compiled object file which is auto-generated by
-// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_object
-// overrides the recovery variant of the cc object with the same name, if BOARD_VNDK_VERSION is set.
-func RecoverySnapshotObjectFactory() android.Module {
- module := newObject(android.DeviceSupported)
-
- prebuilt := &snapshotObjectLinker{
- objectLinker: objectLinker{
- baseLinker: NewBaseLinker(nil),
- },
- }
- module.linker = prebuilt
-
- prebuilt.Init(module, RecoverySnapshotImageSingleton, snapshotObjectSuffix)
- module.AddProperties(&prebuilt.properties)
- return module.Init()
-}
-
type SnapshotInterface interface {
MatchesWithDevice(config android.DeviceConfig) bool
IsSnapshotPrebuilt() bool
@@ -838,6 +29,3 @@
}
var _ SnapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil)
-var _ SnapshotInterface = (*snapshotLibraryDecorator)(nil)
-var _ SnapshotInterface = (*snapshotBinaryDecorator)(nil)
-var _ SnapshotInterface = (*snapshotObjectLinker)(nil)
diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go
deleted file mode 100644
index 1ee120e..0000000
--- a/cc/snapshot_utils.go
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2020 The Android Open Source Project
-//
-// 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 cc
-
-// This file contains utility types and functions for VNDK / vendor snapshot.
-
-import (
- "android/soong/android"
-)
-
-var (
- HeaderExts = []string{".h", ".hh", ".hpp", ".hxx", ".h++", ".inl", ".inc", ".ipp", ".h.generic"}
-)
-
-func (m *Module) IsSnapshotLibrary() bool {
- if _, ok := m.linker.(snapshotLibraryInterface); ok {
- return true
- }
- return false
-}
-
-func (m *Module) SnapshotHeaders() android.Paths {
- if m.IsSnapshotLibrary() {
- return m.linker.(snapshotLibraryInterface).snapshotHeaders()
- }
- return android.Paths{}
-}
-
-func (m *Module) Dylib() bool {
- return false
-}
-
-func (m *Module) Rlib() bool {
- return false
-}
-
-func (m *Module) SnapshotRuntimeLibs() []string {
- return m.Properties.SnapshotRuntimeLibs
-}
-
-func (m *Module) SnapshotSharedLibs() []string {
- return m.Properties.SnapshotSharedLibs
-}
-
-func (m *Module) SnapshotStaticLibs() []string {
- return m.Properties.SnapshotStaticLibs
-}
-
-func (m *Module) SnapshotRlibs() []string {
- return []string{}
-}
-
-func (m *Module) SnapshotDylibs() []string {
- return []string{}
-}
-
-// snapshotLibraryInterface is an interface for libraries captured to VNDK / vendor snapshots.
-type snapshotLibraryInterface interface {
- libraryInterface
-
- // collectHeadersForSnapshot is called in GenerateAndroidBuildActions for snapshot aware
- // modules (See isSnapshotAware below).
- // This function should gather all headers needed for snapshot.
- collectHeadersForSnapshot(ctx android.ModuleContext)
-
- // snapshotHeaders should return collected headers by collectHeadersForSnapshot.
- // Calling snapshotHeaders before collectHeadersForSnapshot is an error.
- snapshotHeaders() android.Paths
-}
-
-var _ snapshotLibraryInterface = (*prebuiltLibraryLinker)(nil)
-var _ snapshotLibraryInterface = (*libraryDecorator)(nil)
-
-// snapshotMap is a helper wrapper to a map from base module name to snapshot module name.
-type snapshotMap struct {
- snapshots map[string]string
-}
-
-func newSnapshotMap() *snapshotMap {
- return &snapshotMap{
- snapshots: make(map[string]string),
- }
-}
-
-func snapshotMapKey(name string, arch android.ArchType) string {
- return name + ":" + arch.String()
-}
-
-// Adds a snapshot name for given module name and architecture.
-// e.g. add("libbase", X86, "libbase.vndk.29.x86")
-func (s *snapshotMap) add(name string, arch android.ArchType, snapshot string) {
- s.snapshots[snapshotMapKey(name, arch)] = snapshot
-}
-
-// Returns snapshot name for given module name and architecture, if found.
-// e.g. get("libcutils", X86) => "libcutils.vndk.29.x86", true
-func (s *snapshotMap) get(name string, arch android.ArchType) (snapshot string, found bool) {
- snapshot, found = s.snapshots[snapshotMapKey(name, arch)]
- return snapshot, found
-}
-
-// ShouldCollectHeadersForSnapshot determines if the module is a possible candidate for snapshot.
-// If it's true, collectHeadersForSnapshot will be called in GenerateAndroidBuildActions.
-func ShouldCollectHeadersForSnapshot(ctx android.ModuleContext, m LinkableInterface, apexInfo android.ApexInfo) bool {
- if ctx.DeviceConfig().VndkVersion() != "current" &&
- ctx.DeviceConfig().RecoverySnapshotVersion() != "current" {
- return false
- }
- if _, ok := isVndkSnapshotAware(ctx.DeviceConfig(), m, apexInfo); ok {
- return ctx.Config().VndkSnapshotBuildArtifacts()
- }
-
- for _, image := range []SnapshotImage{VendorSnapshotImageSingleton, RecoverySnapshotImageSingleton} {
- if isSnapshotAware(ctx.DeviceConfig(), m, image.IsProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()), apexInfo, image) {
- return true
- }
- }
- return false
-}
diff --git a/cc/testing.go b/cc/testing.go
index 9c2900c..20c435a 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -15,14 +15,12 @@
package cc
import (
- "encoding/json"
"path/filepath"
"testing"
"android/soong/android"
"android/soong/genrule"
"android/soong/multitree"
- "android/soong/snapshot"
)
func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
@@ -305,10 +303,7 @@
recovery_available: true,
host_supported: true,
min_sdk_version: "29",
- vndk: {
- enabled: true,
- support_system_process: true,
- },
+ double_loadable: true,
apex_available: [
"//apex_available:platform",
"//apex_available:anyapex",
@@ -585,6 +580,7 @@
"defaults/cc/common/crtend_so.c": nil,
"defaults/cc/common/crtend.c": nil,
"defaults/cc/common/crtbrand.c": nil,
+ "external/compiler-rt/lib/cfi/cfi_blocklist.txt": nil,
"defaults/cc/common/libclang_rt.ubsan_minimal.android_arm64.a": nil,
"defaults/cc/common/libclang_rt.ubsan_minimal.android_arm.a": nil,
@@ -624,19 +620,6 @@
android.FixtureOverrideTextFile(linuxBionicDefaultsPath, withLinuxBionic()),
)
-// This adds some additional modules and singletons which might negatively impact the performance
-// of tests so they are not included in the PrepareForIntegrationTestWithCc.
-var PrepareForTestWithCcIncludeVndk = android.GroupFixturePreparers(
- PrepareForIntegrationTestWithCc,
- android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
- snapshot.VendorSnapshotImageSingleton.Init(ctx)
- snapshot.RecoverySnapshotImageSingleton.Init(ctx)
- RegisterVendorSnapshotModules(ctx)
- RegisterRecoverySnapshotModules(ctx)
- ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
- }),
-)
-
// PrepareForTestWithHostMusl sets the host configuration to musl libc instead of glibc. It also disables the test
// on mac, which doesn't support musl libc, and adds musl modules.
var PrepareForTestWithHostMusl = android.GroupFixturePreparers(
@@ -718,11 +701,6 @@
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
- snapshot.VendorSnapshotImageSingleton.Init(ctx)
- snapshot.RecoverySnapshotImageSingleton.Init(ctx)
- RegisterVendorSnapshotModules(ctx)
- RegisterRecoverySnapshotModules(ctx)
- ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
RegisterVndkLibraryTxtTypes(ctx)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
@@ -776,14 +754,6 @@
checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, true, true)
}
-func AssertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool, variant string) {
- t.Helper()
- m := ctx.ModuleForTests(name, variant).Module().(LinkableInterface)
- if m.ExcludeFromVendorSnapshot() != expected {
- t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected)
- }
-}
-
func GetOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
for _, moduleName := range moduleNames {
module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
@@ -792,30 +762,3 @@
}
return paths
}
-
-func AssertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool, variant string) {
- t.Helper()
- m := ctx.ModuleForTests(name, variant).Module().(LinkableInterface)
- if m.ExcludeFromRecoverySnapshot() != expected {
- t.Errorf("expected %q ExcludeFromRecoverySnapshot to be %t", m.String(), expected)
- }
-}
-
-func checkOverrides(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, jsonPath string, expected []string) {
- t.Helper()
- out := singleton.MaybeOutput(jsonPath)
- content := android.ContentFromFileRuleForTests(t, ctx, out)
-
- var flags snapshotJsonFlags
- if err := json.Unmarshal([]byte(content), &flags); err != nil {
- t.Errorf("Error while unmarshalling json %q: %s", jsonPath, err.Error())
- return
- }
-
- for _, moduleName := range expected {
- if !android.InList(moduleName, flags.Overrides) {
- t.Errorf("expected %q to be in %q: %q", moduleName, flags.Overrides, content)
- return
- }
- }
-}
diff --git a/cc/util.go b/cc/util.go
index c93646b..3ede8ff 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -19,7 +19,6 @@
"strings"
"android/soong/android"
- "android/soong/snapshot"
)
// Efficiently converts a list of include directories to a single string
@@ -56,18 +55,19 @@
localCppFlags: strings.Join(in.Local.CppFlags, " "),
localLdFlags: strings.Join(in.Local.LdFlags, " "),
- aidlFlags: strings.Join(in.aidlFlags, " "),
- rsFlags: strings.Join(in.rsFlags, " "),
- libFlags: strings.Join(in.libFlags, " "),
- extraLibFlags: strings.Join(in.extraLibFlags, " "),
- tidyFlags: strings.Join(in.TidyFlags, " "),
- sAbiFlags: strings.Join(in.SAbiFlags, " "),
- toolchain: in.Toolchain,
- gcovCoverage: in.GcovCoverage,
- tidy: in.Tidy,
- needTidyFiles: in.NeedTidyFiles,
- sAbiDump: in.SAbiDump,
- emitXrefs: in.EmitXrefs,
+ noOverrideFlags: strings.Join(in.NoOverrideFlags, " "),
+ aidlFlags: strings.Join(in.aidlFlags, " "),
+ rsFlags: strings.Join(in.rsFlags, " "),
+ libFlags: strings.Join(in.libFlags, " "),
+ extraLibFlags: strings.Join(in.extraLibFlags, " "),
+ tidyFlags: strings.Join(in.TidyFlags, " "),
+ sAbiFlags: strings.Join(in.SAbiFlags, " "),
+ toolchain: in.Toolchain,
+ gcovCoverage: in.GcovCoverage,
+ tidy: in.Tidy,
+ needTidyFiles: in.NeedTidyFiles,
+ sAbiDump: in.SAbiDump,
+ emitXrefs: in.EmitXrefs,
systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "),
@@ -100,6 +100,12 @@
"ln -sf " + target + " " + filepath.Join(dir, linkName)
}
+func WriteStringToFileRule(ctx android.SingletonContext, content, out string) android.OutputPath {
+ outPath := android.PathForOutput(ctx, out)
+ android.WriteFileRule(ctx, outPath, content)
+ return outPath
+}
+
// Dump a map to a list file as:
//
// {key1} {value1}
@@ -115,5 +121,5 @@
txtBuilder.WriteString(" ")
txtBuilder.WriteString(m[k])
}
- return snapshot.WriteStringToFileRule(ctx, txtBuilder.String(), path)
+ return WriteStringToFileRule(ctx, txtBuilder.String(), path)
}
diff --git a/cc/vendor_public_library_test.go b/cc/vendor_public_library_test.go
index 769be09..7385f2b 100644
--- a/cc/vendor_public_library_test.go
+++ b/cc/vendor_public_library_test.go
@@ -65,8 +65,8 @@
`)
coreVariant := "android_arm64_armv8-a_shared"
- vendorVariant := "android_vendor.29_arm64_armv8-a_shared"
- productVariant := "android_product.29_arm64_armv8-a_shared"
+ vendorVariant := "android_vendor_arm64_armv8-a_shared"
+ productVariant := "android_product_arm64_armv8-a_shared"
// test if header search paths are correctly added
// _static variant is used since _shared reuses *.o from the static variant
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
deleted file mode 100644
index a33ed5f..0000000
--- a/cc/vendor_snapshot.go
+++ /dev/null
@@ -1,459 +0,0 @@
-// Copyright 2020 The Android Open Source Project
-//
-// 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 cc
-
-import (
- "encoding/json"
- "path/filepath"
- "strings"
-
- "android/soong/android"
- "android/soong/snapshot"
-)
-
-// This file defines how to capture cc modules into snapshot package.
-
-// Checks if the target image would contain VNDK
-func includeVndk(image snapshot.SnapshotImage) bool {
- if image.ImageName() == snapshot.VendorSnapshotImageName {
- return true
- }
-
- return false
-}
-
-// Check if the module is VNDK private
-func isPrivate(image snapshot.SnapshotImage, m LinkableInterface) bool {
- if image.ImageName() == snapshot.VendorSnapshotImageName && m.IsVndkPrivate() {
- return true
- }
-
- return false
-}
-
-// Checks if target image supports VNDK Ext
-func supportsVndkExt(image snapshot.SnapshotImage) bool {
- if image.ImageName() == snapshot.VendorSnapshotImageName {
- return true
- }
-
- return false
-}
-
-// Determines if the module is a candidate for snapshot.
-func isSnapshotAware(cfg android.DeviceConfig, m LinkableInterface, inProprietaryPath bool, apexInfo android.ApexInfo, image snapshot.SnapshotImage) bool {
- if !m.Enabled() || m.HiddenFromMake() {
- return false
- }
- // When android/prebuilt.go selects between source and prebuilt, it sets
- // HideFromMake on the other one to avoid duplicate install rules in make.
- if m.IsHideFromMake() {
- return false
- }
- // skip proprietary modules, but (for the vendor snapshot only)
- // include all VNDK (static)
- if inProprietaryPath && (!includeVndk(image) || !m.IsVndk()) {
- return false
- }
- // If the module would be included based on its path, check to see if
- // the module is marked to be excluded. If so, skip it.
- if image.ExcludeFromSnapshot(m) {
- return false
- }
- if m.Target().Os.Class != android.Device {
- return false
- }
- if m.Target().NativeBridge == android.NativeBridgeEnabled {
- return false
- }
- // the module must be installed in target image
- if !apexInfo.IsForPlatform() || m.IsSnapshotPrebuilt() || !image.InImage(m)() {
- return false
- }
- // skip kernel_headers which always depend on vendor
- if m.KernelHeadersDecorator() {
- return false
- }
-
- if m.IsLlndk() {
- return false
- }
-
- // Libraries
- if sanitizable, ok := m.(PlatformSanitizeable); ok && sanitizable.IsSnapshotLibrary() {
- if sanitizable.SanitizePropDefined() {
- // scs exports both sanitized and unsanitized variants for static and header
- // Always use unsanitized variant of it.
- if !sanitizable.Shared() && sanitizable.IsSanitizerEnabled(scs) {
- return false
- }
- // cfi and hwasan cannot be enabled at the same time.
- // Skip variants that have both cfi and hwasan enabled.
- if sanitizable.IsSanitizerEnabled(cfi) && sanitizable.IsSanitizerEnabled(Hwasan) {
- return false
- }
- // cfi and hwasan also export both variants. But for static, we capture both.
- // This is because cfi static libraries can't be linked from non-cfi modules,
- // and vice versa.
- // hwasan is captured as well to support hwasan build.
- if !sanitizable.Static() &&
- !sanitizable.Shared() &&
- (sanitizable.IsSanitizerEnabled(cfi) || sanitizable.IsSanitizerEnabled(Hwasan)) {
- return false
- }
- }
- if sanitizable.Static() || sanitizable.Rlib() {
- return sanitizable.OutputFile().Valid() && !isPrivate(image, m)
- }
- if sanitizable.Shared() || sanitizable.Dylib() {
- if !sanitizable.OutputFile().Valid() {
- return false
- }
- if includeVndk(image) {
- if !sanitizable.IsVndk() {
- return true
- }
- return sanitizable.IsVndkExt()
- }
- }
- return true
- }
-
- // Binaries and Objects
- if m.Binary() || m.Object() {
- return m.OutputFile().Valid()
- }
-
- return false
-}
-
-// Extend the snapshot.SnapshotJsonFlags to include cc specific fields.
-type snapshotJsonFlags struct {
- snapshot.SnapshotJsonFlags
- // library flags
- ExportedDirs []string `json:",omitempty"`
- ExportedSystemDirs []string `json:",omitempty"`
- ExportedFlags []string `json:",omitempty"`
- Sanitize string `json:",omitempty"`
- SanitizeMinimalDep bool `json:",omitempty"`
- SanitizeUbsanDep bool `json:",omitempty"`
-
- // binary flags
- Symlinks []string `json:",omitempty"`
- StaticExecutable bool `json:",omitempty"`
- InstallInRoot bool `json:",omitempty"`
-
- // dependencies
- SharedLibs []string `json:",omitempty"`
- StaticLibs []string `json:",omitempty"`
- RuntimeLibs []string `json:",omitempty"`
- Dylibs []string `json:",omitempty"`
- Rlibs []string `json:",omitempty"`
-
- // extra config files
- InitRc []string `json:",omitempty"`
- VintfFragments []string `json:",omitempty"`
- MinSdkVersion string `json:",omitempty"`
-}
-
-var ccSnapshotAction snapshot.GenerateSnapshotAction = func(s snapshot.SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) snapshot.SnapshotPaths {
- /*
- Vendor snapshot zipped artifacts directory structure for cc modules:
- {SNAPSHOT_ARCH}/
- arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
- shared/
- (.so shared libraries)
- static/
- (.a static libraries)
- header/
- (header only libraries)
- binary/
- (executable binaries)
- object/
- (.o object files)
- arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
- shared/
- (.so shared libraries)
- static/
- (.a static libraries)
- header/
- (header only libraries)
- binary/
- (executable binaries)
- object/
- (.o object files)
- NOTICE_FILES/
- (notice files, e.g. libbase.txt)
- configs/
- (config files, e.g. init.rc files, vintf_fragments.xml files, etc.)
- include/
- (header files of same directory structure with source tree)
- */
-
- var snapshotOutputs android.Paths
- var snapshotNotices android.Paths
-
- includeDir := filepath.Join(snapshotArchDir, "include")
- configsDir := filepath.Join(snapshotArchDir, "configs")
-
- installedNotices := make(map[string]bool)
- installedConfigs := make(map[string]bool)
-
- var headers android.Paths
-
- copyFile := func(ctx android.SingletonContext, path android.Path, out string, fake bool) android.OutputPath {
- if fake {
- // All prebuilt binaries and headers are installed by copyFile function. This makes a fake
- // snapshot just touch prebuilts and headers, rather than installing real files.
- return snapshot.WriteStringToFileRule(ctx, "", out)
- } else {
- return snapshot.CopyFileRule(pctx, ctx, path, out)
- }
- }
-
- // installSnapshot function copies prebuilt file (.so, .a, or executable) and json flag file.
- // For executables, init_rc and vintf_fragments files are also copied.
- installSnapshot := func(m LinkableInterface, fake bool) android.Paths {
- targetArch := "arch-" + m.Target().Arch.ArchType.String()
- if m.Target().Arch.ArchVariant != "" {
- targetArch += "-" + m.Target().Arch.ArchVariant
- }
-
- var ret android.Paths
-
- prop := snapshotJsonFlags{}
-
- // Common properties among snapshots.
- prop.InitBaseSnapshotPropsWithName(m, ctx.ModuleName(m))
- if supportsVndkExt(s.Image) && m.IsVndkExt() {
- // vndk exts are installed to /vendor/lib(64)?/vndk(-sp)?
- if m.IsVndkSp() {
- prop.RelativeInstallPath = "vndk-sp"
- } else {
- prop.RelativeInstallPath = "vndk"
- }
- } else {
- prop.RelativeInstallPath = m.RelativeInstallPath()
- }
- prop.RuntimeLibs = m.SnapshotRuntimeLibs()
- prop.Required = m.RequiredModuleNames()
- if o, ok := m.(overridable); ok {
- prop.Overrides = o.overriddenModules()
- }
- for _, path := range m.InitRc() {
- prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
- }
- for _, path := range m.VintfFragments() {
- prop.VintfFragments = append(prop.VintfFragments, filepath.Join("configs", path.Base()))
- }
- if m.IsPrebuilt() {
- prop.MinSdkVersion = "apex_inherit"
- } else {
- prop.MinSdkVersion = m.MinSdkVersion()
- }
-
- // install config files. ignores any duplicates.
- for _, path := range append(m.InitRc(), m.VintfFragments()...) {
- out := filepath.Join(configsDir, path.Base())
- if !installedConfigs[out] {
- installedConfigs[out] = true
- ret = append(ret, copyFile(ctx, path, out, fake))
- }
- }
-
- var propOut string
-
- if m.IsSnapshotLibrary() {
- exporterInfo, _ := android.SingletonModuleProvider(ctx, m.Module(), FlagExporterInfoProvider)
-
- // library flags
- prop.ExportedFlags = exporterInfo.Flags
- for _, dir := range exporterInfo.IncludeDirs {
- prop.ExportedDirs = append(prop.ExportedDirs, filepath.Join("include", dir.String()))
- }
- for _, dir := range exporterInfo.SystemIncludeDirs {
- prop.ExportedSystemDirs = append(prop.ExportedSystemDirs, filepath.Join("include", dir.String()))
- }
-
- // shared libs dependencies aren't meaningful on static or header libs
- if m.Shared() {
- prop.SharedLibs = m.SnapshotSharedLibs()
- }
-
- // dylibs collect both shared and dylib dependencies.
- if m.Dylib() {
- prop.SharedLibs = m.SnapshotSharedLibs()
- prop.Dylibs = m.SnapshotDylibs()
- }
-
- // static and rlib libs dependencies are required to collect the NOTICE files.
- prop.StaticLibs = m.SnapshotStaticLibs()
- prop.Rlibs = m.SnapshotRlibs()
-
- if sanitizable, ok := m.(PlatformSanitizeable); ok {
- if sanitizable.Static() && sanitizable.SanitizePropDefined() {
- prop.SanitizeMinimalDep = sanitizable.MinimalRuntimeDep() || sanitizable.MinimalRuntimeNeeded()
- prop.SanitizeUbsanDep = sanitizable.UbsanRuntimeDep() || sanitizable.UbsanRuntimeNeeded()
- }
- }
-
- var libType string
- if m.Static() {
- libType = "static"
- } else if m.Shared() {
- libType = "shared"
- } else if m.Rlib() {
- libType = "rlib"
- } else if m.Dylib() {
- libType = "dylib"
- } else {
- libType = "header"
- }
-
- var stem string
-
- // install .a, .rlib, .dylib.so, or .so
- if libType != "header" {
- libPath := m.OutputFile().Path()
- stem = libPath.Base()
- if sanitizable, ok := m.(PlatformSanitizeable); ok {
- if (sanitizable.Static() || sanitizable.Rlib()) && sanitizable.SanitizePropDefined() {
- if sanitizable.IsSanitizerEnabled(cfi) {
- // both cfi and non-cfi variant for static libraries can exist.
- // attach .cfi to distinguish between cfi and non-cfi.
- // e.g. libbase.a -> libbase.cfi.a
- ext := filepath.Ext(stem)
- stem = strings.TrimSuffix(stem, ext) + ".cfi" + ext
- prop.Sanitize = "cfi"
- prop.ModuleName += ".cfi"
- } else if sanitizable.IsSanitizerEnabled(Hwasan) {
- // Same for the hwasan
- ext := filepath.Ext(stem)
- stem = strings.TrimSuffix(stem, ext) + ".hwasan" + ext
- prop.Sanitize = "hwasan"
- prop.ModuleName += ".hwasan"
- }
- }
- }
- if m.Rlib() && m.RlibStd() {
- // rlibs produce both rlib-std and dylib-std variants
- ext := filepath.Ext(stem)
- stem = strings.TrimSuffix(stem, ext) + ".rlib-std" + ext
- prop.ModuleName += ".rlib-std"
- }
- snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, m.RelativeInstallPath(), stem)
- ret = append(ret, copyFile(ctx, libPath, snapshotLibOut, fake))
- } else {
- stem = ctx.ModuleName(m)
- }
-
- propOut = filepath.Join(snapshotArchDir, targetArch, libType, m.RelativeInstallPath(), stem+".json")
- } else if m.Binary() {
- // binary flags
- prop.Symlinks = m.Symlinks()
- prop.StaticExecutable = m.StaticExecutable()
- prop.InstallInRoot = m.InstallInRoot()
- prop.SharedLibs = m.SnapshotSharedLibs()
- prop.Dylibs = m.SnapshotDylibs()
-
- // static and rlib dependencies are required to collect the NOTICE files.
- prop.StaticLibs = m.SnapshotStaticLibs()
- prop.Rlibs = m.SnapshotRlibs()
-
- // install bin
- binPath := m.OutputFile().Path()
- snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
- ret = append(ret, copyFile(ctx, binPath, snapshotBinOut, fake))
- propOut = snapshotBinOut + ".json"
- } else if m.Object() {
- // object files aren't installed to the device, so their names can conflict.
- // Use module name as stem.
- objPath := m.OutputFile().Path()
- snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
- ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
- ret = append(ret, copyFile(ctx, objPath, snapshotObjOut, fake))
- propOut = snapshotObjOut + ".json"
- } else {
- ctx.Errorf("unknown module %q in vendor snapshot", m.String())
- return nil
- }
-
- j, err := json.Marshal(prop)
- if err != nil {
- ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
- return nil
- }
- ret = append(ret, snapshot.WriteStringToFileRule(ctx, string(j), propOut))
-
- return ret
- }
-
- ctx.VisitAllModules(func(module android.Module) {
- m, ok := module.(LinkableInterface)
- if !ok {
- return
- }
-
- moduleDir := ctx.ModuleDir(module)
- inProprietaryPath := s.Image.IsProprietaryPath(moduleDir, ctx.DeviceConfig())
- apexInfo, _ := android.SingletonModuleProvider(ctx, module, android.ApexInfoProvider)
-
- if s.Image.ExcludeFromSnapshot(m) {
- if inProprietaryPath {
- // Error: exclude_from_vendor_snapshot applies
- // to framework-path modules only.
- ctx.Errorf("module %q in vendor proprietary path %q may not use \"exclude_from_vendor_snapshot: true\"", m.String(), moduleDir)
- return
- }
- }
-
- if !isSnapshotAware(ctx.DeviceConfig(), m, inProprietaryPath, apexInfo, s.Image) {
- return
- }
-
- // If we are using directed snapshot and a module is not included in the
- // list, we will still include the module as if it was a fake module.
- // The reason is that soong needs all the dependencies to be present, even
- // if they are not using during the build.
- installAsFake := s.Fake
- if s.Image.ExcludeFromDirectedSnapshot(ctx.DeviceConfig(), m.BaseModuleName()) {
- installAsFake = true
- }
-
- // installSnapshot installs prebuilts and json flag files
- snapshotOutputs = append(snapshotOutputs, installSnapshot(m, installAsFake)...)
- // just gather headers and notice files here, because they are to be deduplicated
- if m.IsSnapshotLibrary() {
- headers = append(headers, m.SnapshotHeaders()...)
- }
-
- for _, notice := range m.EffectiveLicenseFiles() {
- if _, ok := installedNotices[notice.String()]; !ok {
- installedNotices[notice.String()] = true
- snapshotNotices = append(snapshotNotices, notice)
- }
- }
- })
-
- // install all headers after removing duplicates
- for _, header := range android.FirstUniquePaths(headers) {
- snapshotOutputs = append(snapshotOutputs, copyFile(ctx, header, filepath.Join(includeDir, header.String()), s.Fake))
- }
-
- return snapshot.SnapshotPaths{OutputFiles: snapshotOutputs, NoticeFiles: snapshotNotices}
-}
-
-func init() {
- snapshot.RegisterSnapshotAction(ccSnapshotAction)
-}
diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go
deleted file mode 100644
index 0a55431..0000000
--- a/cc/vendor_snapshot_test.go
+++ /dev/null
@@ -1,1751 +0,0 @@
-// Copyright 2021 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 cc
-
-import (
- "android/soong/android"
- "fmt"
- "path/filepath"
- "reflect"
- "strings"
- "testing"
-)
-
-func checkJsonContents(t *testing.T, ctx *android.TestContext, snapshotSingleton android.TestingSingleton, jsonPath string, key string, value string) {
- jsonOut := snapshotSingleton.MaybeOutput(jsonPath)
- if jsonOut.Rule == nil {
- t.Errorf("%q expected but not found", jsonPath)
- return
- }
- content := android.ContentFromFileRuleForTests(t, ctx, jsonOut)
- if !strings.Contains(content, fmt.Sprintf("%q:%q", key, value)) {
- t.Errorf("%q must include %q:%q but it only has %v", jsonPath, key, value, jsonOut.Args["content"])
- }
-}
-
-func TestVendorSnapshotCapture(t *testing.T) {
- bp := `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvendor",
- vendor: true,
- nocrt: true,
- }
-
- cc_library {
- name: "libvendor_override",
- vendor: true,
- nocrt: true,
- overrides: ["libvendor"],
- }
-
- cc_library {
- name: "libvendor_available",
- vendor_available: true,
- nocrt: true,
- min_sdk_version: "29",
- }
-
- cc_library_headers {
- name: "libvendor_headers",
- vendor_available: true,
- nocrt: true,
- }
-
- cc_binary {
- name: "vendor_bin",
- vendor: true,
- nocrt: true,
- }
-
- cc_binary {
- name: "vendor_available_bin",
- vendor_available: true,
- nocrt: true,
- }
-
- cc_binary {
- name: "vendor_bin_override",
- vendor: true,
- nocrt: true,
- overrides: ["vendor_bin"],
- }
-
- cc_prebuilt_library_static {
- name: "libb",
- vendor_available: true,
- srcs: ["libb.a"],
- nocrt: true,
- no_libcrt: true,
- stl: "none",
- }
-
- cc_object {
- name: "obj",
- vendor_available: true,
- }
-
- cc_library {
- name: "libllndk",
- llndk: {
- symbol_file: "libllndk.map.txt",
- },
- }
-`
-
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- ctx := testCcWithConfig(t, config)
-
- // Check Vendor snapshot output.
-
- snapshotDir := "vendor-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
-
- var jsonFiles []string
-
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- []string{"arm", "armv7-a-neon"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- // For shared libraries, only non-VNDK vendor_available modules are captured
- sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
- CheckSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(sharedDir, "libvendor.so.json"),
- filepath.Join(sharedDir, "libvendor_available.so.json"))
-
- // LLNDK modules are not captured
- CheckSnapshotExclude(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", sharedDir, sharedVariant)
-
- // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
- // Also cfi variants are captured, except for prebuilts like toolchain_library
- staticVariant := fmt.Sprintf("android_vendor.29_%s_%s_static", archType, archVariant)
- staticCfiVariant := fmt.Sprintf("android_vendor.29_%s_%s_static_cfi", archType, archVariant)
- staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
- CheckSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.cfi.a", staticDir, staticCfiVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.cfi.a", staticDir, staticCfiVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.cfi.a", staticDir, staticCfiVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(staticDir, "libb.a.json"),
- filepath.Join(staticDir, "libvndk.a.json"),
- filepath.Join(staticDir, "libvndk.cfi.a.json"),
- filepath.Join(staticDir, "libvendor.a.json"),
- filepath.Join(staticDir, "libvendor.cfi.a.json"),
- filepath.Join(staticDir, "libvendor_available.a.json"),
- filepath.Join(staticDir, "libvendor_available.cfi.a.json"))
-
- checkJsonContents(t, ctx, snapshotSingleton, filepath.Join(staticDir, "libb.a.json"), "MinSdkVersion", "apex_inherit")
- checkJsonContents(t, ctx, snapshotSingleton, filepath.Join(staticDir, "libvendor_available.a.json"), "MinSdkVersion", "29")
-
- // For binary executables, all vendor:true and vendor_available modules are captured.
- if archType == "arm64" {
- binaryVariant := fmt.Sprintf("android_vendor.29_%s_%s", archType, archVariant)
- binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
- CheckSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(binaryDir, "vendor_bin.json"),
- filepath.Join(binaryDir, "vendor_available_bin.json"))
-
- checkOverrides(t, ctx, snapshotSingleton, filepath.Join(binaryDir, "vendor_bin_override.json"), []string{"vendor_bin"})
- }
-
- // For header libraries, all vendor:true and vendor_available modules are captured.
- headerDir := filepath.Join(snapshotVariantPath, archDir, "header")
- jsonFiles = append(jsonFiles, filepath.Join(headerDir, "libvendor_headers.json"))
-
- // For object modules, all vendor:true and vendor_available modules are captured.
- objectVariant := fmt.Sprintf("android_vendor.29_%s_%s", archType, archVariant)
- objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
- CheckSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
- jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
-
- checkOverrides(t, ctx, snapshotSingleton, filepath.Join(sharedDir, "libvendor_override.so.json"), []string{"libvendor"})
- }
-
- for _, jsonFile := range jsonFiles {
- // verify all json files exist
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("%q expected but not found", jsonFile)
- }
- }
-
- // fake snapshot should have all outputs in the normal snapshot.
- fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot")
- for _, output := range snapshotSingleton.AllOutputs() {
- fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1)
- if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil {
- t.Errorf("%q expected but not found", fakeOutput)
- }
- }
-}
-
-func TestVendorSnapshotDirected(t *testing.T) {
- bp := `
- cc_library_shared {
- name: "libvendor",
- vendor: true,
- nocrt: true,
- }
-
- cc_library_shared {
- name: "libvendor_available",
- vendor_available: true,
- nocrt: true,
- }
-
- genrule {
- name: "libfoo_gen",
- cmd: "",
- out: ["libfoo.so"],
- }
-
- cc_prebuilt_library_shared {
- name: "libfoo",
- vendor: true,
- prefer: true,
- srcs: [":libfoo_gen"],
- }
-
- cc_library_shared {
- name: "libfoo",
- vendor: true,
- nocrt: true,
- }
-`
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- config.TestProductVariables.DirectedVendorSnapshot = true
- config.TestProductVariables.VendorSnapshotModules = make(map[string]bool)
- config.TestProductVariables.VendorSnapshotModules["libvendor"] = true
- config.TestProductVariables.VendorSnapshotModules["libfoo"] = true
- ctx := testCcWithConfig(t, config)
-
- // Check Vendor snapshot output.
-
- snapshotDir := "vendor-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
-
- var includeJsonFiles []string
-
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- []string{"arm", "armv7-a-neon"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
-
- // Included modules
- CheckSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
- // Check that snapshot captures "prefer: true" prebuilt
- CheckSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json"))
-
- // Excluded modules. Modules not included in the directed vendor snapshot
- // are still include as fake modules.
- CheckSnapshotRule(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor_available.so.json"))
- }
-
- // Verify that each json file for an included module has a rule.
- for _, jsonFile := range includeJsonFiles {
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("include json file %q not found", jsonFile)
- }
- }
-}
-
-func TestVendorSnapshotUse(t *testing.T) {
- frameworkBp := `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvendor",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- stl: "none",
- system_shared_libs: [],
- }
-
- cc_library {
- name: "libvendor_available",
- vendor_available: true,
- nocrt: true,
- no_libcrt: true,
- stl: "none",
- system_shared_libs: [],
- }
-
- cc_library {
- name: "lib32",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- stl: "none",
- system_shared_libs: [],
- compile_multilib: "32",
- }
-
- cc_library {
- name: "lib64",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- no_crt_pad_segment: true,
- stl: "none",
- system_shared_libs: [],
- compile_multilib: "64",
- }
-
- cc_library {
- name: "libllndk",
- llndk: {
- symbol_file: "libllndk.map.txt",
- },
- }
-
- cc_binary {
- name: "bin",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- stl: "none",
- system_shared_libs: [],
- }
-
- cc_binary {
- name: "bin32",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- stl: "none",
- system_shared_libs: [],
- compile_multilib: "32",
- }
-`
-
- vndkBp := `
- vndk_prebuilt_shared {
- name: "libvndk",
- version: "31",
- target_arch: "arm64",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- arch: {
- arm64: {
- srcs: ["libvndk.so"],
- export_include_dirs: ["include/libvndk"],
- },
- arm: {
- srcs: ["libvndk.so"],
- export_include_dirs: ["include/libvndk"],
- },
- },
- }
-
- // old snapshot module which has to be ignored
- vndk_prebuilt_shared {
- name: "libvndk",
- version: "26",
- target_arch: "arm64",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- arch: {
- arm64: {
- srcs: ["libvndk.so"],
- export_include_dirs: ["include/libvndk"],
- },
- arm: {
- srcs: ["libvndk.so"],
- export_include_dirs: ["include/libvndk"],
- },
- },
- }
-
- // different arch snapshot which has to be ignored
- vndk_prebuilt_shared {
- name: "libvndk",
- version: "31",
- target_arch: "arm",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- arch: {
- arm: {
- srcs: ["libvndk.so"],
- export_include_dirs: ["include/libvndk"],
- },
- },
- }
-
- vndk_prebuilt_shared {
- name: "libllndk",
- version: "31",
- target_arch: "arm64",
- vendor_available: true,
- product_available: true,
- arch: {
- arm64: {
- srcs: ["libllndk.so"],
- },
- arm: {
- srcs: ["libllndk.so"],
- },
- },
- }
-`
-
- vendorProprietaryBp := `
- cc_library {
- name: "libvendor_without_snapshot",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- no_crt_pad_segment: true,
- stl: "none",
- system_shared_libs: [],
- }
-
- cc_library_shared {
- name: "libclient",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- no_crt_pad_segment: true,
- stl: "none",
- system_shared_libs: [],
- shared_libs: ["libvndk", "libvendor_available", "libllndk"],
- static_libs: ["libvendor", "libvendor_without_snapshot"],
- arch: {
- arm64: {
- shared_libs: ["lib64"],
- },
- arm: {
- shared_libs: ["lib32"],
- },
- },
- srcs: ["client.cpp"],
- }
-
- cc_library_shared {
- name: "libclient_cfi",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- no_crt_pad_segment: true,
- stl: "none",
- system_shared_libs: [],
- static_libs: ["libvendor"],
- sanitize: {
- cfi: true,
- },
- srcs: ["client.cpp"],
- }
-
- cc_library_shared {
- name: "libvndkext",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- no_crt_pad_segment: true,
- stl: "none",
- system_shared_libs: [],
- vndk: {
- extends: "libvndk",
- enabled: true,
- }
- }
-
- cc_binary {
- name: "bin_without_snapshot",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- stl: "libc++_static",
- system_shared_libs: [],
- static_libs: ["libvndk"],
- srcs: ["bin.cpp"],
- }
-
- vendor_snapshot {
- name: "vendor_snapshot",
- version: "31",
- arch: {
- arm64: {
- vndk_libs: [
- "libvndk",
- "libllndk",
- ],
- static_libs: [
- "libc++_static",
- "libc++demangle",
- "libunwind",
- "libvendor",
- "libvendor_available",
- "libvndk",
- "lib64",
- ],
- shared_libs: [
- "libvendor",
- "libvendor_override",
- "libvendor_available",
- "lib64",
- ],
- binaries: [
- "bin",
- "bin_override",
- ],
- },
- arm: {
- vndk_libs: [
- "libvndk",
- "libllndk",
- ],
- static_libs: [
- "libvendor",
- "libvendor_available",
- "libvndk",
- "lib32",
- ],
- shared_libs: [
- "libvendor",
- "libvendor_override",
- "libvendor_available",
- "lib32",
- ],
- binaries: [
- "bin32",
- ],
- },
- }
- }
-
- vendor_snapshot_static {
- name: "libvndk",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "both",
- vendor: true,
- arch: {
- arm64: {
- src: "libvndk.a",
- },
- arm: {
- src: "libvndk.a",
- },
- },
- shared_libs: ["libvndk"],
- export_shared_lib_headers: ["libvndk"],
- }
-
- vendor_snapshot_shared {
- name: "libvendor",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "both",
- vendor: true,
- no_crt_pad_segment: true,
- shared_libs: [
- "libvendor_without_snapshot",
- "libvendor_available",
- "libvndk",
- ],
- arch: {
- arm64: {
- src: "libvendor.so",
- export_include_dirs: ["include/libvendor"],
- },
- arm: {
- src: "libvendor.so",
- export_include_dirs: ["include/libvendor"],
- },
- },
- }
-
- vendor_snapshot_shared {
- name: "libvendor_override",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "both",
- vendor: true,
- no_crt_pad_segment: true,
- overrides: ["libvendor"],
- shared_libs: [
- "libvendor_without_snapshot",
- "libvendor_available",
- "libvndk",
- ],
- arch: {
- arm64: {
- src: "override/libvendor.so",
- export_include_dirs: ["include/libvendor"],
- },
- arm: {
- src: "override/libvendor.so",
- export_include_dirs: ["include/libvendor"],
- },
- },
- }
-
- vendor_snapshot_static {
- name: "lib32",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "32",
- vendor: true,
- arch: {
- arm: {
- src: "lib32.a",
- },
- },
- }
-
- vendor_snapshot_shared {
- name: "lib32",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "32",
- vendor: true,
- no_crt_pad_segment: true,
- arch: {
- arm: {
- src: "lib32.so",
- },
- },
- }
-
- vendor_snapshot_static {
- name: "lib64",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "64",
- vendor: true,
- arch: {
- arm64: {
- src: "lib64.a",
- },
- },
- }
-
- vendor_snapshot_shared {
- name: "lib64",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "64",
- vendor: true,
- no_crt_pad_segment: true,
- arch: {
- arm64: {
- src: "lib64.so",
- },
- },
- }
-
- vendor_snapshot_static {
- name: "libvendor",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "both",
- vendor: true,
- arch: {
- arm64: {
- cfi: {
- src: "libvendor.cfi.a",
- export_include_dirs: ["include/libvendor_cfi"],
- },
- src: "libvendor.a",
- export_include_dirs: ["include/libvendor"],
- },
- arm: {
- cfi: {
- src: "libvendor.cfi.a",
- export_include_dirs: ["include/libvendor_cfi"],
- },
- src: "libvendor.a",
- export_include_dirs: ["include/libvendor"],
- },
- },
- }
-
- vendor_snapshot_shared {
- name: "libvendor_available",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "both",
- vendor: true,
- no_crt_pad_segment: true,
- arch: {
- arm64: {
- src: "libvendor_available.so",
- export_include_dirs: ["include/libvendor"],
- },
- arm: {
- src: "libvendor_available.so",
- export_include_dirs: ["include/libvendor"],
- },
- },
- }
-
- vendor_snapshot_static {
- name: "libvendor_available",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "both",
- vendor: true,
- arch: {
- arm64: {
- src: "libvendor_available.a",
- export_include_dirs: ["include/libvendor"],
- },
- arm: {
- src: "libvendor_available.so",
- export_include_dirs: ["include/libvendor"],
- },
- },
- }
-
- vendor_snapshot_static {
- name: "libc++_static",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "64",
- vendor: true,
- arch: {
- arm64: {
- src: "libc++_static.a",
- },
- },
- }
-
- vendor_snapshot_static {
- name: "libc++demangle",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "64",
- vendor: true,
- arch: {
- arm64: {
- src: "libc++demangle.a",
- },
- },
- }
-
- vendor_snapshot_static {
- name: "libunwind",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "64",
- vendor: true,
- arch: {
- arm64: {
- src: "libunwind.a",
- },
- },
- }
-
- vendor_snapshot_binary {
- name: "bin",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "64",
- vendor: true,
- arch: {
- arm64: {
- src: "bin",
- },
- },
- symlinks: ["binfoo", "binbar"],
- }
-
- vendor_snapshot_binary {
- name: "bin_override",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "64",
- vendor: true,
- overrides: ["bin"],
- arch: {
- arm64: {
- src: "override/bin",
- },
- },
- symlinks: ["binfoo", "binbar"],
- }
-
- vendor_snapshot_binary {
- name: "bin32",
- version: "31",
- target_arch: "arm64",
- compile_multilib: "32",
- vendor: true,
- arch: {
- arm: {
- src: "bin32",
- },
- },
- }
-
- // old snapshot module which has to be ignored
- vendor_snapshot_binary {
- name: "bin",
- version: "26",
- target_arch: "arm64",
- compile_multilib: "first",
- vendor: true,
- arch: {
- arm64: {
- src: "bin",
- },
- },
- }
-
- // different arch snapshot which has to be ignored
- vendor_snapshot_binary {
- name: "bin",
- version: "31",
- target_arch: "arm",
- compile_multilib: "first",
- vendor: true,
- arch: {
- arm64: {
- src: "bin",
- },
- },
- }
-`
- depsBp := GatherRequiredDepsForTest(android.Android)
-
- mockFS := map[string][]byte{
- "deps/Android.bp": []byte(depsBp),
- "framework/Android.bp": []byte(frameworkBp),
- "framework/symbol.txt": nil,
- "vendor/Android.bp": []byte(vendorProprietaryBp),
- "vendor/bin": nil,
- "vendor/override/bin": nil,
- "vendor/bin32": nil,
- "vendor/bin.cpp": nil,
- "vendor/client.cpp": nil,
- "vendor/include/libvndk/a.h": nil,
- "vendor/include/libvendor/b.h": nil,
- "vendor/include/libvendor_cfi/c.h": nil,
- "vendor/libc++_static.a": nil,
- "vendor/libc++demangle.a": nil,
- "vendor/libunwind.a": nil,
- "vendor/libvndk.a": nil,
- "vendor/libvendor.a": nil,
- "vendor/libvendor.cfi.a": nil,
- "vendor/libvendor.so": nil,
- "vendor/override/libvendor.so": nil,
- "vendor/lib32.a": nil,
- "vendor/lib32.so": nil,
- "vendor/lib64.a": nil,
- "vendor/lib64.so": nil,
- "vndk/Android.bp": []byte(vndkBp),
- "vndk/include/libvndk/a.h": nil,
- "vndk/libvndk.so": nil,
- "vndk/libllndk.so": nil,
- }
-
- config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("31")
- config.TestProductVariables.Platform_vndk_version = StringPtr("32")
- ctx := CreateTestContext(config)
- ctx.Register()
-
- _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "vendor/Android.bp", "vndk/Android.bp"})
- android.FailIfErrored(t, errs)
- _, errs = ctx.PrepareBuildActions(config)
- android.FailIfErrored(t, errs)
-
- sharedVariant := "android_vendor.31_arm64_armv8-a_shared"
- staticVariant := "android_vendor.31_arm64_armv8-a_static"
- binaryVariant := "android_vendor.31_arm64_armv8-a"
-
- sharedCfiVariant := "android_vendor.31_arm64_armv8-a_shared_cfi"
- staticCfiVariant := "android_vendor.31_arm64_armv8-a_static_cfi"
-
- shared32Variant := "android_vendor.31_arm_armv7-a-neon_shared"
- binary32Variant := "android_vendor.31_arm_armv7-a-neon"
-
- // libclient uses libvndk.vndk.31.arm64, libvendor.vendor_static.31.arm64, libvendor_without_snapshot
- libclientCcFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("cc").Args["cFlags"]
- for _, includeFlags := range []string{
- "-Ivndk/include/libvndk", // libvndk
- "-Ivendor/include/libvendor", // libvendor
- } {
- if !strings.Contains(libclientCcFlags, includeFlags) {
- t.Errorf("flags for libclient must contain %#v, but was %#v.",
- includeFlags, libclientCcFlags)
- }
- }
-
- libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("ld").Args["libFlags"]
- for _, input := range [][]string{
- []string{sharedVariant, "libvndk.vndk.31.arm64"},
- []string{sharedVariant, "libllndk.vndk.31.arm64"},
- []string{staticVariant, "libvendor.vendor_static.31.arm64"},
- []string{staticVariant, "libvendor_without_snapshot"},
- } {
- outputPaths := GetOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */)
- if !strings.Contains(libclientLdFlags, outputPaths[0].String()) {
- t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags)
- }
-
- }
-
- libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkSharedLibs
- if g, w := libclientAndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "libllndk.vendor", "lib64"}; !reflect.DeepEqual(g, w) {
- t.Errorf("wanted libclient AndroidMkSharedLibs %q, got %q", w, g)
- }
-
- libclientAndroidMkStaticLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkStaticLibs
- if g, w := libclientAndroidMkStaticLibs, []string{"libvendor", "libvendor_without_snapshot"}; !reflect.DeepEqual(g, w) {
- t.Errorf("wanted libclient AndroidMkStaticLibs %q, got %q", w, g)
- }
-
- libclient32AndroidMkSharedLibs := ctx.ModuleForTests("libclient", shared32Variant).Module().(*Module).Properties.AndroidMkSharedLibs
- if g, w := libclient32AndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "libllndk.vendor", "lib32"}; !reflect.DeepEqual(g, w) {
- t.Errorf("wanted libclient32 AndroidMkSharedLibs %q, got %q", w, g)
- }
-
- // libclient_cfi uses libvendor.vendor_static.31.arm64's cfi variant
- libclientCfiCcFlags := ctx.ModuleForTests("libclient_cfi", sharedCfiVariant).Rule("cc").Args["cFlags"]
- if !strings.Contains(libclientCfiCcFlags, "-Ivendor/include/libvendor_cfi") {
- t.Errorf("flags for libclient_cfi must contain %#v, but was %#v.",
- "-Ivendor/include/libvendor_cfi", libclientCfiCcFlags)
- }
-
- libclientCfiLdFlags := ctx.ModuleForTests("libclient_cfi", sharedCfiVariant).Rule("ld").Args["libFlags"]
- libvendorCfiOutputPaths := GetOutputPaths(ctx, staticCfiVariant, []string{"libvendor.vendor_static.31.arm64"})
- if !strings.Contains(libclientCfiLdFlags, libvendorCfiOutputPaths[0].String()) {
- t.Errorf("libflags for libclientCfi must contain %#v, but was %#v", libvendorCfiOutputPaths[0], libclientCfiLdFlags)
- }
-
- // bin_without_snapshot uses libvndk.vendor_static.31.arm64 (which reexports vndk's exported headers)
- binWithoutSnapshotCcFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("cc").Args["cFlags"]
- if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivndk/include/libvndk") {
- t.Errorf("flags for bin_without_snapshot must contain %#v, but was %#v.",
- "-Ivendor/include/libvndk", binWithoutSnapshotCcFlags)
- }
-
- binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("ld").Args["libFlags"]
- libVndkStaticOutputPaths := GetOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.31.arm64"})
- if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
- t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
- libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags)
- }
-
- // libvendor.so is installed by libvendor.vendor_shared.31.arm64
- ctx.ModuleForTests("libvendor.vendor_shared.31.arm64", sharedVariant).Output("libvendor.so")
-
- // lib64.so is installed by lib64.vendor_shared.31.arm64
- ctx.ModuleForTests("lib64.vendor_shared.31.arm64", sharedVariant).Output("lib64.so")
-
- // lib32.so is installed by lib32.vendor_shared.31.arm64
- ctx.ModuleForTests("lib32.vendor_shared.31.arm64", shared32Variant).Output("lib32.so")
-
- // libvendor_available.so is installed by libvendor_available.vendor_shared.31.arm64
- ctx.ModuleForTests("libvendor_available.vendor_shared.31.arm64", sharedVariant).Output("libvendor_available.so")
-
- // libvendor_without_snapshot.so is installed by libvendor_without_snapshot
- ctx.ModuleForTests("libvendor_without_snapshot", sharedVariant).Output("libvendor_without_snapshot.so")
-
- // bin is installed by bin.vendor_binary.31.arm64
- bin64Module := ctx.ModuleForTests("bin.vendor_binary.31.arm64", binaryVariant)
- bin64Module.Output("bin")
-
- // also test symlinks
- bin64MkEntries := android.AndroidMkEntriesForTest(t, ctx, bin64Module.Module())
- bin64KatiSymlinks := bin64MkEntries[0].EntryMap["LOCAL_SOONG_INSTALL_SYMLINKS"]
-
- // Either AndroidMk entries contain symlinks, or symlinks should be installed by Soong
- for _, symlink := range []string{"binfoo", "binbar"} {
- if inList(symlink, bin64KatiSymlinks) {
- continue
- }
-
- bin64Module.Output(symlink)
- }
-
- // bin32 is installed by bin32.vendor_binary.31.arm64
- ctx.ModuleForTests("bin32.vendor_binary.31.arm64", binary32Variant).Output("bin32")
-
- // bin_without_snapshot is installed by bin_without_snapshot
- ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot")
-
- // libvendor, libvendor_available and bin don't have vendor.31 variant
- libvendorVariants := ctx.ModuleVariantsForTests("libvendor")
- if inList(sharedVariant, libvendorVariants) {
- t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant)
- }
-
- libvendorAvailableVariants := ctx.ModuleVariantsForTests("libvendor_available")
- if inList(sharedVariant, libvendorAvailableVariants) {
- t.Errorf("libvendor_available must not have variant %#v, but it does", sharedVariant)
- }
-
- binVariants := ctx.ModuleVariantsForTests("bin")
- if inList(binaryVariant, binVariants) {
- t.Errorf("bin must not have variant %#v, but it does", sharedVariant)
- }
-
- // test overrides property
- binOverrideModule := ctx.ModuleForTests("bin_override.vendor_binary.31.arm64", binaryVariant)
- binOverrideModule.Output("bin")
- binOverrideMkEntries := android.AndroidMkEntriesForTest(t, ctx, binOverrideModule.Module())
- binOverrideEntry := binOverrideMkEntries[0].EntryMap["LOCAL_OVERRIDES_MODULES"]
- if !inList("bin", binOverrideEntry) {
- t.Errorf("bin_override must override bin but was %q\n", binOverrideEntry)
- }
-
- libvendorOverrideModule := ctx.ModuleForTests("libvendor_override.vendor_shared.31.arm64", sharedVariant)
- libvendorOverrideModule.Output("libvendor.so")
- libvendorOverrideMkEntries := android.AndroidMkEntriesForTest(t, ctx, libvendorOverrideModule.Module())
- libvendorOverrideEntry := libvendorOverrideMkEntries[0].EntryMap["LOCAL_OVERRIDES_MODULES"]
- if !inList("libvendor", libvendorOverrideEntry) {
- t.Errorf("libvendor_override must override libvendor but was %q\n", libvendorOverrideEntry)
- }
-}
-
-func TestVendorSnapshotSanitizer(t *testing.T) {
- bp := `
- vendor_snapshot {
- name: "vendor_snapshot",
- version: "28",
- arch: {
- arm64: {
- static_libs: [
- "libsnapshot",
- "note_memtag_heap_sync",
- ],
- objects: [
- "snapshot_object",
- ],
- vndk_libs: [
- "libclang_rt.hwasan",
- ],
- },
- },
- }
-
- vendor_snapshot_static {
- name: "libsnapshot",
- vendor: true,
- target_arch: "arm64",
- version: "28",
- arch: {
- arm64: {
- src: "libsnapshot.a",
- cfi: {
- src: "libsnapshot.cfi.a",
- },
- hwasan: {
- src: "libsnapshot.hwasan.a",
- },
- },
- },
- }
-
- vendor_snapshot_static {
- name: "note_memtag_heap_sync",
- vendor: true,
- target_arch: "arm64",
- version: "28",
- arch: {
- arm64: {
- src: "note_memtag_heap_sync.a",
- },
- },
- }
-
- vndk_prebuilt_shared {
- name: "libclang_rt.hwasan",
- version: "28",
- target_arch: "arm64",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- arch: {
- arm64: {
- srcs: ["libclang_rt.hwasan.so"],
- },
- },
- }
-
- vendor_snapshot_object {
- name: "snapshot_object",
- vendor: true,
- target_arch: "arm64",
- version: "28",
- arch: {
- arm64: {
- src: "snapshot_object.o",
- },
- },
- stl: "none",
- }
-
- cc_test {
- name: "vstest",
- gtest: false,
- vendor: true,
- compile_multilib: "64",
- nocrt: true,
- no_libcrt: true,
- stl: "none",
- static_libs: ["libsnapshot"],
- system_shared_libs: [],
- }
-`
-
- mockFS := map[string][]byte{
- "vendor/Android.bp": []byte(bp),
- "vendor/libc++demangle.a": nil,
- "vendor/libclang_rt.hwasan.so": nil,
- "vendor/libsnapshot.a": nil,
- "vendor/libsnapshot.cfi.a": nil,
- "vendor/libsnapshot.hwasan.a": nil,
- "vendor/note_memtag_heap_sync.a": nil,
- "vendor/snapshot_object.o": nil,
- }
-
- config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("28")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- config.TestProductVariables.SanitizeDevice = []string{"hwaddress"}
- ctx := testCcWithConfig(t, config)
-
- // Check non-cfi, cfi and hwasan variant.
- staticVariant := "android_vendor.28_arm64_armv8-a_static"
- staticCfiVariant := "android_vendor.28_arm64_armv8-a_static_cfi"
- staticHwasanVariant := "android_vendor.28_arm64_armv8-a_static_hwasan"
- staticHwasanCfiVariant := "android_vendor.28_arm64_armv8-a_static_hwasan_cfi"
-
- staticModule := ctx.ModuleForTests("libsnapshot.vendor_static.28.arm64", staticVariant).Module().(*Module)
- assertString(t, staticModule.outputFile.Path().Base(), "libsnapshot.a")
-
- staticCfiModule := ctx.ModuleForTests("libsnapshot.vendor_static.28.arm64", staticCfiVariant).Module().(*Module)
- assertString(t, staticCfiModule.outputFile.Path().Base(), "libsnapshot.cfi.a")
-
- staticHwasanModule := ctx.ModuleForTests("libsnapshot.vendor_static.28.arm64", staticHwasanVariant).Module().(*Module)
- assertString(t, staticHwasanModule.outputFile.Path().Base(), "libsnapshot.hwasan.a")
-
- staticHwasanCfiModule := ctx.ModuleForTests("libsnapshot.vendor_static.28.arm64", staticHwasanCfiVariant).Module().(*Module)
- if !staticHwasanCfiModule.HiddenFromMake() || !staticHwasanCfiModule.PreventInstall() {
- t.Errorf("Hwasan and Cfi cannot enabled at the same time.")
- }
-
- snapshotObjModule := ctx.ModuleForTests("snapshot_object.vendor_object.28.arm64", "android_vendor.28_arm64_armv8-a").Module()
- snapshotObjMkEntries := android.AndroidMkEntriesForTest(t, ctx, snapshotObjModule)
- // snapshot object must not add ".hwasan" suffix
- assertString(t, snapshotObjMkEntries[0].EntryMap["LOCAL_MODULE"][0], "snapshot_object")
-}
-
-func TestVendorSnapshotExclude(t *testing.T) {
-
- // This test verifies that the exclude_from_vendor_snapshot property
- // makes its way from the Android.bp source file into the module data
- // structure. It also verifies that modules are correctly included or
- // excluded in the vendor snapshot based on their path (framework or
- // vendor) and the exclude_from_vendor_snapshot property.
-
- frameworkBp := `
- cc_library_shared {
- name: "libinclude",
- srcs: ["src/include.cpp"],
- vendor_available: true,
- }
- cc_library_shared {
- name: "libexclude",
- srcs: ["src/exclude.cpp"],
- vendor: true,
- exclude_from_vendor_snapshot: true,
- }
- cc_library_shared {
- name: "libavailable_exclude",
- srcs: ["src/exclude.cpp"],
- vendor_available: true,
- exclude_from_vendor_snapshot: true,
- }
- `
-
- vendorProprietaryBp := `
- cc_library_shared {
- name: "libvendor",
- srcs: ["vendor.cpp"],
- vendor: true,
- }
- `
-
- depsBp := GatherRequiredDepsForTest(android.Android)
-
- mockFS := map[string][]byte{
- "deps/Android.bp": []byte(depsBp),
- "framework/Android.bp": []byte(frameworkBp),
- "framework/include.cpp": nil,
- "framework/exclude.cpp": nil,
- "device/Android.bp": []byte(vendorProprietaryBp),
- "device/vendor.cpp": nil,
- }
-
- config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- ctx := CreateTestContext(config)
- ctx.Register()
-
- _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"})
- android.FailIfErrored(t, errs)
- _, errs = ctx.PrepareBuildActions(config)
- android.FailIfErrored(t, errs)
-
- // Test an include and exclude framework module.
- AssertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false, vendorVariant)
- AssertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true, vendorVariant)
- AssertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true, vendorVariant)
-
- // A vendor module is excluded, but by its path, not the
- // exclude_from_vendor_snapshot property.
- AssertExcludeFromVendorSnapshotIs(t, ctx, "libvendor", false, vendorVariant)
-
- // Verify the content of the vendor snapshot.
-
- snapshotDir := "vendor-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
-
- var includeJsonFiles []string
- var excludeJsonFiles []string
-
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- []string{"arm", "armv7-a-neon"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
-
- // Included modules
- CheckSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
-
- // Excluded modules
- CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
- CheckSnapshotExclude(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
- CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
- }
-
- // Verify that each json file for an included module has a rule.
- for _, jsonFile := range includeJsonFiles {
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("include json file %q not found", jsonFile)
- }
- }
-
- // Verify that each json file for an excluded module has no rule.
- for _, jsonFile := range excludeJsonFiles {
- if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
- t.Errorf("exclude json file %q found", jsonFile)
- }
- }
-}
-
-func TestVendorSnapshotExcludeInVendorProprietaryPathErrors(t *testing.T) {
-
- // This test verifies that using the exclude_from_vendor_snapshot
- // property on a module in a vendor proprietary path generates an
- // error. These modules are already excluded, so we prohibit using the
- // property in this way, which could add to confusion.
-
- vendorProprietaryBp := `
- cc_library_shared {
- name: "libvendor",
- srcs: ["vendor.cpp"],
- vendor: true,
- exclude_from_vendor_snapshot: true,
- }
- `
-
- depsBp := GatherRequiredDepsForTest(android.Android)
-
- mockFS := map[string][]byte{
- "deps/Android.bp": []byte(depsBp),
- "device/Android.bp": []byte(vendorProprietaryBp),
- "device/vendor.cpp": nil,
- }
-
- config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- ctx := CreateTestContext(config)
- ctx.Register()
-
- _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "device/Android.bp"})
- android.FailIfErrored(t, errs)
-
- _, errs = ctx.PrepareBuildActions(config)
- android.CheckErrorsAgainstExpectations(t, errs, []string{
- `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
- `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
- `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
- `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
- `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
- `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
- })
-}
-
-func TestRecoverySnapshotCapture(t *testing.T) {
- bp := `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- recovery_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "librecovery",
- recovery: true,
- nocrt: true,
- }
-
- cc_library {
- name: "librecovery_available",
- recovery_available: true,
- nocrt: true,
- }
-
- cc_library_headers {
- name: "librecovery_headers",
- recovery_available: true,
- nocrt: true,
- }
-
- cc_binary {
- name: "recovery_bin",
- recovery: true,
- nocrt: true,
- }
-
- cc_binary {
- name: "recovery_available_bin",
- recovery_available: true,
- nocrt: true,
- }
-
- cc_prebuilt_library_static {
- name: "libb",
- recovery_available: true,
- srcs: ["libb.a"],
- nocrt: true,
- no_libcrt: true,
- stl: "none",
- }
-
- cc_object {
- name: "obj",
- recovery_available: true,
- }
-`
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- ctx := testCcWithConfig(t, config)
-
- // Check Recovery snapshot output.
-
- snapshotDir := "recovery-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
-
- var jsonFiles []string
-
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- // For shared libraries, only recovery_available modules are captured.
- sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
- CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", sharedDir, sharedVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(sharedDir, "libvndk.so.json"),
- filepath.Join(sharedDir, "librecovery.so.json"),
- filepath.Join(sharedDir, "librecovery_available.so.json"))
-
- // For static libraries, all recovery:true and recovery_available modules are captured.
- staticVariant := fmt.Sprintf("android_recovery_%s_%s_static", archType, archVariant)
- staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
- CheckSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(staticDir, "libb.a.json"),
- filepath.Join(staticDir, "librecovery.a.json"),
- filepath.Join(staticDir, "librecovery_available.a.json"))
-
- // For binary executables, all recovery:true and recovery_available modules are captured.
- if archType == "arm64" {
- binaryVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
- binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
- CheckSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(binaryDir, "recovery_bin.json"),
- filepath.Join(binaryDir, "recovery_available_bin.json"))
- }
-
- // For header libraries, all vendor:true and vendor_available modules are captured.
- headerDir := filepath.Join(snapshotVariantPath, archDir, "header")
- jsonFiles = append(jsonFiles, filepath.Join(headerDir, "librecovery_headers.json"))
-
- // For object modules, all vendor:true and vendor_available modules are captured.
- objectVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
- objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
- CheckSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
- jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
- }
-
- for _, jsonFile := range jsonFiles {
- // verify all json files exist
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("%q expected but not found", jsonFile)
- }
- }
-}
-
-func TestRecoverySnapshotExclude(t *testing.T) {
- // This test verifies that the exclude_from_recovery_snapshot property
- // makes its way from the Android.bp source file into the module data
- // structure. It also verifies that modules are correctly included or
- // excluded in the recovery snapshot based on their path (framework or
- // vendor) and the exclude_from_recovery_snapshot property.
-
- frameworkBp := `
- cc_library_shared {
- name: "libinclude",
- srcs: ["src/include.cpp"],
- recovery_available: true,
- }
- cc_library_shared {
- name: "libexclude",
- srcs: ["src/exclude.cpp"],
- recovery: true,
- exclude_from_recovery_snapshot: true,
- }
- cc_library_shared {
- name: "libavailable_exclude",
- srcs: ["src/exclude.cpp"],
- recovery_available: true,
- exclude_from_recovery_snapshot: true,
- }
- `
-
- vendorProprietaryBp := `
- cc_library_shared {
- name: "librecovery",
- srcs: ["recovery.cpp"],
- recovery: true,
- }
- `
-
- depsBp := GatherRequiredDepsForTest(android.Android)
-
- mockFS := map[string][]byte{
- "deps/Android.bp": []byte(depsBp),
- "framework/Android.bp": []byte(frameworkBp),
- "framework/include.cpp": nil,
- "framework/exclude.cpp": nil,
- "device/Android.bp": []byte(vendorProprietaryBp),
- "device/recovery.cpp": nil,
- }
-
- config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS)
- config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- ctx := CreateTestContext(config)
- ctx.Register()
-
- _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"})
- android.FailIfErrored(t, errs)
- _, errs = ctx.PrepareBuildActions(config)
- android.FailIfErrored(t, errs)
-
- // Test an include and exclude framework module.
- AssertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude", false, recoveryVariant)
- AssertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude", true, recoveryVariant)
- AssertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude", true, recoveryVariant)
-
- // A recovery module is excluded, but by its path, not the
- // exclude_from_recovery_snapshot property.
- AssertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery", false, recoveryVariant)
-
- // Verify the content of the recovery snapshot.
-
- snapshotDir := "recovery-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
-
- var includeJsonFiles []string
- var excludeJsonFiles []string
-
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
-
- // Included modules
- CheckSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
-
- // Excluded modules
- CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
- CheckSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
- CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
- }
-
- // Verify that each json file for an included module has a rule.
- for _, jsonFile := range includeJsonFiles {
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("include json file %q not found", jsonFile)
- }
- }
-
- // Verify that each json file for an excluded module has no rule.
- for _, jsonFile := range excludeJsonFiles {
- if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
- t.Errorf("exclude json file %q found", jsonFile)
- }
- }
-}
-
-func TestRecoverySnapshotDirected(t *testing.T) {
- bp := `
- cc_library_shared {
- name: "librecovery",
- recovery: true,
- nocrt: true,
- }
-
- cc_library_shared {
- name: "librecovery_available",
- recovery_available: true,
- nocrt: true,
- }
-
- genrule {
- name: "libfoo_gen",
- cmd: "",
- out: ["libfoo.so"],
- }
-
- cc_prebuilt_library_shared {
- name: "libfoo",
- recovery: true,
- prefer: true,
- srcs: [":libfoo_gen"],
- }
-
- cc_library_shared {
- name: "libfoo",
- recovery: true,
- nocrt: true,
- }
-`
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- config.TestProductVariables.DirectedRecoverySnapshot = true
- config.TestProductVariables.RecoverySnapshotModules = make(map[string]bool)
- config.TestProductVariables.RecoverySnapshotModules["librecovery"] = true
- config.TestProductVariables.RecoverySnapshotModules["libfoo"] = true
- ctx := testCcWithConfig(t, config)
-
- // Check recovery snapshot output.
-
- snapshotDir := "recovery-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
-
- var includeJsonFiles []string
-
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
-
- // Included modules
- CheckSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
- // Check that snapshot captures "prefer: true" prebuilt
- CheckSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json"))
-
- // Excluded modules. Modules not included in the directed recovery snapshot
- // are still include as fake modules.
- CheckSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery_available.so.json"))
- }
-
- // Verify that each json file for an included module has a rule.
- for _, jsonFile := range includeJsonFiles {
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("include json file %q not found", jsonFile)
- }
- }
-}
-
-func TestSnapshotInRelativeInstallPath(t *testing.T) {
- bp := `
- cc_library {
- name: "libvendor_available",
- vendor_available: true,
- nocrt: true,
- }
-
- cc_library {
- name: "libvendor_available_var",
- vendor_available: true,
- stem: "libvendor_available",
- relative_install_path: "var",
- nocrt: true,
- }
-`
-
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
- ctx := testCcWithConfig(t, config)
-
- // Check Vendor snapshot output.
-
- snapshotDir := "vendor-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
-
- var jsonFiles []string
-
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- []string{"arm", "armv7-a-neon"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- // For shared libraries, only non-VNDK vendor_available modules are captured
- sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
- sharedDirVar := filepath.Join(sharedDir, "var")
- CheckSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
- CheckSnapshot(t, ctx, snapshotSingleton, "libvendor_available_var", "libvendor_available.so", sharedDirVar, sharedVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(sharedDir, "libvendor_available.so.json"),
- filepath.Join(sharedDirVar, "libvendor_available.so.json"))
- }
-
- for _, jsonFile := range jsonFiles {
- // verify all json files exist
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("%q expected but not found", jsonFile)
- }
- }
-
- // fake snapshot should have all outputs in the normal snapshot.
- fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot")
- for _, output := range snapshotSingleton.AllOutputs() {
- fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1)
- if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil {
- t.Errorf("%q expected but not found", fakeOutput)
- }
- }
-}
diff --git a/cc/vndk.go b/cc/vndk.go
index 2b2ea64..14b44b6 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -15,17 +15,13 @@
package cc
import (
- "encoding/json"
"errors"
"fmt"
- "path/filepath"
- "sort"
"strings"
"android/soong/android"
"android/soong/cc/config"
"android/soong/etc"
- "android/soong/snapshot"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -42,28 +38,6 @@
)
func VndkLibrariesTxtModules(vndkVersion string, ctx android.BaseModuleContext) []string {
- // Return the list of vndk txt files for the vndk apex of the vndkVersion.
- if vndkVersion == "current" {
- // We can assume all txt files are snapshotted if we find one of them.
- currentVndkSnapshotted := ctx.OtherModuleExists(insertVndkVersion(llndkLibrariesTxt, ctx.DeviceConfig().PlatformVndkVersion()))
- if currentVndkSnapshotted {
- // If the current VNDK is already snapshotted (which can happen with
- // the `next` config), use the prebuilt txt files in the snapshot.
- // This is because the txt files built from source are probably be
- // for the in-development version.
- vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
- } else {
- // Use the txt files generated from the source
- return []string{
- llndkLibrariesTxtForApex,
- vndkCoreLibrariesTxt,
- vndkSpLibrariesTxt,
- vndkPrivateLibrariesTxt,
- vndkProductLibrariesTxt,
- }
- }
- }
-
// Snapshot vndks have their own *.libraries.VER.txt files.
// Note that snapshots don't have "vndkcorevariant.libraries.VER.txt"
result := []string{
@@ -376,15 +350,6 @@
if !p.MatchesWithDevice(mctx.DeviceConfig()) {
return false
}
-
- platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
- if platformVndkVersion != "" {
- // ignore prebuilt vndk modules that are newer than or equal to the platform vndk version
- platformVndkApiLevel := android.ApiLevelOrPanic(mctx, platformVndkVersion)
- if platformVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, p.Version())) {
- return false
- }
- }
}
if lib, ok := m.linker.(libraryInterface); ok {
@@ -392,8 +357,7 @@
if lib.buildStubs() {
return false
}
- useCoreVariant := m.VndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
- mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant()
+ useCoreVariant := mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant()
return lib.shared() && m.InVendor() && m.IsVndk() && !m.IsVndkExt() && !useCoreVariant
}
return false
@@ -437,7 +401,6 @@
func init() {
RegisterVndkLibraryTxtTypes(android.InitRegistrationContext)
- android.RegisterParallelSingletonType("vndk-snapshot", VndkSnapshotSingleton)
}
func RegisterVndkLibraryTxtTypes(ctx android.RegistrationContext) {
@@ -548,22 +511,9 @@
return filename
}
-func (txt *vndkLibrariesTxt) DepsMutator(mctx android.BottomUpMutatorContext) {
- versionedName := insertVndkVersion(txt.Name(), mctx.DeviceConfig().PlatformVndkVersion())
- if mctx.OtherModuleExists(versionedName) {
- // If the prebuilt vndk libraries txt files exist, install them instead.
- txt.HideFromMake()
- mctx.AddDependency(txt, nil, versionedName)
- }
-}
-
func (txt *vndkLibrariesTxt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
filename := proptools.StringDefault(txt.properties.Stem, txt.Name())
- if Bool(txt.properties.Insert_vndk_version) {
- filename = insertVndkVersion(filename, ctx.DeviceConfig().PlatformVndkVersion())
- }
-
txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath
installPath := android.PathForModuleInstall(ctx, "etc")
@@ -627,280 +577,6 @@
func (txt *vndkLibrariesTxt) OutputFiles(tag string) (android.Paths, error) {
return android.Paths{txt.outputFile}, nil
}
-
-func VndkSnapshotSingleton() android.Singleton {
- return &vndkSnapshotSingleton{}
-}
-
-type vndkSnapshotSingleton struct {
- vndkLibrariesFile android.OutputPath
- vndkSnapshotZipFile android.OptionalPath
-}
-
-func isVndkSnapshotAware(config android.DeviceConfig, m LinkableInterface,
- apexInfo android.ApexInfo) (vndkType string, isVndkSnapshotLib bool) {
-
- if m.Target().NativeBridge == android.NativeBridgeEnabled {
- return "", false
- }
- // !inVendor: There's product/vendor variants for VNDK libs. We only care about vendor variants.
- // !installable: Snapshot only cares about "installable" modules.
- // !m.IsLlndk: llndk stubs are required for building against snapshots.
- // IsSnapshotPrebuilt: Snapshotting a snapshot doesn't make sense.
- // !outputFile.Valid: Snapshot requires valid output file.
- if !m.InVendor() || (!installable(m, apexInfo) && !m.IsLlndk()) || m.IsSnapshotPrebuilt() || !m.OutputFile().Valid() {
- return "", false
- }
- if !m.IsSnapshotLibrary() || !m.Shared() {
- return "", false
- }
- if m.VndkVersion() == config.PlatformVndkVersion() {
- if m.IsVndk() && !m.IsVndkExt() {
- if m.IsVndkSp() {
- return "vndk-sp", true
- } else {
- return "vndk-core", true
- }
- } else if m.HasLlndkStubs() && m.StubsVersion() == "" {
- // Use default version for the snapshot.
- return "llndk-stub", true
- }
- }
-
- return "", false
-}
-
-func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
- // build these files even if PlatformVndkVersion or BoardVndkVersion is not set
- c.buildVndkLibrariesTxtFiles(ctx)
-
- // BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot.
- if ctx.DeviceConfig().VndkVersion() != "current" {
- return
- }
-
- if ctx.DeviceConfig().PlatformVndkVersion() == "" {
- return
- }
-
- var snapshotOutputs android.Paths
-
- /*
- VNDK snapshot zipped artifacts directory structure:
- {SNAPSHOT_ARCH}/
- arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
- shared/
- vndk-core/
- (VNDK-core libraries, e.g. libbinder.so)
- vndk-sp/
- (VNDK-SP libraries, e.g. libc++.so)
- llndk-stub/
- (LLNDK stub libraries)
- arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
- shared/
- vndk-core/
- (VNDK-core libraries, e.g. libbinder.so)
- vndk-sp/
- (VNDK-SP libraries, e.g. libc++.so)
- llndk-stub/
- (LLNDK stub libraries)
- binder32/
- (This directory is newly introduced in v28 (Android P) to hold
- prebuilts built for 32-bit binder interface.)
- arch-{TARGET_ARCH}-{TARGE_ARCH_VARIANT}/
- ...
- configs/
- (various *.txt configuration files)
- include/
- (header files of same directory structure with source tree)
- NOTICE_FILES/
- (notice files of libraries, e.g. libcutils.so.txt)
- */
-
- snapshotDir := "vndk-snapshot"
- snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
-
- configsDir := filepath.Join(snapshotArchDir, "configs")
- noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
- includeDir := filepath.Join(snapshotArchDir, "include")
-
- // set of notice files copied.
- noticeBuilt := make(map[string]bool)
-
- // paths of VNDK modules for GPL license checking
- modulePaths := make(map[string]string)
-
- // actual module names of .so files
- // e.g. moduleNames["libprotobuf-cpp-full-3.9.1.so"] = "libprotobuf-cpp-full"
- moduleNames := make(map[string]string)
-
- var headers android.Paths
-
- // installVndkSnapshotLib copies built .so file from the module.
- // Also, if the build artifacts is on, write a json file which contains all exported flags
- // with FlagExporterInfo.
- installVndkSnapshotLib := func(m *Module, vndkType string) (android.Paths, bool) {
- var ret android.Paths
-
- targetArch := "arch-" + m.Target().Arch.ArchType.String()
- if m.Target().Arch.ArchVariant != "" {
- targetArch += "-" + m.Target().Arch.ArchVariant
- }
-
- libPath := m.outputFile.Path()
- snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "shared", vndkType, libPath.Base())
- ret = append(ret, snapshot.CopyFileRule(pctx, ctx, libPath, snapshotLibOut))
-
- // json struct to export snapshot information
- prop := struct {
- MinSdkVersion string `json:",omitempty"`
- LicenseKinds []string `json:",omitempty"`
- LicenseTexts []string `json:",omitempty"`
- ExportedDirs []string `json:",omitempty"`
- ExportedSystemDirs []string `json:",omitempty"`
- ExportedFlags []string `json:",omitempty"`
- RelativeInstallPath string `json:",omitempty"`
- }{}
-
- prop.LicenseKinds = m.EffectiveLicenseKinds()
- prop.LicenseTexts = m.EffectiveLicenseFiles().Strings()
- prop.MinSdkVersion = m.MinSdkVersion()
-
- if ctx.Config().VndkSnapshotBuildArtifacts() {
- exportedInfo, _ := android.SingletonModuleProvider(ctx, m, FlagExporterInfoProvider)
- prop.ExportedFlags = exportedInfo.Flags
- prop.ExportedDirs = exportedInfo.IncludeDirs.Strings()
- prop.ExportedSystemDirs = exportedInfo.SystemIncludeDirs.Strings()
- prop.RelativeInstallPath = m.RelativeInstallPath()
- }
-
- propOut := snapshotLibOut + ".json"
-
- j, err := json.Marshal(prop)
- if err != nil {
- ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
- return nil, false
- }
- ret = append(ret, snapshot.WriteStringToFileRule(ctx, string(j), propOut))
-
- return ret, true
- }
-
- ctx.VisitAllModules(func(module android.Module) {
- m, ok := module.(*Module)
- if !ok || !m.Enabled() {
- return
- }
-
- apexInfo, _ := android.SingletonModuleProvider(ctx, module, android.ApexInfoProvider)
-
- vndkType, ok := isVndkSnapshotAware(ctx.DeviceConfig(), m, apexInfo)
- if !ok {
- return
- }
-
- // For all snapshot candidates, the followings are captured.
- // - .so files
- // - notice files
- //
- // The followings are also captured if VNDK_SNAPSHOT_BUILD_ARTIFACTS.
- // - .json files containing exported flags
- // - exported headers from collectHeadersForSnapshot()
- //
- // Headers are deduplicated after visiting all modules.
-
- // install .so files for appropriate modules.
- // Also install .json files if VNDK_SNAPSHOT_BUILD_ARTIFACTS
- libs, ok := installVndkSnapshotLib(m, vndkType)
- if !ok {
- return
- }
- snapshotOutputs = append(snapshotOutputs, libs...)
-
- // These are for generating module_names.txt and module_paths.txt
- stem := m.outputFile.Path().Base()
- moduleNames[stem] = ctx.ModuleName(m)
- modulePaths[stem] = ctx.ModuleDir(m)
-
- for _, notice := range m.EffectiveLicenseFiles() {
- if _, ok := noticeBuilt[notice.String()]; !ok {
- noticeBuilt[notice.String()] = true
- snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule(
- pctx, ctx, notice, filepath.Join(noticeDir, notice.String())))
- }
- }
-
- if ctx.Config().VndkSnapshotBuildArtifacts() {
- headers = append(headers, m.SnapshotHeaders()...)
- }
- })
-
- // install all headers after removing duplicates
- for _, header := range android.FirstUniquePaths(headers) {
- snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule(
- pctx, ctx, header, filepath.Join(includeDir, header.String())))
- }
-
- // install *.libraries.txt except vndkcorevariant.libraries.txt
- ctx.VisitAllModules(func(module android.Module) {
- m, ok := module.(*vndkLibrariesTxt)
- if !ok || !m.Enabled() || m.Name() == vndkUsingCoreVariantLibrariesTxt {
- return
- }
- snapshotOutputs = append(snapshotOutputs, snapshot.CopyFileRule(
- pctx, ctx, m.OutputFile(), filepath.Join(configsDir, m.Name())))
- })
-
- /*
- module_paths.txt contains paths on which VNDK modules are defined.
- e.g.,
- libbase.so system/libbase
- libc.so bionic/libc
- ...
- */
- snapshotOutputs = append(snapshotOutputs, installMapListFileRule(ctx, modulePaths, filepath.Join(configsDir, "module_paths.txt")))
-
- /*
- module_names.txt contains names as which VNDK modules are defined,
- because output filename and module name can be different with stem and suffix properties.
-
- e.g.,
- libcutils.so libcutils
- libprotobuf-cpp-full-3.9.2.so libprotobuf-cpp-full
- ...
- */
- snapshotOutputs = append(snapshotOutputs, installMapListFileRule(ctx, moduleNames, filepath.Join(configsDir, "module_names.txt")))
-
- // All artifacts are ready. Sort them to normalize ninja and then zip.
- sort.Slice(snapshotOutputs, func(i, j int) bool {
- return snapshotOutputs[i].String() < snapshotOutputs[j].String()
- })
-
- zipPath := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+".zip")
- zipRule := android.NewRuleBuilder(pctx, ctx)
-
- // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
- snapshotOutputList := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+"_list")
- rspFile := snapshotOutputList.ReplaceExtension(ctx, "rsp")
- zipRule.Command().
- Text("tr").
- FlagWithArg("-d ", "\\'").
- FlagWithRspFileInputList("< ", rspFile, snapshotOutputs).
- FlagWithOutput("> ", snapshotOutputList)
-
- zipRule.Temporary(snapshotOutputList)
-
- zipRule.Command().
- BuiltTool("soong_zip").
- FlagWithOutput("-o ", zipPath).
- FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
- FlagWithInput("-l ", snapshotOutputList)
-
- zipRule.Build(zipPath.String(), "vndk snapshot "+zipPath.String())
- zipRule.DeleteTemporaryFiles()
- c.vndkSnapshotZipFile = android.OptionalPathForPath(zipPath)
-}
-
func getVndkFileName(m *Module) (string, error) {
if library, ok := m.linker.(*libraryDecorator); ok {
return library.getLibNameHelper(m.BaseModuleName(), true, false) + ".so", nil
@@ -910,43 +586,3 @@
}
return "", fmt.Errorf("VNDK library should have libraryDecorator or prebuiltLibraryLinker as linker: %T", m.linker)
}
-
-func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.SingletonContext) {
- // Build list of vndk libs as merged & tagged & filter-out(libclang_rt):
- // Since each target have different set of libclang_rt.* files,
- // keep the common set of files in vndk.libraries.txt
- _, llndk := vndkModuleListRemover(llndkLibraries, "libclang_rt.")(ctx)
- _, vndkcore := vndkModuleListRemover(vndkCoreLibraries, "libclang_rt.")(ctx)
- _, vndksp := vndkSPLibraries(ctx)
- _, vndkprivate := vndkPrivateLibraries(ctx)
- _, vndkproduct := vndkModuleListRemover(vndkProductLibraries, "libclang_rt.")(ctx)
- var merged []string
- merged = append(merged, addPrefix(llndk, "LLNDK: ")...)
- merged = append(merged, addPrefix(vndksp, "VNDK-SP: ")...)
- merged = append(merged, addPrefix(vndkcore, "VNDK-core: ")...)
- merged = append(merged, addPrefix(vndkprivate, "VNDK-private: ")...)
- merged = append(merged, addPrefix(vndkproduct, "VNDK-product: ")...)
- c.vndkLibrariesFile = android.PathForOutput(ctx, "vndk", "vndk.libraries.txt")
- android.WriteFileRule(ctx, c.vndkLibrariesFile, strings.Join(merged, "\n"))
-}
-
-func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
- // Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to avoid installing libraries on /system if
- // they been moved to an apex.
- movedToApexLlndkLibraries := make(map[string]bool)
- ctx.VisitAllModules(func(module android.Module) {
- if library := moduleLibraryInterface(module); library != nil && library.hasLLNDKStubs() {
- // Skip bionic libs, they are handled in different manner
- name := library.implementationModuleName(module.(*Module).BaseModuleName())
- if module.(android.ApexModule).DirectlyInAnyApex() && !isBionic(name) {
- movedToApexLlndkLibraries[name] = true
- }
- }
- })
-
- ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES",
- strings.Join(android.SortedKeys(movedToApexLlndkLibraries), " "))
-
- ctx.Strict("VNDK_LIBRARIES_FILE", c.vndkLibrariesFile.String())
- ctx.Strict("SOONG_VNDK_SNAPSHOT_ZIP", c.vndkSnapshotZipFile.String())
-}
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index 43030b8..4d2412f 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -131,16 +131,6 @@
func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path {
- platformVndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
- if platformVndkVersion != "" {
- platformVndkApiLevel := android.ApiLevelOrPanic(ctx, platformVndkVersion)
- if platformVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(ctx, p.Version())) {
- // This prebuilt VNDK module is not required for the current build
- ctx.Module().HideFromMake()
- return nil
- }
- }
-
if !p.MatchesWithDevice(ctx.DeviceConfig()) {
ctx.Module().HideFromMake()
return nil
@@ -169,11 +159,6 @@
p.androidMkSuffix = p.NameSuffix()
- vndkVersion := ctx.DeviceConfig().VndkVersion()
- if vndkVersion == p.Version() {
- p.androidMkSuffix = ""
- }
-
android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{
SharedLibrary: in,
Target: ctx.Target(),
diff --git a/cmd/release_config/build_flag/Android.bp b/cmd/release_config/build_flag/Android.bp
new file mode 100644
index 0000000..0f10c91
--- /dev/null
+++ b/cmd/release_config/build_flag/Android.bp
@@ -0,0 +1,32 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+blueprint_go_binary {
+ name: "build-flag",
+ deps: [
+ "golang-protobuf-encoding-prototext",
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ "soong-cmd-release_config-proto",
+ "soong-cmd-release_config-lib",
+ ],
+ srcs: [
+ "main.go",
+ ],
+}
+
+bootstrap_go_package {
+ name: "soong-cmd-release_config-build_flag",
+ pkgPath: "android/soong/cmd/release_config/build_flag",
+ deps: [
+ "golang-protobuf-encoding-prototext",
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ "soong-cmd-release_config-proto",
+ "soong-cmd-release_config-lib",
+ ],
+ srcs: [
+ "main.go",
+ ],
+}
diff --git a/cmd/release_config/build_flag/main.go b/cmd/release_config/build_flag/main.go
new file mode 100644
index 0000000..6f909af
--- /dev/null
+++ b/cmd/release_config/build_flag/main.go
@@ -0,0 +1,229 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ rc_lib "android/soong/cmd/release_config/release_config_lib"
+ rc_proto "android/soong/cmd/release_config/release_config_proto"
+
+ "google.golang.org/protobuf/proto"
+)
+
+type Flags struct {
+ // The path to the top of the workspace. Default: ".".
+ top string
+
+ // Pathlist of release config map textproto files.
+ // If not specified, then the value is (if present):
+ // - build/release/release_config_map.textproto
+ // - vendor/google_shared/build/release/release_config_map.textproto
+ // - vendor/google/release/release_config_map.textproto
+ //
+ // Additionally, any maps specified in the environment variable
+ // `PRODUCT_RELEASE_CONFIG_MAPS` are used.
+ maps rc_lib.StringList
+
+ // Output directory (relative to `top`).
+ outDir string
+
+ // Which $TARGET_RELEASE(s) should we use. Some commands will only
+ // accept one value, others also accept `--release --all`.
+ targetReleases rc_lib.StringList
+
+ // Disable warning messages
+ quiet bool
+}
+
+type CommandFunc func(*rc_lib.ReleaseConfigs, Flags, string, []string) error
+
+var commandMap map[string]CommandFunc = map[string]CommandFunc{
+ "get": GetCommand,
+ "set": SetCommand,
+ "trace": GetCommand, // Also handled by GetCommand
+}
+
+// Find the top of the release config contribution directory.
+// Returns the parent of the flag_declarations and flag_values directories.
+func GetMapDir(path string) (string, error) {
+ for p := path; p != "."; p = filepath.Dir(p) {
+ switch filepath.Base(p) {
+ case "flag_declarations":
+ return filepath.Dir(p), nil
+ case "flag_values":
+ return filepath.Dir(p), nil
+ }
+ }
+ return "", fmt.Errorf("Could not determine directory from %s", path)
+}
+
+func MarshalFlagValue(config *rc_lib.ReleaseConfig, name string) (ret string, err error) {
+ fa, ok := config.FlagArtifacts[name]
+ if !ok {
+ return "", fmt.Errorf("%s not found in %s", name, config.Name)
+ }
+ return rc_lib.MarshalValue(fa.Value), nil
+}
+
+func GetReleaseArgs(configs *rc_lib.ReleaseConfigs, commonFlags Flags) ([]*rc_lib.ReleaseConfig, error) {
+ var all bool
+ relFlags := flag.NewFlagSet("set", flag.ExitOnError)
+ relFlags.BoolVar(&all, "all", false, "Display all flags")
+ relFlags.Parse(commonFlags.targetReleases)
+ var ret []*rc_lib.ReleaseConfig
+ if all {
+ for _, config := range configs.ReleaseConfigs {
+ ret = append(ret, config)
+ }
+ return ret, nil
+ }
+ for _, arg := range relFlags.Args() {
+ config, err := configs.GetReleaseConfig(arg)
+ if err != nil {
+ return nil, err
+ }
+ ret = append(ret, config)
+ }
+ return ret, nil
+}
+
+func GetCommand(configs *rc_lib.ReleaseConfigs, commonFlags Flags, cmd string, args []string) error {
+ isTrace := cmd == "trace"
+ var all bool
+ getFlags := flag.NewFlagSet("set", flag.ExitOnError)
+ getFlags.BoolVar(&all, "all", false, "Display all flags")
+ getFlags.Parse(args)
+ args = getFlags.Args()
+
+ releaseConfigList, err := GetReleaseArgs(configs, commonFlags)
+ if err != nil {
+ return err
+ }
+ if isTrace && len(releaseConfigList) > 1 {
+ return fmt.Errorf("trace command only allows one --release argument. Got: %s", strings.Join(commonFlags.targetReleases, " "))
+ }
+
+ if all {
+ args = []string{}
+ for _, fa := range configs.FlagArtifacts {
+ args = append(args, *fa.FlagDeclaration.Name)
+ }
+ }
+
+ showName := len(releaseConfigList) > 1 || len(args) > 1
+ for _, config := range releaseConfigList {
+ var configName string
+ if len(releaseConfigList) > 1 {
+ configName = fmt.Sprintf("%s.", config.Name)
+ }
+ for _, arg := range args {
+ val, err := MarshalFlagValue(config, arg)
+ if err != nil {
+ return err
+ }
+ if showName {
+ fmt.Printf("%s%s=%s\n", configName, arg, val)
+ } else {
+ fmt.Printf("%s\n", val)
+ }
+ if isTrace {
+ for _, trace := range config.FlagArtifacts[arg].Traces {
+ fmt.Printf(" => \"%s\" in %s\n", rc_lib.MarshalValue(trace.Value), *trace.Source)
+ }
+ }
+ }
+ }
+ return nil
+}
+
+func SetCommand(configs *rc_lib.ReleaseConfigs, commonFlags Flags, cmd string, args []string) error {
+ var valueDir string
+ if len(commonFlags.targetReleases) > 1 {
+ return fmt.Errorf("set command only allows one --release argument. Got: %s", strings.Join(commonFlags.targetReleases, " "))
+ }
+ targetRelease := commonFlags.targetReleases[0]
+
+ setFlags := flag.NewFlagSet("set", flag.ExitOnError)
+ setFlags.StringVar(&valueDir, "dir", "", "Directory in which to place the value")
+ setFlags.Parse(args)
+ setArgs := setFlags.Args()
+ if len(setArgs) != 2 {
+ return fmt.Errorf("set command expected flag and value, got: %s", strings.Join(setArgs, " "))
+ }
+ name := setArgs[0]
+ value := setArgs[1]
+ release, err := configs.GetReleaseConfig(targetRelease)
+ targetRelease = release.Name
+ if err != nil {
+ return err
+ }
+ flagArtifact, ok := release.FlagArtifacts[name]
+ if !ok {
+ return fmt.Errorf("Unknown build flag %s", name)
+ }
+ if valueDir == "" {
+ mapDir, err := GetMapDir(*flagArtifact.Traces[len(flagArtifact.Traces)-1].Source)
+ if err != nil {
+ return err
+ }
+ valueDir = mapDir
+ }
+
+ flagValue := &rc_proto.FlagValue{
+ Name: proto.String(name),
+ Value: rc_lib.UnmarshalValue(value),
+ }
+ flagPath := filepath.Join(valueDir, "flag_values", targetRelease, fmt.Sprintf("%s.textproto", name))
+ return rc_lib.WriteMessage(flagPath, flagValue)
+}
+
+func main() {
+ var err error
+ var commonFlags Flags
+ var configs *rc_lib.ReleaseConfigs
+
+ outEnv := os.Getenv("OUT_DIR")
+ if outEnv == "" {
+ outEnv = "out"
+ }
+ // Handle the common arguments
+ flag.StringVar(&commonFlags.top, "top", ".", "path to top of workspace")
+ flag.BoolVar(&commonFlags.quiet, "quiet", false, "disable warning messages")
+ flag.Var(&commonFlags.maps, "map", "path to a release_config_map.textproto. may be repeated")
+ flag.StringVar(&commonFlags.outDir, "out_dir", rc_lib.GetDefaultOutDir(), "basepath for the output. Multiple formats are created")
+ flag.Var(&commonFlags.targetReleases, "release", "TARGET_RELEASE for this build")
+ flag.Parse()
+
+ if commonFlags.quiet {
+ rc_lib.DisableWarnings()
+ }
+
+ if len(commonFlags.targetReleases) == 0 {
+ commonFlags.targetReleases = rc_lib.StringList{"trunk_staging"}
+ }
+
+ if err = os.Chdir(commonFlags.top); err != nil {
+ panic(err)
+ }
+
+ // Get the current state of flagging.
+ relName := commonFlags.targetReleases[0]
+ if relName == "--all" || relName == "-all" {
+ // If the users said `--release --all`, grab trunk staging for simplicity.
+ relName = "trunk_staging"
+ }
+ configs, err = rc_lib.ReadReleaseConfigMaps(commonFlags.maps, relName)
+ if err != nil {
+ panic(err)
+ }
+
+ if cmd, ok := commandMap[flag.Arg(0)]; ok {
+ args := flag.Args()
+ if err = cmd(configs, commonFlags, args[0], args[1:]); err != nil {
+ panic(err)
+ }
+ }
+}
diff --git a/cmd/release_config/crunch_flags/Android.bp b/cmd/release_config/crunch_flags/Android.bp
new file mode 100644
index 0000000..89c9591
--- /dev/null
+++ b/cmd/release_config/crunch_flags/Android.bp
@@ -0,0 +1,32 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+blueprint_go_binary {
+ name: "crunch-flags",
+ deps: [
+ "golang-protobuf-encoding-prototext",
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ "soong-cmd-release_config-lib",
+ "soong-cmd-release_config-proto",
+ ],
+ srcs: [
+ "main.go",
+ ],
+}
+
+bootstrap_go_package {
+ name: "soong-cmd-release_config-crunch_flags",
+ pkgPath: "android/soong/cmd/release_config/crunch_flags",
+ deps: [
+ "golang-protobuf-encoding-prototext",
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ "soong-cmd-release_config-lib",
+ "soong-cmd-release_config-proto",
+ ],
+ srcs: [
+ "main.go",
+ ],
+}
diff --git a/cmd/release_config/crunch_flags/main.go b/cmd/release_config/crunch_flags/main.go
new file mode 100644
index 0000000..616674b
--- /dev/null
+++ b/cmd/release_config/crunch_flags/main.go
@@ -0,0 +1,359 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+
+ rc_lib "android/soong/cmd/release_config/release_config_lib"
+ rc_proto "android/soong/cmd/release_config/release_config_proto"
+ "google.golang.org/protobuf/encoding/prototext"
+ "google.golang.org/protobuf/proto"
+)
+
+// When a flag declaration has an initial value that is a string, the default workflow is PREBUILT.
+// If the flag name starts with any of prefixes in manualFlagNamePrefixes, it is MANUAL.
+var manualFlagNamePrefixes []string = []string{
+ "RELEASE_ACONFIG_",
+ "RELEASE_PLATFORM_",
+}
+
+var defaultFlagNamespace string = "android_UNKNOWN"
+
+func RenameNext(name string) string {
+ if name == "next" {
+ return "ap3a"
+ }
+ return name
+}
+
+func WriteFile(path string, message proto.Message) error {
+ data, err := prototext.MarshalOptions{Multiline: true}.Marshal(message)
+ if err != nil {
+ return err
+ }
+
+ err = os.MkdirAll(filepath.Dir(path), 0775)
+ if err != nil {
+ return err
+ }
+ return os.WriteFile(path, data, 0644)
+}
+
+func WalkValueFiles(dir string, Func fs.WalkDirFunc) error {
+ valPath := filepath.Join(dir, "build_config")
+ if _, err := os.Stat(valPath); err != nil {
+ fmt.Printf("%s not found, ignoring.\n", valPath)
+ return nil
+ }
+
+ return filepath.WalkDir(valPath, func(path string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+ if strings.HasSuffix(d.Name(), ".scl") && d.Type().IsRegular() {
+ return Func(path, d, err)
+ }
+ return nil
+ })
+}
+
+func ProcessBuildFlags(dir string, namespaceMap map[string]string) error {
+ var rootAconfigModule string
+
+ path := filepath.Join(dir, "build_flags.scl")
+ if _, err := os.Stat(path); err != nil {
+ fmt.Printf("%s not found, ignoring.\n", path)
+ return nil
+ } else {
+ fmt.Printf("Processing %s\n", path)
+ }
+ commentRegexp, err := regexp.Compile("^[[:space:]]*#(?<comment>.+)")
+ if err != nil {
+ return err
+ }
+ declRegexp, err := regexp.Compile("^[[:space:]]*flag.\"(?<name>[A-Z_0-9]+)\",[[:space:]]*(?<container>[_A-Z]*),[[:space:]]*(?<value>(\"[^\"]*\"|[^\",)]*))")
+ if err != nil {
+ return err
+ }
+ declIn, err := os.ReadFile(path)
+ if err != nil {
+ return err
+ }
+ lines := strings.Split(string(declIn), "\n")
+ var description string
+ for _, line := range lines {
+ if comment := commentRegexp.FindStringSubmatch(commentRegexp.FindString(line)); comment != nil {
+ // Description is the text from any contiguous series of lines before a `flag()` call.
+ description += fmt.Sprintf(" %s", strings.TrimSpace(comment[commentRegexp.SubexpIndex("comment")]))
+ continue
+ }
+ matches := declRegexp.FindStringSubmatch(declRegexp.FindString(line))
+ if matches == nil {
+ // The line is neither a comment nor a `flag()` call.
+ // Discard any description we have gathered and process the next line.
+ description = ""
+ continue
+ }
+ declValue := matches[declRegexp.SubexpIndex("value")]
+ declName := matches[declRegexp.SubexpIndex("name")]
+ container := rc_proto.Container(rc_proto.Container_value[matches[declRegexp.SubexpIndex("container")]])
+ description = strings.TrimSpace(description)
+ var namespace string
+ var ok bool
+ if namespace, ok = namespaceMap[declName]; !ok {
+ namespace = defaultFlagNamespace
+ }
+ flagDeclaration := &rc_proto.FlagDeclaration{
+ Name: proto.String(declName),
+ Namespace: proto.String(namespace),
+ Description: proto.String(description),
+ Container: &container,
+ }
+ description = ""
+ // Most build flags are `workflow: PREBUILT`.
+ workflow := rc_proto.Workflow(rc_proto.Workflow_PREBUILT)
+ switch {
+ case declName == "RELEASE_ACONFIG_VALUE_SETS":
+ rootAconfigModule = declValue[1 : len(declValue)-1]
+ continue
+ case strings.HasPrefix(declValue, "\""):
+ // String values mean that the flag workflow is (most likely) either MANUAL or PREBUILT.
+ declValue = declValue[1 : len(declValue)-1]
+ flagDeclaration.Value = &rc_proto.Value{Val: &rc_proto.Value_StringValue{declValue}}
+ for _, prefix := range manualFlagNamePrefixes {
+ if strings.HasPrefix(declName, prefix) {
+ workflow = rc_proto.Workflow(rc_proto.Workflow_MANUAL)
+ break
+ }
+ }
+ case declValue == "False" || declValue == "True":
+ // Boolean values are LAUNCH flags.
+ flagDeclaration.Value = &rc_proto.Value{Val: &rc_proto.Value_BoolValue{declValue == "True"}}
+ workflow = rc_proto.Workflow(rc_proto.Workflow_LAUNCH)
+ case declValue == "None":
+ // Use PREBUILT workflow with no initial value.
+ default:
+ fmt.Printf("%s: Unexpected value %s=%s\n", path, declName, declValue)
+ }
+ flagDeclaration.Workflow = &workflow
+ if flagDeclaration != nil {
+ declPath := filepath.Join(dir, "flag_declarations", fmt.Sprintf("%s.textproto", declName))
+ err := WriteFile(declPath, flagDeclaration)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ if rootAconfigModule != "" {
+ rootProto := &rc_proto.ReleaseConfig{
+ Name: proto.String("root"),
+ AconfigValueSets: []string{rootAconfigModule},
+ }
+ return WriteFile(filepath.Join(dir, "release_configs", "root.textproto"), rootProto)
+ }
+ return nil
+}
+
+func ProcessBuildConfigs(dir, name string, paths []string, releaseProto *rc_proto.ReleaseConfig) error {
+ valRegexp, err := regexp.Compile("[[:space:]]+value.\"(?<name>[A-Z_0-9]+)\",[[:space:]]*(?<value>[^,)]*)")
+ if err != nil {
+ return err
+ }
+ for _, path := range paths {
+ fmt.Printf("Processing %s\n", path)
+ valIn, err := os.ReadFile(path)
+ if err != nil {
+ fmt.Printf("%s: error: %v\n", path, err)
+ return err
+ }
+ vals := valRegexp.FindAllString(string(valIn), -1)
+ for _, val := range vals {
+ matches := valRegexp.FindStringSubmatch(val)
+ valValue := matches[valRegexp.SubexpIndex("value")]
+ valName := matches[valRegexp.SubexpIndex("name")]
+ flagValue := &rc_proto.FlagValue{
+ Name: proto.String(valName),
+ }
+ switch {
+ case valName == "RELEASE_ACONFIG_VALUE_SETS":
+ flagValue = nil
+ if releaseProto.AconfigValueSets == nil {
+ releaseProto.AconfigValueSets = []string{}
+ }
+ releaseProto.AconfigValueSets = append(releaseProto.AconfigValueSets, valValue[1:len(valValue)-1])
+ case strings.HasPrefix(valValue, "\""):
+ valValue = valValue[1 : len(valValue)-1]
+ flagValue.Value = &rc_proto.Value{Val: &rc_proto.Value_StringValue{valValue}}
+ case valValue == "None":
+ // nothing to do here.
+ case valValue == "True":
+ flagValue.Value = &rc_proto.Value{Val: &rc_proto.Value_BoolValue{true}}
+ case valValue == "False":
+ flagValue.Value = &rc_proto.Value{Val: &rc_proto.Value_BoolValue{false}}
+ default:
+ fmt.Printf("%s: Unexpected value %s=%s\n", path, valName, valValue)
+ }
+ if flagValue != nil {
+ valPath := filepath.Join(dir, "flag_values", RenameNext(name), fmt.Sprintf("%s.textproto", valName))
+ err := WriteFile(valPath, flagValue)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ }
+ return err
+}
+
+func ProcessReleaseConfigMap(dir string, descriptionMap map[string]string) error {
+ path := filepath.Join(dir, "release_config_map.mk")
+ if _, err := os.Stat(path); err != nil {
+ fmt.Printf("%s not found, ignoring.\n", path)
+ return nil
+ } else {
+ fmt.Printf("Processing %s\n", path)
+ }
+ configRegexp, err := regexp.Compile("^..call[[:space:]]+declare-release-config,[[:space:]]+(?<name>[_a-z0-0A-Z]+),[[:space:]]+(?<files>[^,]*)(,[[:space:]]*(?<inherits>.*)|[[:space:]]*)[)]$")
+ if err != nil {
+ return err
+ }
+ aliasRegexp, err := regexp.Compile("^..call[[:space:]]+alias-release-config,[[:space:]]+(?<name>[_a-z0-9A-Z]+),[[:space:]]+(?<target>[_a-z0-9A-Z]+)")
+ if err != nil {
+ return err
+ }
+
+ mapIn, err := os.ReadFile(path)
+ if err != nil {
+ return err
+ }
+ cleanDir := strings.TrimLeft(dir, "../")
+ var defaultContainer rc_proto.Container
+ switch {
+ case strings.HasPrefix(cleanDir, "build/") || cleanDir == "vendor/google_shared/build":
+ defaultContainer = rc_proto.Container(rc_proto.Container_ALL)
+ case cleanDir == "vendor/google/release":
+ defaultContainer = rc_proto.Container(rc_proto.Container_ALL)
+ default:
+ defaultContainer = rc_proto.Container(rc_proto.Container_VENDOR)
+ }
+ releaseConfigMap := &rc_proto.ReleaseConfigMap{DefaultContainer: &defaultContainer}
+ // If we find a description for the directory, include it.
+ if description, ok := descriptionMap[cleanDir]; ok {
+ releaseConfigMap.Description = proto.String(description)
+ }
+ lines := strings.Split(string(mapIn), "\n")
+ for _, line := range lines {
+ alias := aliasRegexp.FindStringSubmatch(aliasRegexp.FindString(line))
+ if alias != nil {
+ fmt.Printf("processing alias %s\n", line)
+ name := alias[aliasRegexp.SubexpIndex("name")]
+ target := alias[aliasRegexp.SubexpIndex("target")]
+ if target == "next" {
+ if RenameNext(target) != name {
+ return fmt.Errorf("Unexpected name for next (%s)", RenameNext(target))
+ }
+ target, name = name, target
+ }
+ releaseConfigMap.Aliases = append(releaseConfigMap.Aliases,
+ &rc_proto.ReleaseAlias{
+ Name: proto.String(name),
+ Target: proto.String(target),
+ })
+ }
+ config := configRegexp.FindStringSubmatch(configRegexp.FindString(line))
+ if config == nil {
+ continue
+ }
+ name := config[configRegexp.SubexpIndex("name")]
+ releaseConfig := &rc_proto.ReleaseConfig{
+ Name: proto.String(RenameNext(name)),
+ }
+ configFiles := config[configRegexp.SubexpIndex("files")]
+ files := strings.Split(strings.ReplaceAll(configFiles, "$(local_dir)", dir+"/"), " ")
+ configInherits := config[configRegexp.SubexpIndex("inherits")]
+ if len(configInherits) > 0 {
+ releaseConfig.Inherits = strings.Split(configInherits, " ")
+ }
+ err := ProcessBuildConfigs(dir, name, files, releaseConfig)
+ if err != nil {
+ return err
+ }
+
+ releasePath := filepath.Join(dir, "release_configs", fmt.Sprintf("%s.textproto", RenameNext(name)))
+ err = WriteFile(releasePath, releaseConfig)
+ if err != nil {
+ return err
+ }
+ }
+ return WriteFile(filepath.Join(dir, "release_config_map.textproto"), releaseConfigMap)
+}
+
+func main() {
+ var err error
+ var top string
+ var dirs rc_lib.StringList
+ var namespacesFile string
+ var descriptionsFile string
+
+ flag.StringVar(&top, "top", ".", "path to top of workspace")
+ flag.Var(&dirs, "dir", "directory to process, relative to the top of the workspace")
+ flag.StringVar(&namespacesFile, "namespaces", "", "location of file with 'flag_name namespace' information")
+ flag.StringVar(&descriptionsFile, "descriptions", "", "location of file with 'directory description' information")
+ flag.Parse()
+
+ if err = os.Chdir(top); err != nil {
+ panic(err)
+ }
+ if len(dirs) == 0 {
+ dirs = rc_lib.StringList{"build/release", "vendor/google_shared/build/release", "vendor/google/release"}
+ }
+
+ namespaceMap := make(map[string]string)
+ if namespacesFile != "" {
+ data, err := os.ReadFile(namespacesFile)
+ if err != nil {
+ panic(err)
+ }
+ for idx, line := range strings.Split(string(data), "\n") {
+ fields := strings.Split(line, " ")
+ if len(fields) > 2 {
+ panic(fmt.Errorf("line %d: too many fields: %s", idx, line))
+ }
+ namespaceMap[fields[0]] = fields[1]
+ }
+
+ }
+
+ descriptionMap := make(map[string]string)
+ descriptionMap["build/release"] = "Published open-source flags and declarations"
+ if descriptionsFile != "" {
+ data, err := os.ReadFile(descriptionsFile)
+ if err != nil {
+ panic(err)
+ }
+ for _, line := range strings.Split(string(data), "\n") {
+ if strings.TrimSpace(line) != "" {
+ fields := strings.SplitN(line, " ", 2)
+ descriptionMap[fields[0]] = fields[1]
+ }
+ }
+
+ }
+
+ for _, dir := range dirs {
+ err = ProcessBuildFlags(dir, namespaceMap)
+ if err != nil {
+ panic(err)
+ }
+
+ err = ProcessReleaseConfigMap(dir, descriptionMap)
+ if err != nil {
+ panic(err)
+ }
+ }
+}
diff --git a/cmd/release_config/release_config/Android.bp b/cmd/release_config/release_config/Android.bp
new file mode 100644
index 0000000..3c73826
--- /dev/null
+++ b/cmd/release_config/release_config/Android.bp
@@ -0,0 +1,18 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-cmd-release_config-release_config",
+ pkgPath: "android/soong/cmd/release_config/release_config",
+ deps: [
+ "golang-protobuf-encoding-prototext",
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ "soong-cmd-release_config-proto",
+ "soong-cmd-release_config-lib",
+ ],
+ srcs: [
+ "main.go",
+ ],
+}
diff --git a/cmd/release_config/release_config/main.go b/cmd/release_config/release_config/main.go
new file mode 100644
index 0000000..a43fdcc
--- /dev/null
+++ b/cmd/release_config/release_config/main.go
@@ -0,0 +1,96 @@
+// Copyright 2024 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 main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "path/filepath"
+
+ rc_lib "android/soong/cmd/release_config/release_config_lib"
+)
+
+func main() {
+ var top string
+ var quiet bool
+ var releaseConfigMapPaths rc_lib.StringList
+ var targetRelease string
+ var outputDir string
+ var err error
+ var configs *rc_lib.ReleaseConfigs
+ var json, pb, textproto bool
+ var product string
+
+ defaultRelease := os.Getenv("TARGET_RELEASE")
+ if defaultRelease == "" {
+ defaultRelease = "trunk_staging"
+ }
+
+ flag.StringVar(&top, "top", ".", "path to top of workspace")
+ flag.StringVar(&product, "product", os.Getenv("TARGET_PRODUCT"), "TARGET_PRODUCT for the build")
+ flag.BoolVar(&quiet, "quiet", false, "disable warning messages")
+ flag.Var(&releaseConfigMapPaths, "map", "path to a release_config_map.textproto. may be repeated")
+ flag.StringVar(&targetRelease, "release", defaultRelease, "TARGET_RELEASE for this build")
+ flag.StringVar(&outputDir, "out_dir", rc_lib.GetDefaultOutDir(), "basepath for the output. Multiple formats are created")
+ flag.BoolVar(&textproto, "textproto", true, "write artifacts as text protobuf")
+ flag.BoolVar(&json, "json", true, "write artifacts as json")
+ flag.BoolVar(&pb, "pb", true, "write artifacts as binary protobuf")
+ flag.Parse()
+
+ if quiet {
+ rc_lib.DisableWarnings()
+ }
+
+ if err = os.Chdir(top); err != nil {
+ panic(err)
+ }
+ configs, err = rc_lib.ReadReleaseConfigMaps(releaseConfigMapPaths, targetRelease)
+ if err != nil {
+ panic(err)
+ }
+ config, err := configs.GetReleaseConfig(targetRelease)
+ if err != nil {
+ panic(err)
+ }
+ releaseName := config.Name
+ err = os.MkdirAll(outputDir, 0775)
+ if err != nil {
+ panic(err)
+ }
+ makefilePath := filepath.Join(outputDir, fmt.Sprintf("release_config-%s-%s.mk", product, releaseName))
+ err = configs.WriteMakefile(makefilePath, targetRelease)
+ if err != nil {
+ panic(err)
+ }
+ if json {
+ err = configs.WriteArtifact(outputDir, product, "json")
+ if err != nil {
+ panic(err)
+ }
+ }
+ if pb {
+ err = configs.WriteArtifact(outputDir, product, "pb")
+ if err != nil {
+ panic(err)
+ }
+ }
+ if textproto {
+ err = configs.WriteArtifact(outputDir, product, "textproto")
+ if err != nil {
+ panic(err)
+ }
+ }
+}
diff --git a/cmd/release_config/release_config_lib/Android.bp b/cmd/release_config/release_config_lib/Android.bp
new file mode 100644
index 0000000..0c67e11
--- /dev/null
+++ b/cmd/release_config/release_config_lib/Android.bp
@@ -0,0 +1,36 @@
+// Copyright 2024 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-cmd-release_config-lib",
+ pkgPath: "android/soong/cmd/release_config/release_config_lib",
+ deps: [
+ "golang-protobuf-encoding-prototext",
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ "soong-cmd-release_config-proto",
+ ],
+ srcs: [
+ "flag_artifact.go",
+ "flag_declaration.go",
+ "flag_value.go",
+ "release_config.go",
+ "release_configs.go",
+ "util.go",
+ ],
+}
diff --git a/cmd/release_config/release_config_lib/flag_artifact.go b/cmd/release_config/release_config_lib/flag_artifact.go
new file mode 100644
index 0000000..4446655
--- /dev/null
+++ b/cmd/release_config/release_config_lib/flag_artifact.go
@@ -0,0 +1,119 @@
+// Copyright 2024 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 release_config_lib
+
+import (
+ "fmt"
+
+ rc_proto "android/soong/cmd/release_config/release_config_proto"
+
+ "google.golang.org/protobuf/proto"
+)
+
+// A flag artifact, with its final value and declaration/override history.
+type FlagArtifact struct {
+ // The flag_declaration message.
+ FlagDeclaration *rc_proto.FlagDeclaration
+
+ // The index of the config directory where this flag was declared.
+ // Flag values cannot be set in a location with a lower index.
+ DeclarationIndex int
+
+ // A history of value assignments and overrides.
+ Traces []*rc_proto.Tracepoint
+
+ // The value of the flag.
+ Value *rc_proto.Value
+}
+
+// Key is flag name.
+type FlagArtifacts map[string]*FlagArtifact
+
+// Create a clone of the flag artifact.
+//
+// Returns:
+//
+// *FlagArtifact: the copy of the artifact.
+func (src *FlagArtifact) Clone() *FlagArtifact {
+ value := &rc_proto.Value{}
+ proto.Merge(value, src.Value)
+ return &FlagArtifact{
+ FlagDeclaration: src.FlagDeclaration,
+ Traces: src.Traces,
+ Value: value,
+ }
+}
+
+// Clone FlagArtifacts.
+//
+// Returns:
+//
+// FlagArtifacts: a copy of the source FlagArtifacts.
+func (src FlagArtifacts) Clone() (dst FlagArtifacts) {
+ if dst == nil {
+ dst = make(FlagArtifacts)
+ }
+ for k, v := range src {
+ dst[k] = v.Clone()
+ }
+ return
+}
+
+// Update the value of a flag.
+//
+// This appends to flagArtifact.Traces, and updates flagArtifact.Value.
+//
+// Args:
+//
+// flagValue FlagValue: the value to assign
+//
+// Returns:
+//
+// error: any error encountered
+func (fa *FlagArtifact) UpdateValue(flagValue FlagValue) error {
+ name := *flagValue.proto.Name
+ fa.Traces = append(fa.Traces, &rc_proto.Tracepoint{Source: proto.String(flagValue.path), Value: flagValue.proto.Value})
+ if fa.Value.GetObsolete() {
+ return fmt.Errorf("Attempting to set obsolete flag %s. Trace=%v", name, fa.Traces)
+ }
+ var newValue *rc_proto.Value
+ switch val := flagValue.proto.Value.Val.(type) {
+ case *rc_proto.Value_StringValue:
+ newValue = &rc_proto.Value{Val: &rc_proto.Value_StringValue{val.StringValue}}
+ case *rc_proto.Value_BoolValue:
+ newValue = &rc_proto.Value{Val: &rc_proto.Value_BoolValue{val.BoolValue}}
+ case *rc_proto.Value_Obsolete:
+ if !val.Obsolete {
+ return fmt.Errorf("%s: Cannot set obsolete=false. Trace=%v", name, fa.Traces)
+ }
+ newValue = &rc_proto.Value{Val: &rc_proto.Value_Obsolete{true}}
+ default:
+ return fmt.Errorf("Invalid type for flag_value: %T. Trace=%v", val, fa.Traces)
+ }
+ if proto.Equal(newValue, fa.Value) {
+ warnf("%s: redundant override (set in %s)\n", flagValue.path, *fa.Traces[len(fa.Traces)-2].Source)
+ }
+ fa.Value = newValue
+ return nil
+}
+
+// Marshal the FlagArtifact into a flag_artifact message.
+func (fa *FlagArtifact) Marshal() (*rc_proto.FlagArtifact, error) {
+ return &rc_proto.FlagArtifact{
+ FlagDeclaration: fa.FlagDeclaration,
+ Value: fa.Value,
+ Traces: fa.Traces,
+ }, nil
+}
diff --git a/cmd/release_config/release_config_lib/flag_declaration.go b/cmd/release_config/release_config_lib/flag_declaration.go
new file mode 100644
index 0000000..97d4d4c
--- /dev/null
+++ b/cmd/release_config/release_config_lib/flag_declaration.go
@@ -0,0 +1,27 @@
+// Copyright 2024 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 release_config_lib
+
+import (
+ rc_proto "android/soong/cmd/release_config/release_config_proto"
+)
+
+func FlagDeclarationFactory(protoPath string) (fd *rc_proto.FlagDeclaration) {
+ fd = &rc_proto.FlagDeclaration{}
+ if protoPath != "" {
+ LoadMessage(protoPath, fd)
+ }
+ return fd
+}
diff --git a/cmd/release_config/release_config_lib/flag_value.go b/cmd/release_config/release_config_lib/flag_value.go
new file mode 100644
index 0000000..e155e77
--- /dev/null
+++ b/cmd/release_config/release_config_lib/flag_value.go
@@ -0,0 +1,73 @@
+// Copyright 2024 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 release_config_lib
+
+import (
+ "strings"
+
+ rc_proto "android/soong/cmd/release_config/release_config_proto"
+)
+
+type FlagValue struct {
+ // The path providing this value.
+ path string
+
+ // Protobuf
+ proto rc_proto.FlagValue
+}
+
+func FlagValueFactory(protoPath string) (fv *FlagValue) {
+ fv = &FlagValue{path: protoPath}
+ if protoPath != "" {
+ LoadMessage(protoPath, &fv.proto)
+ }
+ return fv
+}
+
+func UnmarshalValue(str string) *rc_proto.Value {
+ ret := &rc_proto.Value{}
+ switch v := strings.ToLower(str); v {
+ case "true":
+ ret = &rc_proto.Value{Val: &rc_proto.Value_BoolValue{true}}
+ case "false":
+ ret = &rc_proto.Value{Val: &rc_proto.Value_BoolValue{false}}
+ case "##obsolete":
+ ret = &rc_proto.Value{Val: &rc_proto.Value_Obsolete{true}}
+ default:
+ ret = &rc_proto.Value{Val: &rc_proto.Value_StringValue{str}}
+ }
+ return ret
+}
+
+func MarshalValue(value *rc_proto.Value) string {
+ switch val := value.Val.(type) {
+ case *rc_proto.Value_UnspecifiedValue:
+ // Value was never set.
+ return ""
+ case *rc_proto.Value_StringValue:
+ return val.StringValue
+ case *rc_proto.Value_BoolValue:
+ if val.BoolValue {
+ return "true"
+ }
+ // False ==> empty string
+ return ""
+ case *rc_proto.Value_Obsolete:
+ return " #OBSOLETE"
+ default:
+ // Flagged as error elsewhere, so return empty string here.
+ return ""
+ }
+}
diff --git a/cmd/release_config/release_config_lib/flag_value_test.go b/cmd/release_config/release_config_lib/flag_value_test.go
new file mode 100644
index 0000000..aaa4caf
--- /dev/null
+++ b/cmd/release_config/release_config_lib/flag_value_test.go
@@ -0,0 +1,67 @@
+// Copyright 2024 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 release_config_lib
+
+import (
+ "os"
+ "path/filepath"
+ "testing"
+
+ rc_proto "android/soong/cmd/release_config/release_config_proto"
+
+ "google.golang.org/protobuf/proto"
+)
+
+type testCaseFlagValue struct {
+ protoPath string
+ name string
+ data []byte
+ expected rc_proto.FlagValue
+ err error
+}
+
+func (tc testCaseFlagValue) assertProtoEqual(t *testing.T, expected, actual proto.Message) {
+ if !proto.Equal(expected, actual) {
+ t.Errorf("Expected %q found %q", expected, actual)
+ }
+}
+
+func TestFlagValue(t *testing.T) {
+ testCases := []testCaseFlagValue{
+ {
+ name: "stringVal",
+ protoPath: "build/release/flag_values/test/RELEASE_FOO.textproto",
+ data: []byte(`name: "RELEASE_FOO" value {string_value: "BAR"}`),
+ expected: rc_proto.FlagValue{
+ Name: proto.String("RELEASE_FOO"),
+ Value: &rc_proto.Value{Val: &rc_proto.Value_StringValue{"BAR"}},
+ },
+ err: nil,
+ },
+ }
+ for _, tc := range testCases {
+ var err error
+ tempdir := t.TempDir()
+ path := filepath.Join(tempdir, tc.protoPath)
+ if err = os.MkdirAll(filepath.Dir(path), 0755); err != nil {
+ t.Fatal(err)
+ }
+ if err = os.WriteFile(path, tc.data, 0644); err != nil {
+ t.Fatal(err)
+ }
+ actual := FlagValueFactory(path)
+ tc.assertProtoEqual(t, &tc.expected, &actual.proto)
+ }
+}
diff --git a/cmd/release_config/release_config_lib/release_config.go b/cmd/release_config/release_config_lib/release_config.go
new file mode 100644
index 0000000..c67cee5
--- /dev/null
+++ b/cmd/release_config/release_config_lib/release_config.go
@@ -0,0 +1,202 @@
+// Copyright 2024 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 release_config_lib
+
+import (
+ "fmt"
+ "strings"
+
+ rc_proto "android/soong/cmd/release_config/release_config_proto"
+
+ "google.golang.org/protobuf/proto"
+)
+
+// One directory's contribution to the a release config.
+type ReleaseConfigContribution struct {
+ // Paths to files providing this config.
+ path string
+
+ // The index of the config directory where this release config
+ // contribution was declared.
+ // Flag values cannot be set in a location with a lower index.
+ DeclarationIndex int
+
+ // Protobufs relevant to the config.
+ proto rc_proto.ReleaseConfig
+
+ FlagValues []*FlagValue
+}
+
+// A generated release config.
+type ReleaseConfig struct {
+ // the Name of the release config
+ Name string
+
+ // The index of the config directory where this release config was
+ // first declared.
+ // Flag values cannot be set in a location with a lower index.
+ DeclarationIndex int
+
+ // What contributes to this config.
+ Contributions []*ReleaseConfigContribution
+
+ // Aliases for this release
+ OtherNames []string
+
+ // The names of release configs that we inherit
+ InheritNames []string
+
+ // Unmarshalled flag artifacts
+ FlagArtifacts FlagArtifacts
+
+ // Generated release config
+ ReleaseConfigArtifact *rc_proto.ReleaseConfigArtifact
+
+ // We have begun compiling this release config.
+ compileInProgress bool
+}
+
+func ReleaseConfigFactory(name string, index int) (c *ReleaseConfig) {
+ return &ReleaseConfig{Name: name, DeclarationIndex: index}
+}
+
+func (config *ReleaseConfig) GenerateReleaseConfig(configs *ReleaseConfigs) error {
+ if config.ReleaseConfigArtifact != nil {
+ return nil
+ }
+ if config.compileInProgress {
+ return fmt.Errorf("Loop detected for release config %s", config.Name)
+ }
+ config.compileInProgress = true
+ isRoot := config.Name == "root"
+
+ // Generate any configs we need to inherit. This will detect loops in
+ // the config.
+ contributionsToApply := []*ReleaseConfigContribution{}
+ myInherits := []string{}
+ myInheritsSet := make(map[string]bool)
+ // If there is a "root" release config, it is the start of every inheritance chain.
+ _, err := configs.GetReleaseConfig("root")
+ if err == nil && !isRoot {
+ config.InheritNames = append([]string{"root"}, config.InheritNames...)
+ }
+ for _, inherit := range config.InheritNames {
+ if _, ok := myInheritsSet[inherit]; ok {
+ continue
+ }
+ myInherits = append(myInherits, inherit)
+ myInheritsSet[inherit] = true
+ iConfig, err := configs.GetReleaseConfig(inherit)
+ if err != nil {
+ return err
+ }
+ iConfig.GenerateReleaseConfig(configs)
+ contributionsToApply = append(contributionsToApply, iConfig.Contributions...)
+ }
+ contributionsToApply = append(contributionsToApply, config.Contributions...)
+
+ myAconfigValueSets := []string{}
+ myAconfigValueSetsMap := map[string]bool{}
+ myFlags := configs.FlagArtifacts.Clone()
+ workflowManual := rc_proto.Workflow(rc_proto.Workflow_MANUAL)
+ container := rc_proto.Container(rc_proto.Container_ALL)
+ releaseAconfigValueSets := FlagArtifact{
+ FlagDeclaration: &rc_proto.FlagDeclaration{
+ Name: proto.String("RELEASE_ACONFIG_VALUE_SETS"),
+ Namespace: proto.String("android_UNKNOWN"),
+ Description: proto.String("Aconfig value sets assembled by release-config"),
+ Workflow: &workflowManual,
+ Container: &container,
+ Value: &rc_proto.Value{Val: &rc_proto.Value_StringValue{""}},
+ },
+ DeclarationIndex: -1,
+ Traces: []*rc_proto.Tracepoint{
+ &rc_proto.Tracepoint{
+ Source: proto.String("$release-config"),
+ Value: &rc_proto.Value{Val: &rc_proto.Value_StringValue{""}},
+ },
+ },
+ }
+ myFlags["RELEASE_ACONFIG_VALUE_SETS"] = &releaseAconfigValueSets
+ myDirsMap := make(map[int]bool)
+ for _, contrib := range contributionsToApply {
+ if len(contrib.proto.AconfigValueSets) > 0 {
+ contribAconfigValueSets := []string{}
+ for _, v := range contrib.proto.AconfigValueSets {
+ if _, ok := myAconfigValueSetsMap[v]; !ok {
+ contribAconfigValueSets = append(contribAconfigValueSets, v)
+ myAconfigValueSetsMap[v] = true
+ }
+ }
+ myAconfigValueSets = append(myAconfigValueSets, contribAconfigValueSets...)
+ releaseAconfigValueSets.Traces = append(
+ releaseAconfigValueSets.Traces,
+ &rc_proto.Tracepoint{
+ Source: proto.String(contrib.path),
+ Value: &rc_proto.Value{Val: &rc_proto.Value_StringValue{strings.Join(contribAconfigValueSets, " ")}},
+ })
+ }
+ myDirsMap[contrib.DeclarationIndex] = true
+ for _, value := range contrib.FlagValues {
+ fa, ok := myFlags[*value.proto.Name]
+ if !ok {
+ return fmt.Errorf("Setting value for undefined flag %s in %s\n", *value.proto.Name, value.path)
+ }
+ myDirsMap[fa.DeclarationIndex] = true
+ if fa.DeclarationIndex > contrib.DeclarationIndex {
+ // Setting location is to the left of declaration.
+ return fmt.Errorf("Setting value for flag %s not allowed in %s\n", *value.proto.Name, value.path)
+ }
+ if isRoot && *fa.FlagDeclaration.Workflow != workflowManual {
+ // The "root" release config can only contain workflow: MANUAL flags.
+ return fmt.Errorf("Setting value for non-MANUAL flag %s is not allowed in %s", *value.proto.Name, value.path)
+ }
+ if err := fa.UpdateValue(*value); err != nil {
+ return err
+ }
+ }
+ }
+ releaseAconfigValueSets.Value = &rc_proto.Value{Val: &rc_proto.Value_StringValue{strings.Join(myAconfigValueSets, " ")}}
+
+ directories := []string{}
+ for idx, confDir := range configs.configDirs {
+ if _, ok := myDirsMap[idx]; ok {
+ directories = append(directories, confDir)
+ }
+ }
+
+ config.FlagArtifacts = myFlags
+ config.ReleaseConfigArtifact = &rc_proto.ReleaseConfigArtifact{
+ Name: proto.String(config.Name),
+ OtherNames: config.OtherNames,
+ FlagArtifacts: func() []*rc_proto.FlagArtifact {
+ ret := []*rc_proto.FlagArtifact{}
+ for _, flag := range myFlags {
+ ret = append(ret, &rc_proto.FlagArtifact{
+ FlagDeclaration: flag.FlagDeclaration,
+ Traces: flag.Traces,
+ Value: flag.Value,
+ })
+ }
+ return ret
+ }(),
+ AconfigValueSets: myAconfigValueSets,
+ Inherits: myInherits,
+ Directories: directories,
+ }
+
+ config.compileInProgress = false
+ return nil
+}
diff --git a/cmd/release_config/release_config_lib/release_configs.go b/cmd/release_config/release_config_lib/release_configs.go
new file mode 100644
index 0000000..6efdb2f
--- /dev/null
+++ b/cmd/release_config/release_config_lib/release_configs.go
@@ -0,0 +1,386 @@
+// Copyright 2024 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 release_config_lib
+
+import (
+ "cmp"
+ "fmt"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "slices"
+ "strings"
+
+ rc_proto "android/soong/cmd/release_config/release_config_proto"
+
+ "google.golang.org/protobuf/proto"
+)
+
+// A single release_config_map.textproto and its associated data.
+// Used primarily for debugging.
+type ReleaseConfigMap struct {
+ // The path to this release_config_map file.
+ path string
+
+ // Data received
+ proto rc_proto.ReleaseConfigMap
+
+ // Map of name:contribution for release config contributions.
+ ReleaseConfigContributions map[string]*ReleaseConfigContribution
+
+ // Flags declared this directory's flag_declarations/*.textproto
+ FlagDeclarations []rc_proto.FlagDeclaration
+}
+
+type ReleaseConfigDirMap map[string]int
+
+// The generated release configs.
+type ReleaseConfigs struct {
+ // Ordered list of release config maps processed.
+ ReleaseConfigMaps []*ReleaseConfigMap
+
+ // Aliases
+ Aliases map[string]*string
+
+ // Dictionary of flag_name:FlagDeclaration, with no overrides applied.
+ FlagArtifacts FlagArtifacts
+
+ // Generated release configs artifact
+ Artifact rc_proto.ReleaseConfigsArtifact
+
+ // Dictionary of name:ReleaseConfig
+ // Use `GetReleaseConfigs(name)` to get a release config.
+ ReleaseConfigs map[string]*ReleaseConfig
+
+ // Map of directory to *ReleaseConfigMap
+ releaseConfigMapsMap map[string]*ReleaseConfigMap
+
+ // The list of config directories used.
+ configDirs []string
+
+ // A map from the config directory to its order in the list of config
+ // directories.
+ configDirIndexes ReleaseConfigDirMap
+}
+
+// Write the "all_release_configs" artifact.
+//
+// The file will be in "{outDir}/all_release_configs-{product}.{format}"
+//
+// Args:
+//
+// outDir string: directory path. Will be created if not present.
+// product string: TARGET_PRODUCT for the release_configs.
+// format string: one of "json", "pb", or "textproto"
+//
+// Returns:
+//
+// error: Any error encountered.
+func (configs *ReleaseConfigs) WriteArtifact(outDir, product, format string) error {
+ return WriteMessage(
+ filepath.Join(outDir, fmt.Sprintf("all_release_configs-%s.%s", product, format)),
+ &configs.Artifact)
+}
+
+func ReleaseConfigsFactory() (c *ReleaseConfigs) {
+ return &ReleaseConfigs{
+ Aliases: make(map[string]*string),
+ FlagArtifacts: make(map[string]*FlagArtifact),
+ ReleaseConfigs: make(map[string]*ReleaseConfig),
+ releaseConfigMapsMap: make(map[string]*ReleaseConfigMap),
+ configDirs: []string{},
+ configDirIndexes: make(ReleaseConfigDirMap),
+ }
+}
+
+func ReleaseConfigMapFactory(protoPath string) (m *ReleaseConfigMap) {
+ m = &ReleaseConfigMap{
+ path: protoPath,
+ ReleaseConfigContributions: make(map[string]*ReleaseConfigContribution),
+ }
+ if protoPath != "" {
+ LoadMessage(protoPath, &m.proto)
+ }
+ return m
+}
+
+func (configs *ReleaseConfigs) LoadReleaseConfigMap(path string, ConfigDirIndex int) error {
+ m := ReleaseConfigMapFactory(path)
+ if m.proto.DefaultContainer == nil {
+ return fmt.Errorf("Release config map %s lacks default_container", path)
+ }
+ dir := filepath.Dir(path)
+ // Record any aliases, checking for duplicates.
+ for _, alias := range m.proto.Aliases {
+ name := *alias.Name
+ oldTarget, ok := configs.Aliases[name]
+ if ok {
+ if *oldTarget != *alias.Target {
+ return fmt.Errorf("Conflicting alias declarations: %s vs %s",
+ *oldTarget, *alias.Target)
+ }
+ }
+ configs.Aliases[name] = alias.Target
+ }
+ var err error
+ err = WalkTextprotoFiles(dir, "flag_declarations", func(path string, d fs.DirEntry, err error) error {
+ flagDeclaration := FlagDeclarationFactory(path)
+ // Container must be specified.
+ if flagDeclaration.Container == nil {
+ flagDeclaration.Container = m.proto.DefaultContainer
+ }
+ // TODO: once we have namespaces initialized, we can throw an error here.
+ if flagDeclaration.Namespace == nil {
+ flagDeclaration.Namespace = proto.String("android_UNKNOWN")
+ }
+ // If the input didn't specify a value, create one (== UnspecifiedValue).
+ if flagDeclaration.Value == nil {
+ flagDeclaration.Value = &rc_proto.Value{Val: &rc_proto.Value_UnspecifiedValue{false}}
+ }
+ m.FlagDeclarations = append(m.FlagDeclarations, *flagDeclaration)
+ name := *flagDeclaration.Name
+ if def, ok := configs.FlagArtifacts[name]; !ok {
+ configs.FlagArtifacts[name] = &FlagArtifact{FlagDeclaration: flagDeclaration, DeclarationIndex: ConfigDirIndex}
+ } else if !proto.Equal(def.FlagDeclaration, flagDeclaration) {
+ return fmt.Errorf("Duplicate definition of %s", *flagDeclaration.Name)
+ }
+ // Set the initial value in the flag artifact.
+ configs.FlagArtifacts[name].UpdateValue(
+ FlagValue{path: path, proto: rc_proto.FlagValue{
+ Name: proto.String(name), Value: flagDeclaration.Value}})
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+
+ err = WalkTextprotoFiles(dir, "release_configs", func(path string, d fs.DirEntry, err error) error {
+ releaseConfigContribution := &ReleaseConfigContribution{path: path, DeclarationIndex: ConfigDirIndex}
+ LoadMessage(path, &releaseConfigContribution.proto)
+ name := *releaseConfigContribution.proto.Name
+ if fmt.Sprintf("%s.textproto", name) != filepath.Base(path) {
+ return fmt.Errorf("%s incorrectly declares release config %s", path, name)
+ }
+ if _, ok := configs.ReleaseConfigs[name]; !ok {
+ configs.ReleaseConfigs[name] = ReleaseConfigFactory(name, ConfigDirIndex)
+ }
+ config := configs.ReleaseConfigs[name]
+ config.InheritNames = append(config.InheritNames, releaseConfigContribution.proto.Inherits...)
+
+ // Only walk flag_values/{RELEASE} for defined releases.
+ err2 := WalkTextprotoFiles(dir, filepath.Join("flag_values", name), func(path string, d fs.DirEntry, err error) error {
+ flagValue := FlagValueFactory(path)
+ if fmt.Sprintf("%s.textproto", *flagValue.proto.Name) != filepath.Base(path) {
+ return fmt.Errorf("%s incorrectly sets value for flag %s", path, *flagValue.proto.Name)
+ }
+ releaseConfigContribution.FlagValues = append(releaseConfigContribution.FlagValues, flagValue)
+ return nil
+ })
+ if err2 != nil {
+ return err2
+ }
+ m.ReleaseConfigContributions[name] = releaseConfigContribution
+ config.Contributions = append(config.Contributions, releaseConfigContribution)
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+ configs.ReleaseConfigMaps = append(configs.ReleaseConfigMaps, m)
+ configs.releaseConfigMapsMap[dir] = m
+ return nil
+}
+
+func (configs *ReleaseConfigs) GetReleaseConfig(name string) (*ReleaseConfig, error) {
+ trace := []string{name}
+ for target, ok := configs.Aliases[name]; ok; target, ok = configs.Aliases[name] {
+ name = *target
+ trace = append(trace, name)
+ }
+ if config, ok := configs.ReleaseConfigs[name]; ok {
+ return config, nil
+ }
+ return nil, fmt.Errorf("Missing config %s. Trace=%v", name, trace)
+}
+
+// Write the makefile for this targetRelease.
+func (configs *ReleaseConfigs) WriteMakefile(outFile, targetRelease string) error {
+ makeVars := make(map[string]string)
+ var allReleaseNames []string
+ for _, v := range configs.ReleaseConfigs {
+ allReleaseNames = append(allReleaseNames, v.Name)
+ allReleaseNames = append(allReleaseNames, v.OtherNames...)
+ }
+ config, err := configs.GetReleaseConfig(targetRelease)
+ if err != nil {
+ return err
+ }
+
+ myFlagArtifacts := config.FlagArtifacts.Clone()
+ // Sort the flags by name first.
+ names := []string{}
+ for k, _ := range myFlagArtifacts {
+ names = append(names, k)
+ }
+ slices.SortFunc(names, func(a, b string) int {
+ return cmp.Compare(a, b)
+ })
+ partitions := make(map[string][]string)
+
+ vNames := []string{}
+ addVar := func(name, suffix, value string) {
+ fullName := fmt.Sprintf("_ALL_RELEASE_FLAGS.%s.%s", name, suffix)
+ vNames = append(vNames, fullName)
+ makeVars[fullName] = value
+ }
+
+ for _, name := range names {
+ flag := myFlagArtifacts[name]
+ decl := flag.FlagDeclaration
+
+ // cName := strings.ToLower(rc_proto.Container_name[decl.GetContainer()])
+ cName := strings.ToLower(decl.Container.String())
+ if cName == strings.ToLower(rc_proto.Container_ALL.String()) {
+ partitions["product"] = append(partitions["product"], name)
+ partitions["system"] = append(partitions["system"], name)
+ partitions["system_ext"] = append(partitions["system_ext"], name)
+ partitions["vendor"] = append(partitions["vendor"], name)
+ } else {
+ partitions[cName] = append(partitions[cName], name)
+ }
+ value := MarshalValue(flag.Value)
+ makeVars[name] = value
+ addVar(name, "PARTITIONS", cName)
+ addVar(name, "DEFAULT", MarshalValue(decl.Value))
+ addVar(name, "VALUE", value)
+ addVar(name, "DECLARED_IN", *flag.Traces[0].Source)
+ addVar(name, "SET_IN", *flag.Traces[len(flag.Traces)-1].Source)
+ addVar(name, "NAMESPACE", *decl.Namespace)
+ }
+ pNames := []string{}
+ for k, _ := range partitions {
+ pNames = append(pNames, k)
+ }
+ slices.SortFunc(pNames, func(a, b string) int {
+ return cmp.Compare(a, b)
+ })
+
+ // Now sort the make variables, and output them.
+ slices.SortFunc(vNames, func(a, b string) int {
+ return cmp.Compare(a, b)
+ })
+
+ // Write the flags as:
+ // _ALL_RELELASE_FLAGS
+ // _ALL_RELEASE_FLAGS.PARTITIONS.*
+ // all _ALL_RELEASE_FLAGS.*, sorted by name
+ // Final flag values, sorted by name.
+ data := fmt.Sprintf("# TARGET_RELEASE=%s\n", config.Name)
+ if targetRelease != config.Name {
+ data += fmt.Sprintf("# User specified TARGET_RELEASE=%s\n", targetRelease)
+ }
+ // The variable _all_release_configs will get deleted during processing, so do not mark it read-only.
+ data += fmt.Sprintf("_all_release_configs := %s\n", strings.Join(allReleaseNames, " "))
+ data += fmt.Sprintf("_ALL_RELEASE_FLAGS :=$= %s\n", strings.Join(names, " "))
+ for _, pName := range pNames {
+ data += fmt.Sprintf("_ALL_RELEASE_FLAGS.PARTITIONS.%s :=$= %s\n", pName, strings.Join(partitions[pName], " "))
+ }
+ for _, vName := range vNames {
+ data += fmt.Sprintf("%s :=$= %s\n", vName, makeVars[vName])
+ }
+ data += "\n\n# Values for all build flags\n"
+ for _, name := range names {
+ data += fmt.Sprintf("%s :=$= %s\n", name, makeVars[name])
+ }
+ return os.WriteFile(outFile, []byte(data), 0644)
+}
+
+func (configs *ReleaseConfigs) GenerateReleaseConfigs(targetRelease string) error {
+ otherNames := make(map[string][]string)
+ for aliasName, aliasTarget := range configs.Aliases {
+ if _, ok := configs.ReleaseConfigs[aliasName]; ok {
+ return fmt.Errorf("Alias %s is a declared release config", aliasName)
+ }
+ if _, ok := configs.ReleaseConfigs[*aliasTarget]; !ok {
+ if _, ok2 := configs.Aliases[*aliasTarget]; !ok2 {
+ return fmt.Errorf("Alias %s points to non-existing config %s", aliasName, *aliasTarget)
+ }
+ }
+ otherNames[*aliasTarget] = append(otherNames[*aliasTarget], aliasName)
+ }
+ for name, aliases := range otherNames {
+ configs.ReleaseConfigs[name].OtherNames = aliases
+ }
+
+ for _, config := range configs.ReleaseConfigs {
+ err := config.GenerateReleaseConfig(configs)
+ if err != nil {
+ return err
+ }
+ }
+
+ releaseConfig, err := configs.GetReleaseConfig(targetRelease)
+ if err != nil {
+ return err
+ }
+ configs.Artifact = rc_proto.ReleaseConfigsArtifact{
+ ReleaseConfig: releaseConfig.ReleaseConfigArtifact,
+ OtherReleaseConfigs: func() []*rc_proto.ReleaseConfigArtifact {
+ orc := []*rc_proto.ReleaseConfigArtifact{}
+ for name, config := range configs.ReleaseConfigs {
+ if name != releaseConfig.Name {
+ orc = append(orc, config.ReleaseConfigArtifact)
+ }
+ }
+ return orc
+ }(),
+ ReleaseConfigMapsMap: func() map[string]*rc_proto.ReleaseConfigMap {
+ ret := make(map[string]*rc_proto.ReleaseConfigMap)
+ for k, v := range configs.releaseConfigMapsMap {
+ ret[k] = &v.proto
+ }
+ return ret
+ }(),
+ }
+ return nil
+}
+
+func ReadReleaseConfigMaps(releaseConfigMapPaths StringList, targetRelease string) (*ReleaseConfigs, error) {
+ var err error
+
+ if len(releaseConfigMapPaths) == 0 {
+ releaseConfigMapPaths = GetDefaultMapPaths()
+ if len(releaseConfigMapPaths) == 0 {
+ return nil, fmt.Errorf("No maps found")
+ }
+ fmt.Printf("No --map argument provided. Using: --map %s\n", strings.Join(releaseConfigMapPaths, " --map "))
+ }
+
+ configs := ReleaseConfigsFactory()
+ for idx, releaseConfigMapPath := range releaseConfigMapPaths {
+ // Maintain an ordered list of release config directories.
+ configDir := filepath.Dir(releaseConfigMapPath)
+ configs.configDirIndexes[configDir] = idx
+ configs.configDirs = append(configs.configDirs, configDir)
+ err = configs.LoadReleaseConfigMap(releaseConfigMapPath, idx)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ // Now that we have all of the release config maps, can meld them and generate the artifacts.
+ err = configs.GenerateReleaseConfigs(targetRelease)
+ return configs, err
+}
diff --git a/cmd/release_config/release_config_lib/util.go b/cmd/release_config/release_config_lib/util.go
new file mode 100644
index 0000000..86940da
--- /dev/null
+++ b/cmd/release_config/release_config_lib/util.go
@@ -0,0 +1,158 @@
+// Copyright 2024 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 release_config_lib
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "google.golang.org/protobuf/encoding/prototext"
+ "google.golang.org/protobuf/proto"
+)
+
+var disableWarnings bool
+
+type StringList []string
+
+func (l *StringList) Set(v string) error {
+ *l = append(*l, v)
+ return nil
+}
+
+func (l *StringList) String() string {
+ return fmt.Sprintf("%v", *l)
+}
+
+// Write a marshalled message to a file.
+//
+// Marshal the message based on the extension of the path we are writing it to.
+//
+// Args:
+//
+// path string: the path of the file to write to. Directories are not created.
+// Supported extensions are: ".json", ".pb", and ".textproto".
+// message proto.Message: the message to write.
+//
+// Returns:
+//
+// error: any error encountered.
+func WriteMessage(path string, message proto.Message) (err error) {
+ var data []byte
+ switch filepath.Ext(path) {
+ case ".json":
+ data, err = json.MarshalIndent(message, "", " ")
+ case ".pb":
+ data, err = proto.Marshal(message)
+ case ".textproto":
+ data, err = prototext.MarshalOptions{Multiline: true}.Marshal(message)
+ default:
+ return fmt.Errorf("Unknown message format for %s", path)
+ }
+ if err != nil {
+ return err
+ }
+ return os.WriteFile(path, data, 0644)
+}
+
+// Read a message from a file.
+//
+// The message is unmarshalled based on the extension of the file read.
+//
+// Args:
+//
+// path string: the path of the file to read.
+// message proto.Message: the message to unmarshal the message into.
+//
+// Returns:
+//
+// error: any error encountered.
+func LoadMessage(path string, message proto.Message) error {
+ data, err := os.ReadFile(path)
+ if err != nil {
+ return err
+ }
+ switch filepath.Ext(path) {
+ case ".json":
+ return json.Unmarshal(data, message)
+ case ".pb":
+ return proto.Unmarshal(data, message)
+ case ".textproto":
+ return prototext.Unmarshal(data, message)
+ }
+ return fmt.Errorf("Unknown message format for %s", path)
+}
+
+// Call Func for any textproto files found in {root}/{subdir}.
+func WalkTextprotoFiles(root string, subdir string, Func fs.WalkDirFunc) error {
+ path := filepath.Join(root, subdir)
+ if _, err := os.Stat(path); err != nil {
+ // Missing subdirs are not an error.
+ return nil
+ }
+ return filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+ if strings.HasSuffix(d.Name(), ".textproto") && d.Type().IsRegular() {
+ return Func(path, d, err)
+ }
+ return nil
+ })
+}
+
+// Turn off all warning output
+func DisableWarnings() {
+ disableWarnings = true
+}
+
+func warnf(format string, args ...any) (n int, err error) {
+ if !disableWarnings {
+ return fmt.Printf(format, args...)
+ }
+ return 0, nil
+}
+
+// Returns the default value for release config artifacts.
+func GetDefaultOutDir() string {
+ outEnv := os.Getenv("OUT_DIR")
+ if outEnv == "" {
+ outEnv = "out"
+ }
+ return filepath.Join(outEnv, "soong", "release-config")
+}
+
+// Return the default list of map files to use.
+func GetDefaultMapPaths() StringList {
+ var defaultMapPaths StringList
+ defaultLocations := StringList{
+ "build/release/release_config_map.textproto",
+ "vendor/google_shared/build/release/release_config_map.textproto",
+ "vendor/google/release/release_config_map.textproto",
+ }
+ for _, path := range defaultLocations {
+ if _, err := os.Stat(path); err == nil {
+ defaultMapPaths = append(defaultMapPaths, path)
+ }
+ }
+ prodMaps := os.Getenv("PRODUCT_RELEASE_CONFIG_MAPS")
+ if prodMaps != "" {
+ defaultMapPaths = append(defaultMapPaths, strings.Split(prodMaps, " ")...)
+ }
+ return defaultMapPaths
+}
diff --git a/cmd/release_config/release_config_proto/Android.bp b/cmd/release_config/release_config_proto/Android.bp
new file mode 100644
index 0000000..8c47f2a
--- /dev/null
+++ b/cmd/release_config/release_config_proto/Android.bp
@@ -0,0 +1,30 @@
+// Copyright 2024 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-cmd-release_config-proto",
+ pkgPath: "android/soong/cmd/release_config/release_config_proto",
+ deps: [
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ ],
+ srcs: [
+ "build_flags_src.pb.go",
+ "build_flags_out.pb.go",
+ ],
+}
diff --git a/cmd/release_config/release_config_proto/build_flags_out.pb.go b/cmd/release_config/release_config_proto/build_flags_out.pb.go
new file mode 100644
index 0000000..0372d63
--- /dev/null
+++ b/cmd/release_config/release_config_proto/build_flags_out.pb.go
@@ -0,0 +1,515 @@
+// 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.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.33.0
+// protoc v3.21.12
+// source: build_flags_out.proto
+
+package release_config_proto
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type Tracepoint struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Path to declaration or value file relative to $TOP
+ Source *string `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"`
+ Value *Value `protobuf:"bytes,201,opt,name=value" json:"value,omitempty"`
+}
+
+func (x *Tracepoint) Reset() {
+ *x = Tracepoint{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_flags_out_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Tracepoint) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Tracepoint) ProtoMessage() {}
+
+func (x *Tracepoint) ProtoReflect() protoreflect.Message {
+ mi := &file_build_flags_out_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Tracepoint.ProtoReflect.Descriptor instead.
+func (*Tracepoint) Descriptor() ([]byte, []int) {
+ return file_build_flags_out_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Tracepoint) GetSource() string {
+ if x != nil && x.Source != nil {
+ return *x.Source
+ }
+ return ""
+}
+
+func (x *Tracepoint) GetValue() *Value {
+ if x != nil {
+ return x.Value
+ }
+ return nil
+}
+
+type FlagArtifact struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The original declaration
+ FlagDeclaration *FlagDeclaration `protobuf:"bytes,1,opt,name=flag_declaration,json=flagDeclaration" json:"flag_declaration,omitempty"`
+ // Value for the flag
+ Value *Value `protobuf:"bytes,201,opt,name=value" json:"value,omitempty"`
+ // Trace of where the flag value was assigned.
+ Traces []*Tracepoint `protobuf:"bytes,8,rep,name=traces" json:"traces,omitempty"`
+}
+
+func (x *FlagArtifact) Reset() {
+ *x = FlagArtifact{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_flags_out_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *FlagArtifact) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FlagArtifact) ProtoMessage() {}
+
+func (x *FlagArtifact) ProtoReflect() protoreflect.Message {
+ mi := &file_build_flags_out_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use FlagArtifact.ProtoReflect.Descriptor instead.
+func (*FlagArtifact) Descriptor() ([]byte, []int) {
+ return file_build_flags_out_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *FlagArtifact) GetFlagDeclaration() *FlagDeclaration {
+ if x != nil {
+ return x.FlagDeclaration
+ }
+ return nil
+}
+
+func (x *FlagArtifact) GetValue() *Value {
+ if x != nil {
+ return x.Value
+ }
+ return nil
+}
+
+func (x *FlagArtifact) GetTraces() []*Tracepoint {
+ if x != nil {
+ return x.Traces
+ }
+ return nil
+}
+
+type ReleaseConfigArtifact struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The name of the release config.
+ // See # name for format detail
+ Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+ // Other names by which this release is known (for example, `next`)
+ OtherNames []string `protobuf:"bytes,2,rep,name=other_names,json=otherNames" json:"other_names,omitempty"`
+ // The complete set of build flags in this release config, after all
+ // inheritance and other processing is complete.
+ FlagArtifacts []*FlagArtifact `protobuf:"bytes,3,rep,name=flag_artifacts,json=flagArtifacts" json:"flag_artifacts,omitempty"`
+ // The (complete) list of aconfig_value_sets Soong modules to use.
+ AconfigValueSets []string `protobuf:"bytes,4,rep,name=aconfig_value_sets,json=aconfigValueSets" json:"aconfig_value_sets,omitempty"`
+ // The names of the release_config_artifacts from which we inherited.
+ // Included for reference only.
+ Inherits []string `protobuf:"bytes,5,rep,name=inherits" json:"inherits,omitempty"`
+ // The release config directories used for this config.
+ // For example, "build/release".
+ Directories []string `protobuf:"bytes,6,rep,name=directories" json:"directories,omitempty"`
+}
+
+func (x *ReleaseConfigArtifact) Reset() {
+ *x = ReleaseConfigArtifact{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_flags_out_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ReleaseConfigArtifact) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ReleaseConfigArtifact) ProtoMessage() {}
+
+func (x *ReleaseConfigArtifact) ProtoReflect() protoreflect.Message {
+ mi := &file_build_flags_out_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ReleaseConfigArtifact.ProtoReflect.Descriptor instead.
+func (*ReleaseConfigArtifact) Descriptor() ([]byte, []int) {
+ return file_build_flags_out_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *ReleaseConfigArtifact) GetName() string {
+ if x != nil && x.Name != nil {
+ return *x.Name
+ }
+ return ""
+}
+
+func (x *ReleaseConfigArtifact) GetOtherNames() []string {
+ if x != nil {
+ return x.OtherNames
+ }
+ return nil
+}
+
+func (x *ReleaseConfigArtifact) GetFlagArtifacts() []*FlagArtifact {
+ if x != nil {
+ return x.FlagArtifacts
+ }
+ return nil
+}
+
+func (x *ReleaseConfigArtifact) GetAconfigValueSets() []string {
+ if x != nil {
+ return x.AconfigValueSets
+ }
+ return nil
+}
+
+func (x *ReleaseConfigArtifact) GetInherits() []string {
+ if x != nil {
+ return x.Inherits
+ }
+ return nil
+}
+
+func (x *ReleaseConfigArtifact) GetDirectories() []string {
+ if x != nil {
+ return x.Directories
+ }
+ return nil
+}
+
+type ReleaseConfigsArtifact struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The active release config for this build.
+ ReleaseConfig *ReleaseConfigArtifact `protobuf:"bytes,1,opt,name=release_config,json=releaseConfig" json:"release_config,omitempty"`
+ // All other release configs defined for this TARGET_PRODUCT.
+ OtherReleaseConfigs []*ReleaseConfigArtifact `protobuf:"bytes,2,rep,name=other_release_configs,json=otherReleaseConfigs" json:"other_release_configs,omitempty"`
+ // Map of release_config_artifact.directories to release_config_map message.
+ ReleaseConfigMapsMap map[string]*ReleaseConfigMap `protobuf:"bytes,3,rep,name=release_config_maps_map,json=releaseConfigMapsMap" json:"release_config_maps_map,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+}
+
+func (x *ReleaseConfigsArtifact) Reset() {
+ *x = ReleaseConfigsArtifact{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_flags_out_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ReleaseConfigsArtifact) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ReleaseConfigsArtifact) ProtoMessage() {}
+
+func (x *ReleaseConfigsArtifact) ProtoReflect() protoreflect.Message {
+ mi := &file_build_flags_out_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ReleaseConfigsArtifact.ProtoReflect.Descriptor instead.
+func (*ReleaseConfigsArtifact) Descriptor() ([]byte, []int) {
+ return file_build_flags_out_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *ReleaseConfigsArtifact) GetReleaseConfig() *ReleaseConfigArtifact {
+ if x != nil {
+ return x.ReleaseConfig
+ }
+ return nil
+}
+
+func (x *ReleaseConfigsArtifact) GetOtherReleaseConfigs() []*ReleaseConfigArtifact {
+ if x != nil {
+ return x.OtherReleaseConfigs
+ }
+ return nil
+}
+
+func (x *ReleaseConfigsArtifact) GetReleaseConfigMapsMap() map[string]*ReleaseConfigMap {
+ if x != nil {
+ return x.ReleaseConfigMapsMap
+ }
+ return nil
+}
+
+var File_build_flags_out_proto protoreflect.FileDescriptor
+
+var file_build_flags_out_proto_rawDesc = []byte{
+ 0x0a, 0x15, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5f, 0x6f, 0x75,
+ 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61,
+ 0x67, 0x73, 0x5f, 0x73, 0x72, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x60, 0x0a, 0x0a,
+ 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f,
+ 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72,
+ 0x63, 0x65, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c,
+ 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xe8,
+ 0x01, 0x0a, 0x0d, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74,
+ 0x12, 0x59, 0x0a, 0x10, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x61, 0x6e, 0x64,
+ 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x64,
+ 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x66, 0x6c, 0x61, 0x67,
+ 0x44, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x05, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6e,
+ 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x40, 0x0a, 0x06, 0x74, 0x72, 0x61, 0x63, 0x65,
+ 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x69, 0x6e,
+ 0x74, 0x52, 0x06, 0x74, 0x72, 0x61, 0x63, 0x65, 0x73, 0x22, 0x8e, 0x02, 0x0a, 0x17, 0x72, 0x65,
+ 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x61, 0x72, 0x74,
+ 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6f, 0x74, 0x68,
+ 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a,
+ 0x6f, 0x74, 0x68, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x52, 0x0a, 0x0e, 0x66, 0x6c,
+ 0x61, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c,
+ 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x2e, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52,
+ 0x0d, 0x66, 0x6c, 0x61, 0x67, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x2c,
+ 0x0a, 0x12, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f,
+ 0x73, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x63, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x65, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08,
+ 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08,
+ 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x72, 0x65,
+ 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x64,
+ 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x22, 0xe8, 0x03, 0x0a, 0x18, 0x72,
+ 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x5f, 0x61,
+ 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x5c, 0x0a, 0x0e, 0x72, 0x65, 0x6c, 0x65, 0x61,
+ 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x35, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
+ 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72,
+ 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x61, 0x72,
+ 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x0d, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x69, 0x0a, 0x15, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x72,
+ 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x18, 0x02,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72,
+ 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x13, 0x6f, 0x74, 0x68,
+ 0x65, 0x72, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73,
+ 0x12, 0x87, 0x01, 0x0a, 0x17, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61, 0x70, 0x73, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x03, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x50, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c,
+ 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74,
+ 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x73, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61,
+ 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x73, 0x4d, 0x61, 0x70, 0x45,
+ 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e,
+ 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x73, 0x4d, 0x61, 0x70, 0x1a, 0x79, 0x0a, 0x19, 0x52, 0x65,
+ 0x6c, 0x65, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4d, 0x61, 0x70, 0x73, 0x4d,
+ 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f,
+ 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61, 0x70, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+}
+
+var (
+ file_build_flags_out_proto_rawDescOnce sync.Once
+ file_build_flags_out_proto_rawDescData = file_build_flags_out_proto_rawDesc
+)
+
+func file_build_flags_out_proto_rawDescGZIP() []byte {
+ file_build_flags_out_proto_rawDescOnce.Do(func() {
+ file_build_flags_out_proto_rawDescData = protoimpl.X.CompressGZIP(file_build_flags_out_proto_rawDescData)
+ })
+ return file_build_flags_out_proto_rawDescData
+}
+
+var file_build_flags_out_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
+var file_build_flags_out_proto_goTypes = []interface{}{
+ (*Tracepoint)(nil), // 0: android.release_config_proto.tracepoint
+ (*FlagArtifact)(nil), // 1: android.release_config_proto.flag_artifact
+ (*ReleaseConfigArtifact)(nil), // 2: android.release_config_proto.release_config_artifact
+ (*ReleaseConfigsArtifact)(nil), // 3: android.release_config_proto.release_configs_artifact
+ nil, // 4: android.release_config_proto.release_configs_artifact.ReleaseConfigMapsMapEntry
+ (*Value)(nil), // 5: android.release_config_proto.value
+ (*FlagDeclaration)(nil), // 6: android.release_config_proto.flag_declaration
+ (*ReleaseConfigMap)(nil), // 7: android.release_config_proto.release_config_map
+}
+var file_build_flags_out_proto_depIdxs = []int32{
+ 5, // 0: android.release_config_proto.tracepoint.value:type_name -> android.release_config_proto.value
+ 6, // 1: android.release_config_proto.flag_artifact.flag_declaration:type_name -> android.release_config_proto.flag_declaration
+ 5, // 2: android.release_config_proto.flag_artifact.value:type_name -> android.release_config_proto.value
+ 0, // 3: android.release_config_proto.flag_artifact.traces:type_name -> android.release_config_proto.tracepoint
+ 1, // 4: android.release_config_proto.release_config_artifact.flag_artifacts:type_name -> android.release_config_proto.flag_artifact
+ 2, // 5: android.release_config_proto.release_configs_artifact.release_config:type_name -> android.release_config_proto.release_config_artifact
+ 2, // 6: android.release_config_proto.release_configs_artifact.other_release_configs:type_name -> android.release_config_proto.release_config_artifact
+ 4, // 7: android.release_config_proto.release_configs_artifact.release_config_maps_map:type_name -> android.release_config_proto.release_configs_artifact.ReleaseConfigMapsMapEntry
+ 7, // 8: android.release_config_proto.release_configs_artifact.ReleaseConfigMapsMapEntry.value:type_name -> android.release_config_proto.release_config_map
+ 9, // [9:9] is the sub-list for method output_type
+ 9, // [9:9] is the sub-list for method input_type
+ 9, // [9:9] is the sub-list for extension type_name
+ 9, // [9:9] is the sub-list for extension extendee
+ 0, // [0:9] is the sub-list for field type_name
+}
+
+func init() { file_build_flags_out_proto_init() }
+func file_build_flags_out_proto_init() {
+ if File_build_flags_out_proto != nil {
+ return
+ }
+ file_build_flags_src_proto_init()
+ if !protoimpl.UnsafeEnabled {
+ file_build_flags_out_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Tracepoint); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_build_flags_out_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*FlagArtifact); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_build_flags_out_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ReleaseConfigArtifact); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_build_flags_out_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ReleaseConfigsArtifact); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_build_flags_out_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 5,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_build_flags_out_proto_goTypes,
+ DependencyIndexes: file_build_flags_out_proto_depIdxs,
+ MessageInfos: file_build_flags_out_proto_msgTypes,
+ }.Build()
+ File_build_flags_out_proto = out.File
+ file_build_flags_out_proto_rawDesc = nil
+ file_build_flags_out_proto_goTypes = nil
+ file_build_flags_out_proto_depIdxs = nil
+}
diff --git a/cmd/release_config/release_config_proto/build_flags_out.proto b/cmd/release_config/release_config_proto/build_flags_out.proto
new file mode 100644
index 0000000..05e770f
--- /dev/null
+++ b/cmd/release_config/release_config_proto/build_flags_out.proto
@@ -0,0 +1,89 @@
+// 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.
+
+syntax = "proto2";
+package android.release_config_proto;
+option go_package = "android/soong/release_config/release_config_proto";
+
+import "build_flags_src.proto";
+
+// This protobuf file defines messages used to represent the release config for
+// the android build system, delivered as a build artifact for use by tools such
+// as Gantry.
+//
+// The following format requirements apply across various message fields:
+//
+// # name: name of the flag
+//
+// format: an uppercase string in SNAKE_CASE format starting with RELEASE_,
+// no consecutive underscores, and no leading digit. For example
+// RELEASE_MY_PACKAGE_FLAG is a valid name, while MY_PACKAGE_FLAG, and
+// RELEASE_MY_PACKAGE__FLAG are invalid.
+//
+// # package: package to which the flag belongs
+//
+// format: lowercase strings in snake_case format, delimited by dots, no
+// consecutive underscores and no leading digit in each string. For example
+// com.android.mypackage is a valid name while com.android.myPackage,
+// com.android.1mypackage are invalid
+
+message tracepoint {
+ // Path to declaration or value file relative to $TOP
+ optional string source = 1;
+ optional value value = 201;
+}
+
+message flag_artifact {
+ // The original declaration
+ optional flag_declaration flag_declaration = 1;
+
+ // Value for the flag
+ optional value value = 201;
+
+ // Trace of where the flag value was assigned.
+ repeated tracepoint traces = 8;
+}
+
+message release_config_artifact {
+ // The name of the release config.
+ // See # name for format detail
+ optional string name = 1;
+
+ // Other names by which this release is known (for example, `next`)
+ repeated string other_names = 2;
+
+ // The complete set of build flags in this release config, after all
+ // inheritance and other processing is complete.
+ repeated flag_artifact flag_artifacts = 3;
+
+ // The (complete) list of aconfig_value_sets Soong modules to use.
+ repeated string aconfig_value_sets = 4;
+
+ // The names of the release_config_artifacts from which we inherited.
+ // Included for reference only.
+ repeated string inherits = 5;
+
+ // The release config directories used for this config.
+ // For example, "build/release".
+ repeated string directories = 6;
+}
+
+message release_configs_artifact {
+ // The active release config for this build.
+ optional release_config_artifact release_config = 1;
+
+ // All other release configs defined for this TARGET_PRODUCT.
+ repeated release_config_artifact other_release_configs = 2;
+
+ // Map of release_config_artifact.directories to release_config_map message.
+ map<string, release_config_map> release_config_maps_map = 3;
+}
+
diff --git a/cmd/release_config/release_config_proto/build_flags_src.pb.go b/cmd/release_config/release_config_proto/build_flags_src.pb.go
new file mode 100644
index 0000000..d0c924d
--- /dev/null
+++ b/cmd/release_config/release_config_proto/build_flags_src.pb.go
@@ -0,0 +1,856 @@
+// 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.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.33.0
+// protoc v3.21.12
+// source: build_flags_src.proto
+
+package release_config_proto
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type Workflow int32
+
+const (
+ Workflow_UNSPECIFIED_workflow Workflow = 0
+ // Boolean value flags that progress from false to true.
+ Workflow_LAUNCH Workflow = 1
+ // String value flags that get updated with new version strings to control
+ // prebuilt inclusion.
+ Workflow_PREBUILT Workflow = 2
+ // Manually managed outside flags. These are likely to be found in a
+ // different directory than flags with other workflows.
+ Workflow_MANUAL Workflow = 3
+)
+
+// Enum value maps for Workflow.
+var (
+ Workflow_name = map[int32]string{
+ 0: "UNSPECIFIED_workflow",
+ 1: "LAUNCH",
+ 2: "PREBUILT",
+ 3: "MANUAL",
+ }
+ Workflow_value = map[string]int32{
+ "UNSPECIFIED_workflow": 0,
+ "LAUNCH": 1,
+ "PREBUILT": 2,
+ "MANUAL": 3,
+ }
+)
+
+func (x Workflow) Enum() *Workflow {
+ p := new(Workflow)
+ *p = x
+ return p
+}
+
+func (x Workflow) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Workflow) Descriptor() protoreflect.EnumDescriptor {
+ return file_build_flags_src_proto_enumTypes[0].Descriptor()
+}
+
+func (Workflow) Type() protoreflect.EnumType {
+ return &file_build_flags_src_proto_enumTypes[0]
+}
+
+func (x Workflow) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *Workflow) UnmarshalJSON(b []byte) error {
+ num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
+ if err != nil {
+ return err
+ }
+ *x = Workflow(num)
+ return nil
+}
+
+// Deprecated: Use Workflow.Descriptor instead.
+func (Workflow) EnumDescriptor() ([]byte, []int) {
+ return file_build_flags_src_proto_rawDescGZIP(), []int{0}
+}
+
+type Container int32
+
+const (
+ Container_UNSPECIFIED_container Container = 0
+ // All containers
+ Container_ALL Container = 1
+ // Specific containers
+ Container_PRODUCT Container = 2
+ Container_SYSTEM Container = 3
+ Container_SYSTEM_EXT Container = 4
+ Container_VENDOR Container = 5
+)
+
+// Enum value maps for Container.
+var (
+ Container_name = map[int32]string{
+ 0: "UNSPECIFIED_container",
+ 1: "ALL",
+ 2: "PRODUCT",
+ 3: "SYSTEM",
+ 4: "SYSTEM_EXT",
+ 5: "VENDOR",
+ }
+ Container_value = map[string]int32{
+ "UNSPECIFIED_container": 0,
+ "ALL": 1,
+ "PRODUCT": 2,
+ "SYSTEM": 3,
+ "SYSTEM_EXT": 4,
+ "VENDOR": 5,
+ }
+)
+
+func (x Container) Enum() *Container {
+ p := new(Container)
+ *p = x
+ return p
+}
+
+func (x Container) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Container) Descriptor() protoreflect.EnumDescriptor {
+ return file_build_flags_src_proto_enumTypes[1].Descriptor()
+}
+
+func (Container) Type() protoreflect.EnumType {
+ return &file_build_flags_src_proto_enumTypes[1]
+}
+
+func (x Container) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *Container) UnmarshalJSON(b []byte) error {
+ num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
+ if err != nil {
+ return err
+ }
+ *x = Container(num)
+ return nil
+}
+
+// Deprecated: Use Container.Descriptor instead.
+func (Container) EnumDescriptor() ([]byte, []int) {
+ return file_build_flags_src_proto_rawDescGZIP(), []int{1}
+}
+
+type Value struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Types that are assignable to Val:
+ //
+ // *Value_UnspecifiedValue
+ // *Value_StringValue
+ // *Value_BoolValue
+ // *Value_Obsolete
+ Val isValue_Val `protobuf_oneof:"val"`
+}
+
+func (x *Value) Reset() {
+ *x = Value{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_flags_src_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Value) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Value) ProtoMessage() {}
+
+func (x *Value) ProtoReflect() protoreflect.Message {
+ mi := &file_build_flags_src_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Value.ProtoReflect.Descriptor instead.
+func (*Value) Descriptor() ([]byte, []int) {
+ return file_build_flags_src_proto_rawDescGZIP(), []int{0}
+}
+
+func (m *Value) GetVal() isValue_Val {
+ if m != nil {
+ return m.Val
+ }
+ return nil
+}
+
+func (x *Value) GetUnspecifiedValue() bool {
+ if x, ok := x.GetVal().(*Value_UnspecifiedValue); ok {
+ return x.UnspecifiedValue
+ }
+ return false
+}
+
+func (x *Value) GetStringValue() string {
+ if x, ok := x.GetVal().(*Value_StringValue); ok {
+ return x.StringValue
+ }
+ return ""
+}
+
+func (x *Value) GetBoolValue() bool {
+ if x, ok := x.GetVal().(*Value_BoolValue); ok {
+ return x.BoolValue
+ }
+ return false
+}
+
+func (x *Value) GetObsolete() bool {
+ if x, ok := x.GetVal().(*Value_Obsolete); ok {
+ return x.Obsolete
+ }
+ return false
+}
+
+type isValue_Val interface {
+ isValue_Val()
+}
+
+type Value_UnspecifiedValue struct {
+ UnspecifiedValue bool `protobuf:"varint,200,opt,name=unspecified_value,json=unspecifiedValue,oneof"`
+}
+
+type Value_StringValue struct {
+ StringValue string `protobuf:"bytes,201,opt,name=string_value,json=stringValue,oneof"`
+}
+
+type Value_BoolValue struct {
+ BoolValue bool `protobuf:"varint,202,opt,name=bool_value,json=boolValue,oneof"`
+}
+
+type Value_Obsolete struct {
+ // If true, the flag is obsolete. Assigning it further will be flagged.
+ Obsolete bool `protobuf:"varint,203,opt,name=obsolete,oneof"`
+}
+
+func (*Value_UnspecifiedValue) isValue_Val() {}
+
+func (*Value_StringValue) isValue_Val() {}
+
+func (*Value_BoolValue) isValue_Val() {}
+
+func (*Value_Obsolete) isValue_Val() {}
+
+// The proto used in the source tree.
+type FlagDeclaration struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The name of the flag.
+ // See # name for format detail
+ Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+ // Namespace the flag belongs to (required)
+ // See # namespace for format detail
+ Namespace *string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"`
+ // Text description of the flag's purpose.
+ Description *string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"`
+ // Value for the flag
+ Value *Value `protobuf:"bytes,201,opt,name=value" json:"value,omitempty"`
+ // Workflow for this flag.
+ Workflow *Workflow `protobuf:"varint,205,opt,name=workflow,enum=android.release_config_proto.Workflow" json:"workflow,omitempty"`
+ // The container for this flag. This overrides any default container given
+ // in the release_config_map message.
+ Container *Container `protobuf:"varint,206,opt,name=container,enum=android.release_config_proto.Container" json:"container,omitempty"`
+}
+
+func (x *FlagDeclaration) Reset() {
+ *x = FlagDeclaration{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_flags_src_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *FlagDeclaration) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FlagDeclaration) ProtoMessage() {}
+
+func (x *FlagDeclaration) ProtoReflect() protoreflect.Message {
+ mi := &file_build_flags_src_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use FlagDeclaration.ProtoReflect.Descriptor instead.
+func (*FlagDeclaration) Descriptor() ([]byte, []int) {
+ return file_build_flags_src_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *FlagDeclaration) GetName() string {
+ if x != nil && x.Name != nil {
+ return *x.Name
+ }
+ return ""
+}
+
+func (x *FlagDeclaration) GetNamespace() string {
+ if x != nil && x.Namespace != nil {
+ return *x.Namespace
+ }
+ return ""
+}
+
+func (x *FlagDeclaration) GetDescription() string {
+ if x != nil && x.Description != nil {
+ return *x.Description
+ }
+ return ""
+}
+
+func (x *FlagDeclaration) GetValue() *Value {
+ if x != nil {
+ return x.Value
+ }
+ return nil
+}
+
+func (x *FlagDeclaration) GetWorkflow() Workflow {
+ if x != nil && x.Workflow != nil {
+ return *x.Workflow
+ }
+ return Workflow_UNSPECIFIED_workflow
+}
+
+func (x *FlagDeclaration) GetContainer() Container {
+ if x != nil && x.Container != nil {
+ return *x.Container
+ }
+ return Container_UNSPECIFIED_container
+}
+
+type FlagValue struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Name of the flag.
+ // See # name for format detail
+ Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
+ // Value for the flag
+ Value *Value `protobuf:"bytes,201,opt,name=value" json:"value,omitempty"`
+}
+
+func (x *FlagValue) Reset() {
+ *x = FlagValue{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_flags_src_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *FlagValue) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FlagValue) ProtoMessage() {}
+
+func (x *FlagValue) ProtoReflect() protoreflect.Message {
+ mi := &file_build_flags_src_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use FlagValue.ProtoReflect.Descriptor instead.
+func (*FlagValue) Descriptor() ([]byte, []int) {
+ return file_build_flags_src_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *FlagValue) GetName() string {
+ if x != nil && x.Name != nil {
+ return *x.Name
+ }
+ return ""
+}
+
+func (x *FlagValue) GetValue() *Value {
+ if x != nil {
+ return x.Value
+ }
+ return nil
+}
+
+// This replaces $(call declare-release-config).
+type ReleaseConfig struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The name of the release config.
+ // See # name for format detail
+ Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+ // From which other release configs does this one inherit?
+ Inherits []string `protobuf:"bytes,2,rep,name=inherits" json:"inherits,omitempty"`
+ // List of names of the aconfig_value_set soong module(s) for this
+ // contribution.
+ AconfigValueSets []string `protobuf:"bytes,3,rep,name=aconfig_value_sets,json=aconfigValueSets" json:"aconfig_value_sets,omitempty"`
+}
+
+func (x *ReleaseConfig) Reset() {
+ *x = ReleaseConfig{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_flags_src_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ReleaseConfig) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ReleaseConfig) ProtoMessage() {}
+
+func (x *ReleaseConfig) ProtoReflect() protoreflect.Message {
+ mi := &file_build_flags_src_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ReleaseConfig.ProtoReflect.Descriptor instead.
+func (*ReleaseConfig) Descriptor() ([]byte, []int) {
+ return file_build_flags_src_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *ReleaseConfig) GetName() string {
+ if x != nil && x.Name != nil {
+ return *x.Name
+ }
+ return ""
+}
+
+func (x *ReleaseConfig) GetInherits() []string {
+ if x != nil {
+ return x.Inherits
+ }
+ return nil
+}
+
+func (x *ReleaseConfig) GetAconfigValueSets() []string {
+ if x != nil {
+ return x.AconfigValueSets
+ }
+ return nil
+}
+
+// Any aliases. These are used for continuous integration builder config.
+type ReleaseAlias struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The name of the alias.
+ Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+ // The release that `name` is an alias for.
+ Target *string `protobuf:"bytes,2,opt,name=target" json:"target,omitempty"`
+}
+
+func (x *ReleaseAlias) Reset() {
+ *x = ReleaseAlias{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_flags_src_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ReleaseAlias) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ReleaseAlias) ProtoMessage() {}
+
+func (x *ReleaseAlias) ProtoReflect() protoreflect.Message {
+ mi := &file_build_flags_src_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ReleaseAlias.ProtoReflect.Descriptor instead.
+func (*ReleaseAlias) Descriptor() ([]byte, []int) {
+ return file_build_flags_src_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *ReleaseAlias) GetName() string {
+ if x != nil && x.Name != nil {
+ return *x.Name
+ }
+ return ""
+}
+
+func (x *ReleaseAlias) GetTarget() string {
+ if x != nil && x.Target != nil {
+ return *x.Target
+ }
+ return ""
+}
+
+// This provides the data from release_config_map.mk
+type ReleaseConfigMap struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // Any aliases.
+ Aliases []*ReleaseAlias `protobuf:"bytes,1,rep,name=aliases" json:"aliases,omitempty"`
+ // Description of this map and its intended use.
+ Description *string `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"`
+ // The default container for flags declared here.
+ DefaultContainer *Container `protobuf:"varint,3,opt,name=default_container,json=defaultContainer,enum=android.release_config_proto.Container" json:"default_container,omitempty"`
+}
+
+func (x *ReleaseConfigMap) Reset() {
+ *x = ReleaseConfigMap{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_build_flags_src_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ReleaseConfigMap) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ReleaseConfigMap) ProtoMessage() {}
+
+func (x *ReleaseConfigMap) ProtoReflect() protoreflect.Message {
+ mi := &file_build_flags_src_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ReleaseConfigMap.ProtoReflect.Descriptor instead.
+func (*ReleaseConfigMap) Descriptor() ([]byte, []int) {
+ return file_build_flags_src_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *ReleaseConfigMap) GetAliases() []*ReleaseAlias {
+ if x != nil {
+ return x.Aliases
+ }
+ return nil
+}
+
+func (x *ReleaseConfigMap) GetDescription() string {
+ if x != nil && x.Description != nil {
+ return *x.Description
+ }
+ return ""
+}
+
+func (x *ReleaseConfigMap) GetDefaultContainer() Container {
+ if x != nil && x.DefaultContainer != nil {
+ return *x.DefaultContainer
+ }
+ return Container_UNSPECIFIED_container
+}
+
+var File_build_flags_src_proto protoreflect.FileDescriptor
+
+var file_build_flags_src_proto_rawDesc = []byte{
+ 0x0a, 0x15, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x5f, 0x73, 0x72,
+ 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa5, 0x01, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12,
+ 0x2e, 0x0a, 0x11, 0x75, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc8, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x10, 0x75,
+ 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
+ 0x24, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0xc9, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x20, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x18, 0xca, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f,
+ 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x08, 0x6f, 0x62, 0x73, 0x6f, 0x6c,
+ 0x65, 0x74, 0x65, 0x18, 0xcb, 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x6f, 0x62,
+ 0x73, 0x6f, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x05, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x22, 0xbd, 0x02,
+ 0x0a, 0x10, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x64, 0x65, 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70,
+ 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73,
+ 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+ 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0xc9, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x12, 0x43, 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0xcd,
+ 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+ 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x08, 0x77,
+ 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x46, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61,
+ 0x69, 0x6e, 0x65, 0x72, 0x18, 0xce, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x61, 0x6e,
+ 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61,
+ 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4a,
+ 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x06, 0x08, 0xcf, 0x01, 0x10, 0xd0, 0x01, 0x22, 0x5c, 0x0a,
+ 0x0a, 0x66, 0x6c, 0x61, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+ 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+ 0x3a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0xc9, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x23, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
+ 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x6e, 0x0a, 0x0e, 0x72,
+ 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a,
+ 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
+ 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x18, 0x02, 0x20,
+ 0x03, 0x28, 0x09, 0x52, 0x08, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x73, 0x12, 0x2c, 0x0a,
+ 0x12, 0x61, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x73,
+ 0x65, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x61, 0x63, 0x6f, 0x6e, 0x66,
+ 0x69, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x65, 0x74, 0x73, 0x22, 0x3b, 0x0a, 0x0d, 0x72,
+ 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04,
+ 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+ 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0xd3, 0x01, 0x0a, 0x12, 0x72, 0x65, 0x6c,
+ 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6d, 0x61, 0x70, 0x12,
+ 0x45, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x2b, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61,
+ 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
+ 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x07, 0x61,
+ 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x54, 0x0a, 0x11, 0x64, 0x65, 0x66, 0x61,
+ 0x75, 0x6c, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x72, 0x65,
+ 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x10, 0x64, 0x65,
+ 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2a, 0x4a,
+ 0x0a, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x18, 0x0a, 0x14, 0x55, 0x4e,
+ 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c,
+ 0x6f, 0x77, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x41, 0x55, 0x4e, 0x43, 0x48, 0x10, 0x01,
+ 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x52, 0x45, 0x42, 0x55, 0x49, 0x4c, 0x54, 0x10, 0x02, 0x12, 0x0a,
+ 0x0a, 0x06, 0x4d, 0x41, 0x4e, 0x55, 0x41, 0x4c, 0x10, 0x03, 0x2a, 0x64, 0x0a, 0x09, 0x63, 0x6f,
+ 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x4e, 0x53, 0x50, 0x45,
+ 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
+ 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x50,
+ 0x52, 0x4f, 0x44, 0x55, 0x43, 0x54, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x59, 0x53, 0x54,
+ 0x45, 0x4d, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x45,
+ 0x58, 0x54, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x56, 0x45, 0x4e, 0x44, 0x4f, 0x52, 0x10, 0x05,
+ 0x42, 0x33, 0x5a, 0x31, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e,
+ 0x67, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f,
+}
+
+var (
+ file_build_flags_src_proto_rawDescOnce sync.Once
+ file_build_flags_src_proto_rawDescData = file_build_flags_src_proto_rawDesc
+)
+
+func file_build_flags_src_proto_rawDescGZIP() []byte {
+ file_build_flags_src_proto_rawDescOnce.Do(func() {
+ file_build_flags_src_proto_rawDescData = protoimpl.X.CompressGZIP(file_build_flags_src_proto_rawDescData)
+ })
+ return file_build_flags_src_proto_rawDescData
+}
+
+var file_build_flags_src_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_build_flags_src_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
+var file_build_flags_src_proto_goTypes = []interface{}{
+ (Workflow)(0), // 0: android.release_config_proto.workflow
+ (Container)(0), // 1: android.release_config_proto.container
+ (*Value)(nil), // 2: android.release_config_proto.value
+ (*FlagDeclaration)(nil), // 3: android.release_config_proto.flag_declaration
+ (*FlagValue)(nil), // 4: android.release_config_proto.flag_value
+ (*ReleaseConfig)(nil), // 5: android.release_config_proto.release_config
+ (*ReleaseAlias)(nil), // 6: android.release_config_proto.release_alias
+ (*ReleaseConfigMap)(nil), // 7: android.release_config_proto.release_config_map
+}
+var file_build_flags_src_proto_depIdxs = []int32{
+ 2, // 0: android.release_config_proto.flag_declaration.value:type_name -> android.release_config_proto.value
+ 0, // 1: android.release_config_proto.flag_declaration.workflow:type_name -> android.release_config_proto.workflow
+ 1, // 2: android.release_config_proto.flag_declaration.container:type_name -> android.release_config_proto.container
+ 2, // 3: android.release_config_proto.flag_value.value:type_name -> android.release_config_proto.value
+ 6, // 4: android.release_config_proto.release_config_map.aliases:type_name -> android.release_config_proto.release_alias
+ 1, // 5: android.release_config_proto.release_config_map.default_container:type_name -> android.release_config_proto.container
+ 6, // [6:6] is the sub-list for method output_type
+ 6, // [6:6] is the sub-list for method input_type
+ 6, // [6:6] is the sub-list for extension type_name
+ 6, // [6:6] is the sub-list for extension extendee
+ 0, // [0:6] is the sub-list for field type_name
+}
+
+func init() { file_build_flags_src_proto_init() }
+func file_build_flags_src_proto_init() {
+ if File_build_flags_src_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_build_flags_src_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Value); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_build_flags_src_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*FlagDeclaration); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_build_flags_src_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*FlagValue); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_build_flags_src_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ReleaseConfig); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_build_flags_src_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ReleaseAlias); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_build_flags_src_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ReleaseConfigMap); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ file_build_flags_src_proto_msgTypes[0].OneofWrappers = []interface{}{
+ (*Value_UnspecifiedValue)(nil),
+ (*Value_StringValue)(nil),
+ (*Value_BoolValue)(nil),
+ (*Value_Obsolete)(nil),
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_build_flags_src_proto_rawDesc,
+ NumEnums: 2,
+ NumMessages: 6,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_build_flags_src_proto_goTypes,
+ DependencyIndexes: file_build_flags_src_proto_depIdxs,
+ EnumInfos: file_build_flags_src_proto_enumTypes,
+ MessageInfos: file_build_flags_src_proto_msgTypes,
+ }.Build()
+ File_build_flags_src_proto = out.File
+ file_build_flags_src_proto_rawDesc = nil
+ file_build_flags_src_proto_goTypes = nil
+ file_build_flags_src_proto_depIdxs = nil
+}
diff --git a/cmd/release_config/release_config_proto/build_flags_src.proto b/cmd/release_config/release_config_proto/build_flags_src.proto
new file mode 100644
index 0000000..c077f5c
--- /dev/null
+++ b/cmd/release_config/release_config_proto/build_flags_src.proto
@@ -0,0 +1,157 @@
+// 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.
+
+syntax = "proto2";
+package android.release_config_proto;
+option go_package = "android/soong/release_config/release_config_proto";
+
+// This protobuf file defines messages used to represent the build flags used by
+// a release in a more human-editable form. It is used for on-disk files in the
+// source tree.
+//
+// The following format requirements apply across various message fields:
+//
+// # name: name of the flag
+//
+// format: an uppercase string in SNAKE_CASE format starting with RELEASE_,
+// no consecutive underscores, and no leading digit. For example
+// RELEASE_MY_PACKAGE_FLAG is a valid name, while MY_PACKAGE_FLAG, and
+// RELEASE_MY_PACKAGE__FLAG are invalid.
+//
+// # namespace: namespace the flag belongs to
+//
+// format: a lowercase string in snake_case format, no consecutive underscores, and no leading
+// digit. For example android_bar_system
+//
+// # package: package to which the flag belongs
+//
+// format: lowercase strings in snake_case format, delimited by dots, no
+// consecutive underscores and no leading digit in each string. For example
+// com.android.mypackage is a valid name while com.android.myPackage,
+// com.android.1mypackage are invalid
+
+enum workflow {
+ UNSPECIFIED_workflow = 0;
+
+ // Boolean value flags that progress from false to true.
+ LAUNCH = 1;
+
+ // String value flags that get updated with new version strings to control
+ // prebuilt inclusion.
+ PREBUILT = 2;
+
+ // Manually managed outside flags. These are likely to be found in a
+ // different directory than flags with other workflows.
+ MANUAL = 3;
+}
+
+enum container {
+ UNSPECIFIED_container = 0;
+
+ // All containers
+ ALL = 1;
+
+ // Specific containers
+ PRODUCT = 2;
+ SYSTEM = 3;
+ SYSTEM_EXT = 4;
+ VENDOR = 5;
+}
+
+message value {
+ oneof val {
+ bool unspecified_value = 200;
+ string string_value = 201;
+ bool bool_value = 202;
+ // If true, the flag is obsolete. Assigning it further will be flagged.
+ bool obsolete = 203;
+ }
+}
+
+// The proto used in the source tree.
+message flag_declaration {
+ // The name of the flag.
+ // See # name for format detail
+ optional string name = 1;
+
+ // Namespace the flag belongs to (required)
+ // See # namespace for format detail
+ optional string namespace = 2;
+
+ // Text description of the flag's purpose.
+ optional string description = 3;
+
+ // reserve this for bug, if needed.
+ reserved 4;
+
+ // Value for the flag
+ optional value value = 201;
+
+ // Workflow for this flag.
+ optional workflow workflow = 205;
+
+ // The container for this flag. This overrides any default container given
+ // in the release_config_map message.
+ optional container container = 206;
+
+ // The package associated with this flag.
+ // (when Gantry is ready for it) optional string package = 207;
+ reserved 207;
+}
+
+message flag_value {
+ // Name of the flag.
+ // See # name for format detail
+ optional string name = 2;
+
+ // Value for the flag
+ optional value value = 201;
+}
+
+// This replaces $(call declare-release-config).
+message release_config {
+ // The name of the release config.
+ // See # name for format detail
+ optional string name = 1;
+
+ // From which other release configs does this one inherit?
+ repeated string inherits = 2;
+
+ // List of names of the aconfig_value_set soong module(s) for this
+ // contribution.
+ repeated string aconfig_value_sets = 3;
+}
+
+// Any aliases. These are used for continuous integration builder config.
+message release_alias {
+ // The name of the alias.
+ optional string name = 1;
+
+ // The release that `name` is an alias for.
+ optional string target = 2;
+}
+
+// This provides the data from release_config_map.mk
+message release_config_map {
+ // Any aliases.
+ repeated release_alias aliases = 1;
+
+ // Description of this map and its intended use.
+ optional string description = 2;
+
+ // The default container for flags declared here.
+ optional container default_container = 3;
+
+ // If needed, we can add these fields instead of hardcoding the location.
+ // Flag declarations: `flag_declarations/*.textproto`
+ // Release config contributions: `release_configs/*.textproto`
+ // Flag values: `flag_values/{RELEASE_NAME}/*.textproto`
+}
diff --git a/cmd/release_config/release_config_proto/regen.sh b/cmd/release_config/release_config_proto/regen.sh
new file mode 100644
index 0000000..1846c4d
--- /dev/null
+++ b/cmd/release_config/release_config_proto/regen.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+aprotoc --go_out=paths=source_relative:. build_flags_src.proto build_flags_out.proto
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
index 57c7ae8..af1d33d 100644
--- a/dexpreopt/class_loader_context.go
+++ b/dexpreopt/class_loader_context.go
@@ -323,6 +323,7 @@
} else if clc.Host == hostPath && clc.Device == devicePath {
// Ok, the same library with the same paths. Don't re-add it, but don't raise an error
// either, as the same library may be reachable via different transitional dependencies.
+ clc.Optional = clc.Optional && optional
return nil
} else {
// Fail, as someone is trying to add the same library with different paths. This likely
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 04bc61d..93351f1 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -52,7 +52,7 @@
// GenerateDexpreoptRule generates a set of commands that will preopt a module based on a GlobalConfig and a
// ModuleConfig. The produced files and their install locations will be available through rule.Installs().
func GenerateDexpreoptRule(ctx android.BuilderContext, globalSoong *GlobalSoongConfig,
- global *GlobalConfig, module *ModuleConfig, productPackages android.Path) (
+ global *GlobalConfig, module *ModuleConfig, productPackages android.Path, copyApexSystemServerJarDex bool) (
rule *android.RuleBuilder, err error) {
defer func() {
@@ -94,7 +94,7 @@
for archIdx, _ := range module.Archs {
dexpreoptCommand(ctx, globalSoong, global, module, rule, archIdx, profile, appImage,
- generateDM, productPackages)
+ generateDM, productPackages, copyApexSystemServerJarDex)
}
}
}
@@ -231,7 +231,7 @@
func dexpreoptCommand(ctx android.BuilderContext, globalSoong *GlobalSoongConfig,
global *GlobalConfig, module *ModuleConfig, rule *android.RuleBuilder, archIdx int,
- profile android.WritablePath, appImage bool, generateDM bool, productPackages android.Path) {
+ profile android.WritablePath, appImage bool, generateDM bool, productPackages android.Path, copyApexSystemServerJarDex bool) {
arch := module.Archs[archIdx]
@@ -277,7 +277,7 @@
clcTarget = append(clcTarget, GetSystemServerDexLocation(ctx, global, lib))
}
- if DexpreoptRunningInSoong {
+ if DexpreoptRunningInSoong && copyApexSystemServerJarDex {
// Copy the system server jar to a predefined location where dex2oat will find it.
dexPathHost := SystemServerDexJarHostPath(ctx, module.Name)
rule.Command().Text("mkdir -p").Flag(filepath.Dir(dexPathHost.String()))
diff --git a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
index 8033b48..7512005 100644
--- a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
+++ b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
@@ -205,8 +205,9 @@
panic(err)
}
}
+ cpApexSscpServerJar := false // dexpreopt_gen operates on make modules, and since sscp libraries are in soong, this should be a noop
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(
- ctx, globalSoong, global, module, android.PathForTesting(productPackagesPath))
+ ctx, globalSoong, global, module, android.PathForTesting(productPackagesPath), cpApexSscpServerJar)
if err != nil {
panic(err)
}
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 7071f3e..eff2416 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -101,7 +101,7 @@
module := testSystemModuleConfig(ctx, "test")
productPackages := android.PathForTesting("product_packages.txt")
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
if err != nil {
t.Fatal(err)
}
@@ -161,7 +161,7 @@
for _, test := range tests {
global.PatternsOnSystemOther = test.patterns
for _, mt := range test.moduleTests {
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, mt.module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, mt.module, productPackages, true)
if err != nil {
t.Fatal(err)
}
@@ -181,6 +181,11 @@
}
func TestDexPreoptApexSystemServerJars(t *testing.T) {
+ // modify the global variable for test
+ var oldDexpreoptRunningInSoong = DexpreoptRunningInSoong
+ DexpreoptRunningInSoong = true
+
+ // test begin
config := android.TestConfig("out", nil, "", nil)
ctx := android.BuilderContextForTesting(config)
globalSoong := globalSoongConfigForTests(ctx)
@@ -191,7 +196,7 @@
global.ApexSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"com.android.apex1:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
if err != nil {
t.Fatal(err)
}
@@ -202,6 +207,18 @@
}
android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
+
+ android.AssertStringListContains(t, "apex sscp jar copy", rule.Outputs().Strings(), "out/soong/system_server_dexjars/service-A.jar")
+
+ // rule with apex sscp cp as false
+ rule, err = GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, false)
+ if err != nil {
+ t.Fatal(err)
+ }
+ android.AssertStringListDoesNotContain(t, "apex sscp jar copy", rule.Outputs().Strings(), "out/soong/system_server_dexjars/service-A.jar")
+
+ // cleanup the global variable for test
+ DexpreoptRunningInSoong = oldDexpreoptRunningInSoong
}
func TestDexPreoptStandaloneSystemServerJars(t *testing.T) {
@@ -215,7 +232,7 @@
global.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"platform:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
if err != nil {
t.Fatal(err)
}
@@ -239,7 +256,7 @@
global.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"system_ext:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
if err != nil {
t.Fatal(err)
}
@@ -263,7 +280,7 @@
global.ApexStandaloneSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"com.android.apex1:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
if err != nil {
t.Fatal(err)
}
@@ -286,7 +303,7 @@
module.ProfileClassListing = android.OptionalPathForPath(android.PathForTesting("profile"))
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
if err != nil {
t.Fatal(err)
}
diff --git a/etc/Android.bp b/etc/Android.bp
index cefd717..97788e4 100644
--- a/etc/Android.bp
+++ b/etc/Android.bp
@@ -9,16 +9,13 @@
"blueprint",
"soong",
"soong-android",
- "soong-snapshot",
],
srcs: [
"prebuilt_etc.go",
- "snapshot_etc.go",
"install_symlink.go",
],
testSrcs: [
"prebuilt_etc_test.go",
- "snapshot_etc_test.go",
"install_symlink_test.go",
],
pluginFor: ["soong_build"],
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index a42c576..d1c1d85 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -28,7 +28,6 @@
// various `prebuilt_*` mutators.
import (
- "encoding/json"
"fmt"
"path/filepath"
"strings"
@@ -36,7 +35,6 @@
"github.com/google/blueprint/proptools"
"android/soong/android"
- "android/soong/snapshot"
)
var pctx = android.NewPackageContext("android/soong/etc")
@@ -46,7 +44,6 @@
func init() {
pctx.Import("android/soong/android")
RegisterPrebuiltEtcBuildComponents(android.InitRegistrationContext)
- snapshot.RegisterSnapshotAction(generatePrebuiltSnapshot)
}
func RegisterPrebuiltEtcBuildComponents(ctx android.RegistrationContext) {
@@ -57,6 +54,7 @@
ctx.RegisterModuleType("prebuilt_root_host", PrebuiltRootHostFactory)
ctx.RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory)
ctx.RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory)
+ ctx.RegisterModuleType("prebuilt_usr_hyphendata", PrebuiltUserHyphenDataFactory)
ctx.RegisterModuleType("prebuilt_font", PrebuiltFontFactory)
ctx.RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory)
ctx.RegisterModuleType("prebuilt_dsp", PrebuiltDSPFactory)
@@ -141,9 +139,6 @@
android.ModuleBase
android.DefaultableModuleBase
- snapshot.VendorSnapshotModuleInterface
- snapshot.RecoverySnapshotModuleInterface
-
properties prebuiltEtcProperties
subdirProperties prebuiltSubdirProperties
@@ -304,14 +299,6 @@
return p.ModuleBase.InstallInVendor()
}
-func (p *PrebuiltEtc) ExcludeFromVendorSnapshot() bool {
- return false
-}
-
-func (p *PrebuiltEtc) ExcludeFromRecoverySnapshot() bool {
- return false
-}
-
func (p *PrebuiltEtc) installBaseDir(ctx android.ModuleContext) string {
// If soc install dir was specified and SOC specific is set, set the installDirPath to the
// specified socInstallDirBase.
@@ -611,6 +598,17 @@
return module
}
+// prebuilt_usr_hyphendata is for a prebuilt artifact that is installed in
+// <partition>/usr/hyphen-data/<sub_dir> directory.
+func PrebuiltUserHyphenDataFactory() android.Module {
+ module := &PrebuiltEtc{}
+ InitPrebuiltEtcModule(module, "usr/hyphen-data")
+ // This module is device-only
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+ android.InitDefaultableModule(module)
+ return module
+}
+
// prebuilt_font installs a font in <partition>/fonts directory.
func PrebuiltFontFactory() android.Module {
module := &PrebuiltEtc{}
@@ -674,121 +672,3 @@
android.InitDefaultableModule(module)
return module
}
-
-// Copy file into the snapshot
-func copyFile(ctx android.SingletonContext, path android.Path, out string, fake bool) android.OutputPath {
- if fake {
- // Create empty file instead for the fake snapshot
- return snapshot.WriteStringToFileRule(ctx, "", out)
- } else {
- return snapshot.CopyFileRule(pctx, ctx, path, out)
- }
-}
-
-// Check if the module is target of the snapshot
-func isSnapshotAware(ctx android.SingletonContext, m *PrebuiltEtc, image snapshot.SnapshotImage) bool {
- if !m.Enabled() {
- return false
- }
-
- // Skip if the module is not included in the image
- if !image.InImage(m)() {
- return false
- }
-
- // When android/prebuilt.go selects between source and prebuilt, it sets
- // HideFromMake on the other one to avoid duplicate install rules in make.
- if m.IsHideFromMake() {
- return false
- }
-
- // There are some prebuilt_etc module with multiple definition of same name.
- // Check if the target would be included from the build
- if !m.ExportedToMake() {
- return false
- }
-
- // Skip if the module is in the predefined path list to skip
- if image.IsProprietaryPath(ctx.ModuleDir(m), ctx.DeviceConfig()) {
- return false
- }
-
- // Skip if the module should be excluded
- if image.ExcludeFromSnapshot(m) || image.ExcludeFromDirectedSnapshot(ctx.DeviceConfig(), m.BaseModuleName()) {
- return false
- }
-
- // Skip from other exceptional cases
- if m.Target().Os.Class != android.Device {
- return false
- }
- if m.Target().NativeBridge == android.NativeBridgeEnabled {
- return false
- }
-
- return true
-}
-
-func generatePrebuiltSnapshot(s snapshot.SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) snapshot.SnapshotPaths {
- /*
- Snapshot zipped artifacts directory structure for etc modules:
- {SNAPSHOT_ARCH}/
- arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
- etc/
- (prebuilt etc files)
- arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
- etc/
- (prebuilt etc files)
- NOTICE_FILES/
- (notice files)
- */
- var snapshotOutputs android.Paths
- var snapshotNotices android.Paths
- installedNotices := make(map[string]bool)
-
- ctx.VisitAllModules(func(module android.Module) {
- m, ok := module.(*PrebuiltEtc)
- if !ok {
- return
- }
-
- if !isSnapshotAware(ctx, m, s.Image) {
- return
- }
-
- targetArch := "arch-" + m.Target().Arch.ArchType.String()
-
- snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "etc", m.BaseModuleName())
- outputs, _ := m.OutputFiles("")
- for _, output := range outputs {
- cp := copyFile(ctx, output, snapshotLibOut, s.Fake)
- snapshotOutputs = append(snapshotOutputs, cp)
- }
-
- prop := snapshot.SnapshotJsonFlags{}
- propOut := snapshotLibOut + ".json"
- prop.InitBaseSnapshotProps(m)
- prop.RelativeInstallPath = m.SubDir()
-
- if m.properties.Filename != nil {
- prop.Filename = *m.properties.Filename
- }
-
- j, err := json.Marshal(prop)
- if err != nil {
- ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
- return
- }
- snapshotOutputs = append(snapshotOutputs, snapshot.WriteStringToFileRule(ctx, string(j), propOut))
-
- for _, notice := range m.EffectiveLicenseFiles() {
- if _, ok := installedNotices[notice.String()]; !ok {
- installedNotices[notice.String()] = true
- snapshotNotices = append(snapshotNotices, notice)
- }
- }
-
- })
-
- return snapshot.SnapshotPaths{OutputFiles: snapshotOutputs, NoticeFiles: snapshotNotices}
-}
diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go
index 1d9aa8e..dd9958c 100644
--- a/etc/prebuilt_etc_test.go
+++ b/etc/prebuilt_etc_test.go
@@ -15,7 +15,6 @@
package etc
import (
- "fmt"
"os"
"path/filepath"
"testing"
@@ -23,7 +22,6 @@
"github.com/google/blueprint/proptools"
"android/soong/android"
- "android/soong/snapshot"
)
func TestMain(m *testing.M) {
@@ -40,18 +38,6 @@
}),
)
-var prepareForPrebuiltEtcSnapshotTest = android.GroupFixturePreparers(
- prepareForPrebuiltEtcTest,
- android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
- snapshot.VendorSnapshotImageSingleton.Init(ctx)
- snapshot.RecoverySnapshotImageSingleton.Init(ctx)
- }),
- android.FixtureModifyConfig(func(config android.Config) {
- config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
- config.TestProductVariables.RecoverySnapshotVersion = proptools.StringPtr("current")
- }),
-)
-
func TestPrebuiltEtcVariants(t *testing.T) {
result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
prebuilt_etc {
@@ -287,6 +273,20 @@
android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
}
+func TestPrebuiltPrebuiltUserHyphenDataInstallDirPath(t *testing.T) {
+ result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
+ prebuilt_usr_hyphendata {
+ name: "foo.conf",
+ src: "foo.conf",
+ sub_dir: "bar",
+ }
+ `)
+
+ p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
+ expected := "out/soong/target/product/test_device/system/usr/hyphen-data/bar"
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+}
+
func TestPrebuiltFontInstallDirPath(t *testing.T) {
result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
prebuilt_font {
@@ -401,110 +401,3 @@
})
}
}
-
-func checkIfSnapshotTaken(t *testing.T, result *android.TestResult, image string, moduleName string) {
- checkIfSnapshotExistAsExpected(t, result, image, moduleName, true)
-}
-
-func checkIfSnapshotNotTaken(t *testing.T, result *android.TestResult, image string, moduleName string) {
- checkIfSnapshotExistAsExpected(t, result, image, moduleName, false)
-}
-
-func checkIfSnapshotExistAsExpected(t *testing.T, result *android.TestResult, image string, moduleName string, expectToExist bool) {
- snapshotSingleton := result.SingletonForTests(image + "-snapshot")
- archType := "arm64"
- archVariant := "armv8-a"
- archDir := fmt.Sprintf("arch-%s", archType)
-
- snapshotDir := fmt.Sprintf("%s-snapshot", image)
- snapshotVariantPath := filepath.Join(snapshotDir, archType)
- outputDir := filepath.Join(snapshotVariantPath, archDir, "etc")
- imageVariant := ""
- if image == "recovery" {
- imageVariant = "recovery_"
- }
- mod := result.ModuleForTests(moduleName, fmt.Sprintf("android_%s%s_%s", imageVariant, archType, archVariant))
- outputFiles := mod.OutputFiles(t, "")
- if len(outputFiles) != 1 {
- t.Errorf("%q must have single output\n", moduleName)
- return
- }
- snapshotPath := filepath.Join(outputDir, moduleName)
-
- if expectToExist {
- out := snapshotSingleton.Output(snapshotPath)
-
- if out.Input.String() != outputFiles[0].String() {
- t.Errorf("The input of snapshot %q must be %q, but %q", "prebuilt_vendor", out.Input.String(), outputFiles[0])
- }
-
- snapshotJsonPath := snapshotPath + ".json"
-
- if snapshotSingleton.MaybeOutput(snapshotJsonPath).Rule == nil {
- t.Errorf("%q expected but not found", snapshotJsonPath)
- }
- } else {
- out := snapshotSingleton.MaybeOutput(snapshotPath)
- if out.Rule != nil {
- t.Errorf("There must be no rule for module %q output file %q", moduleName, outputFiles[0])
- }
- }
-}
-
-func TestPrebuiltTakeSnapshot(t *testing.T) {
- var testBp = `
- prebuilt_etc {
- name: "prebuilt_vendor",
- src: "foo.conf",
- vendor: true,
- }
-
- prebuilt_etc {
- name: "prebuilt_vendor_indirect",
- src: "foo.conf",
- vendor: true,
- }
-
- prebuilt_etc {
- name: "prebuilt_recovery",
- src: "bar.conf",
- recovery: true,
- }
-
- prebuilt_etc {
- name: "prebuilt_recovery_indirect",
- src: "bar.conf",
- recovery: true,
- }
- `
-
- t.Run("prebuilt: vendor and recovery snapshot", func(t *testing.T) {
- result := prepareForPrebuiltEtcSnapshotTest.RunTestWithBp(t, testBp)
-
- checkIfSnapshotTaken(t, result, "vendor", "prebuilt_vendor")
- checkIfSnapshotTaken(t, result, "vendor", "prebuilt_vendor_indirect")
- checkIfSnapshotTaken(t, result, "recovery", "prebuilt_recovery")
- checkIfSnapshotTaken(t, result, "recovery", "prebuilt_recovery_indirect")
- })
-
- t.Run("prebuilt: directed snapshot", func(t *testing.T) {
- prepareForPrebuiltEtcDirectedSnapshotTest := android.GroupFixturePreparers(
- prepareForPrebuiltEtcSnapshotTest,
- android.FixtureModifyConfig(func(config android.Config) {
- config.TestProductVariables.DirectedVendorSnapshot = true
- config.TestProductVariables.VendorSnapshotModules = make(map[string]bool)
- config.TestProductVariables.VendorSnapshotModules["prebuilt_vendor"] = true
- config.TestProductVariables.DirectedRecoverySnapshot = true
- config.TestProductVariables.RecoverySnapshotModules = make(map[string]bool)
- config.TestProductVariables.RecoverySnapshotModules["prebuilt_recovery"] = true
- }),
- )
-
- result := prepareForPrebuiltEtcDirectedSnapshotTest.RunTestWithBp(t, testBp)
-
- checkIfSnapshotTaken(t, result, "vendor", "prebuilt_vendor")
- checkIfSnapshotNotTaken(t, result, "vendor", "prebuilt_vendor_indirect")
- checkIfSnapshotTaken(t, result, "recovery", "prebuilt_recovery")
- checkIfSnapshotNotTaken(t, result, "recovery", "prebuilt_recovery_indirect")
- })
-}
diff --git a/etc/snapshot_etc.go b/etc/snapshot_etc.go
deleted file mode 100644
index 0d65ab6..0000000
--- a/etc/snapshot_etc.go
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2021 The Android Open Source Project
-//
-// 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 etc
-
-// This file implements snapshot module of 'prebuilt_etc' type
-// 'snapshot_etc' module defines android.PrebuiltInterface so it can be handled
-// as prebuilt of 'prebuilt_etc' type.
-// Properties of 'snapshot_etc' follows properties from snapshotJsonFlags type
-
-import (
- "android/soong/android"
- "fmt"
- "strings"
-
- "github.com/google/blueprint"
- "github.com/google/blueprint/proptools"
-)
-
-func RegisterSnapshotEtcModule(ctx android.RegistrationContext) {
- ctx.RegisterModuleType("snapshot_etc", SnapshotEtcFactory)
-}
-
-func init() {
- RegisterSnapshotEtcModule(android.InitRegistrationContext)
-}
-
-// snapshot_etc is a prebuilt module type to be installed under etc which is auto-generated by
-// development/vendor_snapshot/update.py. This module will override prebuilt_etc module with same
-// name when 'prefer' property is true.
-func SnapshotEtcFactory() android.Module {
- module := &SnapshotEtc{}
- module.AddProperties(&module.properties)
-
- var srcsSupplier = func(_ android.BaseModuleContext, prebuilt android.Module) []string {
- s, ok := prebuilt.(*SnapshotEtc)
- if !ok || s.properties.Src == nil {
- return []string{}
- }
-
- return []string{*s.properties.Src}
- }
-
- android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
- android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "src")
- return module
-}
-
-type snapshotEtcProperties struct {
- Src *string `android:"path,arch_variant"` // Source of snapshot_etc file
- Filename *string `android:"arch_variant"` // Target file name when it differs from module name
- Relative_install_path *string `android:"arch_variant"` // Relative install path when it should be installed subdirectory of etc
-}
-
-type SnapshotEtc struct {
- android.ModuleBase
- prebuilt android.Prebuilt
- properties snapshotEtcProperties
-
- outputFilePath android.OutputPath
- installDirPath android.InstallPath
-}
-
-func (s *SnapshotEtc) Prebuilt() *android.Prebuilt {
- return &s.prebuilt
-}
-
-func (s *SnapshotEtc) Name() string {
- return s.prebuilt.Name(s.BaseModuleName())
-}
-
-func (s *SnapshotEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- if s.properties.Src == nil {
- ctx.PropertyErrorf("src", "missing prebuilt source file")
- return
- }
-
- sourceFilePath := s.prebuilt.SingleSourcePath(ctx)
-
- // Determine the output file basename.
- // If Filename is set, use the name specified by the property.
- // Otherwise use the module name.
- filename := proptools.String(s.properties.Filename)
- if filename == "" {
- filename = ctx.ModuleName()
- }
-
- s.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath
-
- if strings.Contains(filename, "/") {
- ctx.PropertyErrorf("filename", "filename cannot contain separator '/'")
- return
- }
-
- subDir := ""
- if s.properties.Relative_install_path != nil {
- subDir = *s.properties.Relative_install_path
- }
-
- s.installDirPath = android.PathForModuleInstall(ctx, "etc", subDir)
-
- // This ensures that outputFilePath has the correct name for others to
- // use, as the source file may have a different name.
- ctx.Build(pctx, android.BuildParams{
- Rule: android.Cp,
- Input: sourceFilePath,
- Output: s.outputFilePath,
- Description: "Install snapshot etc module " + s.BaseModuleName(),
- })
-
- ctx.InstallFile(s.installDirPath, s.outputFilePath.Base(), sourceFilePath)
-}
-
-func (p *SnapshotEtc) AndroidMkEntries() []android.AndroidMkEntries {
- return []android.AndroidMkEntries{{
- Class: "ETC",
- OutputFile: android.OptionalPathForPath(p.outputFilePath),
- ExtraEntries: []android.AndroidMkExtraEntriesFunc{
- func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_TAGS", "optional")
- entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
- entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
- },
- },
- }}
-}
-
-type snapshotEtcDependencyTag struct {
- blueprint.DependencyTag
-}
-
-var tag = snapshotEtcDependencyTag{}
-
-func (s *SnapshotEtc) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
- return !s.ModuleBase.InstallInRecovery() && !s.ModuleBase.InstallInRamdisk() &&
- !s.ModuleBase.InstallInVendorRamdisk() && !s.ModuleBase.InstallInDebugRamdisk()
-}
-
-func (p *SnapshotEtc) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return p.ModuleBase.InstallInRamdisk()
-}
-
-func (p *SnapshotEtc) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return p.ModuleBase.InstallInVendorRamdisk()
-}
-
-func (p *SnapshotEtc) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
- return p.ModuleBase.InstallInDebugRamdisk()
-}
-
-func (p *SnapshotEtc) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
- return p.ModuleBase.InstallInRecovery()
-}
-
-func (p *SnapshotEtc) ExtraImageVariations(ctx android.BaseModuleContext) []string {
- return nil
-}
-
-func (p *SnapshotEtc) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
-}
-
-func (p *SnapshotEtc) ImageMutatorBegin(ctx android.BaseModuleContext) {}
-
-func (p *SnapshotEtc) OutputFiles(tag string) (android.Paths, error) {
- switch tag {
- case "":
- return android.Paths{p.outputFilePath}, nil
- default:
- return nil, fmt.Errorf("unsupported module reference tag %q", tag)
- }
-
-}
-
-var _ android.PrebuiltInterface = (*SnapshotEtc)(nil)
-var _ android.ImageInterface = (*SnapshotEtc)(nil)
-var _ android.OutputFileProducer = (*SnapshotEtc)(nil)
diff --git a/etc/snapshot_etc_test.go b/etc/snapshot_etc_test.go
deleted file mode 100644
index b9d5504..0000000
--- a/etc/snapshot_etc_test.go
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2021 The Android Open Source Project
-//
-// 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 etc
-
-import (
- "android/soong/android"
- "testing"
-
- "github.com/google/blueprint"
-)
-
-var registerSourceModule = func(ctx android.RegistrationContext) {
- ctx.RegisterModuleType("source", newSourceModule)
-}
-
-type sourceModuleProperties struct {
- Deps []string `android:"path,arch_variant"`
-}
-
-type sourceModule struct {
- android.ModuleBase
- android.OverridableModuleBase
-
- properties sourceModuleProperties
- dependsOnSourceModule, dependsOnPrebuiltModule bool
- deps android.Paths
- src android.Path
-}
-
-func newSourceModule() android.Module {
- m := &sourceModule{}
- m.AddProperties(&m.properties)
- android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibFirst)
- android.InitOverridableModule(m, nil)
- return m
-}
-
-func (s *sourceModule) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
- // s.properties.Deps are annotated with android:path, so they are
- // automatically added to the dependency by pathDeps mutator
-}
-
-func (s *sourceModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- s.deps = android.PathsForModuleSrc(ctx, s.properties.Deps)
- s.src = android.PathForModuleSrc(ctx, "source_file")
-}
-
-func (s *sourceModule) Srcs() android.Paths {
- return android.Paths{s.src}
-}
-
-var prepareForSnapshotEtcTest = android.GroupFixturePreparers(
- android.PrepareForTestWithArchMutator,
- android.PrepareForTestWithPrebuilts,
- PrepareForTestWithPrebuiltEtc,
- android.FixtureRegisterWithContext(RegisterSnapshotEtcModule),
- android.FixtureRegisterWithContext(registerSourceModule),
- android.FixtureMergeMockFs(android.MockFS{
- "foo.conf": nil,
- "bar.conf": nil,
- }),
-)
-
-func TestSnapshotWithFilename(t *testing.T) {
- var androidBp = `
- snapshot_etc {
- name: "etc_module",
- src: "foo.conf",
- filename: "bar.conf",
- }
- `
-
- result := prepareForSnapshotEtcTest.RunTestWithBp(t, androidBp)
- for _, variant := range result.ModuleVariantsForTests("etc_module") {
- module := result.ModuleForTests("etc_module", variant)
- s, ok := module.Module().(*SnapshotEtc)
- if !ok {
- t.Errorf("Expected snapshot_etc module type")
- }
- if s.outputFilePath.Base() != "bar.conf" {
- t.Errorf("Output file path does not match with specified filename")
- }
- }
-}
-
-func TestSnapshotEtcWithOrigin(t *testing.T) {
- var androidBp = `
- prebuilt_etc {
- name: "etc_module",
- src: "foo.conf",
- }
-
- snapshot_etc {
- name: "etc_module",
- src: "bar.conf",
- }
-
- source {
- name: "source",
- deps: [":etc_module"],
- }
- `
-
- result := prepareForSnapshotEtcTest.RunTestWithBp(t, androidBp)
-
- for _, variant := range result.ModuleVariantsForTests("source") {
- source := result.ModuleForTests("source", variant)
-
- result.VisitDirectDeps(source.Module(), func(m blueprint.Module) {
- if _, ok := m.(*PrebuiltEtc); !ok {
- t.Errorf("Original prebuilt_etc module expected.")
- }
- })
- }
-}
-
-func TestSnapshotEtcWithOriginAndPrefer(t *testing.T) {
- var androidBp = `
- prebuilt_etc {
- name: "etc_module",
- src: "foo.conf",
- }
-
- snapshot_etc {
- name: "etc_module",
- src: "bar.conf",
- prefer: true,
- }
-
- source {
- name: "source",
- deps: [":etc_module"],
- }
- `
-
- result := prepareForSnapshotEtcTest.RunTestWithBp(t, androidBp)
-
- for _, variant := range result.ModuleVariantsForTests("source") {
- source := result.ModuleForTests("source", variant)
-
- result.VisitDirectDeps(source.Module(), func(m blueprint.Module) {
- if _, ok := m.(*SnapshotEtc); !ok {
- t.Errorf("Preferred snapshot_etc module expected.")
- }
- })
- }
-}
-
-func TestSnapshotEtcWithoutOrigin(t *testing.T) {
- var androidBp = `
- snapshot_etc {
- name: "etc_module",
- src: "bar.conf",
- }
-
- source {
- name: "source",
- deps: [":etc_module"],
- }
- `
-
- result := prepareForSnapshotEtcTest.RunTestWithBp(t, androidBp)
-
- for _, variant := range result.ModuleVariantsForTests("source") {
- source := result.ModuleForTests("source", variant)
-
- result.VisitDirectDeps(source.Module(), func(m blueprint.Module) {
- if _, ok := m.(*SnapshotEtc); !ok {
- t.Errorf("Only source snapshot_etc module expected.")
- }
- })
- }
-}
diff --git a/filesystem/Android.bp b/filesystem/Android.bp
index cdf6682..854a366 100644
--- a/filesystem/Android.bp
+++ b/filesystem/Android.bp
@@ -10,13 +10,16 @@
"soong",
"soong-android",
"soong-bpf", // for testing
+ "soong-java", // for testing
"soong-linkerconfig",
+ "soong-phony", // for testing
],
srcs: [
"avb_add_hash_footer.go",
"avb_gen_vbmeta_image.go",
"bootimg.go",
"filesystem.go",
+ "fsverity_metadata.go",
"logical_partition.go",
"raw_binary.go",
"system_image.go",
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index efc889c..cadf9c24 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -20,6 +20,7 @@
"io"
"path/filepath"
"slices"
+ "strconv"
"strings"
"android/soong/android"
@@ -35,6 +36,7 @@
func registerBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("android_filesystem", filesystemFactory)
+ ctx.RegisterModuleType("android_filesystem_defaults", filesystemDefaultsFactory)
ctx.RegisterModuleType("android_system_image", systemImageFactory)
ctx.RegisterModuleType("avb_add_hash_footer", avbAddHashFooterFactory)
ctx.RegisterModuleType("avb_add_hash_footer_defaults", avbAddHashFooterDefaultsFactory)
@@ -45,6 +47,7 @@
type filesystem struct {
android.ModuleBase
android.PackagingBase
+ android.DefaultableModuleBase
properties filesystemProperties
@@ -57,7 +60,7 @@
output android.OutputPath
installDir android.InstallPath
- // For testing. Keeps the result of CopyDepsToZip()
+ // For testing. Keeps the result of CopySpecsToDir()
entries []string
}
@@ -81,6 +84,9 @@
// avbtool. Default used by avbtool is sha1.
Avb_hash_algorithm *string
+ // The index used to prevent rollback of the image. Only used if use_avb is true.
+ Rollback_index *int64
+
// Name of the partition stored in vbmeta desc. Defaults to the name of this module.
Partition_name *string
@@ -120,6 +126,8 @@
// modules would be installed to the same location as a make module, they will overwrite
// the make version.
Include_make_built_files string
+
+ Fsverity fsverityProperties
}
// android_filesystem packages a set of modules and their transitive dependencies into a filesystem
@@ -137,6 +145,7 @@
module.AddProperties(&module.properties)
android.InitPackageModule(module)
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
}
var dependencyTag = struct {
@@ -176,12 +185,14 @@
return f.BaseModuleName() + ".img"
}
+func (f *filesystem) partitionName() string {
+ return proptools.StringDefault(f.properties.Partition_name, f.Name())
+}
+
var pctx = android.NewPackageContext("android/soong/filesystem")
func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- if !android.InList(f.PartitionType(), validPartitions) {
- ctx.PropertyErrorf("partition_type", "partition_type must be one of %s, found: %s", validPartitions, f.PartitionType())
- }
+ validatePartitionType(ctx, f)
switch f.fsType(ctx) {
case ext4Type:
f.output = f.buildImageUsingBuildImage(ctx)
@@ -197,6 +208,22 @@
ctx.InstallFile(f.installDir, f.installFileName(), f.output)
}
+func validatePartitionType(ctx android.ModuleContext, p partition) {
+ if !android.InList(p.PartitionType(), validPartitions) {
+ 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.PropertyErrorf("partition_type",
+ "%s doesn't match with the partition type %s of the filesystem default module %s",
+ p.PartitionType(), fdm.PartitionType(), m.Name())
+ }
+ }
+ })
+}
+
// Copy extra files/dirs that are not from the `deps` property to `rootDir`, checking for conflicts with files
// already in `rootDir`.
func (f *filesystem) buildNonDepsFiles(ctx android.ModuleContext, builder *android.RuleBuilder, rootDir android.OutputPath) {
@@ -255,10 +282,12 @@
builder := android.NewRuleBuilder(pctx, ctx)
// Wipe the root dir to get rid of leftover files from prior builds
builder.Command().Textf("rm -rf %s && mkdir -p %s", rootDir, rootDir)
- f.entries = f.CopySpecsToDir(ctx, builder, f.gatherFilteredPackagingSpecs(ctx), rebasedDir)
+ specs := f.gatherFilteredPackagingSpecs(ctx)
+ f.entries = f.CopySpecsToDir(ctx, builder, specs, rebasedDir)
f.buildNonDepsFiles(ctx, builder, rootDir)
f.addMakeBuiltFiles(ctx, builder, rootDir)
+ f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir)
// run host_init_verifier
// Ideally we should have a concept of pluggable linters that verify the generated image.
@@ -338,13 +367,19 @@
addStr("avb_algorithm", algorithm)
key := android.PathForModuleSrc(ctx, proptools.String(f.properties.Avb_private_key))
addPath("avb_key_path", key)
- partitionName := proptools.StringDefault(f.properties.Partition_name, f.Name())
- addStr("partition_name", partitionName)
+ addStr("partition_name", f.partitionName())
avb_add_hashtree_footer_args := "--do_not_generate_fec"
if hashAlgorithm := proptools.String(f.properties.Avb_hash_algorithm); hashAlgorithm != "" {
avb_add_hashtree_footer_args += " --hash_algorithm " + hashAlgorithm
}
- securityPatchKey := "com.android.build." + partitionName + ".security_patch"
+ if f.properties.Rollback_index != nil {
+ rollbackIndex := proptools.Int(f.properties.Rollback_index)
+ if rollbackIndex < 0 {
+ ctx.PropertyErrorf("rollback_index", "Rollback index must be non-negative")
+ }
+ avb_add_hashtree_footer_args += " --rollback_index " + strconv.Itoa(rollbackIndex)
+ }
+ securityPatchKey := "com.android.build." + f.partitionName() + ".security_patch"
securityPatchValue := ctx.Config().PlatformSecurityPatch()
avb_add_hashtree_footer_args += " --prop " + securityPatchKey + ":" + securityPatchValue
addStr("avb_add_hashtree_footer_args", avb_add_hashtree_footer_args)
@@ -388,9 +423,11 @@
builder := android.NewRuleBuilder(pctx, ctx)
// Wipe the root dir to get rid of leftover files from prior builds
builder.Command().Textf("rm -rf %s && mkdir -p %s", rootDir, rootDir)
- f.entries = f.CopySpecsToDir(ctx, builder, f.gatherFilteredPackagingSpecs(ctx), rebasedDir)
+ specs := f.gatherFilteredPackagingSpecs(ctx)
+ f.entries = f.CopySpecsToDir(ctx, builder, specs, rebasedDir)
f.buildNonDepsFiles(ctx, builder, rootDir)
+ f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir)
output := android.PathForModuleOut(ctx, f.installFileName()).OutputPath
cmd := builder.Command().
@@ -448,10 +485,16 @@
Text(android.PathForArbitraryOutput(ctx, stagingDir).String())
}
+type partition interface {
+ PartitionType() string
+}
+
func (f *filesystem) PartitionType() string {
return proptools.StringDefault(f.properties.Partition_type, "system")
}
+var _ partition = (*filesystem)(nil)
+
var _ android.AndroidMkEntriesProvider = (*filesystem)(nil)
// Implements android.AndroidMkEntriesProvider
@@ -525,3 +568,37 @@
func (*filesystem) IsNativeCoverageNeeded(ctx android.IncomingTransitionContext) bool {
return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
}
+
+// android_filesystem_defaults
+
+type filesystemDefaults struct {
+ android.ModuleBase
+ android.DefaultsModuleBase
+
+ properties filesystemDefaultsProperties
+}
+
+type filesystemDefaultsProperties 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.
+ Partition_type *string
+}
+
+// android_filesystem_defaults is a default module for android_filesystem and android_system_image
+func filesystemDefaultsFactory() android.Module {
+ module := &filesystemDefaults{}
+ module.AddProperties(&module.properties)
+ module.AddProperties(&android.PackagingProperties{})
+ android.InitDefaultsModule(module)
+ return module
+}
+
+func (f *filesystemDefaults) PartitionType() string {
+ return proptools.StringDefault(f.properties.Partition_type, "system")
+}
+
+var _ partition = (*filesystemDefaults)(nil)
+
+func (f *filesystemDefaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ validatePartitionType(ctx, f)
+}
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 74c79e3..3a5071d 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -23,6 +23,8 @@
"android/soong/bpf"
"android/soong/cc"
"android/soong/etc"
+ "android/soong/java"
+ "android/soong/phony"
"github.com/google/blueprint/proptools"
)
@@ -33,9 +35,13 @@
var fixture = android.GroupFixturePreparers(
android.PrepareForIntegrationTestWithAndroid,
+ android.PrepareForTestWithAndroidBuildComponents,
bpf.PrepareForTestWithBpf,
- etc.PrepareForTestWithPrebuiltEtc,
cc.PrepareForIntegrationTestWithCc,
+ etc.PrepareForTestWithPrebuiltEtc,
+ java.PrepareForTestWithJavaBuildComponents,
+ java.PrepareForTestWithJavaDefaultModules,
+ phony.PrepareForTestWithPhony,
PrepareForTestWithFilesystemBuildComponents,
)
@@ -47,6 +53,7 @@
common: {
deps: [
"bpf.o",
+ "phony",
],
},
lib32: {
@@ -77,11 +84,38 @@
cc_library {
name: "libbar",
required: ["libbaz"],
+ target: {
+ platform: {
+ required: ["lib_platform_only"],
+ },
+ },
}
cc_library {
name: "libbaz",
}
+
+ cc_library {
+ name: "lib_platform_only",
+ }
+
+ phony {
+ name: "phony",
+ required: [
+ "libquz",
+ "myapp",
+ ],
+ }
+
+ cc_library {
+ name: "libquz",
+ }
+
+ android_app {
+ name: "myapp",
+ platform_apis: true,
+ installable: true,
+ }
`)
// produces "myfilesystem.img"
@@ -89,10 +123,13 @@
fs := result.ModuleForTests("myfilesystem", "android_common").Module().(*filesystem)
expected := []string{
+ "app/myapp/myapp.apk",
"bin/foo",
"lib/libbar.so",
"lib64/libbar.so",
"lib64/libbaz.so",
+ "lib64/libquz.so",
+ "lib64/lib_platform_only.so",
"etc/bpf/bpf.o",
}
for _, e := range expected {
@@ -351,3 +388,94 @@
t.Error("prebuilt should use cov variant of filesystem")
}
}
+
+func TestSystemImageDefaults(t *testing.T) {
+ result := fixture.RunTestWithBp(t, `
+ android_filesystem_defaults {
+ name: "defaults",
+ multilib: {
+ common: {
+ deps: [
+ "phony",
+ ],
+ },
+ lib64: {
+ deps: [
+ "libbar",
+ ],
+ },
+ },
+ compile_multilib: "both",
+ }
+
+ android_system_image {
+ name: "system",
+ defaults: ["defaults"],
+ multilib: {
+ lib32: {
+ deps: [
+ "foo",
+ "libbar",
+ ],
+ },
+ },
+ }
+
+ cc_binary {
+ name: "foo",
+ compile_multilib: "prefer32",
+ }
+
+ cc_library {
+ name: "libbar",
+ required: ["libbaz"],
+ }
+
+ cc_library {
+ name: "libbaz",
+ }
+
+ phony {
+ name: "phony",
+ required: ["libquz"],
+ }
+
+ cc_library {
+ name: "libquz",
+ }
+ `)
+
+ fs := result.ModuleForTests("system", "android_common").Module().(*systemImage)
+ expected := []string{
+ "bin/foo",
+ "lib/libbar.so",
+ "lib64/libbar.so",
+ "lib64/libbaz.so",
+ "lib64/libquz.so",
+ }
+ for _, e := range expected {
+ android.AssertStringListContains(t, "missing entry", fs.entries, e)
+ }
+}
+
+func TestInconsistentPartitionTypesInDefaults(t *testing.T) {
+ fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(
+ "doesn't match with the partition type")).
+ RunTestWithBp(t, `
+ android_filesystem_defaults {
+ name: "system_ext_def",
+ partition_type: "system_ext",
+ }
+
+ android_filesystem_defaults {
+ name: "system_def",
+ partition_type: "system",
+ defaults: ["system_ext_def"],
+ }
+
+ android_system_image {
+ name: "system",
+ defaults: ["system_def"],
+ }
+ `)
+}
diff --git a/filesystem/fsverity_metadata.go b/filesystem/fsverity_metadata.go
new file mode 100644
index 0000000..3e50ff7
--- /dev/null
+++ b/filesystem/fsverity_metadata.go
@@ -0,0 +1,169 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// 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 filesystem
+
+import (
+ "path/filepath"
+ "strings"
+
+ "android/soong/android"
+)
+
+type fsverityProperties struct {
+ // Patterns of files for fsverity metadata generation. For each matched file, a .fsv_meta file
+ // will be generated and included to the filesystem image.
+ // etc/security/fsverity/BuildManifest.apk will also be generated which contains information
+ // about generated .fsv_meta files.
+ Inputs []string
+
+ // APK libraries to link against, for etc/security/fsverity/BuildManifest.apk
+ Libs []string `android:"path"`
+}
+
+func (f *filesystem) writeManifestGeneratorListFile(ctx android.ModuleContext, outputPath android.OutputPath, matchedSpecs []android.PackagingSpec, rebasedDir android.OutputPath) {
+ var buf strings.Builder
+ for _, spec := range matchedSpecs {
+ buf.WriteString(rebasedDir.Join(ctx, spec.RelPathInPackage()).String())
+ buf.WriteRune('\n')
+ }
+ android.WriteFileRuleVerbatim(ctx, outputPath, buf.String())
+}
+
+func (f *filesystem) buildFsverityMetadataFiles(ctx android.ModuleContext, builder *android.RuleBuilder, specs map[string]android.PackagingSpec, rootDir android.OutputPath, rebasedDir android.OutputPath) {
+ match := func(path string) bool {
+ for _, pattern := range f.properties.Fsverity.Inputs {
+ if matched, err := filepath.Match(pattern, path); matched {
+ return true
+ } else if err != nil {
+ ctx.PropertyErrorf("fsverity.inputs", "bad pattern %q", pattern)
+ return false
+ }
+ }
+ return false
+ }
+
+ var matchedSpecs []android.PackagingSpec
+ for _, relPath := range android.SortedKeys(specs) {
+ if match(relPath) {
+ matchedSpecs = append(matchedSpecs, specs[relPath])
+ }
+ }
+
+ if len(matchedSpecs) == 0 {
+ return
+ }
+
+ fsverityBuilderPath := android.PathForModuleOut(ctx, "fsverity_builder.sh")
+ metadataGeneratorPath := ctx.Config().HostToolPath(ctx, "fsverity_metadata_generator")
+ fsverityPath := ctx.Config().HostToolPath(ctx, "fsverity")
+
+ cmd := builder.Command().Tool(fsverityBuilderPath)
+
+ // STEP 1: generate .fsv_meta
+ var sb strings.Builder
+ sb.WriteString("set -e\n")
+ cmd.Implicit(metadataGeneratorPath).Implicit(fsverityPath)
+ for _, spec := range matchedSpecs {
+ // srcPath is copied by CopySpecsToDir()
+ srcPath := rebasedDir.Join(ctx, spec.RelPathInPackage())
+ destPath := rebasedDir.Join(ctx, spec.RelPathInPackage()+".fsv_meta")
+ sb.WriteString(metadataGeneratorPath.String())
+ sb.WriteString(" --fsverity-path ")
+ sb.WriteString(fsverityPath.String())
+ sb.WriteString(" --signature none --hash-alg sha256 --output ")
+ sb.WriteString(destPath.String())
+ sb.WriteRune(' ')
+ sb.WriteString(srcPath.String())
+ sb.WriteRune('\n')
+ }
+
+ // STEP 2: generate signed BuildManifest.apk
+ // STEP 2-1: generate build_manifest.pb
+ assetsPath := android.PathForModuleOut(ctx, "fsverity_manifest/assets")
+ manifestPbPath := assetsPath.Join(ctx, "build_manifest.pb")
+ manifestGeneratorPath := ctx.Config().HostToolPath(ctx, "fsverity_manifest_generator")
+ cmd.Implicit(manifestGeneratorPath)
+ sb.WriteString("rm -rf ")
+ sb.WriteString(assetsPath.String())
+ sb.WriteString(" && mkdir -p ")
+ sb.WriteString(assetsPath.String())
+ sb.WriteRune('\n')
+ sb.WriteString(manifestGeneratorPath.String())
+ sb.WriteString(" --fsverity-path ")
+ sb.WriteString(fsverityPath.String())
+ sb.WriteString(" --base-dir ")
+ sb.WriteString(rootDir.String())
+ sb.WriteString(" --output ")
+ sb.WriteString(manifestPbPath.String())
+ sb.WriteRune(' ')
+
+ manifestGeneratorListPath := android.PathForModuleOut(ctx, "fsverity_manifest.list")
+ f.writeManifestGeneratorListFile(ctx, manifestGeneratorListPath.OutputPath, matchedSpecs, rebasedDir)
+ sb.WriteRune('@')
+ sb.WriteString(manifestGeneratorListPath.String())
+ sb.WriteRune('\n')
+ cmd.Implicit(manifestGeneratorListPath)
+
+ // STEP 2-2: generate BuildManifest.apk (unsigned)
+ aapt2Path := ctx.Config().HostToolPath(ctx, "aapt2")
+ apkPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", "BuildManifest.apk")
+ manifestTemplatePath := android.PathForSource(ctx, "system/security/fsverity/AndroidManifest.xml")
+ libs := android.PathsForModuleSrc(ctx, f.properties.Fsverity.Libs)
+ cmd.Implicit(aapt2Path)
+ cmd.Implicit(manifestTemplatePath)
+ cmd.Implicits(libs)
+
+ sb.WriteString(aapt2Path.String())
+ sb.WriteString(" link -o ")
+ sb.WriteString(apkPath.String())
+ sb.WriteString(" -A ")
+ sb.WriteString(assetsPath.String())
+ for _, lib := range libs {
+ sb.WriteString(" -I ")
+ sb.WriteString(lib.String())
+ }
+ minSdkVersion := ctx.Config().PlatformSdkCodename()
+ if minSdkVersion == "REL" {
+ minSdkVersion = ctx.Config().PlatformSdkVersion().String()
+ }
+ sb.WriteString(" --min-sdk-version ")
+ sb.WriteString(minSdkVersion)
+ sb.WriteString(" --version-code ")
+ sb.WriteString(ctx.Config().PlatformSdkVersion().String())
+ sb.WriteString(" --version-name ")
+ sb.WriteString(ctx.Config().AppsDefaultVersionName())
+ sb.WriteString(" --manifest ")
+ sb.WriteString(manifestTemplatePath.String())
+ sb.WriteString(" --rename-manifest-package com.android.security.fsverity_metadata.")
+ sb.WriteString(f.partitionName())
+ sb.WriteRune('\n')
+
+ // STEP 2-3: sign BuildManifest.apk
+ apksignerPath := ctx.Config().HostToolPath(ctx, "apksigner")
+ pemPath, keyPath := ctx.Config().DefaultAppCertificate(ctx)
+ cmd.Implicit(apksignerPath)
+ cmd.Implicit(pemPath)
+ cmd.Implicit(keyPath)
+ sb.WriteString(apksignerPath.String())
+ sb.WriteString(" sign --in ")
+ sb.WriteString(apkPath.String())
+ sb.WriteString(" --cert ")
+ sb.WriteString(pemPath.String())
+ sb.WriteString(" --key ")
+ sb.WriteString(keyPath.String())
+ sb.WriteRune('\n')
+
+ android.WriteExecutableFileRuleVerbatim(ctx, fsverityBuilderPath, sb.String())
+}
diff --git a/java/aar.go b/java/aar.go
index 770d8b6..f8955ce 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -164,7 +164,9 @@
}
func (a *aapt) useResourceProcessorBusyBox(ctx android.BaseModuleContext) bool {
- return BoolDefault(a.aaptProperties.Use_resource_processor, ctx.Config().UseResourceProcessorByDefault())
+ return BoolDefault(a.aaptProperties.Use_resource_processor, ctx.Config().UseResourceProcessorByDefault()) &&
+ // TODO(b/331641946): remove this when ResourceProcessorBusyBox supports generating shared libraries.
+ !slices.Contains(a.aaptProperties.Aaptflags, "--shared-lib")
}
func (a *aapt) filterProduct() string {
@@ -354,12 +356,13 @@
forceNonFinalResourceIDs bool
extraLinkFlags []string
aconfigTextFiles android.Paths
+ usesLibrary *usesLibrary
}
func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptions) {
staticResourcesNodesDepSet, sharedResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedExportPackages, libFlags :=
- aaptLibs(ctx, opts.sdkContext, opts.classLoaderContexts)
+ aaptLibs(ctx, opts.sdkContext, opts.classLoaderContexts, opts.usesLibrary)
// Exclude any libraries from the supplied list.
opts.classLoaderContexts = opts.classLoaderContexts.ExcludeLibs(opts.excludedLibs)
@@ -701,7 +704,8 @@
}
// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
-func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoaderContexts dexpreopt.ClassLoaderContextMap) (
+func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext,
+ classLoaderContexts dexpreopt.ClassLoaderContextMap, usesLibrary *usesLibrary) (
staticResourcesNodes, sharedResourcesNodes *android.DepSet[*resourcesNode], staticRRODirs *android.DepSet[rroDir],
staticManifests *android.DepSet[android.Path], sharedLibs android.Paths, flags []string) {
@@ -751,6 +755,9 @@
}
addCLCFromDep(ctx, module, classLoaderContexts)
+ if usesLibrary != nil {
+ addMissingOptionalUsesLibsFromDep(ctx, module, usesLibrary)
+ }
})
// AAPT2 overlays are in lowest to highest priority order, the topological order will be reversed later.
@@ -803,12 +810,12 @@
var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
+ a.usesLibrary.deps(ctx, false)
a.Module.deps(ctx)
sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
if sdkDep.hasFrameworkLibs() {
a.aapt.deps(ctx, sdkDep)
}
- a.usesLibrary.deps(ctx, false)
for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
@@ -827,6 +834,7 @@
classLoaderContexts: a.classLoaderContexts,
enforceDefaultTargetSdkVersion: false,
aconfigTextFiles: getAconfigFilePaths(ctx),
+ usesLibrary: &a.usesLibrary,
},
)
@@ -920,7 +928,8 @@
module.Module.addHostAndDeviceProperties()
module.AddProperties(
&module.aaptProperties,
- &module.androidLibraryProperties)
+ &module.androidLibraryProperties,
+ &module.sourceProperties)
module.androidLibraryProperties.BuildAAR = true
module.Module.linter.library = true
@@ -1161,11 +1170,17 @@
a.rTxt = extractedAARDir.Join(ctx, "R.txt")
a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
+ transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx)
android.SetProvider(ctx, ProguardSpecInfoProvider, ProguardSpecInfo{
ProguardFlagsFiles: android.NewDepSet[android.Path](
android.POSTORDER,
android.Paths{a.proguardFlags},
+ transitiveProguardFlags,
+ ),
+ UnconditionallyExportedProguardFlags: android.NewDepSet[android.Path](
+ android.POSTORDER,
nil,
+ transitiveUnconditionalExportedFlags,
),
})
@@ -1206,7 +1221,7 @@
linkDeps = append(linkDeps, a.manifest)
staticResourcesNodesDepSet, sharedResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedLibs, libFlags :=
- aaptLibs(ctx, android.SdkContext(a), nil)
+ aaptLibs(ctx, android.SdkContext(a), nil, nil)
_ = sharedResourcesNodesDepSet
_ = staticRRODirsDepSet
@@ -1278,6 +1293,7 @@
}
}
addCLCFromDep(ctx, module, a.classLoaderContexts)
+ addMissingOptionalUsesLibsFromDep(ctx, module, &a.usesLibrary)
})
var implementationJarFile android.OutputPath
@@ -1396,6 +1412,12 @@
var _ android.PrebuiltInterface = (*AARImport)(nil)
+func (a *AARImport) UsesLibrary() *usesLibrary {
+ return &a.usesLibrary
+}
+
+var _ ModuleWithUsesLibrary = (*AARImport)(nil)
+
// android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
//
// This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
diff --git a/java/app.go b/java/app.go
old mode 100755
new mode 100644
index 2abc451..50d1a2f
--- a/java/app.go
+++ b/java/app.go
@@ -249,13 +249,13 @@
}
func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
- a.Module.deps(ctx)
-
if String(a.appProperties.Stl) == "c++_shared" && !a.SdkVersion(ctx).Specified() {
ctx.PropertyErrorf("stl", "sdk_version must be set in order to use c++_shared")
}
sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
+ a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
+ a.Module.deps(ctx)
if sdkDep.hasFrameworkLibs() {
a.aapt.deps(ctx, sdkDep)
}
@@ -285,9 +285,6 @@
}
ctx.AddFarVariationDependencies(variation, jniLibTag, a.appProperties.Jni_libs...)
}
-
- a.usesLibrary.deps(ctx, sdkDep.hasFrameworkLibs())
-
for _, aconfig_declaration := range a.aaptProperties.Flags_packages {
ctx.AddDependency(ctx.Module(), aconfigDeclarationTag, aconfig_declaration)
}
@@ -329,6 +326,10 @@
a.aapt.manifestValues.applicationId = *applicationId
}
a.generateAndroidBuildActions(ctx)
+ android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
+ TestOnly: true,
+ })
+
}
func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -530,6 +531,7 @@
forceNonFinalResourceIDs: nonFinalIds,
extraLinkFlags: aaptLinkFlags,
aconfigTextFiles: getAconfigFilePaths(ctx),
+ usesLibrary: &a.usesLibrary,
},
)
@@ -811,18 +813,10 @@
// The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
a.usesLibrary.freezeEnforceUsesLibraries()
- // Add implicit SDK libraries to <uses-library> list.
- requiredUsesLibs, optionalUsesLibs := a.classLoaderContexts.UsesLibs()
- for _, usesLib := range requiredUsesLibs {
- a.usesLibrary.addLib(usesLib, false)
- }
- for _, usesLib := range optionalUsesLibs {
- a.usesLibrary.addLib(usesLib, true)
- }
-
// Check that the <uses-library> list is coherent with the manifest.
if a.usesLibrary.enforceUsesLibraries() {
- manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(ctx, a.mergedManifestFile)
+ manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
+ ctx, a.mergedManifestFile, &a.classLoaderContexts)
apkDeps = append(apkDeps, manifestCheckFile)
}
@@ -1191,7 +1185,8 @@
module.AddProperties(
&module.aaptProperties,
&module.appProperties,
- &module.overridableAppProperties)
+ &module.overridableAppProperties,
+ &module.Library.sourceProperties)
module.usesLibrary.enforce = true
@@ -1337,7 +1332,14 @@
OutputFile: a.OutputFile(),
TestConfig: a.testConfig,
HostRequiredModuleNames: a.HostRequiredModuleNames(),
+ TestSuites: a.testProperties.Test_suites,
+ IsHost: false,
})
+ android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
+ TestOnly: true,
+ TopLevelTarget: true,
+ })
+
}
func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
@@ -1530,9 +1532,13 @@
android.OverrideModuleBase
}
-func (i *OverrideAndroidTest) GenerateAndroidBuildActions(_ android.ModuleContext) {
+func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// All the overrides happen in the base module.
// TODO(jungjw): Check the base module type.
+ android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
+ TestOnly: true,
+ TopLevelTarget: true,
+ })
}
// override_android_test is used to create an android_app module based on another android_test by overriding
@@ -1580,6 +1586,9 @@
// provide the android.test.base statically and use jarjar to rename them so they do not collide
// with the classes provided by the android.test.base library.
Exclude_uses_libs []string
+
+ // The module names of optional uses-library libraries that are missing from the source tree.
+ Missing_optional_uses_libs []string `blueprint:"mutated"`
}
// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
@@ -1596,20 +1605,11 @@
shouldDisableDexpreopt bool
}
-func (u *usesLibrary) addLib(lib string, optional bool) {
- if !android.InList(lib, u.usesLibraryProperties.Uses_libs) && !android.InList(lib, u.usesLibraryProperties.Optional_uses_libs) {
- if optional {
- u.usesLibraryProperties.Optional_uses_libs = append(u.usesLibraryProperties.Optional_uses_libs, lib)
- } else {
- u.usesLibraryProperties.Uses_libs = append(u.usesLibraryProperties.Uses_libs, lib)
- }
- }
-}
-
func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...)
- ctx.AddVariationDependencies(nil, usesLibOptTag, u.presentOptionalUsesLibs(ctx)...)
+ presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
+ ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
// Only add these extra dependencies if the module is an app that depends on framework
// libs. This avoids creating a cyclic dependency:
// e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
@@ -1620,6 +1620,8 @@
ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
}
+ _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs, presentOptionalUsesLibs)
+ u.usesLibraryProperties.Missing_optional_uses_libs = diff
} else {
ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs...)
ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
@@ -1638,15 +1640,6 @@
return optionalUsesLibs
}
-// Helper function to replace string in a list.
-func replaceInList(list []string, oldstr, newstr string) {
- for i, str := range list {
- if str == oldstr {
- list[i] = newstr
- }
- }
-}
-
// Returns a map of module names of shared library dependencies to the paths to their dex jars on
// host and on device.
func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap {
@@ -1688,11 +1681,6 @@
libName := dep
if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil {
libName = *ulib.ProvidesUsesLib()
- // Replace module name with library name in `uses_libs`/`optional_uses_libs` in
- // order to pass verify_uses_libraries check (which compares these properties
- // against library names written in the manifest).
- replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName)
- replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
}
clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
lib.DexJarBuildPath(ctx).PathOrNil(), lib.DexJarInstallPath(),
@@ -1726,7 +1714,7 @@
// an APK with the manifest embedded in it (manifest_check will know which one it is by the file
// extension: APKs are supposed to end with '.apk').
func (u *usesLibrary) verifyUsesLibraries(ctx android.ModuleContext, inputFile android.Path,
- outputFile android.WritablePath) android.Path {
+ outputFile android.WritablePath, classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
statusFile := dexpreopt.UsesLibrariesStatusFile(ctx)
@@ -1754,27 +1742,37 @@
cmd.Flag("--enforce-uses-libraries-relax")
}
- for _, lib := range u.usesLibraryProperties.Uses_libs {
+ requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
+ for _, lib := range requiredUsesLibs {
cmd.FlagWithArg("--uses-library ", lib)
}
-
- for _, lib := range u.usesLibraryProperties.Optional_uses_libs {
+ for _, lib := range optionalUsesLibs {
cmd.FlagWithArg("--optional-uses-library ", lib)
}
+ // Also add missing optional uses libs, as the manifest check expects them.
+ // Note that what we add here are the module names of those missing libs, not library names, while
+ // the manifest check actually expects library names. However, the case where a library is missing
+ // and the module name != the library name is too rare for us to handle.
+ for _, lib := range u.usesLibraryProperties.Missing_optional_uses_libs {
+ cmd.FlagWithArg("--missing-optional-uses-library ", lib)
+ }
+
rule.Build("verify_uses_libraries", "verify <uses-library>")
return outputFile
}
// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against
// the build system and returns the path to a copy of the manifest.
-func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path {
+func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path,
+ classLoaderContexts *dexpreopt.ClassLoaderContextMap) android.Path {
outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
- return u.verifyUsesLibraries(ctx, manifest, outputFile)
+ return u.verifyUsesLibraries(ctx, manifest, outputFile, classLoaderContexts)
}
// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the build
// system and returns the path to a copy of the APK.
-func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) {
- u.verifyUsesLibraries(ctx, apk, nil) // for APKs manifest_check does not write output file
+func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path,
+ classLoaderContexts *dexpreopt.ClassLoaderContextMap) {
+ u.verifyUsesLibraries(ctx, apk, nil, classLoaderContexts) // for APKs manifest_check does not write output file
}
diff --git a/java/app_import.go b/java/app_import.go
index 7387e16..bb07c42 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -355,7 +355,7 @@
}
if a.usesLibrary.enforceUsesLibraries() {
- a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
+ a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk, &a.dexpreopter.classLoaderContexts)
}
a.dexpreopter.dexpreopt(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), jnisUncompressed)
@@ -611,6 +611,12 @@
return return_struct
}
+func (a *AndroidAppImport) UsesLibrary() *usesLibrary {
+ return &a.usesLibrary
+}
+
+var _ ModuleWithUsesLibrary = (*AndroidAppImport)(nil)
+
// android_app_import imports a prebuilt apk with additional processing specified in the module.
// DPI-specific apk source files can be specified using dpi_variants. Example:
//
diff --git a/java/app_test.go b/java/app_test.go
index ca9d317..eab40e7 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -3244,7 +3244,10 @@
name: "static-y",
srcs: ["a.java"],
uses_libs: ["runtime-required-y"],
- optional_uses_libs: ["runtime-optional-y"],
+ optional_uses_libs: [
+ "runtime-optional-y",
+ "missing-lib-a",
+ ],
sdk_version: "current",
}
@@ -3280,7 +3283,7 @@
sdk_version: "current",
optional_uses_libs: [
"bar",
- "baz",
+ "missing-lib-b",
],
}
@@ -3295,7 +3298,7 @@
],
optional_uses_libs: [
"bar",
- "baz",
+ "missing-lib-b",
],
}
`
@@ -3317,10 +3320,10 @@
// propagated from dependencies.
actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
expectManifestFixerArgs := `--extract-native-libs=true ` +
- `--uses-library qux ` +
- `--uses-library quuz ` +
`--uses-library foo ` +
`--uses-library com.non.sdk.lib ` +
+ `--uses-library qux ` +
+ `--uses-library quuz ` +
`--uses-library runtime-library ` +
`--uses-library runtime-required-x ` +
`--uses-library runtime-required-y ` +
@@ -3339,9 +3342,10 @@
`--uses-library runtime-required-x ` +
`--uses-library runtime-required-y ` +
`--optional-uses-library bar ` +
- `--optional-uses-library baz ` +
`--optional-uses-library runtime-optional-x ` +
- `--optional-uses-library runtime-optional-y `
+ `--optional-uses-library runtime-optional-y ` +
+ `--missing-optional-uses-library missing-lib-b ` +
+ `--missing-optional-uses-library missing-lib-a`
android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs)
// Test that all libraries are verified for an APK (library order matters).
@@ -3350,7 +3354,7 @@
`--uses-library com.non.sdk.lib ` +
`--uses-library android.test.runner ` +
`--optional-uses-library bar ` +
- `--optional-uses-library baz `
+ `--missing-optional-uses-library missing-lib-b `
android.AssertStringDoesContain(t, "verify apk cmd args", verifyApkCmd, verifyApkArgs)
// Test that necessary args are passed for constructing CLC in Ninja phase.
@@ -3625,7 +3629,10 @@
android_app {
name: "foo",
sdk_version: "current",
- static_libs: ["lib1"],
+ static_libs: [
+ "lib1",
+ "lib3",
+ ],
}
android_library {
@@ -3633,22 +3640,49 @@
sdk_version: "current",
optimize: {
proguard_flags_files: ["lib1proguard.cfg"],
+ },
+ static_libs: ["lib2"],
+ }
+
+ android_library {
+ name: "lib2",
+ sdk_version: "current",
+ optimize: {
+ proguard_flags_files: ["lib2proguard.cfg"],
}
}
+
+ android_library_import {
+ name: "lib3",
+ sdk_version: "current",
+ aars: ["lib3.aar"],
+ static_libs: ["lib4"],
+ }
+
+ android_library {
+ name: "lib4",
+ sdk_version: "current",
+ optimize: {
+ proguard_flags_files: ["lib4proguard.cfg"],
+ }
+ }
+
+
`)
m := ctx.ModuleForTests("foo", "android_common")
- hasLib1Proguard := false
- for _, s := range m.Rule("java.r8").Implicits.Strings() {
- if s == "lib1proguard.cfg" {
- hasLib1Proguard = true
- break
- }
- }
+ r8 := m.Rule("java.r8")
+ implicits := r8.Implicits.RelativeToTop().Strings()
+ android.AssertStringListContains(t, "r8 implicits", implicits, "lib1proguard.cfg")
+ android.AssertStringListContains(t, "r8 implicits", implicits, "lib2proguard.cfg")
+ android.AssertStringListContains(t, "r8 implicits", implicits, "lib4proguard.cfg")
+ android.AssertStringListContains(t, "r8 implicits", implicits, "out/soong/.intermediates/lib3/android_common/aar/proguard.txt")
- if !hasLib1Proguard {
- t.Errorf("App does not use library proguard config")
- }
+ flags := r8.Args["r8Flags"]
+ android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib1proguard.cfg")
+ android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib2proguard.cfg")
+ android.AssertStringDoesContain(t, "r8 flags", flags, "-include lib4proguard.cfg")
+ android.AssertStringDoesContain(t, "r8 flags", flags, "-include out/soong/.intermediates/lib3/android_common/aar/proguard.txt")
}
func TestTargetSdkVersionManifestFixer(t *testing.T) {
@@ -4402,6 +4436,44 @@
android.AssertBoolEquals(t, "dexpreopt should be disabled if optional_uses_libs does not have an implementation", true, dexpreopt == nil)
}
+func TestTestOnlyApp(t *testing.T) {
+ t.Parallel()
+ ctx := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ ).RunTestWithBp(t, `
+ // These should be test-only
+ android_test {
+ name: "android-test",
+ }
+ android_test_helper_app {
+ name: "helper-app",
+ }
+ override_android_test {
+ name: "override-test",
+ base: "android-app",
+ }
+ // And these should not be
+ android_app {
+ name: "android-app",
+ srcs: ["b.java"],
+ sdk_version: "current",
+ }
+ `)
+
+ expectedTestOnly := []string{
+ "android-test",
+ "helper-app",
+ "override-test",
+ }
+
+ expectedTopLevel := []string{
+ "android-test",
+ "override-test",
+ }
+
+ assertTestOnlyAndTopLevel(t, ctx, expectedTestOnly, expectedTopLevel)
+}
+
func TestAppStem(t *testing.T) {
ctx := testApp(t, `
android_app {
diff --git a/java/base.go b/java/base.go
index be286fe..938ac5e 100644
--- a/java/base.go
+++ b/java/base.go
@@ -94,9 +94,6 @@
// if not blank, used as prefix to generate repackage rule
Jarjar_prefix *string
- // if set to true, skip the jarjar repackaging
- Skip_jarjar_repackage *bool
-
// If not blank, set the java version passed to javac as -source and -target
Java_version *string
@@ -200,6 +197,9 @@
// Additional srcJars tacked in by GeneratedJavaLibraryModule
Generated_srcjars []android.Path `android:"mutated"`
+ // intermediate aconfig cache file tacked in by GeneratedJavaLibraryModule
+ Aconfig_Cache_files []android.Path `android:"mutated"`
+
// If true, then only the headers are built and not the implementation jar.
Headers_only *bool
@@ -435,6 +435,7 @@
deviceProperties DeviceProperties
overridableProperties OverridableProperties
+ sourceProperties android.SourceProperties
// jar file containing header classes including static library dependencies, suitable for
// inserting into the bootclasspath/classpath of another compile
@@ -544,6 +545,11 @@
jarjarRenameRules map[string]string
stubsLinkType StubsLinkType
+
+ // Paths to the aconfig intermediate cache files that are provided by the
+ // java_aconfig_library or java_library modules that are statically linked
+ // to this module. Does not contain cache files from all transitive dependencies.
+ aconfigCacheFiles android.Paths
}
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
@@ -804,7 +810,7 @@
// Add dependency on libraries that provide additional hidden api annotations.
ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...)
- if ctx.DeviceConfig().VndkVersion() != "" && ctx.Config().EnforceInterPartitionJavaSdkLibrary() {
+ if ctx.Config().EnforceInterPartitionJavaSdkLibrary() {
// Require java_sdk_library at inter-partition java dependency to ensure stable
// interface between partitions. If inter-partition java_library dependency is detected,
// raise build error because java_library doesn't have a stable interface.
@@ -837,9 +843,11 @@
if dep != nil {
if component, ok := dep.(SdkLibraryComponentDependency); ok {
if lib := component.OptionalSdkLibraryImplementation(); lib != nil {
- // Add library as optional if it's one of the optional compatibility libs.
+ // Add library as optional if it's one of the optional compatibility libs or it's
+ // explicitly listed in the optional_uses_libs property.
tag := usesLibReqTag
- if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) {
+ if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) ||
+ android.InList(*lib, j.usesLibrary.usesLibraryProperties.Optional_uses_libs) {
tag = usesLibOptTag
}
ctx.AddVariationDependencies(nil, tag, *lib)
@@ -1103,13 +1111,11 @@
jarjarProviderData := j.collectJarJarRules(ctx)
if jarjarProviderData != nil {
android.SetProvider(ctx, JarJarProvider, *jarjarProviderData)
- if !proptools.Bool(j.properties.Skip_jarjar_repackage) {
- text := getJarJarRuleText(jarjarProviderData)
- if text != "" {
- ruleTextFile := android.PathForModuleOut(ctx, "repackaged-jarjar", "repackaging.txt")
- android.WriteFileRule(ctx, ruleTextFile, text)
- j.repackageJarjarRules = ruleTextFile
- }
+ text := getJarJarRuleText(jarjarProviderData)
+ if text != "" {
+ ruleTextFile := android.PathForModuleOut(ctx, "repackaged-jarjar", "repackaging.txt")
+ android.WriteFileRule(ctx, ruleTextFile, text)
+ j.repackageJarjarRules = ruleTextFile
}
}
@@ -1202,6 +1208,8 @@
// final R classes from the app.
flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...)
+ j.aconfigCacheFiles = append(deps.aconfigProtoFiles, j.properties.Aconfig_Cache_files...)
+
// If compiling headers then compile them and skip the rest
if proptools.Bool(j.properties.Headers_only) {
if srcFiles.HasExt(".kt") {
@@ -1294,10 +1302,12 @@
return
}
+ kotlinJarPath := j.repackageFlagsIfNecessary(ctx, kotlinJar.OutputPath, jarName, "kotlinc")
+
// Make javac rule depend on the kotlinc rule
flags.classpath = append(classpath{kotlinHeaderJar}, flags.classpath...)
- kotlinJars = append(kotlinJars, kotlinJar)
+ kotlinJars = append(kotlinJars, kotlinJarPath)
kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar)
// Jar kotlin classes into the final jar after javac
@@ -1377,6 +1387,7 @@
for idx, shardSrc := range shardSrcs {
classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
nil, flags, extraJarDeps)
+ classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx))
jars = append(jars, classes)
}
}
@@ -1389,11 +1400,13 @@
for idx, shardSrcJars := range shardSrcJarsList {
classes := j.compileJavaClasses(ctx, jarName, startIdx+idx,
nil, shardSrcJars, flags, extraJarDeps)
+ classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx))
jars = append(jars, classes)
}
}
} else {
classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
+ classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac")
jars = append(jars, classes)
}
if ctx.Failed() {
@@ -1552,16 +1565,6 @@
}
}
- // Automatic jarjar rules propagation
- if j.repackageJarjarRules != nil {
- repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", jarName).OutputPath
- TransformJarJar(ctx, repackagedJarjarFile, outputFile, j.repackageJarjarRules)
- outputFile = repackagedJarjarFile
- if ctx.Failed() {
- return
- }
- }
-
// Check package restrictions if necessary.
if len(j.properties.Permitted_packages) > 0 {
// Time stamp file created by the package check rule.
@@ -1746,7 +1749,7 @@
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
JacocoReportClassesFile: j.jacocoReportClassesFile,
StubsLinkType: j.stubsLinkType,
- AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles,
+ AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles,
})
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
@@ -1757,10 +1760,7 @@
return android.InList("androidx.compose.runtime_runtime", j.properties.Static_libs)
}
-func (j *Module) collectProguardSpecInfo(ctx android.ModuleContext) ProguardSpecInfo {
- transitiveUnconditionalExportedFlags := []*android.DepSet[android.Path]{}
- transitiveProguardFlags := []*android.DepSet[android.Path]{}
-
+func collectDepProguardSpecInfo(ctx android.ModuleContext) (transitiveProguardFlags, transitiveUnconditionalExportedFlags []*android.DepSet[android.Path]) {
ctx.VisitDirectDeps(func(m android.Module) {
depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider)
depTag := ctx.OtherModuleDependencyTag(m)
@@ -1775,6 +1775,12 @@
}
})
+ return transitiveProguardFlags, transitiveUnconditionalExportedFlags
+}
+
+func (j *Module) collectProguardSpecInfo(ctx android.ModuleContext) ProguardSpecInfo {
+ transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx)
+
directUnconditionalExportedFlags := android.Paths{}
proguardFlagsForThisModule := android.PathsForModuleSrc(ctx, j.dexProperties.Optimize.Proguard_flags_files)
exportUnconditionally := proptools.Bool(j.dexProperties.Optimize.Export_proguard_flags_files)
@@ -2357,7 +2363,10 @@
deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
}
} else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
- deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
+ switch tag {
+ case staticLibTag:
+ deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
+ }
} else {
switch tag {
case bootClasspathTag:
@@ -2380,6 +2389,7 @@
}
addCLCFromDep(ctx, module, j.classLoaderContexts)
+ addMissingOptionalUsesLibsFromDep(ctx, module, &j.usesLibrary)
})
return deps
@@ -2683,6 +2693,16 @@
return result
}
+// Repackage the flags if the jarjar rule txt for the flags is generated
+func (j *Module) repackageFlagsIfNecessary(ctx android.ModuleContext, infile android.WritablePath, jarName, info string) android.WritablePath {
+ if j.repackageJarjarRules == nil {
+ return infile
+ }
+ repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", info+jarName)
+ TransformJarJar(ctx, repackagedJarjarFile, infile, j.repackageJarjarRules)
+ return repackagedJarjarFile
+}
+
func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) {
deps.processorPath = append(deps.processorPath, pluginJars...)
deps.processorClasses = append(deps.processorClasses, pluginClasses...)
@@ -2703,3 +2723,13 @@
}
var _ ModuleWithStem = (*Module)(nil)
+
+type ModuleWithUsesLibrary interface {
+ UsesLibrary() *usesLibrary
+}
+
+func (j *Module) UsesLibrary() *usesLibrary {
+ return &j.usesLibrary
+}
+
+var _ ModuleWithUsesLibrary = (*Module)(nil)
diff --git a/java/config/config.go b/java/config/config.go
index d720046..2bb50f6 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -26,8 +26,7 @@
)
var (
- pctx = android.NewPackageContext("android/soong/java/config")
- exportedVars = android.NewExportedVariables(pctx)
+ pctx = android.NewPackageContext("android/soong/java/config")
LegacyCorePlatformBootclasspathLibraries = []string{"legacy.core.platform.api.stubs", "core-lambda-stubs"}
LegacyCorePlatformSystemModules = "legacy-core-platform-api-stubs-system-modules"
@@ -79,30 +78,30 @@
func init() {
pctx.Import("github.com/google/blueprint/bootstrap")
- exportedVars.ExportStringStaticVariable("JavacHeapSize", "4096M")
- exportedVars.ExportStringStaticVariable("JavacHeapFlags", "-J-Xmx${JavacHeapSize}")
+ pctx.StaticVariable("JavacHeapSize", "4096M")
+ pctx.StaticVariable("JavacHeapFlags", "-J-Xmx${JavacHeapSize}")
// ErrorProne can use significantly more memory than javac alone, give it a higher heap
// size (b/221480398).
- exportedVars.ExportStringStaticVariable("ErrorProneHeapSize", "8192M")
- exportedVars.ExportStringStaticVariable("ErrorProneHeapFlags", "-J-Xmx${ErrorProneHeapSize}")
+ pctx.StaticVariable("ErrorProneHeapSize", "8192M")
+ pctx.StaticVariable("ErrorProneHeapFlags", "-J-Xmx${ErrorProneHeapSize}")
// D8 invocations are shorter lived, so we restrict their JIT tiering relative to R8.
// Note that the `-JXX` prefix syntax is specific to the R8/D8 invocation wrappers.
- exportedVars.ExportStringListStaticVariable("D8Flags", append([]string{
+ pctx.StaticVariable("D8Flags", strings.Join(append([]string{
"-JXmx4096M",
"-JXX:+TieredCompilation",
"-JXX:TieredStopAtLevel=1",
"-JDcom.android.tools.r8.emitRecordAnnotationsInDex",
"-JDcom.android.tools.r8.emitPermittedSubclassesAnnotationsInDex",
- }, dexerJavaVmFlagsList...))
- exportedVars.ExportStringListStaticVariable("R8Flags", append([]string{
+ }, dexerJavaVmFlagsList...), " "))
+ pctx.StaticVariable("R8Flags", strings.Join(append([]string{
"-JXmx4096M",
"-JDcom.android.tools.r8.emitRecordAnnotationsInDex",
"-JDcom.android.tools.r8.emitPermittedSubclassesAnnotationsInDex",
- }, dexerJavaVmFlagsList...))
+ }, dexerJavaVmFlagsList...), " "))
- exportedVars.ExportStringListStaticVariable("CommonJdkFlags", []string{
+ pctx.StaticVariable("CommonJdkFlags", strings.Join([]string{
`-Xmaxerrs 9999999`,
`-encoding UTF-8`,
`-sourcepath ""`,
@@ -116,10 +115,10 @@
// b/65004097: prevent using java.lang.invoke.StringConcatFactory when using -target 1.9
`-XDstringConcat=inline`,
- })
+ }, " "))
- exportedVars.ExportStringListStaticVariable("JavaVmFlags", javaVmFlagsList)
- exportedVars.ExportStringListStaticVariable("JavacVmFlags", javacVmFlagsList)
+ pctx.StaticVariable("JavaVmFlags", strings.Join(javaVmFlagsList, " "))
+ pctx.StaticVariable("JavacVmFlags", strings.Join(javacVmFlagsList, " "))
pctx.VariableConfigMethod("hostPrebuiltTag", android.Config.PrebuiltOS)
diff --git a/java/config/droidstubs.go b/java/config/droidstubs.go
index 39eec44..04a3f96 100644
--- a/java/config/droidstubs.go
+++ b/java/config/droidstubs.go
@@ -58,11 +58,7 @@
)
func init() {
- exportedVars.ExportStringList("MetalavaFlags", metalavaFlags)
+ pctx.StaticVariable("MetalavaAnnotationsFlags", strings.Join(metalavaAnnotationsFlags, " "))
- exportedVars.ExportString("MetalavaAddOpens", MetalavaAddOpens)
-
- exportedVars.ExportStringListStaticVariable("MetalavaAnnotationsFlags", metalavaAnnotationsFlags)
-
- exportedVars.ExportStringListStaticVariable("MetalavaAnnotationWarningsFlags", metalavaAnnotationsWarningsFlags)
+ pctx.StaticVariable("MetalavaAnnotationWarningsFlags", strings.Join(metalavaAnnotationsWarningsFlags, " "))
}
diff --git a/java/config/error_prone.go b/java/config/error_prone.go
index 5f853c8..767164f 100644
--- a/java/config/error_prone.go
+++ b/java/config/error_prone.go
@@ -15,6 +15,7 @@
package config
import (
+ "android/soong/android"
"strings"
)
@@ -29,23 +30,23 @@
)
// Wrapper that grabs value of val late so it can be initialized by a later module's init function
-func errorProneVar(val *[]string, sep string) func() string {
- return func() string {
+func errorProneVar(val *[]string, sep string) func(android.PackageVarContext) string {
+ return func(android.PackageVarContext) string {
return strings.Join(*val, sep)
}
}
func init() {
- exportedVars.ExportVariableFuncVariable("ErrorProneClasspath", errorProneVar(&ErrorProneClasspath, ":"))
- exportedVars.ExportVariableFuncVariable("ErrorProneChecksError", errorProneVar(&ErrorProneChecksError, " "))
- exportedVars.ExportVariableFuncVariable("ErrorProneChecksWarning", errorProneVar(&ErrorProneChecksWarning, " "))
- exportedVars.ExportVariableFuncVariable("ErrorProneChecksDefaultDisabled", errorProneVar(&ErrorProneChecksDefaultDisabled, " "))
- exportedVars.ExportVariableFuncVariable("ErrorProneChecksOff", errorProneVar(&ErrorProneChecksOff, " "))
- exportedVars.ExportVariableFuncVariable("ErrorProneFlags", errorProneVar(&ErrorProneFlags, " "))
- exportedVars.ExportStringListStaticVariable("ErrorProneChecks", []string{
+ pctx.VariableFunc("ErrorProneClasspath", errorProneVar(&ErrorProneClasspath, ":"))
+ pctx.VariableFunc("ErrorProneChecksError", errorProneVar(&ErrorProneChecksError, " "))
+ pctx.VariableFunc("ErrorProneChecksWarning", errorProneVar(&ErrorProneChecksWarning, " "))
+ pctx.VariableFunc("ErrorProneChecksDefaultDisabled", errorProneVar(&ErrorProneChecksDefaultDisabled, " "))
+ pctx.VariableFunc("ErrorProneChecksOff", errorProneVar(&ErrorProneChecksOff, " "))
+ pctx.VariableFunc("ErrorProneFlags", errorProneVar(&ErrorProneFlags, " "))
+ pctx.StaticVariable("ErrorProneChecks", strings.Join([]string{
"${ErrorProneChecksOff}",
"${ErrorProneChecksError}",
"${ErrorProneChecksWarning}",
"${ErrorProneChecksDefaultDisabled}",
- })
+ }, " "))
}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 38ed856..25e95db 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -243,10 +243,6 @@
return true
}
- if disableSourceApexVariant(ctx) {
- return true
- }
-
if _, isApex := android.ModuleProvider(ctx, android.ApexBundleInfoProvider); isApex {
// dexpreopt rules for system server jars can be generated in the ModuleCtx of prebuilt apexes
return false
@@ -501,8 +497,12 @@
Output(appProductPackages)
productPackagesRule.Restat().Build("product_packages."+dexJarStem, "dexpreopt product_packages")
+ // Prebuilts are active, do not copy the dexpreopt'd source javalib to out/soong/system_server_dexjars
+ // The javalib from the deapexed prebuilt will be copied to this location.
+ // TODO (b/331665856): Implement a principled solution for this.
+ copyApexSystemServerJarDex := !disableSourceApexVariant(ctx)
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(
- ctx, globalSoong, global, dexpreoptConfig, appProductPackages)
+ ctx, globalSoong, global, dexpreoptConfig, appProductPackages, copyApexSystemServerJarDex)
if err != nil {
ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error())
return
diff --git a/java/droiddoc.go b/java/droiddoc.go
index aec40b3..176779e 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -391,12 +391,14 @@
} else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
deps.classpath = append(deps.classpath, dep.HeaderJars...)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
+ deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
} else if dep, ok := module.(android.SourceFileProducer); ok {
checkProducesJars(ctx, dep)
deps.classpath = append(deps.classpath, dep.Srcs()...)
} else {
ctx.ModuleErrorf("depends on non-java module %q", otherName)
}
+
case java9LibTag:
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
@@ -429,6 +431,19 @@
srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
j.implicits = append(j.implicits, srcFiles...)
+ // Module can depend on a java_aconfig_library module using the ":module_name{.tag}" syntax.
+ // Find the corresponding aconfig_declarations module name for such case.
+ for _, src := range j.properties.Srcs {
+ if moduleName, tag := android.SrcIsModuleWithTag(src); moduleName != "" {
+ otherModule := android.GetModuleFromPathDep(ctx, moduleName, tag)
+ if otherModule != nil {
+ if dep, ok := android.OtherModuleProvider(ctx, otherModule, android.CodegenInfoProvider); ok {
+ deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
+ }
+ }
+ }
+ }
+
filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
if filterPackages == nil {
return srcs
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 9556e95..870c643 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -532,8 +532,8 @@
cmd.Flag(config.MetalavaAnnotationsFlags)
if params.migratingNullability {
- previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
- cmd.FlagWithInput("--migrate-nullness ", previousApi)
+ previousApiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Previous_api)})
+ cmd.FlagForEachInput("--migrate-nullness ", previousApiFiles)
}
if s := String(d.properties.Validate_nullability_from_list); s != "" {
@@ -687,6 +687,23 @@
}
}
+func (d *Droidstubs) apiCompatibilityFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsType StubsType) {
+ if len(d.Javadoc.properties.Out) > 0 {
+ ctx.PropertyErrorf("out", "out property may not be combined with check_api")
+ }
+
+ apiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Check_api.Last_released.Api_file)})
+ removedApiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Check_api.Last_released.Removed_api_file)})
+
+ cmd.FlagForEachInput("--check-compatibility:api:released ", apiFiles)
+ cmd.FlagForEachInput("--check-compatibility:removed:released ", removedApiFiles)
+
+ baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
+ if baselineFile.Valid() {
+ cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
+ }
+}
+
func metalavaUseRbe(ctx android.ModuleContext) bool {
return ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_METALAVA")
}
@@ -831,6 +848,10 @@
d.inclusionAnnotationsFlags(ctx, cmd)
d.apiLevelsAnnotationsFlags(ctx, cmd, params.stubConfig.stubsType, params.apiVersionsXml)
+ if params.stubConfig.doCheckReleased {
+ d.apiCompatibilityFlags(ctx, cmd, params.stubConfig.stubsType)
+ }
+
d.expandArgs(ctx, cmd)
for _, o := range d.Javadoc.properties.Out {
@@ -929,9 +950,12 @@
// Add API lint options.
if doApiLint {
- newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
- if newSince.Valid() {
- cmd.FlagWithInput("--api-lint ", newSince.Path())
+ var newSince android.Paths
+ if d.properties.Check_api.Api_lint.New_since != nil {
+ newSince = android.PathsForModuleSrc(ctx, []string{proptools.String(d.properties.Check_api.Api_lint.New_since)})
+ }
+ if len(newSince) > 0 {
+ cmd.FlagForEachInput("--api-lint ", newSince)
} else {
cmd.Flag("--api-lint")
}
@@ -989,25 +1013,12 @@
// Add "check released" options. (Detect incompatible API changes from the last public release)
if doCheckReleased {
- if len(d.Javadoc.properties.Out) > 0 {
- ctx.PropertyErrorf("out", "out property may not be combined with check_api")
- }
-
- apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
- removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
- updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
-
d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, Everything.String(), "check_last_released_api.timestamp")
-
- cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
- cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
-
if baselineFile.Valid() {
- cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
+ updatedBaselineOutput := android.PathForModuleOut(ctx, Everything.String(), "last_released_baseline.txt")
cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
}
-
// Note this string includes quote ($' ... '), which decodes the "\n"s.
msg := `$'\n******************************\n` +
`You have tried to change the API from what has been previously released in\n` +
diff --git a/java/fuzz.go b/java/fuzz.go
index dc4c6be..fb31ce7 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -64,6 +64,8 @@
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Top_level_test_target = true
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
disableLinuxBionic := struct {
diff --git a/java/generated_java_library.go b/java/generated_java_library.go
index e8316cc..d5e6d8f 100644
--- a/java/generated_java_library.go
+++ b/java/generated_java_library.go
@@ -34,7 +34,7 @@
// Called from inside GenerateAndroidBuildActions. Add the build rules to
// make the srcjar, and return the path to it.
- GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path
+ GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) (android.Path, android.Path)
}
// GeneratedJavaLibraryModuleFactory provides a utility for modules that are generated
@@ -103,8 +103,10 @@
checkPropertyEmpty(ctx, module, "plugins", module.Library.properties.Plugins)
checkPropertyEmpty(ctx, module, "exported_plugins", module.Library.properties.Exported_plugins)
- srcJarPath := module.callbacks.GenerateSourceJarBuildActions(module, ctx)
+ srcJarPath, cacheOutputPath := module.callbacks.GenerateSourceJarBuildActions(module, ctx)
+
module.Library.properties.Generated_srcjars = append(module.Library.properties.Generated_srcjars, srcJarPath)
+ module.Library.properties.Aconfig_Cache_files = append(module.Library.properties.Aconfig_Cache_files, cacheOutputPath)
module.Library.GenerateAndroidBuildActions(ctx)
}
diff --git a/java/generated_java_library_test.go b/java/generated_java_library_test.go
index be816cd..a5c4be1 100644
--- a/java/generated_java_library_test.go
+++ b/java/generated_java_library_test.go
@@ -36,8 +36,8 @@
func (callbacks *JavaGenLibTestCallbacks) DepsMutator(module *GeneratedJavaLibraryModule, ctx android.BottomUpMutatorContext) {
}
-func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path {
- return android.PathForOutput(ctx, "blah.srcjar")
+func (callbacks *JavaGenLibTestCallbacks) GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) (android.Path, android.Path) {
+ return android.PathForOutput(ctx, "blah.srcjar"), android.PathForOutput(ctx, "blah.pb")
}
func testGenLib(t *testing.T, errorHandler android.FixtureErrorHandler, bp string) *android.TestResult {
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index e4beb5e..ae587ea 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -1478,13 +1478,3 @@
}
return bootDexJar.Path()
}
-
-// extractEncodedDexJarsFromModules extracts the encoded dex jars from the supplied modules.
-func extractEncodedDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule {
- encodedDexJarsByModuleName := bootDexJarByModule{}
- for _, module := range contents {
- path := retrieveEncodedBootDexJarFromModule(ctx, module)
- encodedDexJarsByModuleName.addPath(module, path)
- }
- return encodedDexJarsByModuleName
-}
diff --git a/java/java.go b/java/java.go
index b5f7077..725e25a 100644
--- a/java/java.go
+++ b/java/java.go
@@ -587,6 +587,7 @@
JAVA_VERSION_9 = 9
JAVA_VERSION_11 = 11
JAVA_VERSION_17 = 17
+ JAVA_VERSION_21 = 21
)
func (v javaVersion) String() string {
@@ -605,6 +606,8 @@
return "11"
case JAVA_VERSION_17:
return "17"
+ case JAVA_VERSION_21:
+ return "21"
default:
return "unsupported"
}
@@ -647,6 +650,8 @@
return JAVA_VERSION_11
case "17":
return JAVA_VERSION_17
+ case "21":
+ return JAVA_VERSION_21
case "10", "12", "13", "14", "15", "16":
ctx.PropertyErrorf("java_version", "Java language level %s is not supported", javaVersion)
return JAVA_VERSION_UNSUPPORTED
@@ -800,6 +805,7 @@
"android.hardware.security.keymint-V2-java": true,
"android.hardware.security.keymint-V3-java": true,
"android.hardware.security.keymint-V4-java": true,
+ "android.hardware.security.secretkeeper-V1-java": true,
"android.hardware.security.secureclock-V1-java": true,
"android.hardware.security.secureclock-V2-java": true,
"android.hardware.thermal-V1-java": true,
@@ -885,6 +891,12 @@
}
func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if disableSourceApexVariant(ctx) {
+ // Prebuilts are active, do not create the installation rules for the source javalib.
+ // Even though the source javalib is not used, we need to hide it to prevent duplicate installation rules.
+ // TODO (b/331665856): Implement a principled solution for this.
+ j.HideFromMake()
+ }
j.provideHiddenAPIPropertyInfo(ctx)
j.sdkVersion = j.SdkVersion(ctx)
@@ -957,11 +969,16 @@
}
j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...)
}
+
+ android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
+ TestOnly: Bool(j.sourceProperties.Test_only),
+ TopLevelTarget: j.sourceProperties.Top_level_test_target,
+ })
}
func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
- j.deps(ctx)
j.usesLibrary.deps(ctx, false)
+ j.deps(ctx)
}
const (
@@ -1122,6 +1139,7 @@
module := &Library{}
module.addHostAndDeviceProperties()
+ module.AddProperties(&module.sourceProperties)
module.initModuleAndImport(module)
@@ -1438,6 +1456,14 @@
j.Test.generateAndroidBuildActionsWithConfig(ctx, configs)
android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
+ android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
+ InstalledFiles: j.data,
+ OutputFile: j.outputFile,
+ TestConfig: j.testConfig,
+ RequiredModuleNames: j.RequiredModuleNames(),
+ TestSuites: j.testProperties.Test_suites,
+ IsHost: true,
+ })
}
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1595,6 +1621,8 @@
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Top_level_test_target = true
InitJavaModule(module, android.HostAndDeviceSupported)
return module
@@ -1610,6 +1638,7 @@
module.Module.properties.Installable = proptools.BoolPtr(true)
module.Module.dexpreopter.isTest = true
module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true)
+ module.Module.sourceProperties.Test_only = proptools.BoolPtr(true)
InitJavaModule(module, android.HostAndDeviceSupported)
return module
@@ -1665,6 +1694,8 @@
th.properties.Installable = installable
th.testProperties.Auto_gen_config = autoGenConfig
th.testProperties.Test_suites = testSuites
+ th.sourceProperties.Test_only = proptools.BoolPtr(true)
+ th.sourceProperties.Top_level_test_target = true
}
//
@@ -1790,7 +1821,7 @@
module := &Binary{}
module.addHostAndDeviceProperties()
- module.AddProperties(&module.binaryProperties)
+ module.AddProperties(&module.binaryProperties, &module.sourceProperties)
module.Module.properties.Installable = proptools.BoolPtr(true)
@@ -3142,13 +3173,35 @@
// <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies
// from its CLC should be added to the current CLC.
if sdkLib != nil {
- clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false,
+ optional := false
+ if module, ok := ctx.Module().(ModuleWithUsesLibrary); ok {
+ if android.InList(*sdkLib, module.UsesLibrary().usesLibraryProperties.Optional_uses_libs) {
+ optional = true
+ }
+ }
+ clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, optional,
dep.DexJarBuildPath(ctx).PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
} else {
clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
}
}
+func addMissingOptionalUsesLibsFromDep(ctx android.ModuleContext, depModule android.Module,
+ usesLibrary *usesLibrary) {
+
+ dep, ok := depModule.(ModuleWithUsesLibrary)
+ if !ok {
+ return
+ }
+
+ for _, lib := range dep.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)
+ }
+ }
+}
+
type JavaApiContributionImport struct {
JavaApiContribution
diff --git a/java/java_test.go b/java/java_test.go
index 7969d97..a1192bb 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -2838,6 +2838,99 @@
android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "revert-annotations-exportable.txt")
}
+func TestTestOnly(t *testing.T) {
+ t.Parallel()
+ ctx := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ ).RunTestWithBp(t, `
+ // These should be test-only
+ java_library {
+ name: "lib1-test-only",
+ srcs: ["a.java"],
+ test_only: true,
+ }
+ java_test {
+ name: "java-test",
+ }
+ java_test_host {
+ name: "java-test-host",
+ }
+ java_test_helper_library {
+ name: "helper-library",
+ }
+ java_binary {
+ name: "java-data-binary",
+ srcs: ["foo.java"],
+ main_class: "foo.bar.jb",
+ test_only: true,
+ }
+
+ // These are NOT
+ java_library {
+ name: "lib2-app",
+ srcs: ["b.java"],
+ }
+ java_import {
+ name: "bar",
+ jars: ["bar.jar"],
+ }
+ java_binary {
+ name: "java-binary",
+ srcs: ["foo.java"],
+ main_class: "foo.bar.jb",
+ }
+ `)
+
+ expectedTestOnlyModules := []string{
+ "lib1-test-only",
+ "java-test",
+ "java-test-host",
+ "helper-library",
+ "java-data-binary",
+ }
+ expectedTopLevelTests := []string{
+ "java-test",
+ "java-test-host",
+ }
+ assertTestOnlyAndTopLevel(t, ctx, expectedTestOnlyModules, expectedTopLevelTests)
+}
+
+// Don't allow setting test-only on things that are always tests or never tests.
+func TestInvalidTestOnlyTargets(t *testing.T) {
+ testCases := []string{
+ ` java_test { name: "java-test", test_only: true, srcs: ["foo.java"], } `,
+ ` java_test_host { name: "java-test-host", test_only: true, srcs: ["foo.java"], } `,
+ ` java_test_import { name: "java-test-import", test_only: true, } `,
+ ` java_api_library { name: "java-api-library", test_only: true, } `,
+ ` java_test_helper_library { name: "test-help-lib", test_only: true, } `,
+ ` java_defaults { name: "java-defaults", test_only: true, } `,
+ }
+
+ for i, bp := range testCases {
+ android.GroupFixturePreparers(prepareForJavaTest).
+ ExtendWithErrorHandler(
+ expectOneError("unrecognized property \"test_only\"",
+ fmt.Sprintf("testcase: %d", i))).
+ RunTestWithBp(t, bp)
+ }
+}
+
+// Expect exactly one that matches 'expected'.
+// Append 'msg' to the Errorf that printed.
+func expectOneError(expected string, msg string) android.FixtureErrorHandler {
+ return android.FixtureCustomErrorHandler(func(t *testing.T, result *android.TestResult) {
+ t.Helper()
+ if len(result.Errs) != 1 {
+ t.Errorf("Expected exactly one error, but found: %d when setting test_only on: %s", len(result.Errs), msg)
+ return
+ }
+ actualErrMsg := result.Errs[0].Error()
+ if !strings.Contains(actualErrMsg, expected) {
+ t.Errorf("Different error than expected. Received: [%v] on %s expected: %s", actualErrMsg, msg, expected)
+ }
+ })
+}
+
func TestJavaLibHostWithStem(t *testing.T) {
ctx, _ := testJava(t, `
java_library_host {
@@ -2917,3 +3010,34 @@
android.AssertStringEquals(t, "baz relative output path",
"baz.jar", bazOutputPath.Rel())
}
+
+func assertTestOnlyAndTopLevel(t *testing.T, ctx *android.TestResult, expectedTestOnly []string, expectedTopLevel []string) {
+ t.Helper()
+ actualTrueModules := []string{}
+ actualTopLevelTests := []string{}
+ addActuals := func(m blueprint.Module, key blueprint.ProviderKey[android.TestModuleInformation]) {
+ if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, key); ok {
+ if provider.TestOnly {
+ actualTrueModules = append(actualTrueModules, m.Name())
+ }
+ if provider.TopLevelTarget {
+ actualTopLevelTests = append(actualTopLevelTests, m.Name())
+ }
+ }
+ }
+
+ ctx.VisitAllModules(func(m blueprint.Module) {
+ addActuals(m, android.TestOnlyProviderKey)
+
+ })
+
+ notEqual, left, right := android.ListSetDifference(expectedTestOnly, actualTrueModules)
+ if notEqual {
+ t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right)
+ }
+
+ notEqual, left, right = android.ListSetDifference(expectedTopLevel, actualTopLevelTests)
+ if notEqual {
+ t.Errorf("top-level: Expected but not found: %v, Found but not expected: %v", left, right)
+ }
+}
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 6a79e58..00613ee 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -367,10 +367,23 @@
info := latest[k]
name := PrebuiltApiCombinedModuleName(info.module, info.scope, "latest")
+ // Iterate until the currentApiScope does not extend any other api scopes
+ // i.e. is not a superset of any other api scopes
+ // the relationship between the api scopes is defined in java/sdk_library.go
var srcs []string
currentApiScope := scopeByName[info.scope]
- srcs = append(srcs, PrebuiltApiModuleName(info.module, currentApiScope.name, "latest"))
+ for currentApiScope != nil {
+ if _, ok := latest[fmt.Sprintf("%s.%s", info.module, currentApiScope.name)]; ok {
+ srcs = append(srcs, PrebuiltApiModuleName(info.module, currentApiScope.name, "latest"))
+ }
+ currentApiScope = currentApiScope.extends
+ }
+ // srcs is currently listed in the order from the widest api scope to the narrowest api scopes
+ // e.g. module lib -> system -> public
+ // In order to pass the files in metalava from the narrowest api scope to the widest api scope,
+ // the list has to be reversed.
+ android.ReverseSliceInPlace(srcs)
createCombinedApiFilegroupModule(mctx, name, srcs)
}
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 5ddc675..bb5730d 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -705,10 +705,10 @@
annotationsZip android.OptionalPath
// The path to the latest API file.
- latestApiPath android.OptionalPath
+ latestApiPaths android.Paths
// The path to the latest removed API file.
- latestRemovedApiPath android.OptionalPath
+ latestRemovedApiPaths android.Paths
}
func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error {
@@ -829,28 +829,25 @@
})
}
-func extractSingleOptionalOutputPath(dep android.Module) (android.OptionalPath, error) {
+func extractOutputPaths(dep android.Module) (android.Paths, error) {
var paths android.Paths
if sourceFileProducer, ok := dep.(android.SourceFileProducer); ok {
paths = sourceFileProducer.Srcs()
+ return paths, nil
} else {
- return android.OptionalPath{}, fmt.Errorf("module %q does not produce source files", dep)
+ return nil, fmt.Errorf("module %q does not produce source files", dep)
}
- if len(paths) != 1 {
- return android.OptionalPath{}, fmt.Errorf("expected one path from %q, got %q", dep, paths)
- }
- return android.OptionalPathForPath(paths[0]), nil
}
func (paths *scopePaths) extractLatestApiPath(ctx android.ModuleContext, dep android.Module) error {
- outputPath, err := extractSingleOptionalOutputPath(dep)
- paths.latestApiPath = outputPath
+ outputPaths, err := extractOutputPaths(dep)
+ paths.latestApiPaths = outputPaths
return err
}
func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, dep android.Module) error {
- outputPath, err := extractSingleOptionalOutputPath(dep)
- paths.latestRemovedApiPath = outputPath
+ outputPaths, err := extractOutputPaths(dep)
+ paths.latestRemovedApiPaths = outputPaths
return err
}
@@ -949,6 +946,10 @@
// Functionality related to this being used as a component of a java_sdk_library.
EmbeddableSdkLibraryComponent
+
+ // Path to the header jars of the implementation library
+ // This is non-empty only when api_only is false.
+ implLibraryHeaderJars android.Paths
}
func (c *commonToSdkLibraryAndImport) initCommon(module commonSdkLibraryAndImportModule) {
@@ -1356,13 +1357,6 @@
// class changes but it does not contain and implementation or JavaDoc.
SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths
- // Get the implementation jars appropriate for the supplied sdk version.
- //
- // These are either the implementation jar for the whole sdk library or the implementation
- // jars for the stubs. The latter should only be needed when generating JavaDoc as otherwise
- // they are identical to the corresponding header jars.
- SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths
-
// SdkApiStubDexJar returns the dex jar for the stubs for the prebuilt
// java_sdk_library_import module. It is needed by the hiddenapi processing tool which
// processes dex files.
@@ -1565,6 +1559,12 @@
}
func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if disableSourceApexVariant(ctx) {
+ // Prebuilts are active, do not create the installation rules for the source javalib.
+ // Even though the source javalib is not used, we need to hide it to prevent duplicate installation rules.
+ // TODO (b/331665856): Implement a principled solution for this.
+ module.HideFromMake()
+ }
if proptools.String(module.deviceProperties.Min_sdk_version) != "" {
module.CheckMinSdkVersion(ctx)
}
@@ -1599,6 +1599,12 @@
exportedComponents[ctx.OtherModuleName(to)] = struct{}{}
}
+
+ if tag == implLibraryTag {
+ if dep, ok := android.OtherModuleProvider(ctx, to, JavaInfoProvider); ok {
+ module.implLibraryHeaderJars = append(module.implLibraryHeaderJars, dep.HeaderJars...)
+ }
+ }
})
// Make the set of components exported by this module available for use elsewhere.
@@ -1616,11 +1622,15 @@
scopes[scope.name] = scopeInfo
scopeInfo["current_api"] = scope.snapshotRelativeCurrentApiTxtPath(baseModuleName)
scopeInfo["removed_api"] = scope.snapshotRelativeRemovedApiTxtPath(baseModuleName)
- if p := scopePaths.latestApiPath; p.Valid() {
- scopeInfo["latest_api"] = p.Path().String()
+ if p := scopePaths.latestApiPaths; len(p) > 0 {
+ // The last path in the list is the one that applies to this scope, the
+ // preceding ones, if any, are for the scope(s) that it extends.
+ scopeInfo["latest_api"] = p[len(p)-1].String()
}
- if p := scopePaths.latestRemovedApiPath; p.Valid() {
- scopeInfo["latest_removed_api"] = p.Path().String()
+ if p := scopePaths.latestRemovedApiPaths; len(p) > 0 {
+ // The last path in the list is the one that applies to this scope, the
+ // preceding ones, if any, are for the scope(s) that it extends.
+ scopeInfo["latest_removed_api"] = p[len(p)-1].String()
}
}
android.SetProvider(ctx, android.AdditionalSdkInfoProvider, android.AdditionalSdkInfo{additionalSdkInfo})
@@ -2238,7 +2248,7 @@
return len(otherApexInfo.InApexVariants) > 0 && reflect.DeepEqual(apexInfo.InApexVariants, otherApexInfo.InApexVariants)
}
-func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec, headerJars bool) android.Paths {
+func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
// If the client doesn't set sdk_version, but if this library prefers stubs over
// the impl library, let's provide the widest API surface possible. To do so,
// force override sdk_version to module_current so that the closest possible API
@@ -2255,11 +2265,7 @@
// * No sdk_version specified on the referencing module.
// * The referencing module is in the same apex as this.
if sdkVersion.Kind == android.SdkPrivate || withinSameApexesAs(ctx, module) {
- if headerJars {
- return module.HeaderJars()
- } else {
- return module.ImplementationJars()
- }
+ return module.implLibraryHeaderJars
}
}
@@ -2268,12 +2274,7 @@
// to satisfy SdkLibraryDependency interface
func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
- return module.sdkJars(ctx, sdkVersion, true /*headerJars*/)
-}
-
-// to satisfy SdkLibraryDependency interface
-func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
- return module.sdkJars(ctx, sdkVersion, false /*headerJars*/)
+ return module.sdkJars(ctx, sdkVersion)
}
var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
@@ -2983,12 +2984,6 @@
return module.sdkJars(ctx, sdkVersion, true)
}
-// to satisfy SdkLibraryDependency interface
-func (module *SdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
- // This module is just a wrapper for the stubs.
- return module.sdkJars(ctx, sdkVersion, false)
-}
-
// to satisfy UsesLibraryDependency interface
func (module *SdkLibraryImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath {
// The dex implementation jar extracted from the .apex file should be used in preference to the
@@ -3250,14 +3245,14 @@
if value == nil {
return ""
}
- return fmt.Sprintf(` %s=\"%s\"\n`, attrName, *value)
+ return fmt.Sprintf(" %s=\"%s\"\n", attrName, *value)
}
func formattedDependenciesAttribute(dependencies []string) string {
if dependencies == nil {
return ""
}
- return fmt.Sprintf(` dependency=\"%s\"\n`, strings.Join(dependencies, ":"))
+ return fmt.Sprintf(" dependency=\"%s\"\n", strings.Join(dependencies, ":"))
}
func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) string {
@@ -3274,28 +3269,28 @@
// similarly, min_device_sdk is only understood from T. So if a library is using that, we need to use the apex-library to make sure this library is not loaded before T
var libraryTag string
if module.properties.Min_device_sdk != nil {
- libraryTag = ` <apex-library\n`
+ libraryTag = " <apex-library\n"
} else {
- libraryTag = ` <library\n`
+ libraryTag = " <library\n"
}
return strings.Join([]string{
- `<?xml version=\"1.0\" encoding=\"utf-8\"?>\n`,
- `<!-- Copyright (C) 2018 The Android Open Source Project\n`,
- `\n`,
- ` Licensed under the Apache License, Version 2.0 (the \"License\");\n`,
- ` you may not use this file except in compliance with the License.\n`,
- ` You may obtain a copy of the License at\n`,
- `\n`,
- ` http://www.apache.org/licenses/LICENSE-2.0\n`,
- `\n`,
- ` Unless required by applicable law or agreed to in writing, software\n`,
- ` distributed under the License is distributed on an \"AS IS\" BASIS,\n`,
- ` WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n`,
- ` See the License for the specific language governing permissions and\n`,
- ` limitations under the License.\n`,
- `-->\n`,
- `<permissions>\n`,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
+ "<!-- Copyright (C) 2018 The Android Open Source Project\n",
+ "\n",
+ " Licensed under the Apache License, Version 2.0 (the \"License\");\n",
+ " you may not use this file except in compliance with the License.\n",
+ " You may obtain a copy of the License at\n",
+ "\n",
+ " http://www.apache.org/licenses/LICENSE-2.0\n",
+ "\n",
+ " Unless required by applicable law or agreed to in writing, software\n",
+ " distributed under the License is distributed on an \"AS IS\" BASIS,\n",
+ " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
+ " See the License for the specific language governing permissions and\n",
+ " limitations under the License.\n",
+ "-->\n",
+ "<permissions>\n",
libraryTag,
libNameAttr,
filePathAttr,
@@ -3304,8 +3299,9 @@
minSdkAttr,
maxSdkAttr,
dependenciesAttr,
- ` />\n`,
- `</permissions>\n`}, "")
+ " />\n",
+ "</permissions>\n",
+ }, "")
}
func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -3317,12 +3313,7 @@
xmlContent := module.permissionsContents(ctx)
module.outputFilePath = android.PathForModuleOut(ctx, libName+".xml").OutputPath
- rule := android.NewRuleBuilder(pctx, ctx)
- rule.Command().
- Text("/bin/bash -c \"echo -e '" + xmlContent + "'\" > ").
- Output(module.outputFilePath)
-
- rule.Build("java_sdk_xml", "Permission XML")
+ android.WriteFileRuleVerbatim(ctx, module.outputFilePath, xmlContent)
module.installDirPath = android.PathForModuleInstall(ctx, "etc", module.SubDir())
}
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index fb584c5..0f163e6 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -227,19 +227,21 @@
`)
// test that updatability attributes are passed on correctly
- fooUpdatable := result.ModuleForTests("fooUpdatable.xml", "android_common").Rule("java_sdk_xml")
- android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `on-bootclasspath-since=\"U\"`)
- android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `on-bootclasspath-before=\"V\"`)
- android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `min-device-sdk=\"W\"`)
- android.AssertStringDoesContain(t, "fooUpdatable.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `max-device-sdk=\"X\"`)
+ fooUpdatable := result.ModuleForTests("fooUpdatable.xml", "android_common").Output("fooUpdatable.xml")
+ fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable)
+ android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-since="U"`)
+ android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `on-bootclasspath-before="V"`)
+ android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `min-device-sdk="W"`)
+ android.AssertStringDoesContain(t, "fooUpdatable.xml contents", fooUpdatableContents, `max-device-sdk="X"`)
// double check that updatability attributes are not written if they don't exist in the bp file
// the permissions file for the foo library defined above
- fooPermissions := result.ModuleForTests("foo.xml", "android_common").Rule("java_sdk_xml")
- android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `on-bootclasspath-since`)
- android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `on-bootclasspath-before`)
- android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `min-device-sdk`)
- android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooPermissions.RuleParams.Command, `max-device-sdk`)
+ fooPermissions := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml")
+ fooPermissionsContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooPermissions)
+ android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-since`)
+ android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `on-bootclasspath-before`)
+ android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `min-device-sdk`)
+ android.AssertStringDoesNotContain(t, "foo.xml contents", fooPermissionsContents, `max-device-sdk`)
}
func TestJavaSdkLibrary_UpdatableLibrary_Validation_ValidVersion(t *testing.T) {
@@ -370,9 +372,10 @@
}
`)
// test that updatability attributes are passed on correctly
- fooUpdatable := result.ModuleForTests("foo.xml", "android_common").Rule("java_sdk_xml")
- android.AssertStringDoesContain(t, "foo.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `<apex-library`)
- android.AssertStringDoesNotContain(t, "foo.xml java_sdk_xml command", fooUpdatable.RuleParams.Command, `<library`)
+ fooUpdatable := result.ModuleForTests("foo.xml", "android_common").Output("foo.xml")
+ fooUpdatableContents := android.ContentFromFileRuleForTests(t, result.TestContext, fooUpdatable)
+ android.AssertStringDoesContain(t, "foo.xml contents", fooUpdatableContents, `<apex-library`)
+ android.AssertStringDoesNotContain(t, "foo.xml contents", fooUpdatableContents, `<library`)
}
func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) {
@@ -1082,18 +1085,6 @@
t.Run("prefer", func(t *testing.T) {
testJavaSdkLibraryImport_Preferred(t, "prefer: true,", android.NullFixturePreparer)
})
-
- t.Run("use_source_config_var", func(t *testing.T) {
- testJavaSdkLibraryImport_Preferred(t,
- "use_source_config_var: {config_namespace: \"acme\", var_name: \"use_source\"},",
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.VendorVars = map[string]map[string]string{
- "acme": {
- "use_source": "false",
- },
- }
- }))
- })
}
// If a module is listed in `mainline_module_contributions, it should be used
@@ -1239,7 +1230,6 @@
libraryType string
fromPartition string
toPartition string
- enforceVendorInterface bool
enforceProductInterface bool
enforceJavaSdkLibraryCheck bool
allowList []string
@@ -1274,9 +1264,6 @@
android.FixtureWithRootAndroidBp(bpFile),
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.EnforceProductPartitionInterface = proptools.BoolPtr(info.enforceProductInterface)
- if info.enforceVendorInterface {
- variables.DeviceVndkVersion = proptools.StringPtr("current")
- }
variables.EnforceInterPartitionJavaSdkLibrary = proptools.BoolPtr(info.enforceJavaSdkLibraryCheck)
variables.InterPartitionJavaLibraryAllowList = info.allowList
}),
@@ -1304,7 +1291,6 @@
libraryType: "java_library",
fromPartition: "product",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: false,
}, "")
@@ -1313,7 +1299,6 @@
libraryType: "java_library",
fromPartition: "product",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: false,
enforceJavaSdkLibraryCheck: true,
}, "")
@@ -1322,7 +1307,6 @@
libraryType: "java_library",
fromPartition: "product",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
}, errorMessage)
@@ -1331,7 +1315,6 @@
libraryType: "java_library",
fromPartition: "vendor",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
}, errorMessage)
@@ -1340,7 +1323,6 @@
libraryType: "java_library",
fromPartition: "vendor",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
allowList: []string{"bar"},
@@ -1350,7 +1332,6 @@
libraryType: "java_library",
fromPartition: "vendor",
toPartition: "product",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
}, errorMessage)
@@ -1359,7 +1340,6 @@
libraryType: "java_sdk_library",
fromPartition: "product",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
}, "")
@@ -1368,7 +1348,6 @@
libraryType: "java_sdk_library",
fromPartition: "vendor",
toPartition: "system",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
}, "")
@@ -1377,7 +1356,6 @@
libraryType: "java_sdk_library",
fromPartition: "vendor",
toPartition: "product",
- enforceVendorInterface: true,
enforceProductInterface: true,
enforceJavaSdkLibraryCheck: true,
}, "")
@@ -1720,9 +1698,9 @@
}
`)
- barPermissions := result.ModuleForTests("bar.xml", "android_common").Rule("java_sdk_xml")
-
- android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barPermissions.RuleParams.Command, `dependency=\"foo\"`)
+ barPermissions := result.ModuleForTests("bar.xml", "android_common").Output("bar.xml")
+ barContents := android.ContentFromFileRuleForTests(t, result.TestContext, barPermissions)
+ android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barContents, `dependency="foo"`)
}
func TestSdkLibraryExportableStubsLibrary(t *testing.T) {
diff --git a/java/testing.go b/java/testing.go
index 631d516..5ae326d 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -711,7 +711,7 @@
func registerFakeApexMutator(ctx android.RegistrationContext) {
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("apex", fakeApexMutator).Parallel()
+ ctx.Transition("apex", &fakeApexMutator{})
})
}
@@ -726,16 +726,30 @@
// `apex_available`. It helps us avoid a dependency on the real mutator defined in "soong-apex",
// which will cause a cyclic dependency, and it provides an easy way to create an APEX variant for
// testing without dealing with all the complexities in the real mutator.
-func fakeApexMutator(mctx android.BottomUpMutatorContext) {
- switch mctx.Module().(type) {
+type fakeApexMutator struct{}
+
+func (f *fakeApexMutator) Split(ctx android.BaseModuleContext) []string {
+ switch ctx.Module().(type) {
case *Library, *SdkLibrary:
- if len(mctx.Module().(apexModuleBase).ApexAvailable()) > 0 {
- modules := mctx.CreateVariations("", "apex1000")
- apexInfo := android.ApexInfo{
- ApexVariationName: "apex1000",
- }
- mctx.SetVariationProvider(modules[1], android.ApexInfoProvider, apexInfo)
+ return []string{"", "apex1000"}
+ }
+ return []string{""}
+}
+
+func (f *fakeApexMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+ return sourceVariation
+}
+
+func (f *fakeApexMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
+ return incomingVariation
+}
+
+func (f *fakeApexMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
+ if variation != "" {
+ apexInfo := android.ApexInfo{
+ ApexVariationName: "apex1000",
}
+ android.SetProvider(ctx, android.ApexInfoProvider, apexInfo)
}
}
diff --git a/licenses/Android.bp b/licenses/Android.bp
index d045725..e4e5da7 100644
--- a/licenses/Android.bp
+++ b/licenses/Android.bp
@@ -1126,6 +1126,12 @@
}
license_kind {
+ name: "SPDX-license-identifier-Unicode-3.0",
+ conditions: ["notice"],
+ url: "https://spdx.org/licenses/Unicode-3.0.html",
+}
+
+license_kind {
name: "SPDX-license-identifier-Unicode-DFS-2015",
conditions: ["notice"],
url: "https://spdx.org/licenses/Unicode-DFS-2015.html",
diff --git a/partner/androidmk/androidmk_test.go b/partner/androidmk/androidmk_test.go
index 6bae836..3ace750 100644
--- a/partner/androidmk/androidmk_test.go
+++ b/partner/androidmk/androidmk_test.go
@@ -54,6 +54,9 @@
}
func TestEndToEnd(t *testing.T) {
+ // Skip checking Android.mk path with cleaning "ANDROID_BUILD_TOP"
+ t.Setenv("ANDROID_BUILD_TOP", "")
+
for i, test := range testCases {
expected, err := bpfix.Reformat(test.expected)
if err != nil {
diff --git a/phony/phony.go b/phony/phony.go
index b8dbd00..5469238 100644
--- a/phony/phony.go
+++ b/phony/phony.go
@@ -23,10 +23,17 @@
)
func init() {
- android.RegisterModuleType("phony", PhonyFactory)
- android.RegisterModuleType("phony_rule", PhonyRuleFactory)
+ registerPhonyModuleTypes(android.InitRegistrationContext)
}
+func registerPhonyModuleTypes(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("phony", PhonyFactory)
+ ctx.RegisterModuleType("phony_rule", PhonyRuleFactory)
+ ctx.RegisterModuleType("phony_rule_defaults", PhonyRuleDefaultsFactory)
+}
+
+var PrepareForTestWithPhony = android.FixtureRegisterWithContext(registerPhonyModuleTypes)
+
type phony struct {
android.ModuleBase
requiredModuleNames []string
@@ -79,6 +86,7 @@
type PhonyRule struct {
android.ModuleBase
+ android.DefaultableModuleBase
properties PhonyProperties
}
@@ -96,6 +104,7 @@
module := &PhonyRule{}
android.InitAndroidModule(module)
module.AddProperties(&module.properties)
+ android.InitDefaultableModule(module)
return module
}
@@ -113,3 +122,45 @@
},
}
}
+
+// PhonyRuleDefaults
+type PhonyRuleDefaults struct {
+ android.ModuleBase
+ android.DefaultsModuleBase
+}
+
+// phony_rule_defaults provides a set of properties that can be inherited by other phony_rules.
+//
+// A module can use the properties from a phony_rule_defaults module using `defaults: ["defaults_module_name"]`. Each
+// property in the defaults module that exists in the depending module will be prepended to the depending module's
+// value for that property.
+//
+// Example:
+//
+// phony_rule_defaults {
+// name: "add_module1_defaults",
+// phony_deps: [
+// "module1",
+// ],
+// }
+//
+// phony_rule {
+// name: "example",
+// defaults: ["add_module1_defaults"],
+// }
+//
+// is functionally identical to:
+//
+// phony_rule {
+// name: "example",
+// phony_deps: [
+// "module1",
+// ],
+// }
+func PhonyRuleDefaultsFactory() android.Module {
+ module := &PhonyRuleDefaults{}
+ module.AddProperties(&PhonyProperties{})
+ android.InitDefaultsModule(module)
+
+ return module
+}
diff --git a/python/binary.go b/python/binary.go
index d6750c6..c84eeee 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -203,7 +203,7 @@
}
func (p *PythonBinaryModule) isEmbeddedLauncherEnabled() bool {
- return Bool(p.properties.Embedded_launcher)
+ return BoolDefault(p.properties.Embedded_launcher, true)
}
func (b *PythonBinaryModule) autorun() bool {
diff --git a/python/python.go b/python/python.go
index d3cbd76..e14fdf3 100644
--- a/python/python.go
+++ b/python/python.go
@@ -59,7 +59,7 @@
// list of the Python libraries used only for this Python version.
Libs []string `android:"arch_variant"`
- // whether the binary is required to be built with embedded launcher for this version, defaults to false.
+ // whether the binary is required to be built with embedded launcher for this version, defaults to true.
Embedded_launcher *bool // TODO(b/174041232): Remove this property
}
@@ -151,6 +151,8 @@
// The zip file containing the current module's source/data files, with the
// source files precompiled.
precompiledSrcsZip android.Path
+
+ sourceProperties android.SourceProperties
}
// newModule generates new Python base module
@@ -203,7 +205,7 @@
var _ pythonDependency = (*PythonLibraryModule)(nil)
func (p *PythonLibraryModule) init() android.Module {
- p.AddProperties(&p.properties, &p.protoProperties)
+ p.AddProperties(&p.properties, &p.protoProperties, &p.sourceProperties)
android.InitAndroidArchModule(p, p.hod, p.multilib)
android.InitDefaultableModule(p)
return p
@@ -421,6 +423,11 @@
func (p *PythonLibraryModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
expandedSrcs := android.PathsForModuleSrcExcludes(ctx, p.properties.Srcs, p.properties.Exclude_srcs)
android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: expandedSrcs.Strings()})
+ // Keep before any early returns.
+ android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
+ TestOnly: Bool(p.sourceProperties.Test_only),
+ TopLevelTarget: p.sourceProperties.Top_level_test_target,
+ })
// expand data files from "data" property.
expandedData := android.PathsForModuleSrc(ctx, p.properties.Data)
@@ -545,7 +552,6 @@
var stagedProtoSrcs android.Paths
for _, srcFile := range protoSrcs {
stagedProtoSrc := pkgPathStagingDir.Join(ctx, pkgPath, srcFile.Rel())
- rule.Command().Text("mkdir -p").Flag(filepath.Base(stagedProtoSrc.String()))
rule.Command().Text("cp -f").Input(srcFile).Output(stagedProtoSrc)
stagedProtoSrcs = append(stagedProtoSrcs, stagedProtoSrc)
}
diff --git a/python/python_test.go b/python/python_test.go
index 75a6a89..c0b7295 100644
--- a/python/python_test.go
+++ b/python/python_test.go
@@ -18,10 +18,13 @@
"fmt"
"os"
"path/filepath"
+ "strings"
"testing"
"android/soong/android"
"android/soong/cc"
+
+ "github.com/google/blueprint"
)
type pyModule struct {
@@ -360,6 +363,76 @@
}
}
+func TestTestOnlyProvider(t *testing.T) {
+ t.Parallel()
+ ctx := android.GroupFixturePreparers(
+ PrepareForTestWithPythonBuildComponents,
+ android.PrepareForTestWithAllowMissingDependencies,
+ ).RunTestWithBp(t, `
+ // These should be test-only
+ python_library { name: "py-lib-test", test_only: true }
+ python_library { name: "py-lib-test-host", test_only: true, host_supported: true }
+ python_test { name: "py-test", srcs: ["py-test.py"] }
+ python_test_host { name: "py-test-host", srcs: ["py-test-host.py"] }
+ python_binary_host { name: "py-bin-test", srcs: ["py-bin-test.py"] }
+
+ // These should not be.
+ python_library { name: "py-lib" }
+ python_binary_host { name: "py-bin", srcs: ["py-bin.py"] }
+ `)
+
+ // Visit all modules and ensure only the ones that should
+ // marked as test-only are marked as test-only.
+
+ actualTestOnly := []string{}
+ ctx.VisitAllModules(func(m blueprint.Module) {
+ if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, android.TestOnlyProviderKey); ok {
+ if provider.TestOnly {
+ actualTestOnly = append(actualTestOnly, m.Name())
+ }
+ }
+ })
+ expectedTestOnlyModules := []string{
+ "py-lib-test",
+ "py-lib-test-host",
+ "py-test",
+ "py-test-host",
+ }
+
+ notEqual, left, right := android.ListSetDifference(expectedTestOnlyModules, actualTestOnly)
+ if notEqual {
+ t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right)
+ }
+}
+
+// Don't allow setting test-only on things that are always tests or never tests.
+func TestInvalidTestOnlyTargets(t *testing.T) {
+ testCases := []string{
+ ` python_test { name: "py-test", test_only: true, srcs: ["py-test.py"] } `,
+ ` python_test_host { name: "py-test-host", test_only: true, srcs: ["py-test-host.py"] } `,
+ ` python_defaults { name: "py-defaults", test_only: true, srcs: ["foo.py"] } `,
+ }
+
+ for i, bp := range testCases {
+ ctx := android.GroupFixturePreparers(
+ PrepareForTestWithPythonBuildComponents,
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+
+ ctx.RegisterModuleType("python_defaults", DefaultsFactory)
+ }),
+ android.PrepareForTestWithAllowMissingDependencies).
+ ExtendWithErrorHandler(android.FixtureIgnoreErrors).
+ RunTestWithBp(t, bp)
+ if len(ctx.Errs) != 1 {
+ t.Errorf("Expected err setting test_only in testcase #%d: %d errs", i, len(ctx.Errs))
+ continue
+ }
+ if !strings.Contains(ctx.Errs[0].Error(), "unrecognized property \"test_only\"") {
+ t.Errorf("ERR: %s bad bp: %s", ctx.Errs[0], bp)
+ }
+ }
+}
+
func expectModule(t *testing.T, ctx *android.TestContext, name, variant, expectedSrcsZip string, expectedPyRunfiles []string) {
module := ctx.ModuleForTests(name, variant)
diff --git a/python/scripts/precompile_python.py b/python/scripts/precompile_python.py
index aa1a5df..07b8fe9 100644
--- a/python/scripts/precompile_python.py
+++ b/python/scripts/precompile_python.py
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from __future__ import print_function
import argparse
import py_compile
import os
@@ -63,11 +64,23 @@
parser.add_argument('dst_zip')
args = parser.parse_args()
+ errors = []
with open(args.dst_zip, 'wb') as outf, open(args.src_zip, 'rb') as inf:
with zipfile.ZipFile(outf, mode='w') as outzip, zipfile.ZipFile(inf, mode='r') as inzip:
for name in inzip.namelist():
with inzip.open(name, mode='r') as inzipf:
- process_one_file(name, inzipf, outzip)
+ try:
+ process_one_file(name, inzipf, outzip)
+ except py_compile.PyCompileError as e:
+ errors.append(e)
+
+ if errors:
+ for i, error in enumerate(errors):
+ # Print an empty line in between each error
+ if i > 0:
+ print(file=sys.stderr)
+ print(str(error).strip(), file=sys.stderr)
+ sys.exit(1)
if __name__ == "__main__":
diff --git a/python/test.go b/python/test.go
index 826f353..2b939e7 100644
--- a/python/test.go
+++ b/python/test.go
@@ -36,7 +36,9 @@
}
func NewTest(hod android.HostOrDeviceSupported) *PythonTestModule {
- return &PythonTestModule{PythonBinaryModule: *NewBinary(hod)}
+ p := &PythonTestModule{PythonBinaryModule: *NewBinary(hod)}
+ p.sourceProperties = android.SourceProperties{Test_only: proptools.BoolPtr(true), Top_level_test_target: true}
+ return p
}
func PythonTestHostFactory() android.Module {
diff --git a/rust/Android.bp b/rust/Android.bp
index 637042d..53c9462 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -12,7 +12,6 @@
"soong-bloaty",
"soong-cc",
"soong-rust-config",
- "soong-snapshot",
"soong-testing",
],
srcs: [
@@ -36,8 +35,6 @@
"rust.go",
"sanitize.go",
"source_provider.go",
- "snapshot_prebuilt.go",
- "snapshot_utils.go",
"strip.go",
"test.go",
"testing.go",
@@ -62,7 +59,6 @@
"sanitize_test.go",
"source_provider_test.go",
"test_test.go",
- "vendor_snapshot_test.go",
],
pluginFor: ["soong_build"],
}
diff --git a/rust/androidmk.go b/rust/androidmk.go
index e0cb3ce..021dd60 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -62,6 +62,7 @@
entries.AddStrings("LOCAL_PROC_MACRO_LIBRARIES", mod.Properties.AndroidMkProcMacroLibs...)
entries.AddStrings("LOCAL_SHARED_LIBRARIES", mod.transitiveAndroidMkSharedLibs.ToList()...)
entries.AddStrings("LOCAL_STATIC_LIBRARIES", mod.Properties.AndroidMkStaticLibs...)
+ entries.AddStrings("LOCAL_HEADER_LIBRARIES", mod.Properties.AndroidMkHeaderLibs...)
entries.AddStrings("LOCAL_SOONG_LINK_TYPE", mod.makeLinkType)
if mod.InVendor() {
entries.SetBool("LOCAL_IN_VENDOR", true)
@@ -154,11 +155,6 @@
})
}
-func (library *snapshotLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) {
- ctx.SubAndroidMk(ret, library.libraryDecorator)
- ret.SubName = library.SnapshotAndroidMkSuffix()
-}
-
func (procMacro *procMacroDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) {
ctx.SubAndroidMk(ret, procMacro.baseCompiler)
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 454dd87..11ba74d 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -346,6 +346,6 @@
deps.SharedLibs = append(deps.SharedLibs, b.ClangProperties.Shared_libs...)
deps.StaticLibs = append(deps.StaticLibs, b.ClangProperties.Static_libs...)
- deps.HeaderLibs = append(deps.StaticLibs, b.ClangProperties.Header_libs...)
+ deps.HeaderLibs = append(deps.HeaderLibs, b.ClangProperties.Header_libs...)
return deps
}
diff --git a/rust/bindgen_test.go b/rust/bindgen_test.go
index 0ba0ff8..0c0a6da 100644
--- a/rust/bindgen_test.go
+++ b/rust/bindgen_test.go
@@ -17,6 +17,8 @@
import (
"strings"
"testing"
+
+ "android/soong/android"
)
func TestRustBindgen(t *testing.T) {
@@ -31,7 +33,21 @@
bindgen_flags: ["--bindgen-flag.*"],
cflags: ["--clang-flag()"],
shared_libs: ["libfoo_shared"],
+ }
+ rust_bindgen {
+ name: "libbindgen_staticlib",
+ wrapper_src: "src/any.h",
+ crate_name: "bindgen_staticlib",
+ stem: "libbindgen_staticlib",
+ source_stem: "bindings",
static_libs: ["libfoo_static"],
+ }
+ rust_bindgen {
+ name: "libbindgen_headerlib",
+ wrapper_src: "src/any.h",
+ crate_name: "bindgen_headerlib",
+ stem: "libbindgen_headerlib",
+ source_stem: "bindings",
header_libs: ["libfoo_header"],
}
cc_library_shared {
@@ -52,6 +68,9 @@
}
`)
libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
+ libbindgenStatic := ctx.ModuleForTests("libbindgen_staticlib", "android_arm64_armv8-a_source").Output("bindings.rs")
+ libbindgenHeader := ctx.ModuleForTests("libbindgen_headerlib", "android_arm64_armv8-a_source").Output("bindings.rs")
+ libbindgenHeaderModule := ctx.ModuleForTests("libbindgen_headerlib", "android_arm64_armv8-a_source").Module().(*Module)
// Ensure that the flags are present and escaped
if !strings.Contains(libbindgen.Args["flags"], "'--bindgen-flag.*'") {
t.Errorf("missing bindgen flags in rust_bindgen rule: flags %#v", libbindgen.Args["flags"])
@@ -62,12 +81,17 @@
if !strings.Contains(libbindgen.Args["cflags"], "-Ishared_include") {
t.Errorf("missing shared_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
}
- if !strings.Contains(libbindgen.Args["cflags"], "-Istatic_include") {
- t.Errorf("missing static_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
+ if !strings.Contains(libbindgenStatic.Args["cflags"], "-Istatic_include") {
+ t.Errorf("missing static_libs exported includes in rust_bindgen rule: cflags %#v", libbindgenStatic.Args["cflags"])
}
- if !strings.Contains(libbindgen.Args["cflags"], "-Iheader_include") {
- t.Errorf("missing static_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
+ if !strings.Contains(libbindgenHeader.Args["cflags"], "-Iheader_include") {
+ t.Errorf("missing header_libs exported includes in rust_bindgen rule: cflags %#v", libbindgenHeader.Args["cflags"])
}
+
+ if android.InList("libfoo_static", libbindgenHeaderModule.Properties.AndroidMkHeaderLibs) {
+ t.Errorf("Static library dependency should not be in HeaderLibs list")
+ }
+
if !strings.Contains(libbindgen.Args["cflags"], "--default-flag") {
t.Errorf("rust_bindgen missing cflags defined in cc_defaults: cflags %#v", libbindgen.Args["cflags"])
}
diff --git a/rust/builder.go b/rust/builder.go
index c855cfb..4f45e33 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -32,7 +32,7 @@
"-C linker=${config.RustLinker} " +
"-C link-args=\"${crtBegin} ${earlyLinkFlags} ${linkFlags} ${crtEnd}\" " +
"--emit link -o $out --emit dep-info=$out.d.raw $in ${libFlags} $rustcFlags" +
- " && grep \"^$out:\" $out.d.raw > $out.d",
+ " && grep ^$out: $out.d.raw > $out.d",
CommandDeps: []string{"$rustcCmd"},
// Rustc deps-info writes out make compatible dep files: https://github.com/rust-lang/rust/issues/7633
// Rustc emits unneeded dependency lines for the .d and input .rs files.
@@ -61,7 +61,7 @@
// Use the metadata output as it has the smallest footprint.
"--emit metadata -o $out --emit dep-info=$out.d.raw $in ${libFlags} " +
"$rustcFlags $clippyFlags" +
- " && grep \"^$out:\" $out.d.raw > $out.d",
+ " && grep ^$out: $out.d.raw > $out.d",
CommandDeps: []string{"$clippyCmd"},
Deps: blueprint.DepsGCC,
Depfile: "$out.d",
diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go
index 6c021c7..9850570 100644
--- a/rust/config/arm64_device.go
+++ b/rust/config/arm64_device.go
@@ -54,7 +54,7 @@
strings.Join(rustFlags, " "))
}
- ExportedVars.ExportStringListStaticVariable("DEVICE_ARM64_RUSTC_FLAGS", Arm64RustFlags)
+ pctx.StaticVariable("DEVICE_ARM64_RUSTC_FLAGS", strings.Join(Arm64RustFlags, " "))
}
type toolchainArm64 struct {
diff --git a/rust/config/arm_device.go b/rust/config/arm_device.go
index a5f4afb..5394e8a 100644
--- a/rust/config/arm_device.go
+++ b/rust/config/arm_device.go
@@ -44,7 +44,7 @@
strings.Join(rustFlags, " "))
}
- ExportedVars.ExportStringListStaticVariable("DEVICE_ARM_RUSTC_FLAGS", ArmRustFlags)
+ pctx.StaticVariable("DEVICE_ARM_RUSTC_FLAGS", strings.Join(ArmRustFlags, " "))
}
type toolchainArm struct {
diff --git a/rust/config/global.go b/rust/config/global.go
index e28dbaa..ba08560 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -22,10 +22,9 @@
)
var (
- pctx = android.NewPackageContext("android/soong/rust/config")
- ExportedVars = android.NewExportedVariables(pctx)
+ pctx = android.NewPackageContext("android/soong/rust/config")
- RustDefaultVersion = "1.76.0"
+ RustDefaultVersion = "1.77.1"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2021"
Stdlibs = []string{
@@ -112,17 +111,17 @@
pctx.StaticVariable("DeviceGlobalLinkFlags", strings.Join(deviceGlobalLinkFlags, " "))
- ExportedVars.ExportStringStaticVariable("RUST_DEFAULT_VERSION", RustDefaultVersion)
- ExportedVars.ExportStringListStaticVariable("GLOBAL_RUSTC_FLAGS", GlobalRustFlags)
- ExportedVars.ExportStringListStaticVariable("LINUX_HOST_GLOBAL_LINK_FLAGS", LinuxHostGlobalLinkFlags)
+ pctx.StaticVariable("RUST_DEFAULT_VERSION", RustDefaultVersion)
+ pctx.StaticVariable("GLOBAL_RUSTC_FLAGS", strings.Join(GlobalRustFlags, " "))
+ pctx.StaticVariable("LINUX_HOST_GLOBAL_LINK_FLAGS", strings.Join(LinuxHostGlobalLinkFlags, " "))
- ExportedVars.ExportStringListStaticVariable("DEVICE_GLOBAL_RUSTC_FLAGS", deviceGlobalRustFlags)
- ExportedVars.ExportStringListStaticVariable("DEVICE_GLOBAL_LINK_FLAGS",
- android.RemoveListFromList(deviceGlobalLinkFlags, []string{
+ pctx.StaticVariable("DEVICE_GLOBAL_RUSTC_FLAGS", strings.Join(deviceGlobalRustFlags, " "))
+ pctx.StaticVariable("DEVICE_GLOBAL_LINK_FLAGS",
+ strings.Join(android.RemoveListFromList(deviceGlobalLinkFlags, []string{
// The cc_config flags are retrieved from cc_toolchain by rust rules.
"${cc_config.DeviceGlobalLldflags}",
"-B${cc_config.ClangBin}",
- }))
+ }), " "))
}
func HostPrebuiltTag(config android.Config) string {
diff --git a/rust/config/x86_64_device.go b/rust/config/x86_64_device.go
index 49f7c77..fee1923 100644
--- a/rust/config/x86_64_device.go
+++ b/rust/config/x86_64_device.go
@@ -54,7 +54,7 @@
pctx.StaticVariable("X86_64"+variant+"VariantRustFlags",
strings.Join(rustFlags, " "))
}
- ExportedVars.ExportStringListStaticVariable("DEVICE_X86_64_RUSTC_FLAGS", x86_64RustFlags)
+ pctx.StaticVariable("DEVICE_X86_64_RUSTC_FLAGS", strings.Join(x86_64RustFlags, " "))
}
type toolchainX86_64 struct {
diff --git a/rust/config/x86_device.go b/rust/config/x86_device.go
index 2a57e73..5d9d88a 100644
--- a/rust/config/x86_device.go
+++ b/rust/config/x86_device.go
@@ -56,7 +56,7 @@
strings.Join(rustFlags, " "))
}
- ExportedVars.ExportStringListStaticVariable("DEVICE_X86_RUSTC_FLAGS", x86RustFlags)
+ pctx.StaticVariable("DEVICE_X86_RUSTC_FLAGS", strings.Join(x86RustFlags, " "))
}
type toolchainX86 struct {
diff --git a/rust/image.go b/rust/image.go
index 530c56e..e0d267d 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -208,14 +208,6 @@
if strings.HasPrefix(variant, cc.VendorVariationPrefix) {
m.Properties.VndkVersion = strings.TrimPrefix(variant, cc.VendorVariationPrefix)
}
-
- // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
- // Hide other vendor variants to avoid collision.
- vndkVersion := ctx.DeviceConfig().VndkVersion()
- if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
- m.Properties.HideFromMake = true
- m.HideFromMake()
- }
} else if strings.HasPrefix(variant, cc.ProductVariation) {
m.Properties.ImageVariation = cc.ProductVariation
if strings.HasPrefix(variant, cc.ProductVariationPrefix) {
diff --git a/rust/image_test.go b/rust/image_test.go
index fb4d9c1..ba94906 100644
--- a/rust/image_test.go
+++ b/rust/image_test.go
@@ -24,7 +24,7 @@
// Test that cc modules can link against vendor_available rust_ffi_static libraries.
func TestVendorLinkage(t *testing.T) {
- ctx := testRustVndk(t, `
+ ctx := testRust(t, `
cc_binary {
name: "fizz_vendor",
static_libs: ["libfoo_vendor"],
@@ -38,7 +38,7 @@
}
`)
- vendorBinary := ctx.ModuleForTests("fizz_vendor", "android_vendor.29_arm64_armv8-a").Module().(*cc.Module)
+ vendorBinary := ctx.ModuleForTests("fizz_vendor", "android_vendor_arm64_armv8-a").Module().(*cc.Module)
if !android.InList("libfoo_vendor.vendor", vendorBinary.Properties.AndroidMkStaticLibs) {
t.Errorf("vendorBinary should have a dependency on libfoo_vendor: %#v", vendorBinary.Properties.AndroidMkStaticLibs)
@@ -46,8 +46,8 @@
}
// Test that variants which use the vndk emit the appropriate cfg flag.
-func TestImageVndkCfgFlag(t *testing.T) {
- ctx := testRustVndk(t, `
+func TestImageCfgFlag(t *testing.T) {
+ ctx := testRust(t, `
rust_ffi_static {
name: "libfoo",
crate_name: "foo",
@@ -57,7 +57,7 @@
}
`)
- vendor := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_static").Rule("rustc")
+ vendor := ctx.ModuleForTests("libfoo", "android_vendor_arm64_armv8-a_static").Rule("rustc")
if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vndk'") {
t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
@@ -69,7 +69,7 @@
t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
}
- product := ctx.ModuleForTests("libfoo", "android_product.29_arm64_armv8-a_static").Rule("rustc")
+ product := ctx.ModuleForTests("libfoo", "android_product_arm64_armv8-a_static").Rule("rustc")
if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vndk'") {
t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
}
@@ -95,7 +95,7 @@
// Test that cc modules can link against vendor_ramdisk_available rust_ffi_static libraries.
func TestVendorRamdiskLinkage(t *testing.T) {
- ctx := testRustVndk(t, `
+ ctx := testRust(t, `
cc_library_static {
name: "libcc_vendor_ramdisk",
static_libs: ["libfoo_vendor_ramdisk"],
@@ -119,7 +119,7 @@
// Test that prebuilt libraries cannot be made vendor available.
func TestForbiddenVendorLinkage(t *testing.T) {
- testRustVndkError(t, "Rust prebuilt modules not supported for non-system images.", `
+ testRustError(t, "Rust prebuilt modules not supported for non-system images.", `
rust_prebuilt_library {
name: "librust_prebuilt",
crate_name: "rust_prebuilt",
diff --git a/rust/library.go b/rust/library.go
index 3560d73..6be4917 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -104,8 +104,6 @@
includeDirs android.Paths
sourceProvider SourceProvider
- collectedSnapshotHeaders android.Paths
-
// table-of-contents file for cdylib crates to optimize out relinking when possible
tocFile android.OptionalPath
}
@@ -749,55 +747,3 @@
}
}
}
-
-func (l *libraryDecorator) snapshotHeaders() android.Paths {
- if l.collectedSnapshotHeaders == nil {
- panic("snapshotHeaders() must be called after collectHeadersForSnapshot()")
- }
- return l.collectedSnapshotHeaders
-}
-
-// collectHeadersForSnapshot collects all exported headers from library.
-// It globs header files in the source tree for exported include directories,
-// and tracks generated header files separately.
-//
-// This is to be called from GenerateAndroidBuildActions, and then collected
-// header files can be retrieved by snapshotHeaders().
-func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps) {
- ret := android.Paths{}
-
- // Glob together the headers from the modules include_dirs property
- for _, path := range android.CopyOfPaths(l.includeDirs) {
- dir := path.String()
- globDir := dir + "/**/*"
- glob, err := ctx.GlobWithDeps(globDir, nil)
- if err != nil {
- ctx.ModuleErrorf("glob of %q failed: %s", globDir, err)
- return
- }
-
- for _, header := range glob {
- // Filter out only the files with extensions that are headers.
- found := false
- for _, ext := range cc.HeaderExts {
- if strings.HasSuffix(header, ext) {
- found = true
- break
- }
- }
- if !found {
- continue
- }
- ret = append(ret, android.PathForSource(ctx, header))
- }
- }
-
- // Glob together the headers from C dependencies as well, starting with non-generated headers.
- ret = append(ret, cc.GlobHeadersForSnapshot(ctx, append(android.CopyOfPaths(deps.depIncludePaths), deps.depSystemIncludePaths...))...)
-
- // Collect generated headers from C dependencies.
- ret = append(ret, cc.GlobGeneratedHeadersForSnapshot(ctx, deps.depGeneratedHeaders)...)
-
- // TODO(185577950): If support for generated headers is added, they need to be collected here as well.
- l.collectedSnapshotHeaders = ret
-}
diff --git a/rust/rust.go b/rust/rust.go
index 7d81c72..c2b6151 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -30,7 +30,6 @@
"android/soong/fuzz"
"android/soong/multitree"
"android/soong/rust/config"
- "android/soong/snapshot"
)
var pctx = android.NewPackageContext("android/soong/rust")
@@ -69,6 +68,7 @@
AndroidMkDylibs []string `blueprint:"mutated"`
AndroidMkProcMacroLibs []string `blueprint:"mutated"`
AndroidMkStaticLibs []string `blueprint:"mutated"`
+ AndroidMkHeaderLibs []string `blueprint:"mutated"`
ImageVariation string `blueprint:"mutated"`
VndkVersion string `blueprint:"mutated"`
@@ -971,14 +971,6 @@
ctx.CheckbuildFile(mod.docTimestampFile.Path())
}
- // glob exported headers for snapshot, if BOARD_VNDK_VERSION is current or
- // RECOVERY_SNAPSHOT_VERSION is current.
- if lib, ok := mod.compiler.(snapshotLibraryInterface); ok {
- if cc.ShouldCollectHeadersForSnapshot(ctx, mod, apexInfo) {
- lib.collectHeadersForSnapshot(ctx, deps)
- }
- }
-
apexInfo, _ := android.ModuleProvider(actx, android.ApexInfoProvider)
if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) && !mod.ProcMacro() {
// If the module has been specifically configure to not be installed then
@@ -1124,6 +1116,11 @@
return nil
}
+func (mod *Module) Symlinks() []string {
+ // TODO update this to return the list of symlinks when Rust supports defining symlinks
+ return nil
+}
+
func rustMakeLibName(ctx android.ModuleContext, c cc.LinkableInterface, dep cc.LinkableInterface, depName string) string {
if rustDep, ok := dep.(*Module); ok {
// Use base module name for snapshots when exporting to Makefile.
@@ -1403,6 +1400,7 @@
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
+ mod.Properties.AndroidMkHeaderLibs = append(mod.Properties.AndroidMkHeaderLibs, makeLibName)
case depTag == cc.CrtBeginDepTag:
depPaths.CrtBegin = append(depPaths.CrtBegin, linkObject.Path())
case depTag == cc.CrtEndDepTag:
@@ -1544,7 +1542,6 @@
deps := mod.deps(ctx)
var commonDepVariations []blueprint.Variation
- var snapshotInfo *cc.SnapshotInfo
apiImportInfo := cc.GetApiImports(mod, actx)
if mod.usePublicApi() || mod.useVendorApi() {
@@ -1554,7 +1551,7 @@
}
if ctx.Os() == android.Android {
- deps.SharedLibs, _ = cc.RewriteLibs(mod, &snapshotInfo, actx, ctx.Config(), deps.SharedLibs)
+ deps.SharedLibs, _ = cc.FilterNdkLibs(mod, ctx.Config(), deps.SharedLibs)
}
stdLinkage := "dylib-std"
@@ -1573,15 +1570,13 @@
rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: rlibVariation})
for _, lib := range deps.Rlibs {
depTag := rlibDepTag
- lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
-
actx.AddVariationDependencies(rlibDepVariations, depTag, lib)
}
// dylibs
dylibDepVariations := append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: dylibVariation})
for _, lib := range deps.Dylibs {
- addDylibDependency(actx, lib, mod, &snapshotInfo, dylibDepVariations, dylibDepTag)
+ actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib)
}
// rustlibs
@@ -1591,7 +1586,8 @@
autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
if autoDep.depTag == rlibDepTag {
// Handle the rlib deptag case
- addRlibDependency(actx, lib, mod, &snapshotInfo, rlibDepVariations)
+ actx.AddVariationDependencies(rlibDepVariations, rlibDepTag, lib)
+
} else {
// autoDep.depTag is a dylib depTag. Not all rustlibs may be available as a dylib however.
// Check for the existence of the dylib deptag variant. Select it if available,
@@ -1599,23 +1595,22 @@
autoDepVariations := append(commonDepVariations,
blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation})
- replacementLib := cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Dylibs)
+ if actx.OtherModuleDependencyVariantExists(autoDepVariations, lib) {
+ actx.AddVariationDependencies(autoDepVariations, autoDep.depTag, lib)
- if actx.OtherModuleDependencyVariantExists(autoDepVariations, replacementLib) {
- addDylibDependency(actx, lib, mod, &snapshotInfo, autoDepVariations, autoDep.depTag)
} else {
// If there's no dylib dependency available, try to add the rlib dependency instead.
- addRlibDependency(actx, lib, mod, &snapshotInfo, rlibDepVariations)
+ actx.AddVariationDependencies(rlibDepVariations, rlibDepTag, lib)
+
}
}
}
} else if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
for _, lib := range deps.Rustlibs {
- replacementLib := cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Dylibs)
srcProviderVariations := append(commonDepVariations,
blueprint.Variation{Mutator: "rust_libraries", Variation: "source"})
- if actx.OtherModuleDependencyVariantExists(srcProviderVariations, replacementLib) {
+ if actx.OtherModuleDependencyVariantExists(srcProviderVariations, lib) {
actx.AddVariationDependencies(srcProviderVariations, sourceDepTag, lib)
}
}
@@ -1626,13 +1621,13 @@
if deps.Stdlibs != nil {
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
for _, lib := range deps.Stdlibs {
- lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
rlibDepTag, lib)
}
} else {
for _, lib := range deps.Stdlibs {
- addDylibDependency(actx, lib, mod, &snapshotInfo, dylibDepVariations, dylibDepTag)
+ actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib)
+
}
}
}
@@ -1657,7 +1652,6 @@
for _, lib := range deps.WholeStaticLibs {
depTag := cc.StaticDepTag(true)
- lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
@@ -1666,7 +1660,6 @@
for _, lib := range deps.StaticLibs {
depTag := cc.StaticDepTag(false)
- lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs)
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
@@ -1677,12 +1670,10 @@
crtVariations := cc.GetCrtVariations(ctx, mod)
for _, crt := range deps.CrtBegin {
- actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag,
- cc.GetReplaceModuleName(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
+ actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag, crt)
}
for _, crt := range deps.CrtEnd {
- actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag,
- cc.GetReplaceModuleName(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects))
+ actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag, crt)
}
if mod.sourceProvider != nil {
@@ -1705,17 +1696,6 @@
mod.afdo.addDep(ctx, actx)
}
-// addRlibDependency will add an rlib dependency, rewriting to the snapshot library if available.
-func addRlibDependency(actx android.BottomUpMutatorContext, lib string, mod *Module, snapshotInfo **cc.SnapshotInfo, variations []blueprint.Variation) {
- lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, snapshotInfo, actx).Rlibs)
- actx.AddVariationDependencies(variations, rlibDepTag, lib)
-}
-
-func addDylibDependency(actx android.BottomUpMutatorContext, lib string, mod *Module, snapshotInfo **cc.SnapshotInfo, variations []blueprint.Variation, depTag dependencyTag) {
- lib = cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, snapshotInfo, actx).Dylibs)
- actx.AddVariationDependencies(variations, depTag, lib)
-}
-
func BeginMutator(ctx android.BottomUpMutatorContext) {
if mod, ok := ctx.Module().(*Module); ok && mod.Enabled() {
mod.beginMutator(ctx)
@@ -1747,7 +1727,6 @@
}
var _ android.HostToolProvider = (*Module)(nil)
-var _ snapshot.RelativeInstallPath = (*Module)(nil)
func (mod *Module) HostToolPath() android.OptionalPath {
if !mod.Host() {
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 295a734..6d083f6 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -37,11 +37,7 @@
genrule.PrepareForTestWithGenRuleBuildComponents,
- PrepareForTestWithRustIncludeVndk,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = StringPtr("current")
- variables.Platform_vndk_version = StringPtr("29")
- }),
+ PrepareForIntegrationTestWithRust,
)
var rustMockedFiles = android.MockFS{
@@ -73,60 +69,21 @@
return result.TestContext
}
-func testRustVndk(t *testing.T, bp string) *android.TestContext {
- return testRustVndkFs(t, bp, rustMockedFiles)
-}
-
const (
- sharedVendorVariant = "android_vendor.29_arm64_armv8-a_shared"
- rlibVendorVariant = "android_vendor.29_arm64_armv8-a_rlib_rlib-std"
- rlibDylibStdVendorVariant = "android_vendor.29_arm64_armv8-a_rlib_rlib-std"
- dylibVendorVariant = "android_vendor.29_arm64_armv8-a_dylib"
+ sharedVendorVariant = "android_vendor_arm64_armv8-a_shared"
+ rlibVendorVariant = "android_vendor_arm64_armv8-a_rlib_rlib-std"
+ rlibDylibStdVendorVariant = "android_vendor_arm64_armv8-a_rlib_rlib-std"
+ dylibVendorVariant = "android_vendor_arm64_armv8-a_dylib"
sharedRecoveryVariant = "android_recovery_arm64_armv8-a_shared"
rlibRecoveryVariant = "android_recovery_arm64_armv8-a_rlib_dylib-std"
rlibRlibStdRecoveryVariant = "android_recovery_arm64_armv8-a_rlib_rlib-std"
dylibRecoveryVariant = "android_recovery_arm64_armv8-a_dylib"
binaryCoreVariant = "android_arm64_armv8-a"
- binaryVendorVariant = "android_vendor.29_arm64_armv8-a"
- binaryProductVariant = "android_product.29_arm64_armv8-a"
+ binaryVendorVariant = "android_vendor_arm64_armv8-a"
+ binaryProductVariant = "android_product_arm64_armv8-a"
binaryRecoveryVariant = "android_recovery_arm64_armv8-a"
)
-func testRustVndkFs(t *testing.T, bp string, fs android.MockFS) *android.TestContext {
- return testRustVndkFsVersions(t, bp, fs, "current", "current", "29")
-}
-
-func testRustVndkFsVersions(t *testing.T, bp string, fs android.MockFS, device_version, product_version, vndk_version string) *android.TestContext {
- skipTestIfOsNotSupported(t)
- result := android.GroupFixturePreparers(
- prepareForRustTest,
- fs.AddToFixture(),
- android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = StringPtr(device_version)
- variables.Platform_vndk_version = StringPtr(vndk_version)
- },
- ),
- ).RunTestWithBp(t, bp)
- return result.TestContext
-}
-
-func testRustRecoveryFsVersions(t *testing.T, bp string, fs android.MockFS, device_version, vndk_version, recovery_version string) *android.TestContext {
- skipTestIfOsNotSupported(t)
- result := android.GroupFixturePreparers(
- prepareForRustTest,
- fs.AddToFixture(),
- android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = StringPtr(device_version)
- variables.RecoverySnapshotVersion = StringPtr(recovery_version)
- variables.Platform_vndk_version = StringPtr(vndk_version)
- },
- ),
- ).RunTestWithBp(t, bp)
- return result.TestContext
-}
-
// testRustCov returns a TestContext in which a basic environment has been
// setup. This environment explicitly enables coverage.
func testRustCov(t *testing.T, bp string) *android.TestContext {
@@ -158,27 +115,6 @@
RunTestWithBp(t, bp)
}
-// testRustVndkError is similar to testRustError, but can be used to test VNDK-related errors.
-func testRustVndkError(t *testing.T, pattern string, bp string) {
- testRustVndkFsError(t, pattern, bp, rustMockedFiles)
-}
-
-func testRustVndkFsError(t *testing.T, pattern string, bp string, fs android.MockFS) {
- skipTestIfOsNotSupported(t)
- android.GroupFixturePreparers(
- prepareForRustTest,
- fs.AddToFixture(),
- android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = StringPtr("current")
- variables.Platform_vndk_version = StringPtr("VER")
- },
- ),
- ).
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
- RunTestWithBp(t, bp)
-}
-
// testRustCtx is used to build a particular test environment. Unless your
// tests requires a specific setup, prefer the wrapping functions: testRust,
// testRustCov or testRustError.
diff --git a/rust/sanitize.go b/rust/sanitize.go
index 3c08cd8..bfd3971 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -267,12 +267,6 @@
if Bool(mod.sanitize.Properties.Sanitize.Diag.Memtag_heap) {
noteDep = "note_memtag_heap_sync"
}
- // If we're using snapshots, redirect to snapshot whenever possible
- // TODO(b/178470649): clean manual snapshot redirections
- snapshot, _ := android.ModuleProvider(mctx, cc.SnapshotInfoProvider)
- if lib, ok := snapshot.StaticLibs[noteDep]; ok {
- noteDep = lib
- }
depTag := cc.StaticDepTag(true)
variations := append(mctx.Target().Variations(),
blueprint.Variation{Mutator: "link", Variation: "static"})
diff --git a/rust/snapshot_prebuilt.go b/rust/snapshot_prebuilt.go
deleted file mode 100644
index 42e3cef..0000000
--- a/rust/snapshot_prebuilt.go
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright 2021 The Android Open Source Project
-//
-// 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 rust
-
-import (
- "fmt"
-
- "android/soong/android"
- "android/soong/cc"
-
- "github.com/google/blueprint/proptools"
-)
-
-type snapshotLibraryDecorator struct {
- cc.BaseSnapshotDecorator
- *libraryDecorator
- properties cc.SnapshotLibraryProperties
- sanitizerProperties struct {
- SanitizerVariation cc.SanitizerType `blueprint:"mutated"`
-
- //TODO: Library flags for cfi variant when CFI is supported.
- //Cfi cc.SnapshotLibraryProperties `android:"arch_variant"`
-
- // Library flags for hwasan variant.
- Hwasan cc.SnapshotLibraryProperties `android:"arch_variant"`
- }
-}
-
-var _ cc.SnapshotSanitizer = (*snapshotLibraryDecorator)(nil)
-
-func (library *snapshotLibraryDecorator) IsSanitizerAvailable(t cc.SanitizerType) bool {
- switch t {
- //TODO: When CFI is supported, add a check here as well
- case cc.Hwasan:
- return library.sanitizerProperties.Hwasan.Src != nil
- default:
- return false
- }
-}
-
-func (library *snapshotLibraryDecorator) SetSanitizerVariation(t cc.SanitizerType, enabled bool) {
- if !enabled || library.IsSanitizerEnabled(t) {
- return
- }
- if !library.IsUnsanitizedVariant() {
- panic(fmt.Errorf("snapshot Sanitizer must be one of Cfi or Hwasan but not both"))
- }
- library.sanitizerProperties.SanitizerVariation = t
-}
-
-func (library *snapshotLibraryDecorator) IsSanitizerEnabled(t cc.SanitizerType) bool {
- return library.sanitizerProperties.SanitizerVariation == t
-}
-
-func (library *snapshotLibraryDecorator) IsUnsanitizedVariant() bool {
- //TODO: When CFI is supported, add a check here as well
- return !library.IsSanitizerEnabled(cc.Hwasan)
-}
-
-func init() {
- registerRustSnapshotModules(android.InitRegistrationContext)
-}
-
-func (mod *Module) IsSnapshotSanitizerAvailable(t cc.SanitizerType) bool {
- if ss, ok := mod.compiler.(cc.SnapshotSanitizer); ok {
- return ss.IsSanitizerAvailable(t)
- }
- return false
-}
-
-func (mod *Module) SetSnapshotSanitizerVariation(t cc.SanitizerType, enabled bool) {
- if ss, ok := mod.compiler.(cc.SnapshotSanitizer); ok {
- ss.SetSanitizerVariation(t, enabled)
- } else {
- panic(fmt.Errorf("Calling SetSnapshotSanitizerVariation on a non-snapshotLibraryDecorator: %s", mod.Name()))
- }
-}
-
-func (mod *Module) IsSnapshotUnsanitizedVariant() bool {
- if ss, ok := mod.compiler.(cc.SnapshotSanitizer); ok {
- return ss.IsUnsanitizedVariant()
- }
- return false
-}
-
-func (mod *Module) IsSnapshotSanitizer() bool {
- if _, ok := mod.compiler.(cc.SnapshotSanitizer); ok {
- return true
- }
- return false
-}
-
-func registerRustSnapshotModules(ctx android.RegistrationContext) {
- cc.VendorSnapshotImageSingleton.RegisterAdditionalModule(ctx,
- "vendor_snapshot_rlib", VendorSnapshotRlibFactory)
- cc.VendorSnapshotImageSingleton.RegisterAdditionalModule(ctx,
- "vendor_snapshot_dylib", VendorSnapshotDylibFactory)
- cc.RecoverySnapshotImageSingleton.RegisterAdditionalModule(ctx,
- "recovery_snapshot_rlib", RecoverySnapshotRlibFactory)
-}
-
-func snapshotLibraryFactory(image cc.SnapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
- module, library := NewRustLibrary(android.DeviceSupported)
-
- module.sanitize = nil
- library.stripper.StripProperties.Strip.None = proptools.BoolPtr(true)
-
- prebuilt := &snapshotLibraryDecorator{
- libraryDecorator: library,
- }
-
- module.compiler = prebuilt
-
- prebuilt.Init(module, image, moduleSuffix)
- module.AddProperties(
- &prebuilt.properties,
- &prebuilt.sanitizerProperties,
- )
-
- return module, prebuilt
-}
-
-func (library *snapshotLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
- var variant string
- if library.static() {
- variant = cc.SnapshotStaticSuffix
- } else if library.shared() {
- variant = cc.SnapshotSharedSuffix
- } else if library.rlib() {
- variant = cc.SnapshotRlibSuffix
- } else if library.dylib() {
- variant = cc.SnapshotDylibSuffix
- }
-
- library.SetSnapshotAndroidMkSuffix(ctx, variant)
-
- if library.IsSanitizerEnabled(cc.Hwasan) {
- library.properties = library.sanitizerProperties.Hwasan
- }
- if !library.MatchesWithDevice(ctx.DeviceConfig()) {
- return buildOutput{}
- }
- outputFile := android.PathForModuleSrc(ctx, *library.properties.Src)
- library.unstrippedOutputFile = outputFile
- return buildOutput{outputFile: outputFile}
-}
-
-func (library *snapshotLibraryDecorator) rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath {
- return android.OptionalPath{}
-}
-
-// vendor_snapshot_rlib is a special prebuilt rlib library which is auto-generated by
-// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_rlib
-// overrides the vendor variant of the rust rlib library with the same name, if BOARD_VNDK_VERSION
-// is set.
-func VendorSnapshotRlibFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(cc.VendorSnapshotImageSingleton, cc.SnapshotRlibSuffix)
- prebuilt.libraryDecorator.BuildOnlyRlib()
- prebuilt.libraryDecorator.setNoStdlibs()
- return module.Init()
-}
-
-// vendor_snapshot_dylib is a special prebuilt dylib library which is auto-generated by
-// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_dylib
-// overrides the vendor variant of the rust dylib library with the same name, if BOARD_VNDK_VERSION
-// is set.
-func VendorSnapshotDylibFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(cc.VendorSnapshotImageSingleton, cc.SnapshotDylibSuffix)
- prebuilt.libraryDecorator.BuildOnlyDylib()
- prebuilt.libraryDecorator.setNoStdlibs()
- return module.Init()
-}
-
-func RecoverySnapshotRlibFactory() android.Module {
- module, prebuilt := snapshotLibraryFactory(cc.RecoverySnapshotImageSingleton, cc.SnapshotRlibSuffix)
- prebuilt.libraryDecorator.BuildOnlyRlib()
- prebuilt.libraryDecorator.setNoStdlibs()
- return module.Init()
-}
-
-func (library *snapshotLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
- arches := config.Arches()
- if len(arches) == 0 || arches[0].ArchType.String() != library.Arch() {
- return false
- }
- if library.properties.Src == nil {
- return false
- }
- return true
-}
-
-func (library *snapshotLibraryDecorator) IsSnapshotPrebuilt() bool {
- return true
-}
-
-var _ cc.SnapshotInterface = (*snapshotLibraryDecorator)(nil)
diff --git a/rust/snapshot_utils.go b/rust/snapshot_utils.go
deleted file mode 100644
index 55c85e6..0000000
--- a/rust/snapshot_utils.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2021 The Android Open Source Project
-//
-// 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 rust
-
-import (
- "android/soong/android"
-)
-
-// snapshotLibraryInterface is an interface for libraries captured to VNDK / vendor snapshots.
-type snapshotLibraryInterface interface {
- libraryInterface
-
- // collectHeadersForSnapshot is called in GenerateAndroidBuildActions for snapshot aware
- // modules (See isSnapshotAware below).
- // This function should gather all headers needed for snapshot.
- collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps)
-
- // snapshotHeaders should return collected headers by collectHeadersForSnapshot.
- // Calling snapshotHeaders before collectHeadersForSnapshot is an error.
- snapshotHeaders() android.Paths
-}
-
-func (mod *Module) ExcludeFromVendorSnapshot() bool {
- return Bool(mod.Properties.Exclude_from_vendor_snapshot)
-}
-
-func (mod *Module) ExcludeFromRecoverySnapshot() bool {
- return Bool(mod.Properties.Exclude_from_recovery_snapshot)
-}
-
-func (mod *Module) IsSnapshotLibrary() bool {
- if lib, ok := mod.compiler.(libraryInterface); ok {
- return lib.shared() || lib.static() || lib.rlib() || lib.dylib()
- }
- return false
-}
-
-func (mod *Module) SnapshotRuntimeLibs() []string {
- // TODO Rust does not yet support a runtime libs notion similar to CC
- return []string{}
-}
-
-func (mod *Module) SnapshotSharedLibs() []string {
- return mod.Properties.SnapshotSharedLibs
-}
-
-func (mod *Module) SnapshotStaticLibs() []string {
- return mod.Properties.SnapshotStaticLibs
-}
-
-func (mod *Module) SnapshotRlibs() []string {
- return mod.Properties.SnapshotRlibs
-}
-
-func (mod *Module) SnapshotDylibs() []string {
- return mod.Properties.SnapshotDylibs
-}
-
-func (mod *Module) Symlinks() []string {
- // TODO update this to return the list of symlinks when Rust supports defining symlinks
- return nil
-}
-
-func (m *Module) SnapshotHeaders() android.Paths {
- if l, ok := m.compiler.(snapshotLibraryInterface); ok {
- return l.snapshotHeaders()
- }
- return android.Paths{}
-}
diff --git a/rust/testing.go b/rust/testing.go
index d9cacdc..5837dcc 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -43,11 +43,7 @@
// Preparer that will allow use of all rust modules fully.
var PrepareForIntegrationTestWithRust = android.GroupFixturePreparers(
PrepareForTestWithRustDefaultModules,
-)
-
-var PrepareForTestWithRustIncludeVndk = android.GroupFixturePreparers(
- PrepareForIntegrationTestWithRust,
- cc.PrepareForTestWithCcIncludeVndk,
+ cc.PrepareForIntegrationTestWithCc,
)
func GatherRequiredDepsForTest() string {
@@ -201,5 +197,4 @@
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("rust_sanitizers", rustSanitizerRuntimeMutator).Parallel()
})
- registerRustSnapshotModules(ctx)
}
diff --git a/rust/vendor_snapshot_test.go b/rust/vendor_snapshot_test.go
deleted file mode 100644
index a6ed0e5..0000000
--- a/rust/vendor_snapshot_test.go
+++ /dev/null
@@ -1,1573 +0,0 @@
-// Copyright 2021 The Android Open Source Project
-//
-// 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 rust
-
-import (
- "fmt"
- "path/filepath"
- "reflect"
- "strings"
- "testing"
-
- "android/soong/android"
- "android/soong/cc"
-)
-
-func TestVendorSnapshotCapture(t *testing.T) {
- bp := `
- rust_ffi {
- name: "libffivendor_available",
- crate_name: "ffivendor_available",
- srcs: ["lib.rs"],
- vendor_available: true,
- export_include_dirs: ["rust_headers/"],
- }
-
- rust_ffi {
- name: "libffivendor",
- crate_name: "ffivendor",
- srcs: ["lib.rs"],
- vendor: true,
- export_include_dirs: ["rust_headers/"],
- }
-
- rust_library {
- name: "librustvendor_available",
- crate_name: "rustvendor_available",
- srcs: ["lib.rs"],
- vendor_available: true,
- }
-
- rust_library {
- name: "librustvendor",
- crate_name: "rustvendor",
- srcs: ["lib.rs"],
- vendor: true,
- }
-
- rust_binary {
- name: "vendor_available_bin",
- vendor_available: true,
- srcs: ["srcs/lib.rs"],
- }
-
- rust_binary {
- name: "vendor_bin",
- vendor: true,
- srcs: ["srcs/lib.rs"],
- }
- `
- skipTestIfOsNotSupported(t)
- result := android.GroupFixturePreparers(
- prepareForRustTest,
- rustMockedFiles.AddToFixture(),
- android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = StringPtr("current")
- variables.Platform_vndk_version = StringPtr("29")
- },
- ),
- ).RunTestWithBp(t, bp)
- ctx := result.TestContext
-
- // Check Vendor snapshot output.
-
- snapshotDir := "vendor-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
- var jsonFiles []string
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- []string{"arm", "armv7-a-neon"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- // For shared libraries, only non-VNDK vendor_available modules are captured
- sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor_available", "libffivendor_available.so", sharedDir, sharedVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(sharedDir, "libffivendor_available.so.json"))
-
- // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
- staticVariant := fmt.Sprintf("android_vendor.29_%s_%s_static", archType, archVariant)
- staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor_available", "libffivendor_available.a", staticDir, staticVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor", "libffivendor.a", staticDir, staticVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(staticDir, "libffivendor_available.a.json"))
- jsonFiles = append(jsonFiles,
- filepath.Join(staticDir, "libffivendor.a.json"))
-
- // For rlib libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
- rlibVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_dylib-std", archType, archVariant)
- rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib")
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.rlib", rlibDir, rlibVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor", "librustvendor.rlib", rlibDir, rlibVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(rlibDir, "librustvendor_available.rlib.json"))
- jsonFiles = append(jsonFiles,
- filepath.Join(rlibDir, "librustvendor.rlib.json"))
-
- // For rlib libraries, all rlib-std variants vendor:true and vendor_available modules (including VNDK) are captured.
- rlibStdVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_rlib-std", archType, archVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.rlib-std.rlib", rlibDir, rlibStdVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor", "librustvendor.rlib-std.rlib", rlibDir, rlibStdVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(rlibDir, "librustvendor_available.rlib.json"))
- jsonFiles = append(jsonFiles,
- filepath.Join(rlibDir, "librustvendor.rlib.json"))
-
- // For dylib libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
- dylibVariant := fmt.Sprintf("android_vendor.29_%s_%s_dylib", archType, archVariant)
- dylibDir := filepath.Join(snapshotVariantPath, archDir, "dylib")
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.dylib.so", dylibDir, dylibVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor", "librustvendor.dylib.so", dylibDir, dylibVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(dylibDir, "librustvendor_available.dylib.so.json"))
- jsonFiles = append(jsonFiles,
- filepath.Join(dylibDir, "librustvendor.dylib.so.json"))
-
- // For binary executables, all vendor:true and vendor_available modules are captured.
- if archType == "arm64" {
- binaryVariant := fmt.Sprintf("android_vendor.29_%s_%s", archType, archVariant)
- binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(binaryDir, "vendor_available_bin.json"))
- jsonFiles = append(jsonFiles,
- filepath.Join(binaryDir, "vendor_bin.json"))
- }
- }
-
- for _, jsonFile := range jsonFiles {
- // verify all json files exist
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("%q expected but not found; #%v", jsonFile, jsonFiles)
- }
- }
-
- // fake snapshot should have all outputs in the normal snapshot.
- fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot")
-
- for _, output := range snapshotSingleton.AllOutputs() {
- fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1)
- if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil {
- t.Errorf("%q expected but not found", fakeOutput)
- }
- }
-}
-
-func TestVendorSnapshotDirected(t *testing.T) {
- bp := `
- rust_ffi_shared {
- name: "libffivendor_available",
- crate_name: "ffivendor_available",
- srcs: ["lib.rs"],
- vendor_available: true,
- }
-
- rust_library {
- name: "librustvendor_available",
- crate_name: "rustvendor_available",
- srcs: ["lib.rs"],
- vendor_available: true,
- }
-
- rust_ffi_shared {
- name: "libffivendor_exclude",
- crate_name: "ffivendor_exclude",
- srcs: ["lib.rs"],
- vendor_available: true,
- }
-
- rust_library {
- name: "librustvendor_exclude",
- crate_name: "rustvendor_exclude",
- srcs: ["lib.rs"],
- vendor_available: true,
- }
-`
- ctx := testRustVndk(t, bp)
- ctx.Config().TestProductVariables.VendorSnapshotModules = make(map[string]bool)
- ctx.Config().TestProductVariables.VendorSnapshotModules["librustvendor_available"] = true
- ctx.Config().TestProductVariables.VendorSnapshotModules["libffivendor_available"] = true
- ctx.Config().TestProductVariables.DirectedVendorSnapshot = true
-
- // Check Vendor snapshot output.
-
- snapshotDir := "vendor-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
-
- var includeJsonFiles []string
-
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- []string{"arm", "armv7-a-neon"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
- rlibVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_dylib-std", archType, archVariant)
- rlibRlibStdVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_rlib-std", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
- rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib")
- dylibVariant := fmt.Sprintf("android_vendor.29_%s_%s_dylib", archType, archVariant)
- dylibDir := filepath.Join(snapshotVariantPath, archDir, "dylib")
-
- // Included modules
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.rlib", rlibDir, rlibVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.rlib-std.rlib", rlibDir, rlibRlibStdVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.dylib.so", dylibDir, dylibVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor_available", "libffivendor_available.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librustvendor_available.rlib.json"))
- includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librustvendor_available.rlib-std.rlib.json"))
- includeJsonFiles = append(includeJsonFiles, filepath.Join(dylibDir, "librustvendor_available.dylib.so.json"))
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libffivendor_available.so.json"))
-
- // Excluded modules. Modules not included in the directed vendor snapshot
- // are still include as fake modules.
- cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librustvendor_exclude", "librustvendor_exclude.rlib", rlibDir, rlibVariant)
- cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librustvendor_exclude", "librustvendor_exclude.rlib-std.rlib", rlibDir, rlibRlibStdVariant)
- cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librustvendor_exclude", "librustvendor_exclude.dylib.so", dylibDir, dylibVariant)
- cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "libffivendor_exclude", "libffivendor_exclude.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librustvendor_exclude.rlib.json"))
- includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librustvendor_exclude.rlib-std.rlib.json"))
- includeJsonFiles = append(includeJsonFiles, filepath.Join(dylibDir, "librustvendor_exclude.dylib.so.json"))
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libffivendor_exclude.so.json"))
- }
-
- // Verify that each json file for an included module has a rule.
- for _, jsonFile := range includeJsonFiles {
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("include json file %q not found", jsonFile)
- }
- }
-}
-
-func TestVendorSnapshotExclude(t *testing.T) {
-
- // This test verifies that the exclude_from_vendor_snapshot property
- // makes its way from the Android.bp source file into the module data
- // structure. It also verifies that modules are correctly included or
- // excluded in the vendor snapshot based on their path (framework or
- // vendor) and the exclude_from_vendor_snapshot property.
-
- frameworkBp := `
- rust_ffi_shared {
- name: "libinclude",
- crate_name: "include",
- srcs: ["include.rs"],
- vendor_available: true,
- }
-
- rust_ffi_shared {
- name: "libexclude",
- crate_name: "exclude",
- srcs: ["exclude.rs"],
- vendor: true,
- exclude_from_vendor_snapshot: true,
- }
-
- rust_ffi_shared {
- name: "libavailable_exclude",
- crate_name: "available_exclude",
- srcs: ["lib.rs"],
- vendor_available: true,
- exclude_from_vendor_snapshot: true,
- }
-
- rust_library {
- name: "librust_include",
- crate_name: "rust_include",
- srcs: ["include.rs"],
- vendor_available: true,
- }
-
- rust_library {
- name: "librust_exclude",
- crate_name: "rust_exclude",
- srcs: ["exclude.rs"],
- vendor: true,
- exclude_from_vendor_snapshot: true,
- }
-
- rust_library {
- name: "librust_available_exclude",
- crate_name: "rust_available_exclude",
- srcs: ["lib.rs"],
- vendor_available: true,
- exclude_from_vendor_snapshot: true,
- }
- `
-
- mockFS := map[string][]byte{
- "framework/Android.bp": []byte(frameworkBp),
- "framework/include.rs": nil,
- "framework/exclude.rs": nil,
- }
-
- ctx := testRustVndkFs(t, "", mockFS)
-
- // Test an include and exclude framework module.
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false, sharedVendorVariant)
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true, sharedVendorVariant)
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true, sharedVendorVariant)
-
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_include", false, rlibVendorVariant)
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_exclude", true, rlibVendorVariant)
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_available_exclude", true, rlibVendorVariant)
-
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_include", false, rlibDylibStdVendorVariant)
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_exclude", true, rlibDylibStdVendorVariant)
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_available_exclude", true, rlibDylibStdVendorVariant)
-
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_include", false, dylibVendorVariant)
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_exclude", true, dylibVendorVariant)
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_available_exclude", true, dylibVendorVariant)
-
- // Verify the content of the vendor snapshot.
-
- snapshotDir := "vendor-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
-
- var includeJsonFiles []string
- var excludeJsonFiles []string
-
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- []string{"arm", "armv7-a-neon"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
-
- rlibVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_dylib-std", archType, archVariant)
- rlibRlibStdVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_rlib-std", archType, archVariant)
- rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib")
- dylibVariant := fmt.Sprintf("android_vendor.29_%s_%s_dylib", archType, archVariant)
- dylibDir := filepath.Join(snapshotVariantPath, archDir, "dylib")
-
- // Included modules
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librust_include", "librust_include.rlib", rlibDir, rlibVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librust_include.rlib.json"))
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librust_include", "librust_include.rlib-std.rlib", rlibDir, rlibRlibStdVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librust_include.rlib-std.rlib.json"))
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librust_include", "librust_include.dylib.so", dylibDir, dylibVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(dylibDir, "librust_include.dylib.so.json"))
-
- // Excluded modules
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librust_exclude", "librust_exclude.rlib", rlibDir, rlibVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librust_exclude.rlib.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librust_available_exclude", "librust_available_exclude.rlib", rlibDir, rlibVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librust_available_exclude.rlib.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librust_available_exclude", "librust_available_exclude.rlib-std.rlib", rlibDir, rlibRlibStdVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librust_available_exclude.rlib.rlib-std.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librust_exclude", "librust_exclude.dylib.so", dylibDir, dylibVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(dylibDir, "librust_exclude.dylib.so.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librust_available_exclude", "librust_available_exclude.dylib.so", dylibDir, dylibVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(dylibDir, "librust_available_exclude.dylib.so.json"))
- }
-
- // Verify that each json file for an included module has a rule.
- for _, jsonFile := range includeJsonFiles {
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("include json file %q not found", jsonFile)
- }
- }
-
- // Verify that each json file for an excluded module has no rule.
- for _, jsonFile := range excludeJsonFiles {
- if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
- t.Errorf("exclude json file %q found", jsonFile)
- }
- }
-}
-
-func TestVendorSnapshotUse(t *testing.T) {
- frameworkBp := `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvendor",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- stl: "none",
- system_shared_libs: [],
- }
-
- cc_library {
- name: "libvendor_available",
- vendor_available: true,
- nocrt: true,
- no_libcrt: true,
- stl: "none",
- system_shared_libs: [],
- }
-
- cc_library {
- name: "lib32",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- stl: "none",
- system_shared_libs: [],
- compile_multilib: "32",
- }
-
- cc_library {
- name: "lib64",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- stl: "none",
- system_shared_libs: [],
- compile_multilib: "64",
- }
-
- rust_binary {
- name: "bin",
- vendor: true,
- srcs: ["bin.rs"],
- }
-
- rust_binary {
- name: "bin32",
- vendor: true,
- compile_multilib: "32",
- srcs: ["bin.rs"],
- }
-
- rust_library {
- name: "librust_vendor_available",
- crate_name: "rust_vendor",
- vendor_available: true,
- srcs: ["client.rs"],
- }
-
-`
-
- vndkBp := `
- vndk_prebuilt_shared {
- name: "libvndk",
- version: "30",
- target_arch: "arm64",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- arch: {
- arm64: {
- srcs: ["libvndk.so"],
- export_include_dirs: ["include/libvndk"],
- },
- arm: {
- srcs: ["libvndk.so"],
- export_include_dirs: ["include/libvndk"],
- },
- },
- }
-
- // old snapshot module which has to be ignored
- vndk_prebuilt_shared {
- name: "libvndk",
- version: "26",
- target_arch: "arm64",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- arch: {
- arm64: {
- srcs: ["libvndk.so"],
- export_include_dirs: ["include/libvndk"],
- },
- arm: {
- srcs: ["libvndk.so"],
- export_include_dirs: ["include/libvndk"],
- },
- },
- }
-
- // different arch snapshot which has to be ignored
- vndk_prebuilt_shared {
- name: "libvndk",
- version: "30",
- target_arch: "arm",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- arch: {
- arm: {
- srcs: ["libvndk.so"],
- export_include_dirs: ["include/libvndk"],
- },
- },
- }
-`
-
- vendorProprietaryBp := `
- cc_library {
- name: "libvendor_without_snapshot",
- vendor: true,
- nocrt: true,
- no_libcrt: true,
- no_crt_pad_segment: true,
- stl: "none",
- system_shared_libs: [],
- }
-
- rust_ffi_shared {
- name: "libclient",
- crate_name: "client",
- vendor: true,
- shared_libs: ["libvndk", "libvendor_available"],
- static_libs: ["libvendor", "libvendor_without_snapshot"],
- rustlibs: ["librust_vendor_available"],
- arch: {
- arm64: {
- shared_libs: ["lib64"],
- },
- arm: {
- shared_libs: ["lib32"],
- },
- },
- srcs: ["client.rs"],
- }
-
- rust_library {
- name: "libclient_rust",
- crate_name: "client_rust",
- vendor: true,
- shared_libs: ["libvndk", "libvendor_available"],
- static_libs: ["libvendor", "libvendor_without_snapshot"],
- rustlibs: ["librust_vendor_available"],
- arch: {
- arm64: {
- shared_libs: ["lib64"],
- },
- arm: {
- shared_libs: ["lib32"],
- },
- },
- srcs: ["client.rs"],
- }
-
- rust_binary {
- name: "bin_without_snapshot",
- vendor: true,
- static_libs: ["libvndk"],
- srcs: ["bin.rs"],
- rustlibs: ["librust_vendor_available"],
- }
-
- vendor_snapshot {
- name: "vendor_snapshot",
- version: "30",
- arch: {
- arm64: {
- vndk_libs: [
- "libvndk",
- ],
- static_libs: [
- "libvendor",
- "libvndk",
- "libclang_rt.builtins",
- "note_memtag_heap_sync",
- ],
- shared_libs: [
- "libvendor_available",
- "lib64",
- ],
- rlibs: [
- "libstd",
- "librust_vendor_available",
- "librust_vendor_available.rlib-std"
- ],
- dylibs: [
- "libstd",
- "librust_vendor_available",
- ],
- binaries: [
- "bin",
- ],
- objects: [
- "crtend_so",
- "crtbegin_so",
- "crtbegin_dynamic",
- "crtend_android"
- ],
- },
- arm: {
- vndk_libs: [
- "libvndk",
- ],
- static_libs: [
- "libvendor",
- "libvndk",
- "libclang_rt.builtins",
- ],
- shared_libs: [
- "libvendor_available",
- "lib32",
- ],
- rlibs: [
- "libstd",
- "librust_vendor_available",
- ],
- dylibs: [
- "libstd",
- "librust_vendor_available",
- ],
- binaries: [
- "bin32",
- ],
- objects: [
- "crtend_so",
- "crtbegin_so",
- "crtbegin_dynamic",
- "crtend_android"
- ],
-
- },
- }
- }
-
- vendor_snapshot_object {
- name: "crtend_so",
- version: "30",
- target_arch: "arm64",
- vendor: true,
- stl: "none",
- crt: true,
- arch: {
- arm64: {
- src: "crtend_so.o",
- },
- arm: {
- src: "crtend_so.o",
- },
- },
- }
-
- vendor_snapshot_object {
- name: "crtbegin_so",
- version: "30",
- target_arch: "arm64",
- vendor: true,
- stl: "none",
- crt: true,
- arch: {
- arm64: {
- src: "crtbegin_so.o",
- },
- arm: {
- src: "crtbegin_so.o",
- },
- },
- }
-
- vendor_snapshot_rlib {
- name: "libstd",
- version: "30",
- target_arch: "arm64",
- vendor: true,
- sysroot: true,
- arch: {
- arm64: {
- src: "libstd.rlib",
- },
- arm: {
- src: "libstd.rlib",
- },
- },
- }
-
- vendor_snapshot_rlib {
- name: "librust_vendor_available",
- version: "30",
- target_arch: "arm64",
- vendor: true,
- arch: {
- arm64: {
- src: "librust_vendor_available.rlib",
- },
- arm: {
- src: "librust_vendor_available.rlib",
- },
- },
- }
-
- vendor_snapshot_rlib {
- name: "librust_vendor_available.rlib-std",
- version: "30",
- target_arch: "arm64",
- vendor: true,
- arch: {
- arm64: {
- src: "librust_vendor_available.rlib-std.rlib",
- },
- arm: {
- src: "librust_vendor_available.rlib-std.rlib",
- },
- },
- }
-
- vendor_snapshot_dylib {
- name: "libstd",
- version: "30",
- target_arch: "arm64",
- vendor: true,
- sysroot: true,
- arch: {
- arm64: {
- src: "libstd.dylib.so",
- },
- arm: {
- src: "libstd.dylib.so",
- },
- },
- }
-
- vendor_snapshot_dylib {
- name: "librust_vendor_available",
- version: "30",
- target_arch: "arm64",
- vendor: true,
- arch: {
- arm64: {
- src: "librust_vendor_available.dylib.so",
- },
- arm: {
- src: "librust_vendor_available.dylib.so",
- },
- },
- }
-
- vendor_snapshot_object {
- name: "crtend_android",
- version: "30",
- target_arch: "arm64",
- vendor: true,
- stl: "none",
- crt: true,
- arch: {
- arm64: {
- src: "crtend_so.o",
- },
- arm: {
- src: "crtend_so.o",
- },
- },
- }
-
- vendor_snapshot_object {
- name: "crtbegin_dynamic",
- version: "30",
- target_arch: "arm64",
- vendor: true,
- stl: "none",
- crt: true,
- arch: {
- arm64: {
- src: "crtbegin_so.o",
- },
- arm: {
- src: "crtbegin_so.o",
- },
- },
- }
-
- vendor_snapshot_static {
- name: "libvndk",
- version: "30",
- target_arch: "arm64",
- compile_multilib: "both",
- vendor: true,
- arch: {
- arm64: {
- src: "libvndk.a",
- },
- arm: {
- src: "libvndk.a",
- },
- },
- shared_libs: ["libvndk"],
- export_shared_lib_headers: ["libvndk"],
- }
-
- vendor_snapshot_static {
- name: "libclang_rt.builtins",
- version: "30",
- target_arch: "arm64",
- vendor: true,
- arch: {
- arm: {
- src: "libclang_rt.builtins-arm-android.a",
- },
- arm64: {
- src: "libclang_rt.builtins-aarch64-android.a",
- },
- },
- }
-
- vendor_snapshot_shared {
- name: "lib32",
- version: "30",
- target_arch: "arm64",
- compile_multilib: "32",
- vendor: true,
- no_crt_pad_segment: true,
- arch: {
- arm: {
- src: "lib32.so",
- },
- },
- }
-
- vendor_snapshot_shared {
- name: "lib64",
- version: "30",
- target_arch: "arm64",
- compile_multilib: "64",
- vendor: true,
- no_crt_pad_segment: true,
- arch: {
- arm64: {
- src: "lib64.so",
- },
- },
- }
- vendor_snapshot_shared {
- name: "liblog",
- version: "30",
- target_arch: "arm64",
- compile_multilib: "64",
- vendor: true,
- no_crt_pad_segment: true,
- arch: {
- arm64: {
- src: "liblog.so",
- },
- },
- }
-
- vendor_snapshot_static {
- name: "libvendor",
- version: "30",
- target_arch: "arm64",
- compile_multilib: "both",
- vendor: true,
- arch: {
- arm64: {
- src: "libvendor.a",
- export_include_dirs: ["include/libvendor"],
- },
- arm: {
- src: "libvendor.a",
- export_include_dirs: ["include/libvendor"],
- },
- },
- }
-
- vendor_snapshot_shared {
- name: "libvendor_available",
- version: "30",
- target_arch: "arm64",
- compile_multilib: "both",
- vendor: true,
- no_crt_pad_segment: true,
- arch: {
- arm64: {
- src: "libvendor_available.so",
- export_include_dirs: ["include/libvendor"],
- },
- arm: {
- src: "libvendor_available.so",
- export_include_dirs: ["include/libvendor"],
- },
- },
- }
-
- vendor_snapshot_binary {
- name: "bin",
- version: "30",
- target_arch: "arm64",
- compile_multilib: "64",
- vendor: true,
- arch: {
- arm64: {
- src: "bin",
- },
- },
- }
-
- vendor_snapshot_binary {
- name: "bin32",
- version: "30",
- target_arch: "arm64",
- compile_multilib: "32",
- vendor: true,
- arch: {
- arm: {
- src: "bin32",
- },
- },
- }
-
- // Test sanitizers use the snapshot libraries
- rust_binary {
- name: "memtag_binary",
- srcs: ["vendor/bin.rs"],
- vendor: true,
- compile_multilib: "64",
- sanitize: {
- memtag_heap: true,
- diag: {
- memtag_heap: true,
- }
- },
- }
-
- // old snapshot module which has to be ignored
- vendor_snapshot_binary {
- name: "bin",
- version: "26",
- target_arch: "arm64",
- compile_multilib: "first",
- vendor: true,
- arch: {
- arm64: {
- src: "bin",
- },
- },
- }
-
- // different arch snapshot which has to be ignored
- vendor_snapshot_binary {
- name: "bin",
- version: "30",
- target_arch: "arm",
- compile_multilib: "first",
- vendor: true,
- arch: {
- arm64: {
- src: "bin",
- },
- },
- }
-
- vendor_snapshot_static {
- name: "note_memtag_heap_sync",
- vendor: true,
- target_arch: "arm64",
- version: "30",
- arch: {
- arm64: {
- src: "note_memtag_heap_sync.a",
- },
- },
- }
-
-`
-
- mockFS := android.MockFS{
- "framework/Android.bp": []byte(frameworkBp),
- "framework/bin.rs": nil,
- "note_memtag_heap_sync.a": nil,
- "vendor/Android.bp": []byte(vendorProprietaryBp),
- "vendor/bin": nil,
- "vendor/bin32": nil,
- "vendor/bin.rs": nil,
- "vendor/client.rs": nil,
- "vendor/include/libvndk/a.h": nil,
- "vendor/include/libvendor/b.h": nil,
- "vendor/libvndk.a": nil,
- "vendor/libvendor.a": nil,
- "vendor/libvendor.so": nil,
- "vendor/lib32.so": nil,
- "vendor/lib64.so": nil,
- "vendor/liblog.so": nil,
- "vendor/libstd.rlib": nil,
- "vendor/librust_vendor_available.rlib": nil,
- "vendor/librust_vendor_available.rlib-std.rlib": nil,
- "vendor/libstd.dylib.so": nil,
- "vendor/librust_vendor_available.dylib.so": nil,
- "vendor/crtbegin_so.o": nil,
- "vendor/crtend_so.o": nil,
- "vendor/libclang_rt.builtins-aarch64-android.a": nil,
- "vendor/libclang_rt.builtins-arm-android.a": nil,
- "vndk/Android.bp": []byte(vndkBp),
- "vndk/include/libvndk/a.h": nil,
- "vndk/libvndk.so": nil,
- }
-
- sharedVariant := "android_vendor.30_arm64_armv8-a_shared"
- rlibVariant := "android_vendor.30_arm64_armv8-a_rlib_dylib-std"
- rlibRlibStdVariant := "android_vendor.30_arm64_armv8-a_rlib_rlib-std"
- dylibVariant := "android_vendor.30_arm64_armv8-a_dylib"
- staticVariant := "android_vendor.30_arm64_armv8-a_static"
- binaryVariant := "android_vendor.30_arm64_armv8-a"
-
- shared32Variant := "android_vendor.30_arm_armv7-a-neon_shared"
- binary32Variant := "android_vendor.30_arm_armv7-a-neon"
-
- ctx := testRustVndkFsVersions(t, "", mockFS, "30", "current", "31")
-
- // libclient uses libvndk.vndk.30.arm64, libvendor.vendor_static.30.arm64, libvendor_without_snapshot
- libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustc").Args["linkFlags"]
- for _, input := range [][]string{
- []string{sharedVariant, "libvndk.vndk.30.arm64"},
- []string{staticVariant, "libvendor.vendor_static.30.arm64"},
- []string{staticVariant, "libvendor_without_snapshot"},
- } {
- outputPaths := cc.GetOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */)
- if !strings.Contains(libclientLdFlags, outputPaths[0].String()) {
- t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags)
- }
- }
-
- libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).transitiveAndroidMkSharedLibs.ToList()
- if g, w := libclientAndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "lib64", "liblog.vendor", "libc.vendor", "libm.vendor", "libdl.vendor"}; !reflect.DeepEqual(g, w) {
- t.Errorf("wanted libclient AndroidMkSharedLibs %q, got %q", w, g)
- }
-
- libclientAndroidMkStaticLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkStaticLibs
- if g, w := libclientAndroidMkStaticLibs, []string{"libvendor", "libvendor_without_snapshot", "libclang_rt.builtins.vendor"}; !reflect.DeepEqual(g, w) {
- t.Errorf("wanted libclient AndroidMkStaticLibs %q, got %q", w, g)
- }
-
- libclientAndroidMkDylibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkDylibs
- if g, w := libclientAndroidMkDylibs, []string{"librust_vendor_available.vendor", "libstd.vendor"}; !reflect.DeepEqual(g, w) {
- t.Errorf("wanted libclient libclientAndroidMkDylibs %q, got %q", w, libclientAndroidMkDylibs)
- }
-
- libclient32AndroidMkSharedLibs := ctx.ModuleForTests("libclient", shared32Variant).Module().(*Module).transitiveAndroidMkSharedLibs.ToList()
- if g, w := libclient32AndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "lib32", "liblog.vendor", "libc.vendor", "libm.vendor", "libdl.vendor"}; !reflect.DeepEqual(g, w) {
- t.Errorf("wanted libclient32 AndroidMkSharedLibs %q, got %q", w, g)
- }
-
- libclientRustAndroidMkRlibs := ctx.ModuleForTests("libclient_rust", rlibVariant).Module().(*Module).Properties.AndroidMkRlibs
- if g, w := libclientRustAndroidMkRlibs, []string{"librust_vendor_available.vendor"}; !reflect.DeepEqual(g, w) {
- t.Errorf("wanted rlib libclient libclientAndroidMkRlibs %q, got %q", w, g)
- }
-
- libclientRlibStdRustAndroidMkRlibs := ctx.ModuleForTests("libclient_rust", rlibRlibStdVariant).Module().(*Module).Properties.AndroidMkRlibs
- if g, w := libclientRlibStdRustAndroidMkRlibs, []string{"librust_vendor_available.vendor.rlib-std", "libstd.vendor"}; !reflect.DeepEqual(g, w) {
- t.Errorf("wanted rlib libclient libclientAndroidMkRlibs %q, got %q", w, g)
- }
-
- libclientRustDylibAndroidMkDylibs := ctx.ModuleForTests("libclient_rust", dylibVariant).Module().(*Module).Properties.AndroidMkDylibs
- if g, w := libclientRustDylibAndroidMkDylibs, []string{"librust_vendor_available.vendor", "libstd.vendor"}; !reflect.DeepEqual(g, w) {
- t.Errorf("wanted dylib libclient libclientRustDylibAndroidMkDylibs %q, got %q", w, g)
- }
-
- // rust vendor snapshot must have ".vendor" suffix in AndroidMk
- librustVendorAvailableSnapshotModule := ctx.ModuleForTests("librust_vendor_available.vendor_rlib.30.arm64", rlibVariant).Module()
- librustVendorSnapshotMkName := android.AndroidMkEntriesForTest(t, ctx, librustVendorAvailableSnapshotModule)[0].EntryMap["LOCAL_MODULE"][0]
- expectedRustVendorSnapshotName := "librust_vendor_available.vendor"
- if librustVendorSnapshotMkName != expectedRustVendorSnapshotName {
- t.Errorf("Unexpected rust vendor snapshot name in AndroidMk: %q, expected: %q\n", librustVendorSnapshotMkName, expectedRustVendorSnapshotName)
- }
-
- librustVendorAvailableDylibSnapshotModule := ctx.ModuleForTests("librust_vendor_available.vendor_dylib.30.arm64", dylibVariant).Module()
- librustVendorSnapshotDylibMkName := android.AndroidMkEntriesForTest(t, ctx, librustVendorAvailableDylibSnapshotModule)[0].EntryMap["LOCAL_MODULE"][0]
- expectedRustVendorDylibSnapshotName := "librust_vendor_available.vendor"
- if librustVendorSnapshotDylibMkName != expectedRustVendorDylibSnapshotName {
- t.Errorf("Unexpected rust vendor snapshot name in AndroidMk: %q, expected: %q\n", librustVendorSnapshotDylibMkName, expectedRustVendorDylibSnapshotName)
- }
-
- rustVendorBinModule := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Module()
- rustVendorBinMkDylibName := android.AndroidMkEntriesForTest(t, ctx, rustVendorBinModule)[0].EntryMap["LOCAL_DYLIB_LIBRARIES"][0]
- if rustVendorBinMkDylibName != expectedRustVendorSnapshotName {
- t.Errorf("Unexpected rust rlib name in AndroidMk: %q, expected: %q\n", rustVendorBinMkDylibName, expectedRustVendorSnapshotName)
- }
-
- binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustc").Args["linkFlags"]
- libVndkStaticOutputPaths := cc.GetOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.30.arm64"})
- if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
- t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
- libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags)
- }
-
- // bin is installed by bin.vendor_binary.30.arm64
- ctx.ModuleForTests("bin.vendor_binary.30.arm64", binaryVariant).Output("bin")
-
- // bin32 is installed by bin32.vendor_binary.30.arm64
- ctx.ModuleForTests("bin32.vendor_binary.30.arm64", binary32Variant).Output("bin32")
-
- // bin_without_snapshot is installed by bin_without_snapshot
- ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot")
-
- // libvendor, libvendor_available and bin don't have vendor.30 variant
- libvendorVariants := ctx.ModuleVariantsForTests("libvendor")
- if android.InList(sharedVariant, libvendorVariants) {
- t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant)
- }
-
- libvendorAvailableVariants := ctx.ModuleVariantsForTests("libvendor_available")
- if android.InList(sharedVariant, libvendorAvailableVariants) {
- t.Errorf("libvendor_available must not have variant %#v, but it does", sharedVariant)
- }
-
- binVariants := ctx.ModuleVariantsForTests("bin")
- if android.InList(binaryVariant, binVariants) {
- t.Errorf("bin must not have variant %#v, but it does", sharedVariant)
- }
-
- memtagStaticLibs := ctx.ModuleForTests("memtag_binary", "android_vendor.30_arm64_armv8-a").Module().(*Module).Properties.AndroidMkStaticLibs
- if g, w := memtagStaticLibs, []string{"libclang_rt.builtins.vendor", "note_memtag_heap_sync.vendor"}; !reflect.DeepEqual(g, w) {
- t.Errorf("wanted memtag_binary AndroidMkStaticLibs %q, got %q", w, g)
- }
-}
-
-func TestRecoverySnapshotCapture(t *testing.T) {
- bp := `
- rust_ffi {
- name: "librecovery",
- recovery: true,
- srcs: ["foo.rs"],
- crate_name: "recovery",
- }
-
- rust_ffi {
- name: "librecovery_available",
- recovery_available: true,
- srcs: ["foo.rs"],
- crate_name: "recovery_available",
- }
-
- rust_library {
- name: "librecovery_rustlib",
- recovery: true,
- srcs: ["foo.rs"],
- crate_name: "recovery_rustlib",
- }
-
- rust_library {
- name: "librecovery_available_rustlib",
- recovery_available: true,
- srcs: ["foo.rs"],
- crate_name: "recovery_available_rustlib",
- }
-
- rust_binary {
- name: "recovery_bin",
- recovery: true,
- srcs: ["foo.rs"],
- }
-
- rust_binary {
- name: "recovery_available_bin",
- recovery_available: true,
- srcs: ["foo.rs"],
- }
-
-`
- // Check Recovery snapshot output.
-
- ctx := testRustRecoveryFsVersions(t, bp, rustMockedFiles, "", "29", "current")
- snapshotDir := "recovery-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
-
- var jsonFiles []string
-
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- // For shared libraries, all recovery:true and recovery_available modules are captured.
- sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(sharedDir, "librecovery.so.json"),
- filepath.Join(sharedDir, "librecovery_available.so.json"))
-
- // For static libraries, all recovery:true and recovery_available modules are captured.
- staticVariant := fmt.Sprintf("android_recovery_%s_%s_static", archType, archVariant)
- staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(staticDir, "librecovery.a.json"),
- filepath.Join(staticDir, "librecovery_available.a.json"))
-
- // For rlib libraries, all recovery:true and recovery_available modules are captured.
- rlibVariant := fmt.Sprintf("android_recovery_%s_%s_rlib_dylib-std", archType, archVariant)
- rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib")
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_rustlib", "librecovery_rustlib.rlib", rlibDir, rlibVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_available_rustlib", "librecovery_available_rustlib.rlib", rlibDir, rlibVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(rlibDir, "librecovery_rustlib.rlib.json"),
- filepath.Join(rlibDir, "librecovery_available_rustlib.rlib.json"))
-
- rlibRlibStdVariant := fmt.Sprintf("android_recovery_%s_%s_rlib_rlib-std", archType, archVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_rustlib", "librecovery_rustlib.rlib-std.rlib", rlibDir, rlibRlibStdVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_available_rustlib", "librecovery_available_rustlib.rlib-std.rlib", rlibDir, rlibRlibStdVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(rlibDir, "librecovery_rustlib.rlib-std.rlib.json"),
- filepath.Join(rlibDir, "librecovery_available_rustlib.rlib-std.rlib.json"))
-
- // For dylib libraries, all recovery:true and recovery_available modules are captured.
- dylibVariant := fmt.Sprintf("android_recovery_%s_%s_dylib", archType, archVariant)
- dylibDir := filepath.Join(snapshotVariantPath, archDir, "dylib")
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_rustlib", "librecovery_rustlib.dylib.so", dylibDir, dylibVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_available_rustlib", "librecovery_available_rustlib.dylib.so", dylibDir, dylibVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(dylibDir, "librecovery_rustlib.dylib.so.json"),
- filepath.Join(dylibDir, "librecovery_available_rustlib.dylib.so.json"))
-
- // For binary executables, all recovery:true and recovery_available modules are captured.
- if archType == "arm64" {
- binaryVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
- binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant)
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant)
- jsonFiles = append(jsonFiles,
- filepath.Join(binaryDir, "recovery_bin.json"),
- filepath.Join(binaryDir, "recovery_available_bin.json"))
- }
- }
-
- for _, jsonFile := range jsonFiles {
- // verify all json files exist
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("%q expected but not found", jsonFile)
- }
- }
-}
-
-func TestRecoverySnapshotExclude(t *testing.T) {
- // This test verifies that the exclude_from_recovery_snapshot property
- // makes its way from the Android.bp source file into the module data
- // structure. It also verifies that modules are correctly included or
- // excluded in the recovery snapshot based on their path (framework or
- // vendor) and the exclude_from_recovery_snapshot property.
-
- frameworkBp := `
- rust_ffi_shared {
- name: "libinclude",
- srcs: ["src/include.rs"],
- recovery_available: true,
- crate_name: "include",
- }
- rust_ffi_shared {
- name: "libexclude",
- srcs: ["src/exclude.rs"],
- recovery: true,
- exclude_from_recovery_snapshot: true,
- crate_name: "exclude",
- }
- rust_ffi_shared {
- name: "libavailable_exclude",
- srcs: ["src/exclude.rs"],
- recovery_available: true,
- exclude_from_recovery_snapshot: true,
- crate_name: "available_exclude",
- }
- rust_library {
- name: "libinclude_rustlib",
- srcs: ["src/include.rs"],
- recovery_available: true,
- crate_name: "include_rustlib",
- }
- rust_library {
- name: "libexclude_rustlib",
- srcs: ["src/exclude.rs"],
- recovery: true,
- exclude_from_recovery_snapshot: true,
- crate_name: "exclude_rustlib",
- }
- rust_library {
- name: "libavailable_exclude_rustlib",
- srcs: ["src/exclude.rs"],
- recovery_available: true,
- exclude_from_recovery_snapshot: true,
- crate_name: "available_exclude_rustlib",
- }
- `
-
- vendorProprietaryBp := `
- rust_ffi_shared {
- name: "librecovery",
- srcs: ["recovery.rs"],
- recovery: true,
- crate_name: "recovery",
- }
- rust_library {
- name: "librecovery_rustlib",
- srcs: ["recovery.rs"],
- recovery: true,
- crate_name: "recovery_rustlib",
- }
- `
-
- mockFS := map[string][]byte{
- "framework/Android.bp": []byte(frameworkBp),
- "framework/include.rs": nil,
- "framework/exclude.rs": nil,
- "device/Android.bp": []byte(vendorProprietaryBp),
- "device/recovery.rs": nil,
- }
-
- ctx := testRustRecoveryFsVersions(t, "", mockFS, "", "29", "current")
-
- // Test an include and exclude framework module.
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude", false, sharedRecoveryVariant)
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude", true, sharedRecoveryVariant)
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude", true, sharedRecoveryVariant)
-
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude_rustlib", false, rlibRecoveryVariant)
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude_rustlib", true, rlibRecoveryVariant)
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude_rustlib", true, rlibRlibStdRecoveryVariant)
-
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude_rustlib", false, rlibRlibStdRecoveryVariant)
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude_rustlib", true, rlibRlibStdRecoveryVariant)
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude_rustlib", true, rlibRlibStdRecoveryVariant)
-
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude_rustlib", false, dylibRecoveryVariant)
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude_rustlib", true, dylibRecoveryVariant)
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude_rustlib", true, dylibRecoveryVariant)
-
- // A recovery module is excluded, but by its path not the exclude_from_recovery_snapshot property
- // ('device/' and 'vendor/' are default excluded). See snapshot/recovery_snapshot.go for more detail.
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery", false, sharedRecoveryVariant)
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery_rustlib", false, rlibRecoveryVariant)
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery_rustlib", false, rlibRlibStdRecoveryVariant)
- cc.AssertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery_rustlib", false, dylibRecoveryVariant)
-
- // Verify the content of the recovery snapshot.
-
- snapshotDir := "recovery-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
-
- var includeJsonFiles []string
- var excludeJsonFiles []string
-
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
- rlibVariant := fmt.Sprintf("android_recovery_%s_%s_rlib_dylib-std", archType, archVariant)
- rlibRlibStdVariant := fmt.Sprintf("android_recovery_%s_%s_rlib_rlib-std", archType, archVariant)
- dylibVariant := fmt.Sprintf("android_recovery_%s_%s_dylib", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
- rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib")
- dylibDir := filepath.Join(snapshotVariantPath, archDir, "dylib")
-
- // Included modules
-
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "libinclude_rustlib", "libinclude_rustlib.rlib", rlibDir, rlibVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "libinclude_rustlib.rlib.json"))
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "libinclude_rustlib", "libinclude_rustlib.rlib-std.rlib", rlibDir, rlibRlibStdVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "libinclude_rustlib.rlib-std.rlib.json"))
-
- // Excluded modules
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
-
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude_rustlib", "libexclude_rustlib.rlib", rlibDir, rlibVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "libexclude_rustlib.rlib.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librecovery_rustlib", "librecovery_rustlib.rlib", rlibDir, rlibVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librecovery_rustlib.rlib.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude_rustlib", "libavailable_exclude_rustlib.rlib", rlibDir, rlibVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "libavailable_exclude_rustlib.rlib.json"))
-
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude_rustlib", "libexclude_rustlib.rlib-std.rlib", rlibDir, rlibRlibStdVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "libexclude_rustlib.rlib-std.rlib.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librecovery_rustlib", "librecovery_rustlib.rlib-std.rlib", rlibDir, rlibRlibStdVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librecovery_rustlib.rlib-std.rlib.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude_rustlib", "libavailable_exclude_rustlib.rlib-std.rlib", rlibDir, rlibRlibStdVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "libavailable_exclude_rustlib.rlib-std.rlib.json"))
-
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude_rustlib", "libexclude_rustlib.dylib.so", dylibDir, dylibVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "libexclude_rustlib.dylib.so.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librecovery_rustlib", "librecovery_rustlib.dylib.so", dylibDir, dylibVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librecovery_rustlib.dylib.so.json"))
- cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude_rustlib", "libavailable_exclude_rustlib.dylib.so", dylibDir, dylibVariant)
- excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "libavailable_exclude_rustlib.dylib.so.json"))
- }
-
- // Verify that each json file for an included module has a rule.
- for _, jsonFile := range includeJsonFiles {
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("include json file %q not found", jsonFile)
- }
- }
-
- // Verify that each json file for an excluded module has no rule.
- for _, jsonFile := range excludeJsonFiles {
- if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
- t.Errorf("exclude json file %q found", jsonFile)
- }
- }
-}
-
-func TestRecoverySnapshotDirected(t *testing.T) {
- bp := `
- rust_ffi_shared {
- name: "librecovery",
- recovery: true,
- crate_name: "recovery",
- srcs: ["foo.rs"],
- }
-
- rust_ffi_shared {
- name: "librecovery_available",
- recovery_available: true,
- crate_name: "recovery_available",
- srcs: ["foo.rs"],
- }
-
- rust_library {
- name: "librecovery_rustlib",
- recovery: true,
- crate_name: "recovery",
- srcs: ["foo.rs"],
- }
-
- rust_library {
- name: "librecovery_available_rustlib",
- recovery_available: true,
- crate_name: "recovery_available",
- srcs: ["foo.rs"],
- }
-
- /* TODO: Uncomment when Rust supports the "prefer" property for prebuilts
- rust_library_rlib {
- name: "libfoo_rlib",
- recovery: true,
- crate_name: "foo",
- }
-
- rust_prebuilt_rlib {
- name: "libfoo_rlib",
- recovery: true,
- prefer: true,
- srcs: ["libfoo.rlib"],
- crate_name: "foo",
- }
- */
-`
- ctx := testRustRecoveryFsVersions(t, bp, rustMockedFiles, "current", "29", "current")
- ctx.Config().TestProductVariables.RecoverySnapshotModules = make(map[string]bool)
- ctx.Config().TestProductVariables.RecoverySnapshotModules["librecovery"] = true
- ctx.Config().TestProductVariables.RecoverySnapshotModules["librecovery_rustlib"] = true
- ctx.Config().TestProductVariables.DirectedRecoverySnapshot = true
-
- // Check recovery snapshot output.
- snapshotDir := "recovery-snapshot"
- snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
- snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
-
- var includeJsonFiles []string
-
- for _, arch := range [][]string{
- []string{"arm64", "armv8-a"},
- } {
- archType := arch[0]
- archVariant := arch[1]
- archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
-
- sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
- rlibVariant := fmt.Sprintf("android_recovery_%s_%s_rlib_dylib-std", archType, archVariant)
- rlibRlibStdVariant := fmt.Sprintf("android_recovery_%s_%s_rlib_rlib-std", archType, archVariant)
- dylibVariant := fmt.Sprintf("android_recovery_%s_%s_dylib", archType, archVariant)
- sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
- rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib")
- dylibDir := filepath.Join(snapshotVariantPath, archDir, "dylib")
-
- // Included modules
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_rustlib", "librecovery_rustlib.rlib", rlibDir, rlibVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librecovery_rustlib.rlib.json"))
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_rustlib", "librecovery_rustlib.rlib-std.rlib", rlibDir, rlibRlibStdVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librecovery_rustlib.rlib-std.rlib.json"))
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librecovery_rustlib", "librecovery_rustlib.dylib.so", dylibDir, dylibVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(dylibDir, "librecovery_rustlib.dylib.so.json"))
-
- // TODO: When Rust supports the "prefer" property for prebuilts, perform this check.
- /*
- // Check that snapshot captures "prefer: true" prebuilt
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo_rlib", "libfoo_rlib.rlib", rlibDir, rlibVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo_rlib.rlib.json"))
- */
-
- // Excluded modules. Modules not included in the directed recovery snapshot
- // are still included as fake modules.
- cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery_available.so.json"))
- cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available_rustlib", "librecovery_available_rustlib.rlib", rlibDir, rlibVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librecovery_available_rustlib.rlib.json"))
- cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available_rustlib", "librecovery_available_rustlib.rlib-std.rlib", rlibDir, rlibRlibStdVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librecovery_available_rustlib.rlib-std.rlib.json"))
- cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available_rustlib", "librecovery_available_rustlib.dylib.so", dylibDir, dylibVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(dylibDir, "librecovery_available_rustlib.dylib.so.json"))
- }
-
- // Verify that each json file for an included module has a rule.
- for _, jsonFile := range includeJsonFiles {
- if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
- t.Errorf("include json file %q not found, %#v", jsonFile, includeJsonFiles)
- }
- }
-}
diff --git a/scripts/manifest_check.py b/scripts/manifest_check.py
index c33b104..b101259 100755
--- a/scripts/manifest_check.py
+++ b/scripts/manifest_check.py
@@ -52,6 +52,14 @@
'required:false'
)
parser.add_argument(
+ '--missing-optional-uses-library',
+ dest='missing_optional_uses_libraries',
+ action='append',
+ help='specify uses-library entries missing from the build system with '
+ 'required:false',
+ default=[]
+ )
+ parser.add_argument(
'--enforce-uses-libraries',
dest='enforce_uses_libraries',
action='store_true',
@@ -91,7 +99,7 @@
C_BOLD = "\033[1m"
-def enforce_uses_libraries(manifest, required, optional, relax, is_apk, path):
+def enforce_uses_libraries(manifest, required, optional, missing_optional, relax, is_apk, path):
"""Verify that the <uses-library> tags in the manifest match those provided
by the build system.
@@ -119,7 +127,12 @@
required = trim_namespace_parts(required)
optional = trim_namespace_parts(optional)
- if manifest_required == required and manifest_optional == optional:
+ existing_manifest_optional = [
+ lib for lib in manifest_optional if lib not in missing_optional]
+
+ # The order of the existing libraries matter, while the order of the missing
+ # ones doesn't.
+ if manifest_required == required and existing_manifest_optional == optional:
return None
#pylint: disable=line-too-long
@@ -129,6 +142,7 @@
'\t- required libraries in build system: %s[%s]%s\n' % (C_RED, ', '.join(required), C_OFF),
'\t vs. in the manifest: %s[%s]%s\n' % (C_RED, ', '.join(manifest_required), C_OFF),
'\t- optional libraries in build system: %s[%s]%s\n' % (C_RED, ', '.join(optional), C_OFF),
+ '\t and missing ones in build system: %s[%s]%s\n' % (C_RED, ', '.join(missing_optional), C_OFF),
'\t vs. in the manifest: %s[%s]%s\n' % (C_RED, ', '.join(manifest_optional), C_OFF),
'\t- tags in the manifest (%s):\n' % path,
'\t\t%s\n' % '\t\t'.join(tags),
@@ -340,11 +354,14 @@
if args.enforce_uses_libraries:
# Load dexpreopt.config files and build a mapping from module
- # names to library names. This is necessary because build system
- # addresses libraries by their module name (`uses_libs`,
- # `optional_uses_libs`, `LOCAL_USES_LIBRARIES`,
- # `LOCAL_OPTIONAL_LIBRARY_NAMES` all contain module names), while
- # the manifest addresses libraries by their name.
+ # names to library names. This is for Make only and it's necessary
+ # because Make passes module names from `LOCAL_USES_LIBRARIES`,
+ # `LOCAL_OPTIONAL_LIBRARY_NAMES`, while the manifest addresses
+ # libraries by their name. Soong doesn't use it and doesn't need it
+ # because it converts the module names to the library names and
+ # passes the library names. There is no need to translate missing
+ # optional libs because they are missing and therefore there is no
+ # mapping for them.
mod_to_lib = load_dexpreopt_configs(args.dexpreopt_configs)
required = translate_libnames(args.uses_libraries, mod_to_lib)
optional = translate_libnames(args.optional_uses_libraries,
@@ -354,8 +371,8 @@
# those in the manifest. Raise an exception on mismatch, unless the
# script was passed a special parameter to suppress exceptions.
errmsg = enforce_uses_libraries(manifest, required, optional,
- args.enforce_uses_libraries_relax,
- is_apk, args.input)
+ args.missing_optional_uses_libraries,
+ args.enforce_uses_libraries_relax, is_apk, args.input)
# Create a status file that is empty on success, or contains an
# error message on failure. When exceptions are suppressed,
diff --git a/scripts/manifest_check_test.py b/scripts/manifest_check_test.py
index 3be7a30..8003b3e 100755
--- a/scripts/manifest_check_test.py
+++ b/scripts/manifest_check_test.py
@@ -44,15 +44,17 @@
class EnforceUsesLibrariesTest(unittest.TestCase):
"""Unit tests for add_extract_native_libs function."""
- def run_test(self, xml, apk, uses_libraries=[], optional_uses_libraries=[]): #pylint: disable=dangerous-default-value
+ def run_test(self, xml, apk, uses_libraries=[], optional_uses_libraries=[],
+ missing_optional_uses_libraries=[]): #pylint: disable=dangerous-default-value
doc = minidom.parseString(xml)
try:
relax = False
manifest_check.enforce_uses_libraries(
- doc, uses_libraries, optional_uses_libraries, relax, False,
- 'path/to/X/AndroidManifest.xml')
+ doc, uses_libraries, optional_uses_libraries, missing_optional_uses_libraries,
+ relax, False, 'path/to/X/AndroidManifest.xml')
manifest_check.enforce_uses_libraries(apk, uses_libraries,
optional_uses_libraries,
+ missing_optional_uses_libraries,
relax, True,
'path/to/X/X.apk')
return True
@@ -102,6 +104,15 @@
matches = self.run_test(xml, apk, optional_uses_libraries=['foo'])
self.assertFalse(matches)
+ def test_expected_missing_optional_uses_library(self):
+ xml = self.xml_tmpl % (
+ uses_library_xml('foo') + uses_library_xml('missing') + uses_library_xml('bar'))
+ apk = self.apk_tmpl % (
+ uses_library_apk('foo') + uses_library_apk('missing') + uses_library_apk('bar'))
+ matches = self.run_test(xml, apk, optional_uses_libraries=['foo', 'bar'],
+ missing_optional_uses_libraries=['missing'])
+ self.assertFalse(matches)
+
def test_missing_uses_library(self):
xml = self.xml_tmpl % ('')
apk = self.apk_tmpl % ('')
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 275860f..0a5483b 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -688,6 +688,12 @@
public: {
enabled: true,
},
+ system: {
+ enabled: true,
+ },
+ module_lib: {
+ enabled: true,
+ },
}
java_system_modules {
@@ -752,6 +758,20 @@
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
},
+ system: {
+ jars: ["sdk_library/system/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
+ current_api: "sdk_library/system/myjavalib.txt",
+ removed_api: "sdk_library/system/myjavalib-removed.txt",
+ sdk_version: "system_current",
+ },
+ module_lib: {
+ jars: ["sdk_library/module-lib/myjavalib-stubs.jar"],
+ stub_srcs: ["sdk_library/module-lib/myjavalib_stub_sources"],
+ current_api: "sdk_library/module-lib/myjavalib.txt",
+ removed_api: "sdk_library/module-lib/myjavalib-removed.txt",
+ sdk_version: "module_current",
+ },
}
java_system_modules_import {
@@ -771,6 +791,12 @@
.intermediates/myjavalib.stubs.exportable/android_common/combined/myjavalib.stubs.exportable.jar -> sdk_library/public/myjavalib-stubs.jar
.intermediates/myjavalib.stubs.source/android_common/exportable/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
.intermediates/myjavalib.stubs.source/android_common/exportable/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.exportable.system/android_common/combined/myjavalib.stubs.exportable.system.jar -> sdk_library/system/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source.system/android_common/exportable/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib.txt
+.intermediates/myjavalib.stubs.source.system/android_common/exportable/myjavalib.stubs.source.system_removed.txt -> sdk_library/system/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.exportable.module_lib/android_common/combined/myjavalib.stubs.exportable.module_lib.jar -> sdk_library/module-lib/myjavalib-stubs.jar
+.intermediates/myjavalib.stubs.source.module_lib/android_common/exportable/myjavalib.stubs.source.module_lib_api.txt -> sdk_library/module-lib/myjavalib.txt
+.intermediates/myjavalib.stubs.source.module_lib/android_common/exportable/myjavalib.stubs.source.module_lib_removed.txt -> sdk_library/module-lib/myjavalib-removed.txt
`),
checkInfoContents(result.Config, `
[
@@ -805,11 +831,23 @@
"@name": "myjavalib",
"dist_stem": "myjavalib",
"scopes": {
+ "module-lib": {
+ "current_api": "sdk_library/module-lib/myjavalib.txt",
+ "latest_api": "out/soong/.intermediates/prebuilts/sdk/myjavalib.api.module-lib.latest/gen/myjavalib.api.module-lib.latest",
+ "latest_removed_api": "out/soong/.intermediates/prebuilts/sdk/myjavalib-removed.api.module-lib.latest/gen/myjavalib-removed.api.module-lib.latest",
+ "removed_api": "sdk_library/module-lib/myjavalib-removed.txt"
+ },
"public": {
"current_api": "sdk_library/public/myjavalib.txt",
"latest_api": "out/soong/.intermediates/prebuilts/sdk/myjavalib.api.public.latest/gen/myjavalib.api.public.latest",
"latest_removed_api": "out/soong/.intermediates/prebuilts/sdk/myjavalib-removed.api.public.latest/gen/myjavalib-removed.api.public.latest",
"removed_api": "sdk_library/public/myjavalib-removed.txt"
+ },
+ "system": {
+ "current_api": "sdk_library/system/myjavalib.txt",
+ "latest_api": "out/soong/.intermediates/prebuilts/sdk/myjavalib.api.system.latest/gen/myjavalib.api.system.latest",
+ "latest_removed_api": "out/soong/.intermediates/prebuilts/sdk/myjavalib-removed.api.system.latest/gen/myjavalib-removed.api.system.latest",
+ "removed_api": "sdk_library/system/myjavalib-removed.txt"
}
}
},
diff --git a/sdk/update.go b/sdk/update.go
index b8ae38a..afecf9f 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -163,6 +163,20 @@
})
}
+// A denylist of modules whose host variants will be removed from the generated snapshots above the ApiLevel
+// even if they are listed in the corresponding `sdk`.
+// The key is the module name
+// The value is the _last_ dessert where the host variant of the module will be present
+// This is a workaround to ensure that these modules are generated in <=$ApiLevel, but not in in >=$ApiLevel
+var ignoreHostModuleVariantsAboveDessert = map[string]android.ApiLevel{
+ // ignore host variant of libdexfile and its transitive dependencies.
+ // The platform test that depends on them (`libunwindstack_unit_test` at the time of writing)
+ // no longer requires a prebuilt variant of libdexfile.
+ "libdexfile": android.ApiLevelUpsideDownCake,
+ "libartpalette": android.ApiLevelUpsideDownCake,
+ "libartbase": android.ApiLevelUpsideDownCake,
+}
+
// groupMemberVariantsByMemberThenType groups the member variant dependencies so that all the
// variants of each member are grouped together within an sdkMember instance.
//
@@ -181,6 +195,14 @@
variant := memberVariantDep.variant
name := ctx.OtherModuleName(variant)
+ targetApiLevel, err := android.ApiLevelFromUser(ctx, targetBuildRelease.name)
+ if err != nil {
+ targetApiLevel = android.FutureApiLevel
+ }
+ if lastApiLevel, exists := ignoreHostModuleVariantsAboveDessert[name]; exists && targetApiLevel.GreaterThan(lastApiLevel) && memberVariantDep.Host() {
+ // ignore host variant of this module if the targetApiLevel is V and above.
+ continue
+ }
member := byName[name]
if member == nil {
member = &sdkMember{memberType: memberType, name: name}
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 97adeed..3cbbc45 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -20,12 +20,12 @@
"strings"
"android/soong/testing"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
"android/soong/cc"
- "android/soong/snapshot"
"android/soong/tradefed"
)
@@ -535,5 +535,3 @@
}
var Bool = proptools.Bool
-
-var _ snapshot.RelativeInstallPath = (*ShBinary)(nil)
diff --git a/snapshot/Android.bp b/snapshot/Android.bp
index 3354993..6cb318e 100644
--- a/snapshot/Android.bp
+++ b/snapshot/Android.bp
@@ -16,15 +16,11 @@
srcs: [
"host_fake_snapshot.go",
"host_snapshot.go",
- "recovery_snapshot.go",
- "snapshot.go",
"snapshot_base.go",
"util.go",
- "vendor_snapshot.go",
],
testSrcs: [
"host_test.go",
- "test.go",
],
pluginFor: ["soong_build"],
}
diff --git a/snapshot/recovery_snapshot.go b/snapshot/recovery_snapshot.go
deleted file mode 100644
index ab114b4..0000000
--- a/snapshot/recovery_snapshot.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2021 The Android Open Source Project
-//
-// 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 snapshot
-
-import "android/soong/android"
-
-// Interface for modules which can be captured in the recovery snapshot.
-type RecoverySnapshotModuleInterface interface {
- SnapshotModuleInterfaceBase
- InRecovery() bool
- ExcludeFromRecoverySnapshot() bool
-}
-
-func RecoverySnapshotSingleton() android.Singleton {
- return &SnapshotSingleton{
- "recovery", // name
- "SOONG_RECOVERY_SNAPSHOT_ZIP", // makeVar
- android.OptionalPath{}, // snapshotZipFile
- RecoverySnapshotImageSingleton, // Image
- false, // Fake
- }
-}
-
-// Determine if a dir under source tree is an SoC-owned proprietary directory based
-// on recovery snapshot configuration
-// Examples: device/, vendor/
-func isRecoveryProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
- return RecoverySnapshotSingleton().(*SnapshotSingleton).Image.IsProprietaryPath(dir, deviceConfig)
-}
-
-func IsRecoveryProprietaryModule(ctx android.BaseModuleContext) bool {
-
- // Any module in a recovery proprietary path is a recovery proprietary
- // module.
- if isRecoveryProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) {
- return true
- }
-
- // However if the module is not in a recovery proprietary path, it may
- // still be a recovery proprietary module. This happens for cc modules
- // that are excluded from the recovery snapshot, and it means that the
- // vendor has assumed control of the framework-provided module.
-
- if c, ok := ctx.Module().(RecoverySnapshotModuleInterface); ok {
- if c.ExcludeFromRecoverySnapshot() {
- return true
- }
- }
-
- return false
-}
-
-var RecoverySnapshotImageName = "recovery"
-
-type RecoverySnapshotImage struct{}
-
-func (RecoverySnapshotImage) Init(ctx android.RegistrationContext) {
- ctx.RegisterParallelSingletonType("recovery-snapshot", RecoverySnapshotSingleton)
-}
-
-func (RecoverySnapshotImage) RegisterAdditionalModule(ctx android.RegistrationContext, name string, factory android.ModuleFactory) {
- ctx.RegisterModuleType(name, factory)
-}
-
-func (RecoverySnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
- // RECOVERY_SNAPSHOT_VERSION must be set to 'current' in order to generate a
- // snapshot.
- return ctx.DeviceConfig().RecoverySnapshotVersion() == "current"
-}
-
-func (RecoverySnapshotImage) InImage(m SnapshotModuleInterfaceBase) func() bool {
- r, ok := m.(RecoverySnapshotModuleInterface)
-
- if !ok {
- // This module does not support recovery snapshot
- return func() bool { return false }
- }
- return r.InRecovery
-}
-
-func (RecoverySnapshotImage) IsProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
- return isDirectoryExcluded(dir, deviceConfig.RecoverySnapshotDirsExcludedMap(), deviceConfig.RecoverySnapshotDirsIncludedMap())
-}
-
-func (RecoverySnapshotImage) ExcludeFromSnapshot(m SnapshotModuleInterfaceBase) bool {
- r, ok := m.(RecoverySnapshotModuleInterface)
-
- if !ok {
- // This module does not support recovery snapshot
- return true
- }
- return r.ExcludeFromRecoverySnapshot()
-}
-
-func (RecoverySnapshotImage) IsUsingSnapshot(cfg android.DeviceConfig) bool {
- recoverySnapshotVersion := cfg.RecoverySnapshotVersion()
- return recoverySnapshotVersion != "current" && recoverySnapshotVersion != ""
-}
-
-func (RecoverySnapshotImage) TargetSnapshotVersion(cfg android.DeviceConfig) string {
- return cfg.RecoverySnapshotVersion()
-}
-
-func (RecoverySnapshotImage) ExcludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
- // If we're using full snapshot, not directed snapshot, capture every module
- if !cfg.DirectedRecoverySnapshot() {
- return false
- }
- // Else, checks if name is in RECOVERY_SNAPSHOT_MODULES.
- return !cfg.RecoverySnapshotModules()[name]
-}
-
-func (RecoverySnapshotImage) ImageName() string {
- return RecoverySnapshotImageName
-}
-
-var RecoverySnapshotImageSingleton RecoverySnapshotImage
-
-func init() {
- RecoverySnapshotImageSingleton.Init(android.InitRegistrationContext)
-}
diff --git a/snapshot/snapshot.go b/snapshot/snapshot.go
deleted file mode 100644
index c95a537..0000000
--- a/snapshot/snapshot.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2021 The Android Open Source Project
-//
-// 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 snapshot
-
-import (
- "path/filepath"
- "sort"
-
- "android/soong/android"
-)
-
-// This file contains singletons to capture snapshots. This singleton will generate snapshot of each target
-// image, and capturing snapshot module will be delegated to each module which implements GenerateSnapshotAction
-// function and register with RegisterSnapshotAction.
-
-var pctx = android.NewPackageContext("android/soong/snapshot")
-
-func init() {
- pctx.Import("android/soong/android")
-}
-
-type SnapshotSingleton struct {
- // Name, e.g., "vendor", "recovery", "ramdisk".
- name string
-
- // Make variable that points to the snapshot file, e.g.,
- // "SOONG_RECOVERY_SNAPSHOT_ZIP".
- makeVar string
-
- // Path to the snapshot zip file.
- snapshotZipFile android.OptionalPath
-
- // Implementation of the image interface specific to the image
- // associated with this snapshot (e.g., specific to the vendor image,
- // recovery image, etc.).
- Image SnapshotImage
-
- // Whether this singleton is for fake snapshot or not.
- // Fake snapshot is a snapshot whose prebuilt binaries and headers are empty.
- // It is much faster to generate, and can be used to inspect dependencies.
- Fake bool
-}
-
-// The output files to be included in the snapshot.
-type SnapshotPaths struct {
- // All files to be included in the snapshot
- OutputFiles android.Paths
-
- // Notice files of the snapshot output files
- NoticeFiles android.Paths
-}
-
-// Interface of function to capture snapshot from each module
-// Returns snapshot ouputs and notice files.
-type GenerateSnapshotAction func(snapshot SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) SnapshotPaths
-
-var snapshotActionList []GenerateSnapshotAction
-
-// Register GenerateSnapshotAction function so it can be called while generating snapshot
-func RegisterSnapshotAction(x GenerateSnapshotAction) {
- snapshotActionList = append(snapshotActionList, x)
-}
-
-func (c *SnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
- if !c.Image.shouldGenerateSnapshot(ctx) {
- return
- }
-
- var snapshotOutputs android.Paths
-
- // Snapshot zipped artifacts will be captured under {SNAPSHOT_ARCH} directory
-
- snapshotDir := c.name + "-snapshot"
- if c.Fake {
- // If this is a fake snapshot singleton, place all files under fake/ subdirectory to avoid
- // collision with real snapshot files
- snapshotDir = filepath.Join("fake", snapshotDir)
- }
- snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
- noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
- installedNotices := make(map[string]bool)
-
- for _, f := range snapshotActionList {
- snapshotPaths := f(*c, ctx, snapshotArchDir)
- snapshotOutputs = append(snapshotOutputs, snapshotPaths.OutputFiles...)
- for _, notice := range snapshotPaths.NoticeFiles {
- if _, ok := installedNotices[notice.String()]; !ok {
- installedNotices[notice.String()] = true
- snapshotOutputs = append(snapshotOutputs, CopyFileRule(
- pctx, ctx, notice, filepath.Join(noticeDir, notice.String())))
- }
- }
- }
-
- // All artifacts are ready. Sort them to normalize ninja and then zip.
- sort.Slice(snapshotOutputs, func(i, j int) bool {
- return snapshotOutputs[i].String() < snapshotOutputs[j].String()
- })
-
- zipPath := android.PathForOutput(
- ctx,
- snapshotDir,
- c.name+"-"+ctx.Config().DeviceName()+".zip")
- zipRule := android.NewRuleBuilder(pctx, ctx)
-
- // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
- snapshotOutputList := android.PathForOutput(
- ctx,
- snapshotDir,
- c.name+"-"+ctx.Config().DeviceName()+"_list")
- rspFile := snapshotOutputList.ReplaceExtension(ctx, "rsp")
- zipRule.Command().
- Text("tr").
- FlagWithArg("-d ", "\\'").
- FlagWithRspFileInputList("< ", rspFile, snapshotOutputs).
- FlagWithOutput("> ", snapshotOutputList)
-
- zipRule.Temporary(snapshotOutputList)
-
- zipRule.Command().
- BuiltTool("soong_zip").
- FlagWithOutput("-o ", zipPath).
- FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
- FlagWithInput("-l ", snapshotOutputList)
-
- zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String())
- zipRule.DeleteTemporaryFiles()
- c.snapshotZipFile = android.OptionalPathForPath(zipPath)
-}
-
-func (c *SnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
- ctx.Strict(
- c.makeVar,
- c.snapshotZipFile.String())
-}
diff --git a/snapshot/snapshot_base.go b/snapshot/snapshot_base.go
index fb4ee0c..6bf3c87 100644
--- a/snapshot/snapshot_base.go
+++ b/snapshot/snapshot_base.go
@@ -15,92 +15,12 @@
import (
"android/soong/android"
- "path/filepath"
)
-// Interface for modules which can be captured in the snapshot.
-type SnapshotModuleInterfaceBase interface{}
+var pctx = android.NewPackageContext("android/soong/snapshot")
-// Defines the specifics of different images to which the snapshot process is applicable, e.g.,
-// vendor, recovery, ramdisk.
-type SnapshotImage interface {
- // Returns true if a snapshot should be generated for this image.
- shouldGenerateSnapshot(ctx android.SingletonContext) bool
-
- // Function that returns true if the module is included in this image.
- // Using a function return instead of a value to prevent early
- // evalution of a function that may be not be defined.
- InImage(m SnapshotModuleInterfaceBase) func() bool
-
- // Returns true if a dir under source tree is an SoC-owned proprietary
- // directory, such as device/, vendor/, etc.
- //
- // For a given snapshot (e.g., vendor, recovery, etc.) if
- // isProprietaryPath(dir, deviceConfig) returns true, then the module in dir
- // will be built from sources.
- IsProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool
-
- // Whether a given module has been explicitly excluded from the
- // snapshot, e.g., using the exclude_from_vendor_snapshot or
- // exclude_from_recovery_snapshot properties.
- ExcludeFromSnapshot(m SnapshotModuleInterfaceBase) bool
-
- // Returns true if the build is using a snapshot for this image.
- IsUsingSnapshot(cfg android.DeviceConfig) bool
-
- // Returns a version of which the snapshot should be used in this target.
- // This will only be meaningful when isUsingSnapshot is true.
- TargetSnapshotVersion(cfg android.DeviceConfig) string
-
- // Whether to exclude a given module from the directed snapshot or not.
- // If the makefile variable DIRECTED_{IMAGE}_SNAPSHOT is true, directed snapshot is turned on,
- // and only modules listed in {IMAGE}_SNAPSHOT_MODULES will be captured.
- ExcludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool
-
- // Returns target image name
- ImageName() string
-}
-
-type directoryMap map[string]bool
-
-var (
- // Modules under following directories are ignored. They are OEM's and vendor's
- // proprietary modules(device/, kernel/, vendor/, and hardware/).
- defaultDirectoryExcludedMap = directoryMap{
- "device": true,
- "hardware": true,
- "kernel": true,
- "vendor": true,
- }
-
- // Modules under following directories are included as they are in AOSP,
- // although hardware/ and kernel/ are normally for vendor's own.
- defaultDirectoryIncludedMap = directoryMap{
- "kernel/configs": true,
- "kernel/prebuilts": true,
- "kernel/tests": true,
- "hardware/interfaces": true,
- "hardware/libhardware": true,
- "hardware/libhardware_legacy": true,
- "hardware/ril": true,
- }
-)
-
-func isDirectoryExcluded(dir string, excludedMap directoryMap, includedMap directoryMap) bool {
- if dir == "." || dir == "/" {
- return false
- }
- if includedMap[dir] {
- return false
- } else if excludedMap[dir] {
- return true
- } else if defaultDirectoryIncludedMap[dir] {
- return false
- } else if defaultDirectoryExcludedMap[dir] {
- return true
- } else {
- return isDirectoryExcluded(filepath.Dir(dir), excludedMap, includedMap)
- }
+func init() {
+ pctx.Import("android/soong/android")
}
// This is to be saved as .json files, which is for development/vendor_snapshot/update.py.
diff --git a/snapshot/test.go b/snapshot/test.go
deleted file mode 100644
index 346af2b..0000000
--- a/snapshot/test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2021 The Android Open Source Project
-//
-// 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 snapshot
-
-import (
- "os"
- "testing"
-)
-
-func TestMain(m *testing.M) {
- os.Exit(m.Run())
-}
diff --git a/snapshot/vendor_snapshot.go b/snapshot/vendor_snapshot.go
deleted file mode 100644
index 3e5f546..0000000
--- a/snapshot/vendor_snapshot.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2021 The Android Open Source Project
-//
-// 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 snapshot
-
-import "android/soong/android"
-
-// Interface for modules which can be captured in the vendor snapshot.
-type VendorSnapshotModuleInterface interface {
- SnapshotModuleInterfaceBase
- InVendor() bool
- ExcludeFromVendorSnapshot() bool
-}
-
-func VendorSnapshotSingleton() android.Singleton {
- return &SnapshotSingleton{
- "vendor", // name
- "SOONG_VENDOR_SNAPSHOT_ZIP", // makeVar
- android.OptionalPath{}, // snapshotZipFile
- VendorSnapshotImageSingleton, // Image
- false, // Fake
- }
-}
-
-func VendorFakeSnapshotSingleton() android.Singleton {
- return &SnapshotSingleton{
- "vendor", // name
- "SOONG_VENDOR_FAKE_SNAPSHOT_ZIP", // makeVar
- android.OptionalPath{}, // snapshotZipFile
- VendorSnapshotImageSingleton, // Image
- true, // Fake
- }
-}
-
-// Determine if a dir under source tree is an SoC-owned proprietary directory based
-// on vendor snapshot configuration
-// Examples: device/, vendor/
-func isVendorProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
- return VendorSnapshotSingleton().(*SnapshotSingleton).Image.IsProprietaryPath(dir, deviceConfig)
-}
-
-func IsVendorProprietaryModule(ctx android.BaseModuleContext) bool {
- // Any module in a vendor proprietary path is a vendor proprietary
- // module.
- if isVendorProprietaryPath(ctx.ModuleDir(), ctx.DeviceConfig()) {
- return true
- }
-
- // However if the module is not in a vendor proprietary path, it may
- // still be a vendor proprietary module. This happens for cc modules
- // that are excluded from the vendor snapshot, and it means that the
- // vendor has assumed control of the framework-provided module.
- if c, ok := ctx.Module().(VendorSnapshotModuleInterface); ok {
- if c.ExcludeFromVendorSnapshot() {
- return true
- }
- }
-
- return false
-}
-
-var VendorSnapshotImageName = "vendor"
-
-type VendorSnapshotImage struct{}
-
-func (VendorSnapshotImage) Init(ctx android.RegistrationContext) {
- ctx.RegisterParallelSingletonType("vendor-snapshot", VendorSnapshotSingleton)
- ctx.RegisterParallelSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton)
-}
-
-func (VendorSnapshotImage) RegisterAdditionalModule(ctx android.RegistrationContext, name string, factory android.ModuleFactory) {
- ctx.RegisterModuleType(name, factory)
-}
-
-func (VendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
- // BOARD_VNDK_VERSION must be set to 'current' in order to generate a snapshot.
- return ctx.DeviceConfig().VndkVersion() == "current"
-}
-
-func (VendorSnapshotImage) InImage(m SnapshotModuleInterfaceBase) func() bool {
- v, ok := m.(VendorSnapshotModuleInterface)
-
- if !ok {
- // This module does not support Vendor snapshot
- return func() bool { return false }
- }
-
- return v.InVendor
-}
-
-func (VendorSnapshotImage) IsProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool {
- return isDirectoryExcluded(dir, deviceConfig.VendorSnapshotDirsExcludedMap(), deviceConfig.VendorSnapshotDirsIncludedMap())
-}
-
-func (VendorSnapshotImage) ExcludeFromSnapshot(m SnapshotModuleInterfaceBase) bool {
- v, ok := m.(VendorSnapshotModuleInterface)
-
- if !ok {
- // This module does not support Vendor snapshot
- return true
- }
-
- return v.ExcludeFromVendorSnapshot()
-}
-
-func (VendorSnapshotImage) IsUsingSnapshot(cfg android.DeviceConfig) bool {
- vndkVersion := cfg.VndkVersion()
- return vndkVersion != "current" && vndkVersion != ""
-}
-
-func (VendorSnapshotImage) TargetSnapshotVersion(cfg android.DeviceConfig) string {
- return cfg.VndkVersion()
-}
-
-// returns true iff a given module SHOULD BE EXCLUDED, false if included
-func (VendorSnapshotImage) ExcludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool {
- // If we're using full snapshot, not directed snapshot, capture every module
- if !cfg.DirectedVendorSnapshot() {
- return false
- }
- // Else, checks if name is in VENDOR_SNAPSHOT_MODULES.
- return !cfg.VendorSnapshotModules()[name]
-}
-
-func (VendorSnapshotImage) ImageName() string {
- return VendorSnapshotImageName
-}
-
-var VendorSnapshotImageSingleton VendorSnapshotImage
-
-func init() {
- VendorSnapshotImageSingleton.Init(android.InitRegistrationContext)
-}
diff --git a/soong_ui.bash b/soong_ui.bash
index 8e7cd19..7737880 100755
--- a/soong_ui.bash
+++ b/soong_ui.bash
@@ -35,6 +35,7 @@
soong_build_go soong_ui android/soong/cmd/soong_ui
soong_build_go mk2rbc android/soong/mk2rbc/mk2rbc
soong_build_go rbcrun rbcrun/rbcrun
+soong_build_go release-config android/soong/cmd/release_config/release_config
cd ${TOP}
exec "$(getoutdir)/soong_ui" "$@"
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index dfbbe7d..7d4e69d 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -134,8 +134,6 @@
PrepareForTestWithSyspropBuildComponents,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.DeviceSystemSdkVersions = []string{"28"}
- variables.DeviceVndkVersion = proptools.StringPtr("current")
- variables.Platform_vndk_version = proptools.StringPtr("29")
variables.DeviceCurrentApiLevelForVendorModules = proptools.StringPtr("28")
}),
java.FixtureWithPrebuiltApis(map[string][]string{
@@ -258,10 +256,10 @@
// Check for generated cc_library
for _, variant := range []string{
- "android_vendor.29_arm_armv7-a-neon_shared",
- "android_vendor.29_arm_armv7-a-neon_static",
- "android_vendor.29_arm64_armv8-a_shared",
- "android_vendor.29_arm64_armv8-a_static",
+ "android_vendor_arm_armv7-a-neon_shared",
+ "android_vendor_arm_armv7-a-neon_static",
+ "android_vendor_arm64_armv8-a_shared",
+ "android_vendor_arm64_armv8-a_static",
} {
result.ModuleForTests("libsysprop-platform", variant)
result.ModuleForTests("libsysprop-vendor", variant)
@@ -270,10 +268,10 @@
// product variant of vendor-owned sysprop_library
for _, variant := range []string{
- "android_product.29_arm_armv7-a-neon_shared",
- "android_product.29_arm_armv7-a-neon_static",
- "android_product.29_arm64_armv8-a_shared",
- "android_product.29_arm64_armv8-a_static",
+ "android_product_arm_armv7-a-neon_shared",
+ "android_product_arm_armv7-a-neon_static",
+ "android_product_arm64_armv8-a_shared",
+ "android_product_arm64_armv8-a_static",
} {
result.ModuleForTests("libsysprop-vendor-on-product", variant)
}
@@ -296,16 +294,16 @@
// Check for exported includes
coreVariant := "android_arm64_armv8-a_static"
- vendorVariant := "android_vendor.29_arm64_armv8-a_static"
- productVariant := "android_product.29_arm64_armv8-a_static"
+ vendorVariant := "android_vendor_arm64_armv8-a_static"
+ productVariant := "android_product_arm64_armv8-a_static"
platformInternalPath := "libsysprop-platform/android_arm64_armv8-a_static/gen/sysprop/include"
- platformPublicVendorPath := "libsysprop-platform/android_vendor.29_arm64_armv8-a_static/gen/sysprop/public/include"
+ platformPublicVendorPath := "libsysprop-platform/android_vendor_arm64_armv8-a_static/gen/sysprop/public/include"
- platformOnProductPath := "libsysprop-platform-on-product/android_product.29_arm64_armv8-a_static/gen/sysprop/public/include"
+ platformOnProductPath := "libsysprop-platform-on-product/android_product_arm64_armv8-a_static/gen/sysprop/public/include"
- vendorInternalPath := "libsysprop-vendor/android_vendor.29_arm64_armv8-a_static/gen/sysprop/include"
- vendorOnProductPath := "libsysprop-vendor-on-product/android_product.29_arm64_armv8-a_static/gen/sysprop/public/include"
+ vendorInternalPath := "libsysprop-vendor/android_vendor_arm64_armv8-a_static/gen/sysprop/include"
+ vendorOnProductPath := "libsysprop-vendor-on-product/android_product_arm64_armv8-a_static/gen/sysprop/public/include"
platformClient := result.ModuleForTests("cc-client-platform", coreVariant)
platformFlags := platformClient.Rule("cc").Args["cFlags"]
diff --git a/tests/androidmk_test.sh b/tests/androidmk_test.sh
index b81828b..aecc4e8 100755
--- a/tests/androidmk_test.sh
+++ b/tests/androidmk_test.sh
@@ -5,7 +5,7 @@
# How to run: bash path-to-script/androidmk_test.sh
# Tests of converting license functionality of the androidmk tool
REAL_TOP="$(readlink -f "$(dirname "$0")"/../../..)"
-"$REAL_TOP/build/soong/soong_ui.bash" --make-mode androidmk
+"$REAL_TOP/build/soong/soong_ui.bash" --make-mode TARGET_RELEASE=trunk_staging androidmk
source "$(dirname "$0")/lib.sh"
diff --git a/tests/apex_cc_module_arch_variant_tests.sh b/tests/apex_cc_module_arch_variant_tests.sh
deleted file mode 100755
index 1f5e003..0000000
--- a/tests/apex_cc_module_arch_variant_tests.sh
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/bin/bash
-
-# Copyright (C) 2022 The Android Open Source Project
-#
-# 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.
-
-set -uo pipefail
-
-# Integration test for verifying arch variant cflags set on cc modules included
-# in Bazel-built apexes in the real source tree.
-
-if [ ! -e "build/make/core/Makefile" ]; then
- echo "$0 must be run from the top of the Android source tree."
- exit 1
-fi
-
-############
-# Test Setup
-############
-
-OUTPUT_DIR="$(mktemp -d tmp.XXXXXX)"
-BAZEL_OUTPUT_DIR="$OUTPUT_DIR/bazel"
-
-export TARGET_PRODUCT="aosp_arm64"
-[ "$#" -ge 1 ] && export TARGET_PRODUCT="$1"
-ARCH_VARIANT_CFLAG="armv8-a"
-[ "$#" -ge 2 ] && ARCH_VARIANT_CFLAG="$2"
-CPU_VARIANT_CFLAG=""
-[ "$#" -ge 3 ] && CPU_VARIANT_CFLAG="$3"
-
-function call_bazel() {
- build/bazel/bin/bazel --output_base="$BAZEL_OUTPUT_DIR" $@
-}
-
-function cleanup {
- # call bazel clean because some bazel outputs don't have w bits.
- call_bazel clean
- rm -rf "${OUTPUT_DIR}"
-}
-trap cleanup EXIT
-
-######################
-# Run bp2build / Bazel
-######################
-build/soong/soong_ui.bash --make-mode BP2BUILD_VERBOSE=1 --skip-soong-tests bp2build
-
-# Number of CppCompile actions with arch variant flag
-actions_with_arch_variant_num=$(call_bazel aquery --config=bp2build --config=ci --config=android \
- 'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))' | grep -c \'-march=$ARCH_VARIANT_CFLAG\')
-
-# Number of all CppCompile actions
-all_cppcompile_actions_num=0
-aquery_summary=$(call_bazel aquery --config=bp2build --config=ci --config=android --output=summary \
- 'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))' \
- | egrep -o '.*opt-ST.*: ([0-9]+)$' \
- | cut -d: -f2 -)
-
-while read -r num;
-do
- all_cppcompile_actions_num=$(($all_cppcompile_actions_num + $num))
-done <<< "$aquery_summary"
-
-if [ $actions_with_arch_variant_num -eq $all_cppcompile_actions_num ]
-then
- echo "Pass: arch variant is set."
-else
- echo "Error: number of CppCompile actions with arch variant set: actual=$actions_with_arch_variant_num, expected=$all_cppcompile_actions_num"
- exit 1
-fi
-
-if [ $CPU_VARIANT_CFLAG ]
-then
- # Number of CppCompiler actions with cpu variant flag
- actions_with_cpu_variant_num=$(call_bazel aquery --config=bp2build --config=ci --config=android \
- 'mnemonic("CppCompile", deps(//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))' | grep -c "\-mcpu=$CPU_VARIANT_CFLAG")
-
- if [ $actions_with_cpu_variant_num -eq $all_cppcompile_actions_num ]
- then
- echo "Pass: cpu variant is set."
- else
- echo "Error: number of CppCompile actions with cpu variant set: actual=$actions_with_cpu_variant_num, expected=$all_cppcompile_actions_num"
- exit 1
- fi
-fi
diff --git a/tests/apex_comparison_tests.sh b/tests/apex_comparison_tests.sh
deleted file mode 100755
index 8893060..0000000
--- a/tests/apex_comparison_tests.sh
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/bin/bash
-
-# Copyright (C) 2022 The Android Open Source Project
-#
-# 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.
-
-set -euo pipefail
-
-# Soong/Bazel integration test for building unbundled apexes in the real source tree.
-#
-# These tests build artifacts from head and compares their contents.
-
-if [ ! -e "build/make/core/Makefile" ]; then
- echo "$0 must be run from the top of the Android source tree."
- exit 1
-fi
-
-############
-# Test Setup
-############
-
-OUTPUT_DIR="$(mktemp -d $(pwd)/tmp.XXXXXX)"
-SOONG_OUTPUT_DIR="$OUTPUT_DIR/soong"
-BAZEL_OUTPUT_DIR="$OUTPUT_DIR/bazel"
-
-export TARGET_PRODUCT="module_arm"
-[ "$#" -eq 1 ] && export TARGET_PRODUCT="$1"
-
-function call_bazel() {
- build/bazel/bin/bazel --output_base="$BAZEL_OUTPUT_DIR" $@
-}
-
-function cleanup {
- # call bazel clean because some bazel outputs don't have w bits.
- call_bazel clean
- rm -rf "${OUTPUT_DIR}"
-}
-
-function deapexer() {
- DEBUGFS_PATH="$(realpath $(call_bazel cquery --config=bp2build --config=linux_x86_64 --config=ci --output=files //external/e2fsprogs/debugfs))"
- call_bazel run --config=bp2build //system/apex/tools:deapexer -- --debugfs_path=$DEBUGFS_PATH $@
-}
-
-trap cleanup EXIT
-
-###########
-# Run Soong
-###########
-export UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true # don't rely on prebuilts
-export TARGET_BUILD_APPS="com.android.adbd com.android.tzdata build.bazel.examples.apex.minimal"
-packages/modules/common/build/build_unbundled_mainline_module.sh \
- --product "$TARGET_PRODUCT" \
- --dist_dir "$SOONG_OUTPUT_DIR"
-
-######################
-# Run bp2build / Bazel
-######################
-build/soong/soong_ui.bash --make-mode BP2BUILD_VERBOSE=1 --skip-soong-tests bp2build
-
-BAZEL_OUT="$(call_bazel info --config=bp2build output_path)"
-
-call_bazel build --config=bp2build --config=ci --config=android \
- //packages/modules/adb/apex:com.android.adbd \
- //system/timezone/apex:com.android.tzdata \
- //build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal
-BAZEL_ADBD="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files //packages/modules/adb/apex:com.android.adbd))"
-BAZEL_TZDATA="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files //system/timezone/apex:com.android.tzdata))"
-BAZEL_MINIMAL="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files //build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))"
-
-# # Build debugfs separately, as it's not a dep of apexer, but needs to be an explicit arg.
-call_bazel build --config=bp2build --config=linux_x86_64 //external/e2fsprogs/debugfs
-
-#######
-# Tests
-#######
-
-function compare_deapexer_list() {
- local BAZEL_APEX=$1; shift
- local APEX=$1; shift
-
- # Compare the outputs of `deapexer list`, which lists the contents of the apex filesystem image.
- local SOONG_APEX="$SOONG_OUTPUT_DIR/$APEX"
-
- local SOONG_LIST="$OUTPUT_DIR/soong.list"
- local BAZEL_LIST="$OUTPUT_DIR/bazel.list"
-
- deapexer list "$SOONG_APEX" > "$SOONG_LIST"
- deapexer list "$BAZEL_APEX" > "$BAZEL_LIST"
-
- if cmp -s "$SOONG_LIST" "$BAZEL_LIST"
- then
- echo "ok: $APEX"
- else
- echo "contents of $APEX are different between Soong and Bazel:"
- echo
- echo expected
- echo
- cat "$SOONG_LIST"
- echo
- echo got
- echo
- cat "$BAZEL_LIST"
- exit 1
- fi
-}
-
-compare_deapexer_list "${BAZEL_ADBD}" com.android.adbd.apex
-compare_deapexer_list "${BAZEL_TZDATA}" com.android.tzdata.apex
-compare_deapexer_list "${BAZEL_MINIMAL}" build.bazel.examples.apex.minimal.apex
diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh
index 5fc05f8..2e40950 100755
--- a/tests/bootstrap_test.sh
+++ b/tests/bootstrap_test.sh
@@ -9,6 +9,8 @@
readonly GENERATED_BUILD_FILE_NAME="BUILD.bazel"
+readonly target_product="${TARGET_PRODUCT:-aosp_arm}"
+
function test_smoke {
setup
run_soong
@@ -18,10 +20,10 @@
setup
run_soong
local -r bootstrap_mtime1=$(stat -c "%y" out/soong/bootstrap.ninja)
- local -r output_mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r output_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
run_soong
local -r bootstrap_mtime2=$(stat -c "%y" out/soong/bootstrap.ninja)
- local -r output_mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r output_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
if [[ "$bootstrap_mtime1" == "$bootstrap_mtime2" ]]; then
# Bootstrapping is always done. It doesn't take a measurable amount of time.
@@ -60,7 +62,7 @@
touch a/my_little_binary_host.py
run_soong
- grep -q "^# Module:.*my_little_binary_host" out/soong/build.ninja || fail "module not found"
+ grep -q "^# Module:.*my_little_binary_host" out/soong/build."${target_product}".ninja || fail "module not found"
cat > a/Android.bp <<'EOF'
python_binary_host {
@@ -71,14 +73,14 @@
touch a/my_great_binary_host.py
run_soong
- grep -q "^# Module:.*my_little_binary_host" out/soong/build.ninja && fail "old module found"
- grep -q "^# Module:.*my_great_binary_host" out/soong/build.ninja || fail "new module not found"
+ grep -q "^# Module:.*my_little_binary_host" out/soong/build."${target_product}".ninja && fail "old module found"
+ grep -q "^# Module:.*my_great_binary_host" out/soong/build."${target_product}".ninja || fail "new module not found"
}
function test_add_android_bp() {
setup
run_soong
- local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
mkdir -p a
cat > a/Android.bp <<'EOF'
@@ -90,12 +92,12 @@
touch a/my_little_binary_host.py
run_soong
- local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
if [[ "$mtime1" == "$mtime2" ]]; then
fail "Output Ninja file did not change"
fi
- grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja || fail "New module not in output"
+ grep -q "^# Module:.*my_little_binary_host$" out/soong/build."${target_product}".ninja || fail "New module not in output"
run_soong
}
@@ -112,12 +114,12 @@
touch a/my_little_binary_host.py
run_soong
- grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja || fail "Module not in output"
+ grep -q "^# Module:.*my_little_binary_host$" out/soong/build."${target_product}".ninja || fail "Module not in output"
rm a/Android.bp
run_soong
- if grep -q "^# Module:.*my_little_binary_host$" out/soong/build.ninja; then
+ if grep -q "^# Module:.*my_little_binary_host$" out/soong/build."${target_product}".ninja; then
fail "Old module in output"
fi
}
@@ -141,16 +143,12 @@
EOF
touch a/my_little_binary_host.py
run_soong
- local -r ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
- local glob_deps_file=out/soong/globs/build/0.d
-
- if [ -e "$glob_deps_file" ]; then
- fail "Glob deps file unexpectedly written on first build"
- fi
+ local glob_deps_file=out/soong/globs/"${target_product}"/0.d
run_soong
- local -r ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
# There is an ineffiencency in glob that requires bpglob to rerun once for each glob to update
# the entry in the .ninja_log. It doesn't update the output file, but we can detect the rerun
@@ -166,7 +164,7 @@
fi
run_soong
- local -r ninja_mtime3=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime3=$(stat -c "%y" out/soong/build."${target_product}".ninja)
local -r glob_deps_mtime3=$(stat -c "%y" "$glob_deps_file")
if [[ "$ninja_mtime2" != "$ninja_mtime3" ]]; then
@@ -191,17 +189,17 @@
EOF
touch a/my_little_binary_host.py
run_soong
- local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
touch a/my_little_library.py
run_soong
- local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
if [[ "$mtime1" == "$mtime2" ]]; then
fail "Output Ninja file did not change"
fi
- grep -q my_little_library.py out/soong/build.ninja || fail "new file is not in output"
+ grep -q my_little_library.py out/soong/build."${target_product}".ninja || fail "new file is not in output"
}
function test_soong_build_rerun_iff_environment_changes() {
@@ -267,17 +265,17 @@
export CHERRY=TASTY
run_soong
- grep -q "CHERRY IS TASTY" out/soong/build.ninja \
+ grep -q "CHERRY IS TASTY" out/soong/build."${target_product}".ninja \
|| fail "first value of environment variable is not used"
export CHERRY=RED
run_soong
- grep -q "CHERRY IS RED" out/soong/build.ninja \
+ grep -q "CHERRY IS RED" out/soong/build."${target_product}".ninja \
|| fail "second value of environment variable not used"
- local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
run_soong
- local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
if [[ "$mtime1" != "$mtime2" ]]; then
fail "Output Ninja file changed when environment variable did not"
fi
@@ -287,7 +285,7 @@
function test_create_global_include_directory() {
setup
run_soong
- local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
# Soong needs to know if top level directories like hardware/ exist for use
# as global include directories. Make sure that doesn't cause regens for
@@ -295,7 +293,7 @@
mkdir -p system/core
run_soong
- local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
if [[ "$mtime1" != "$mtime2" ]]; then
fail "Output Ninja file changed when top level directory changed"
fi
@@ -305,7 +303,7 @@
mkdir -p system/core/include
run_soong
- local -r mtime3=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime3=$(stat -c "%y" out/soong/build."${target_product}".ninja)
if [[ "$mtime2" = "$mtime3" ]]; then
fail "Output Ninja file did not change when global include directory created"
fi
@@ -315,7 +313,7 @@
function test_add_file_to_soong_build() {
setup
run_soong
- local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
mkdir -p vendor/foo/picard
cat > vendor/foo/picard/Android.bp <<'EOF'
@@ -377,12 +375,12 @@
EOF
run_soong
- local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
if [[ "$mtime1" == "$mtime2" ]]; then
fail "Output Ninja file did not change"
fi
- grep -q "Make it so" out/soong/build.ninja || fail "New action not present"
+ grep -q "Make it so" out/soong/build."${target_product}".ninja || fail "New action not present"
}
# Tests a glob in a build= statement in an Android.bp file, which is interpreted
@@ -455,9 +453,9 @@
EOF
run_soong
- local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
- grep -q "Make it so" out/soong/build.ninja || fail "Original action not present"
+ grep -q "Make it so" out/soong/build."${target_product}".ninja || fail "Original action not present"
cat > build/soong/picard/foob.bp <<'EOF'
bootstrap_go_package {
@@ -487,14 +485,14 @@
EOF
run_soong
- local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
if [[ "$mtime1" == "$mtime2" ]]; then
fail "Output Ninja file did not change"
fi
- grep -q "Engage" out/soong/build.ninja || fail "New action not present"
+ grep -q "Engage" out/soong/build."${target_product}".ninja || fail "New action not present"
- if grep -q "Make it so" out/soong/build.ninja; then
+ if grep -q "Make it so" out/soong/build."${target_product}".ninja; then
fail "Original action still present"
fi
}
@@ -512,7 +510,7 @@
setup
run_soong
- local -r ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
run_soong soong_docs
local -r docs_mtime1=$(stat -c "%y" out/soong/docs/soong_build.html)
@@ -525,7 +523,7 @@
fi
run_soong
- local -r ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then
fail "Output Ninja file changed on null build"
@@ -565,144 +563,6 @@
fi
}
-function test_bp2build_smoke {
- setup
- run_soong bp2build
- [[ -e out/soong/bp2build_workspace_marker ]] || fail "bp2build marker file not created"
- [[ -e out/soong/workspace ]] || fail "Bazel workspace not created"
-}
-
-function test_bp2build_generates_marker_file {
- setup
-
- run_soong bp2build
-
- if [[ ! -f "./out/soong/bp2build_files_marker" ]]; then
- fail "bp2build marker file was not generated"
- fi
-
- if [[ ! -f "./out/soong/bp2build_workspace_marker" ]]; then
- fail "symlink forest marker file was not generated"
- fi
-}
-
-function test_bp2build_add_irrelevant_file {
- setup
-
- mkdir -p a/b
- touch a/b/c.txt
- cat > a/b/Android.bp <<'EOF'
-filegroup {
- name: "c",
- srcs: ["c.txt"],
- bazel_module: { bp2build_available: true },
-}
-EOF
-
- run_soong bp2build
- if [[ ! -e out/soong/bp2build/a/b/BUILD.bazel ]]; then
- fail "BUILD file in symlink forest was not created";
- fi
-
- local -r mtime1=$(stat -c "%y" out/soong/bp2build/a/b/BUILD.bazel)
-
- touch a/irrelevant.txt
- run_soong bp2build
- local -r mtime2=$(stat -c "%y" out/soong/bp2build/a/b/BUILD.bazel)
-
- if [[ "$mtime1" != "$mtime2" ]]; then
- fail "BUILD.bazel file was regenerated"
- fi
-
- if [[ ! -e "out/soong/workspace/a/irrelevant.txt" ]]; then
- fail "New file was not symlinked into symlink forest"
- fi
-}
-
-function test_bp2build_add_android_bp {
- setup
-
- mkdir -p a
- touch a/a.txt
- cat > a/Android.bp <<'EOF'
-filegroup {
- name: "a",
- srcs: ["a.txt"],
- bazel_module: { bp2build_available: true },
-}
-EOF
-
- run_soong bp2build
- [[ -e out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not created"
- [[ -L out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not symlinked"
-
- mkdir -p b
- touch b/b.txt
- cat > b/Android.bp <<'EOF'
-filegroup {
- name: "b",
- srcs: ["b.txt"],
- bazel_module: { bp2build_available: true },
-}
-EOF
-
- run_soong bp2build
- [[ -e out/soong/bp2build/b/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not created"
- [[ -L out/soong/workspace/b/${GENERATED_BUILD_FILE_NAME} ]] || fail "a/${GENERATED_BUILD_FILE_NAME} not symlinked"
-}
-
-function test_bp2build_null_build {
- setup
-
- run_soong bp2build
- local -r mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
- run_soong bp2build
- local -r mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
- if [[ "$mtime1" != "$mtime2" ]]; then
- fail "Output Ninja file changed on null build"
- fi
-}
-
-function test_bp2build_add_to_glob {
- setup
-
- mkdir -p a
- touch a/a1.txt
- cat > a/Android.bp <<'EOF'
-filegroup {
- name: "a",
- srcs: ["*.txt"],
- bazel_module: { bp2build_available: true },
-}
-EOF
-
- run_soong bp2build
- grep -q a1.txt "out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME}" || fail "a1.txt not in ${GENERATED_BUILD_FILE_NAME} file"
-
- touch a/a2.txt
- run_soong bp2build
- grep -q a2.txt "out/soong/bp2build/a/${GENERATED_BUILD_FILE_NAME}" || fail "a2.txt not in ${GENERATED_BUILD_FILE_NAME} file"
-}
-
-function test_multiple_soong_build_modes() {
- setup
- run_soong json-module-graph bp2build nothing
- if [[ ! -f "out/soong/bp2build_workspace_marker" ]]; then
- fail "bp2build marker file was not generated"
- fi
-
-
- if [[ ! -f "out/soong/module-graph.json" ]]; then
- fail "JSON file was not created"
- fi
-
- if [[ ! -f "out/soong/build.ninja" ]]; then
- fail "Main build.ninja file was not created"
- fi
-}
-
function test_dump_json_module_graph() {
setup
run_soong json-module-graph
@@ -715,13 +575,13 @@
setup
run_soong
- local -r ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
run_soong json-module-graph
local -r json_mtime1=$(stat -c "%y" out/soong/module-graph.json)
run_soong
- local -r ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r ninja_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then
fail "Output Ninja file changed after writing JSON module graph"
fi
@@ -734,143 +594,6 @@
}
-function test_bp2build_bazel_workspace_structure {
- setup
-
- mkdir -p a/b
- touch a/a.txt
- touch a/b/b.txt
- cat > a/b/Android.bp <<'EOF'
-filegroup {
- name: "b",
- srcs: ["b.txt"],
- bazel_module: { bp2build_available: true },
-}
-EOF
-
- run_soong bp2build
- [[ -e out/soong/workspace ]] || fail "Bazel workspace not created"
- [[ -d out/soong/workspace/a/b ]] || fail "module directory not a directory"
- [[ -L "out/soong/workspace/a/b/${GENERATED_BUILD_FILE_NAME}" ]] || fail "${GENERATED_BUILD_FILE_NAME} file not symlinked"
- [[ "$(readlink -f out/soong/workspace/a/b/${GENERATED_BUILD_FILE_NAME})" =~ "bp2build/a/b/${GENERATED_BUILD_FILE_NAME}"$ ]] \
- || fail "BUILD files symlinked at the wrong place"
- [[ -L out/soong/workspace/a/b/b.txt ]] || fail "a/b/b.txt not symlinked"
- [[ -L out/soong/workspace/a/a.txt ]] || fail "a/b/a.txt not symlinked"
- [[ ! -e out/soong/workspace/out ]] || fail "out directory symlinked"
-}
-
-function test_bp2build_bazel_workspace_add_file {
- setup
-
- mkdir -p a
- touch a/a.txt
- cat > a/Android.bp <<EOF
-filegroup {
- name: "a",
- srcs: ["a.txt"],
- bazel_module: { bp2build_available: true },
-}
-EOF
-
- run_soong bp2build
-
- touch a/a2.txt # No reference in the .bp file needed
- run_soong bp2build
- [[ -L out/soong/workspace/a/a2.txt ]] || fail "a/a2.txt not symlinked"
-}
-
-function test_bp2build_build_file_precedence {
- setup
-
- mkdir -p a
- touch a/a.txt
- touch a/${GENERATED_BUILD_FILE_NAME}
- cat > a/Android.bp <<EOF
-filegroup {
- name: "a",
- srcs: ["a.txt"],
- bazel_module: { bp2build_available: true },
-}
-EOF
-
- run_soong bp2build
- [[ -L "out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME}" ]] || fail "${GENERATED_BUILD_FILE_NAME} file not symlinked"
- [[ "$(readlink -f out/soong/workspace/a/${GENERATED_BUILD_FILE_NAME})" =~ "bp2build/a/${GENERATED_BUILD_FILE_NAME}"$ ]] \
- || fail "${GENERATED_BUILD_FILE_NAME} files symlinked to the wrong place"
-}
-
-function test_bp2build_fails_fast {
- setup
-
- mkdir -p "a/${GENERATED_BUILD_FILE_NAME}"
- cat > a/Android.bp <<EOF
-filegroup {
- name: "a",
- srcs: ["a.txt"],
- bazel_module: { bp2build_available: true },
-}
-EOF
-
- mkdir -p "b/${GENERATED_BUILD_FILE_NAME}"
- cat > b/Android.bp <<EOF
-filegroup {
- name: "b",
- srcs: ["b.txt"],
- bazel_module: { bp2build_available: true },
-}
-EOF
-
- if run_soong bp2build >& "$MOCK_TOP/errors"; then
- fail "Build should have failed"
- fi
-
- # we should expect at least one error
- grep -q -E "(a|b)/${GENERATED_BUILD_FILE_NAME}' exist" "$MOCK_TOP/errors" || fail "Error for ${GENERATED_BUILD_FILE_NAME} not found"
-}
-
-function test_bp2build_back_and_forth_null_build {
- setup
-
- run_soong
- local -r output_mtime1=$(stat -c "%y" out/soong/build.ninja)
-
- run_soong bp2build
- local -r output_mtime2=$(stat -c "%y" out/soong/build.ninja)
- if [[ "$output_mtime1" != "$output_mtime2" ]]; then
- fail "Output Ninja file changed when switching to bp2build"
- fi
-
- local -r marker_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
- run_soong
- local -r output_mtime3=$(stat -c "%y" out/soong/build.ninja)
- local -r marker_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
- if [[ "$output_mtime1" != "$output_mtime3" ]]; then
- fail "Output Ninja file changed when switching to regular build from bp2build"
- fi
- if [[ "$marker_mtime1" != "$marker_mtime2" ]]; then
- fail "bp2build marker file changed when switching to regular build from bp2build"
- fi
-
- run_soong bp2build
- local -r output_mtime4=$(stat -c "%y" out/soong/build.ninja)
- local -r marker_mtime3=$(stat -c "%y" out/soong/bp2build_workspace_marker)
- if [[ "$output_mtime1" != "$output_mtime4" ]]; then
- fail "Output Ninja file changed when switching back to bp2build"
- fi
- if [[ "$marker_mtime1" != "$marker_mtime3" ]]; then
- fail "bp2build marker file changed when switching back to bp2build"
- fi
-}
-
-function test_queryview_smoke() {
- setup
-
- run_soong queryview
- [[ -e out/soong/queryview/WORKSPACE ]] || fail "queryview WORKSPACE file not created"
-
-}
-
function test_queryview_null_build() {
setup
@@ -886,14 +609,14 @@
}
# This test verifies that adding a new glob to a blueprint file only
-# causes build.ninja to be regenerated on the *next* build, and *not*
+# causes build."${target_product}".ninja to be regenerated on the *next* build, and *not*
# the build after. (This is a regression test for a bug where globs
# resulted in two successive regenerations.)
function test_new_glob_incrementality {
setup
run_soong nothing
- local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
mkdir -p globdefpkg/
cat > globdefpkg/Android.bp <<'EOF'
@@ -904,14 +627,14 @@
EOF
run_soong nothing
- local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
if [[ "$mtime1" == "$mtime2" ]]; then
fail "Ninja file was not regenerated, despite a new bp file"
fi
run_soong nothing
- local -r mtime3=$(stat -c "%y" out/soong/build.ninja)
+ local -r mtime3=$(stat -c "%y" out/soong/build."${target_product}".ninja)
if [[ "$mtime2" != "$mtime3" ]]; then
fail "Ninja file was regenerated despite no previous bp changes"
diff --git a/tests/bp2build_bazel_test.sh b/tests/bp2build_bazel_test.sh
deleted file mode 100755
index 8a64a56..0000000
--- a/tests/bp2build_bazel_test.sh
+++ /dev/null
@@ -1,445 +0,0 @@
-#!/bin/bash -eu
-
-set -o pipefail
-
-# Test that bp2build and Bazel can play nicely together
-
-source "$(dirname "$0")/lib.sh"
-
-readonly GENERATED_BUILD_FILE_NAME="BUILD.bazel"
-
-function test_bp2build_null_build {
- setup
- run_soong bp2build
- local -r output_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
- run_soong bp2build
- local -r output_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
- if [[ "$output_mtime1" != "$output_mtime2" ]]; then
- fail "Output bp2build marker file changed on null build"
- fi
-}
-
-# Tests that, if bp2build reruns due to a blueprint file changing, that
-# BUILD files whose contents are unchanged are not regenerated.
-function test_bp2build_unchanged {
- setup
-
- mkdir -p pkg
- touch pkg/x.txt
- cat > pkg/Android.bp <<'EOF'
-filegroup {
- name: "x",
- srcs: ["x.txt"],
- bazel_module: {bp2build_available: true},
- }
-EOF
-
- run_soong bp2build
- local -r buildfile_mtime1=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
- local -r marker_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
- # Force bp2build to rerun by updating the timestamp of a blueprint file.
- touch pkg/Android.bp
-
- run_soong bp2build
- local -r buildfile_mtime2=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
- local -r marker_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
- if [[ "$marker_mtime1" == "$marker_mtime2" ]]; then
- fail "Expected bp2build marker file to change"
- fi
- if [[ "$buildfile_mtime1" != "$buildfile_mtime2" ]]; then
- fail "BUILD.bazel was updated even though contents are same"
- fi
-
- # Force bp2build to rerun by updating the timestamp of the constants_exported_to_soong.bzl file.
- touch build/bazel/constants_exported_to_soong.bzl
-
- run_soong bp2build
- local -r buildfile_mtime3=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
- local -r marker_mtime3=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
- if [[ "$marker_mtime2" == "$marker_mtime3" ]]; then
- fail "Expected bp2build marker file to change"
- fi
- if [[ "$buildfile_mtime2" != "$buildfile_mtime3" ]]; then
- fail "BUILD.bazel was updated even though contents are same"
- fi
-}
-
-# Tests that blueprint files that are deleted are not present when the
-# bp2build tree is regenerated.
-function test_bp2build_deleted_blueprint {
- setup
-
- mkdir -p pkg
- touch pkg/x.txt
- cat > pkg/Android.bp <<'EOF'
-filegroup {
- name: "x",
- srcs: ["x.txt"],
- bazel_module: {bp2build_available: true},
- }
-EOF
-
- run_soong bp2build
- if [[ ! -e "./out/soong/bp2build/pkg/BUILD.bazel" ]]; then
- fail "Expected pkg/BUILD.bazel to be generated"
- fi
-
- rm pkg/Android.bp
-
- run_soong bp2build
- if [[ -e "./out/soong/bp2build/pkg/BUILD.bazel" ]]; then
- fail "Expected pkg/BUILD.bazel to be deleted"
- fi
-}
-
-function test_bp2build_null_build_with_globs {
- setup
-
- mkdir -p foo/bar
- cat > foo/bar/Android.bp <<'EOF'
-filegroup {
- name: "globs",
- srcs: ["*.txt"],
- }
-EOF
- touch foo/bar/a.txt foo/bar/b.txt
-
- run_soong bp2build
- local -r output_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
- run_soong bp2build
- local -r output_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
-
- if [[ "$output_mtime1" != "$output_mtime2" ]]; then
- fail "Output bp2build marker file changed on null build"
- fi
-}
-
-function test_different_relative_outdir {
- setup
-
- mkdir -p a
- touch a/g.txt
- cat > a/Android.bp <<'EOF'
-filegroup {
- name: "g",
- srcs: ["g.txt"],
- bazel_module: {bp2build_available: true},
- }
-EOF
-
- # A directory under $MOCK_TOP
- outdir=out2
- trap "rm -rf $outdir" EXIT
- # Modify OUT_DIR in a subshell so it doesn't affect the top level one.
- (export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
-}
-
-function test_different_absolute_outdir {
- setup
-
- mkdir -p a
- touch a/g.txt
- cat > a/Android.bp <<'EOF'
-filegroup {
- name: "g",
- srcs: ["g.txt"],
- bazel_module: {bp2build_available: true},
- }
-EOF
-
- # A directory under /tmp/...
- outdir=$(mktemp -t -d st.XXXXX)
- trap 'rm -rf $outdir' EXIT
- # Modify OUT_DIR in a subshell so it doesn't affect the top level one.
- (export OUT_DIR=$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
-}
-
-function _bp2build_generates_all_buildfiles {
- setup
-
- mkdir -p foo/convertible_soong_module
- cat > foo/convertible_soong_module/Android.bp <<'EOF'
-genrule {
- name: "the_answer",
- cmd: "echo '42' > $(out)",
- out: [
- "the_answer.txt",
- ],
- bazel_module: {
- bp2build_available: true,
- },
- }
-EOF
-
- mkdir -p foo/unconvertible_soong_module
- cat > foo/unconvertible_soong_module/Android.bp <<'EOF'
-genrule {
- name: "not_the_answer",
- cmd: "echo '43' > $(out)",
- out: [
- "not_the_answer.txt",
- ],
- bazel_module: {
- bp2build_available: false,
- },
- }
-EOF
-
- run_soong bp2build
-
- if [[ ! -f "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME}" ]]; then
- fail "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME} was not generated"
- fi
-
- if [[ ! -f "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}" ]]; then
- fail "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME} was not generated"
- fi
-
- if ! grep "the_answer" "./out/soong/workspace/foo/convertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
- fail "missing BUILD target the_answer in convertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
- fi
-
- if grep "not_the_answer" "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
- fail "found unexpected BUILD target not_the_answer in unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
- fi
-
- if ! grep "filegroup" "./out/soong/workspace/foo/unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"; then
- fail "missing filegroup in unconvertible_soong_module/${GENERATED_BUILD_FILE_NAME}"
- fi
-
- # NOTE: We don't actually use the extra BUILD file for anything here
- run_bazel build --config=android --config=bp2build --config=ci //foo/...
-
- local -r the_answer_file="$(find -L bazel-out -name the_answer.txt)"
- if [[ ! -f "${the_answer_file}" ]]; then
- fail "Expected the_answer.txt to be generated, but was missing"
- fi
- if ! grep 42 "${the_answer_file}"; then
- fail "Expected to find 42 in '${the_answer_file}'"
- fi
-}
-
-function test_bp2build_generates_all_buildfiles {
- _save_trap=$(trap -p EXIT)
- trap '[[ $? -ne 0 ]] && echo Are you running this locally? Try changing --sandbox_tmpfs_path to something other than /tmp/ in build/bazel/linux.bazelrc.' EXIT
- _bp2build_generates_all_buildfiles
- eval "${_save_trap}"
-}
-
-function test_build_files_take_precedence {
- _save_trap=$(trap -p EXIT)
- trap '[[ $? -ne 0 ]] && echo Are you running this locally? Try changing --sandbox_tmpfs_path to something other than /tmp/ in build/bazel/linux.bazelrc.' EXIT
- _build_files_take_precedence
- eval "${_save_trap}"
-}
-
-function _build_files_take_precedence {
- setup
-
- # This specific directory is hardcoded in bp2build as being one
- # where the BUILD file should be intentionally kept.
- mkdir -p testpkg/keep_build_file
- cat > testpkg/keep_build_file/Android.bp <<'EOF'
-genrule {
- name: "print_origin",
- cmd: "echo 'from_soong' > $(out)",
- out: [
- "origin.txt",
- ],
- bazel_module: {
- bp2build_available: true,
- },
- }
-EOF
-
- run_soong bp2build
- run_bazel build --config=android --config=bp2build --config=ci //testpkg/keep_build_file:print_origin
-
- local -r output_file="$(find -L bazel-out -name origin.txt)"
- if [[ ! -f "${output_file}" ]]; then
- fail "Expected origin.txt to be generated, but was missing"
- fi
- if ! grep from_soong "${output_file}"; then
- fail "Expected to find 'from_soong' in '${output_file}'"
- fi
-
- cat > testpkg/keep_build_file/BUILD.bazel <<'EOF'
-genrule(
- name = "print_origin",
- outs = ["origin.txt"],
- cmd = "echo 'from_bazel' > $@",
-)
-EOF
-
- # Clean the workspace. There is a test infrastructure bug where run_bazel
- # will symlink Android.bp files in the source directory again and thus
- # pollute the workspace.
- # TODO: b/286059878 - Remove this clean after the underlying bug is fixed.
- run_soong clean
- run_soong bp2build
- run_bazel build --config=android --config=bp2build --config=ci //testpkg/keep_build_file:print_origin
- if ! grep from_bazel "${output_file}"; then
- fail "Expected to find 'from_bazel' in '${output_file}'"
- fi
-}
-
-function test_bp2build_symlinks_files {
- setup
- mkdir -p foo
- touch foo/BLANK1
- touch foo/BLANK2
- touch foo/F2D
- touch foo/BUILD
-
- run_soong bp2build
-
- if [[ -e "./out/soong/workspace/foo/BUILD" ]]; then
- fail "./out/soong/workspace/foo/BUILD should be omitted"
- fi
- for file in BLANK1 BLANK2 F2D
- do
- if [[ ! -L "./out/soong/workspace/foo/$file" ]]; then
- fail "./out/soong/workspace/foo/$file should exist"
- fi
- done
- local -r BLANK1_BEFORE=$(stat -c %y "./out/soong/workspace/foo/BLANK1")
-
- rm foo/BLANK2
- rm foo/F2D
- mkdir foo/F2D
- touch foo/F2D/BUILD
-
- run_soong bp2build
-
- if [[ -e "./out/soong/workspace/foo/BUILD" ]]; then
- fail "./out/soong/workspace/foo/BUILD should be omitted"
- fi
- local -r BLANK1_AFTER=$(stat -c %y "./out/soong/workspace/foo/BLANK1")
- if [[ "$BLANK1_AFTER" != "$BLANK1_BEFORE" ]]; then
- fail "./out/soong/workspace/foo/BLANK1 should be untouched"
- fi
- if [[ -e "./out/soong/workspace/foo/BLANK2" ]]; then
- fail "./out/soong/workspace/foo/BLANK2 should be removed"
- fi
- if [[ -L "./out/soong/workspace/foo/F2D" ]] || [[ ! -d "./out/soong/workspace/foo/F2D" ]]; then
- fail "./out/soong/workspace/foo/F2D should be a dir"
- fi
-}
-
-function test_cc_correctness {
- setup
-
- mkdir -p a
- cat > a/Android.bp <<EOF
-cc_object {
- name: "qq",
- srcs: ["qq.cc"],
- bazel_module: {
- bp2build_available: true,
- },
- stl: "none",
- system_shared_libs: [],
-}
-EOF
-
- cat > a/qq.cc <<EOF
-#include "qq.h"
-int qq() {
- return QQ;
-}
-EOF
-
- cat > a/qq.h <<EOF
-#define QQ 1
-EOF
-
- run_soong bp2build
-
- run_bazel build --config=android --config=bp2build --config=ci //a:qq
- local -r output_mtime1=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
-
- run_bazel build --config=android --config=bp2build --config=ci //a:qq
- local -r output_mtime2=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
-
- if [[ "$output_mtime1" != "$output_mtime2" ]]; then
- fail "output changed on null build"
- fi
-
- cat > a/qq.h <<EOF
-#define QQ 2
-EOF
-
- run_bazel build --config=android --config=bp2build --config=ci //a:qq
- local -r output_mtime3=$(stat -c "%y" bazel-bin/a/_objs/qq/qq.o)
-
- if [[ "$output_mtime1" == "$output_mtime3" ]]; then
- fail "output not changed when included header changed"
- fi
-}
-
-# Regression test for the following failure during symlink forest creation:
-#
-# Cannot stat '/tmp/st.rr054/foo/bar/unresolved_symlink': stat /tmp/st.rr054/foo/bar/unresolved_symlink: no such file or directory
-#
-function test_bp2build_null_build_with_unresolved_symlink_in_source() {
- setup
-
- mkdir -p foo/bar
- ln -s /tmp/non-existent foo/bar/unresolved_symlink
- cat > foo/bar/Android.bp <<'EOF'
-filegroup {
- name: "fg",
- srcs: ["unresolved_symlink/non-existent-file.txt"],
- }
-EOF
-
- run_soong bp2build
-
- dest=$(readlink -f out/soong/workspace/foo/bar/unresolved_symlink)
- if [[ "$dest" != "/tmp/non-existent" ]]; then
- fail "expected to plant an unresolved symlink out/soong/workspace/foo/bar/unresolved_symlink that resolves to /tmp/non-existent"
- fi
-}
-
-function test_bazel_standalone_output_paths_contain_product_name {
- setup
- mkdir -p a
- cat > a/Android.bp <<EOF
-cc_object {
- name: "qq",
- srcs: ["qq.cc"],
- bazel_module: {
- bp2build_available: true,
- },
- stl: "none",
- system_shared_libs: [],
-}
-EOF
-
- cat > a/qq.cc <<EOF
-#include "qq.h"
-int qq() {
- return QQ;
-}
-EOF
-
- cat > a/qq.h <<EOF
-#define QQ 1
-EOF
-
- export TARGET_PRODUCT=aosp_arm; run_soong bp2build
- local -r output=$(run_bazel cquery //a:qq --output=files --config=android --config=bp2build --config=ci)
- if [[ ! $(echo ${output} | grep "bazel-out/aosp_arm") ]]; then
- fail "Did not find the product name '${TARGET_PRODUCT}' in the output path. This can cause " \
- "unnecessary rebuilds when toggling between products as bazel outputs for different products will " \
- "clobber each other. Output paths are: \n${output}"
- fi
-}
-
-scan_and_run_tests
diff --git a/tests/dcla_apex_comparison_test.sh b/tests/dcla_apex_comparison_test.sh
deleted file mode 100755
index e3c189f..0000000
--- a/tests/dcla_apex_comparison_test.sh
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/bin/bash
-
-# Copyright (C) 2023 The Android Open Source Project
-#
-# 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.
-
-set -euo pipefail
-
-# Soong/Bazel integration test to build the mainline modules in mixed build and
-# compare the DCLA libs extracted from those modules to ensure they are identical.
-
-if [ ! -e "build/make/core/Makefile" ]; then
- echo "$0 must be run from the top of the Android source tree."
- exit 1
-fi
-
-TARGET_PRODUCTS=(
- module_arm64
- module_x86_64
-)
-
-MODULES=(
- # These modules depend on the DCLA libs
- com.android.adbd
- com.android.art
- com.android.art.debug
- com.android.art.testing
- com.android.btservices
- com.android.conscrypt
- com.android.i18n
- com.android.media
- com.android.media.swcodec
- com.android.resolv
- com.android.runtime
- com.android.tethering
-)
-
-BAZEL_TARGETS=(
- //packages/modules/adb/apex:com.android.adbd
- //frameworks/av/apex:com.android.media.swcodec
-)
-
-DCLA_LIBS=(
- libbase.so
- libc++.so
- libcrypto.so
- libcutils.so
- libstagefright_flacdec.so
- libutils.so
-)
-
-if [[ -z ${OUT_DIR+x} ]]; then
- OUT_DIR="out"
-fi
-
-if [[ -z ${ANDROID_HOST_OUT+x} ]]; then
- export ANDROID_HOST_OUT="out/host/linux-x86"
-fi
-
-######################
-# Build deapexer and debugfs
-######################
-DEAPEXER="${ANDROID_HOST_OUT}/bin/deapexer"
-DEBUGFS="${ANDROID_HOST_OUT}/bin/debugfs"
-if [[ ! -f "${DEAPEXER}" ]] || [[ ! -f "${DEBUGFS}" ]]; then
- build/soong/soong_ui.bash --make-mode --skip-soong-tests deapexer debugfs
-fi
-
-DEAPEXER="${DEAPEXER} --debugfs_path=${DEBUGFS}"
-
-############
-# Test Setup
-############
-OUTPUT_DIR="$(mktemp -d tmp.XXXXXX)"
-
-function call_bazel() {
- build/bazel/bin/bazel $@
-}
-
-function cleanup {
- rm -rf "${OUTPUT_DIR}"
-}
-trap cleanup EXIT
-
-#######
-# Tests
-#######
-
-function extract_dcla_libs() {
- local product=$1; shift
- local modules=("$@"); shift
-
- for module in "${modules[@]}"; do
- local apex="${OUTPUT_DIR}/${product}/${module}.apex"
- local extract_dir="${OUTPUT_DIR}/${product}/${module}/extract"
-
- $DEAPEXER extract "${apex}" "${extract_dir}"
- done
-}
-
-function compare_dcla_libs() {
- local product=$1; shift
- local modules=("$@"); shift
-
- for lib in "${DCLA_LIBS[@]}"; do
- for arch in lib lib64; do
- local prev_sha=""
- for module in "${modules[@]}"; do
- local file="${OUTPUT_DIR}/${product}/${module}/extract/${arch}/${lib}"
- if [[ ! -f "${file}" ]]; then
- # not all libs are present in a module
- echo "file doesn't exist: ${file}"
- continue
- fi
- sha=$(sha1sum ${file})
- sha="${sha% *}"
- if [ "${prev_sha}" == "" ]; then
- prev_sha="${sha}"
- elif [ "${sha}" != "${prev_sha}" ] && { [ "${lib}" != "libcrypto.so" ] || [[ "${module}" != *"com.android.tethering" ]]; }; then
- echo "Test failed, ${lib} has different hash value"
- exit 1
- fi
- done
- done
- done
-}
-
-export UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true # don't rely on prebuilts
-export TARGET_BUILD_APPS="${MODULES[@]}"
-for product in "${TARGET_PRODUCTS[@]}"; do
- ###########
- # Build the mainline modules
- ###########
- packages/modules/common/build/build_unbundled_mainline_module.sh \
- --product "${product}" \
- --dist_dir "${OUTPUT_DIR}/${product}"
-
- bazel_apexes=()
- if [[ -n ${TEST_BAZEL+x} ]] && [ "${TEST_BAZEL}" = true ]; then
- export TARGET_PRODUCT="${product/module/aosp}"
- call_bazel build --config=bp2build --config=ci --config=android "${BAZEL_TARGETS[@]}"
- for target in "${BAZEL_TARGETS[@]}"; do
- apex_path="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files $target))"
- mkdir -p ${OUTPUT_DIR}/${product}
- bazel_apex="bazel_$(basename $apex_path)"
- mv $apex_path ${OUTPUT_DIR}/${product}/${bazel_apex}
- bazel_apexes+=(${bazel_apex%".apex"})
- done
- fi
-
- all_modeuls=(${MODULES[@]} ${bazel_apexes[@]})
- extract_dcla_libs "${product}" "${all_modeuls[@]}"
- compare_dcla_libs "${product}" "${all_modeuls[@]}"
-done
-
-echo "Test passed"
diff --git a/tests/lib.sh b/tests/lib.sh
index e0b319e..4c320d0 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -140,7 +140,7 @@
# shellcheck disable=SC2120
function run_soong {
- USE_RBE=false build/soong/soong_ui.bash --make-mode --skip-ninja --skip-config --soong-only --skip-soong-tests "$@"
+ USE_RBE=false TARGET_PRODUCT=aosp_arm TARGET_RELEASE=trunk_staging TARGET_BUILD_VARIANT=userdebug build/soong/soong_ui.bash --make-mode --skip-ninja --skip-config --soong-only --skip-soong-tests "$@"
}
function create_mock_bazel {
diff --git a/tests/mixed_mode_test.sh b/tests/mixed_mode_test.sh
deleted file mode 100755
index ca63fdf..0000000
--- a/tests/mixed_mode_test.sh
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/bin/bash
-
-set -o pipefail
-
-# This test exercises mixed builds where Soong and Bazel cooperate in building
-# Android.
-#
-# When the execroot is deleted, the Bazel server process will automatically
-# terminate itself.
-
-source "$(dirname "$0")/lib.sh"
-
-function test_bazel_smoke {
- setup
-
- run_soong bp2build
-
- run_bazel info --config=bp2build
-}
-
-function test_add_irrelevant_file {
- setup
-
- mkdir -p soong_tests/a/b
- touch soong_tests/a/b/c.txt
- cat > soong_tests/a/b/Android.bp <<'EOF'
-filegroup {
- name: "c",
- srcs: ["c.txt"],
- bazel_module: { bp2build_available: true },
-}
-EOF
-
- run_soong --bazel-mode-staging nothing
-
- if [[ ! -e out/soong/bp2build/soong_tests/a/b/BUILD.bazel ]]; then
- fail "BUILD.bazel not created"
- fi
-
- if [[ ! -e out/soong/build.ninja ]]; then
- fail "build.ninja not created"
- fi
-
- local mtime_build1=$(stat -c "%y" out/soong/bp2build/soong_tests/a/b/BUILD.bazel)
- local mtime_ninja1=$(stat -c "%y" out/soong/build.ninja)
-
- touch soong_tests/a/irrelevant.txt
-
- run_soong --bazel-mode-staging nothing
- local mtime_build2=$(stat -c "%y" out/soong/bp2build/soong_tests/a/b/BUILD.bazel)
- local mtime_ninja2=$(stat -c "%y" out/soong/build.ninja)
-
- if [[ "$mtime_build1" != "$mtime_build2" ]]; then
- fail "BUILD.bazel was generated"
- fi
-
- if [[ "$mtime_ninja1" != "$mtime_ninja2" ]]; then
- fail "build.ninja was regenerated"
- fi
-
- if [[ ! -e out/soong/workspace/soong_tests/a/irrelevant.txt ]]; then
- fail "new file was not symlinked"
- fi
-}
-
-function test_force_enabled_modules {
- setup
- # b/273910287 - test force enable modules
- mkdir -p soong_tests/a/b
- cat > soong_tests/a/b/Android.bp <<'EOF'
-genrule {
- name: "touch-file",
- out: ["fake-out.txt"],
- cmd: "touch $(out)",
- bazel_module: { bp2build_available: true },
-}
-
-genrule {
- name: "unenabled-touch-file",
- out: ["fake-out2.txt"],
- cmd: "touch $(out)",
- bazel_module: { bp2build_available: false },
-}
-EOF
- run_soong --bazel-mode-staging --bazel-force-enabled-modules=touch-file nothing
- local bazel_contained=`grep out/soong/.intermediates/soong_tests/a/b/touch-file/gen/fake-out.txt out/soong/build.ninja`
- if [[ $bazel_contained == '' ]]; then
- fail "Bazel actions not found for force-enabled module"
- fi
-
- unused=`run_soong --bazel-force-enabled-modules=unenabled-touch-file --ensure-allowlist-integrity nothing >/dev/null`
-
- if [[ $? -ne 1 ]]; then
- fail "Expected failure due to force-enabling an unenabled module "
- fi
-}
-
-
-scan_and_run_tests
diff --git a/tests/persistent_bazel_test.sh b/tests/persistent_bazel_test.sh
deleted file mode 100755
index 9b7b58f..0000000
--- a/tests/persistent_bazel_test.sh
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/bin/bash -eu
-
-# Copyright (C) 2023 The Android Open Source Project
-#
-# 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.
-
-set -o pipefail
-
-source "$(dirname "$0")/lib.sh"
-
-# This test verifies that adding USE_PERSISTENT_BAZEL creates a Bazel process
-# that outlasts the build process.
-# This test should only be run in sandboxed environments (because this test
-# verifies a Bazel process using global process list, and may spawn lingering
-# Bazel processes).
-function test_persistent_bazel {
- setup
-
- # Ensure no existing Bazel process.
- if [[ -e out/bazel/output/server/server.pid.txt ]]; then
- kill $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null || true
- if kill -0 $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null ; then
- fail "Error killing pre-setup bazel"
- fi
- fi
-
- USE_PERSISTENT_BAZEL=1 run_soong nothing
-
- if ! kill -0 $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null ; then
- fail "Persistent bazel process expected, but not found after first build"
- fi
- BAZEL_PID=$(cat out/bazel/output/server/server.pid.txt)
-
- USE_PERSISTENT_BAZEL=1 run_soong nothing
-
- if ! kill -0 $BAZEL_PID 2>/dev/null ; then
- fail "Bazel pid $BAZEL_PID was killed after second build"
- fi
-
- kill $BAZEL_PID 2>/dev/null
- if ! kill -0 $BAZEL_PID 2>/dev/null ; then
- fail "Error killing bazel on shutdown"
- fi
-}
-
-# Verifies that USE_PERSISTENT_BAZEL mode operates as expected in the event
-# that there are Bazel failures.
-function test_bazel_failure {
- setup
-
- # Ensure no existing Bazel process.
- if [[ -e out/bazel/output/server/server.pid.txt ]]; then
- kill $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null || true
- if kill -0 $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null ; then
- fail "Error killing pre-setup bazel"
- fi
- fi
-
- # Introduce a syntax error in a BUILD file which is used in every build
- # (Note this is a BUILD file which is copied as part of test setup, so this
- # has no effect on sources outside of this test.
- rm -rf build/bazel/rules
-
- USE_PERSISTENT_BAZEL=1 run_soong nothing 1>out/failurelog.txt 2>&1 && fail "Expected build failure" || true
-
- if ! grep -sq "cannot load //build/bazel/rules/common/api_constants.bzl" out/failurelog.txt ; then
- fail "Expected error to contain 'cannot load //build/bazel/rules/common/api_constants.bzl', instead got:\n$(cat out/failurelog.txt)"
- fi
-
- kill $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null || true
-}
-
-scan_and_run_tests
diff --git a/tests/run_integration_tests.sh b/tests/run_integration_tests.sh
index 231e18b..0235f2b 100755
--- a/tests/run_integration_tests.sh
+++ b/tests/run_integration_tests.sh
@@ -4,25 +4,6 @@
TOP="$(readlink -f "$(dirname "$0")"/../../..)"
"$TOP/build/soong/tests/androidmk_test.sh"
-"$TOP/build/soong/tests/b_args_test.sh"
"$TOP/build/soong/tests/bootstrap_test.sh"
-"$TOP/build/soong/tests/mixed_mode_test.sh"
-"$TOP/build/soong/tests/bp2build_bazel_test.sh"
-"$TOP/build/soong/tests/persistent_bazel_test.sh"
"$TOP/build/soong/tests/soong_test.sh"
-"$TOP/build/soong/tests/stale_metrics_files_test.sh"
-"$TOP/build/soong/tests/symlink_forest_rerun_test.sh"
"$TOP/prebuilts/build-tools/linux-x86/bin/py3-cmd" "$TOP/build/bazel/ci/rbc_dashboard.py" aosp_arm64-userdebug
-
-# The following tests build against the full source tree and don't rely on the
-# mock client.
-"$TOP/build/soong/tests/apex_comparison_tests.sh"
-"$TOP/build/soong/tests/apex_comparison_tests.sh" "module_arm64only"
-TEST_BAZEL=true extra_build_params=--bazel-mode-staging "$TOP/build/soong/tests/dcla_apex_comparison_test.sh"
-#BUILD_BROKEN_DISABLE_BAZEL=true "$TOP/build/soong/tests/dcla_apex_comparison_test.sh"
-"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh"
-"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_arm" "armv7-a"
-"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_cf_arm64_phone" "armv8-a" "cortex-a53"
-
-"$TOP/build/bazel/ci/b_test.sh"
-"$TOP/build/soong/tests/symlinks_path_test.sh"
diff --git a/tests/stale_metrics_files_test.sh b/tests/stale_metrics_files_test.sh
deleted file mode 100755
index 0da89c3..0000000
--- a/tests/stale_metrics_files_test.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash -e
-
-# This test ensures that stale metrics files are deleted after each run
-
-# Run bazel
-# Note - bp2build metrics are present after clean runs, only
-build/soong/soong_ui.bash --make-mode clean
-build/bazel/bin/b build libcore:all
-soong_build_metrics_files=("out/soong_build_metrics.pb" "out/build_progress.pb" "out/soong_metrics" "out/bp2build_metrics.pb")
-bazel_build_metrics_files=("out/bazel_metrics.pb" "out/build_progress.pb" "out/soong_metrics" "out/bp2build_metrics.pb")
-
-# Ensure bazel metrics files are present
-for i in ${!bazel_build_metrics_files[@]};
-do
- file=${bazel_build_metrics_files[$i]}
- if [[ ! -f $file ]]; then
- echo "Missing metrics file for Bazel build " $file
- exit 1
- fi
-done
-
-
-# Run a soong build
-build/soong/soong_ui.bash --make-mode nothing
-
-for i in ${!soong_build_metrics_files[@]};
-do
- file=${soong_build_metrics_files[$i]}
- if [[ ! -f $file ]]; then
- echo "Missing metrics file for Soong build " $file
- exit 1
- fi
-done
-
-# Ensure that bazel_metrics.pb is deleted
-if [[ -f out/bazel_metrics.pb ]]; then
- echo "Stale out/bazel_metrics.pb file detected"
- exit 1
-fi
-
-# Run bazel again - to make sure that soong_build_metrics.pb gets deleted
-build/bazel/bin/b build libcore:all
-
-if [[ -f out/soong_build_metrics.pb ]]; then
- echo "Stale out/soong_build_metrics.pb file detected"
- exit 1
-fi
diff --git a/tests/symlink_forest_rerun_test.sh b/tests/symlink_forest_rerun_test.sh
deleted file mode 100755
index 74e779e..0000000
--- a/tests/symlink_forest_rerun_test.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash -eu
-
-set -o pipefail
-
-# Tests that symlink forest will replant if soong_build has changed
-# Any change to the build system should trigger a rerun
-
-source "$(dirname "$0")/lib.sh"
-
-function test_symlink_forest_reruns {
- setup
-
- mkdir -p a
- touch a/g.txt
- cat > a/Android.bp <<'EOF'
-filegroup {
- name: "g",
- srcs: ["g.txt"],
- }
-EOF
-
- run_soong g
-
- mtime=`cat out/soong/workspace/soong_build_mtime`
- # rerun with no changes - ensure that it hasn't changed
- run_soong g
- newmtime=`cat out/soong/workspace/soong_build_mtime`
- if [[ ! "$mtime" == "$mtime" ]]; then
- fail "symlink forest reran when it shouldn't have"
- fi
-
- # change exit codes to force a soong_build rebuild.
- sed -i 's/os.Exit(1)/os.Exit(2)/g' build/soong/bp2build/symlink_forest.go
-
- run_soong g
- newmtime=`cat out/soong/workspace/soong_build_mtime`
- if [[ "$mtime" == "$newmtime" ]]; then
- fail "symlink forest did not rerun when it should have"
- fi
-
-}
-
-scan_and_run_tests
diff --git a/tests/symlinks_path_test.sh b/tests/symlinks_path_test.sh
deleted file mode 100755
index ed42911..0000000
--- a/tests/symlinks_path_test.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/bash -eu
-
-set -o pipefail
-
-# Test that relative symlinks work by recreating the bug in b/259191764
-# In some cases, developers prefer to move their checkouts. This causes
-# issues in that symlinked files (namely, the bazel wrapper script)
-# cannot be found. As such, we implemented relative symlinks so that a
-# moved checkout doesn't need a full clean before rebuilding.
-# The bazel output base will still need to be removed, as Starlark
-# doesn't seem to support relative symlinks yet.
-
-source "$(dirname "$0")/lib.sh"
-
-function check_link_has_mock_top_prefix {
- input_link=$1
- link_target=`readlink $input_link`
- if [[ $link_target != "$MOCK_TOP"* ]]; then
- echo "Symlink for file $input_link -> $link_target doesn't start with $MOCK_TOP"
- exit 1
- fi
-}
-
-function test_symlinks_updated_when_top_dir_changed {
- setup
-
- mkdir -p a
- touch a/g.txt
- cat > a/Android.bp <<'EOF'
-filegroup {
- name: "g",
- srcs: ["g.txt"],
- bazel_module: {bp2build_available: true},
-}
-EOF
- # A directory under $MOCK_TOP
- outdir=out2
-
- # Modify OUT_DIR in a subshell so it doesn't affect the top level one.
- (export OUT_DIR=$MOCK_TOP/$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
-
- g_txt="out2/soong/workspace/a/g.txt"
- check_link_has_mock_top_prefix "$g_txt"
-
- move_mock_top
-
- (export OUT_DIR=$MOCK_TOP/$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
- check_link_has_mock_top_prefix "$g_txt"
-}
-
-scan_and_run_tests
\ No newline at end of file
diff --git a/tradefed/providers.go b/tradefed/providers.go
index f41e09e..66cb625 100644
--- a/tradefed/providers.go
+++ b/tradefed/providers.go
@@ -16,6 +16,11 @@
TestConfig android.Path
// Other modules we require to be installed to run tests. We expect base to build them.
HostRequiredModuleNames []string
+ RequiredModuleNames []string
+ // List of test suites base uses.
+ TestSuites []string
+ // Used for bases that are Host
+ IsHost bool
}
var BaseTestProviderKey = blueprint.NewProvider[BaseTestProviderData]()
diff --git a/tradefed_modules/test_module_config.go b/tradefed_modules/test_module_config.go
index ba6ab94..9127f67 100644
--- a/tradefed_modules/test_module_config.go
+++ b/tradefed_modules/test_module_config.go
@@ -17,6 +17,7 @@
// Register the license_kind module type.
func RegisterTestModuleConfigBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("test_module_config", TestModuleConfigFactory)
+ ctx.RegisterModuleType("test_module_config_host", TestModuleConfigHostFactory)
}
type testModuleConfigModule struct {
@@ -32,6 +33,12 @@
provider tradefed.BaseTestProviderData
}
+// Host is mostly the same as non-host, just some diffs for AddDependency and
+// AndroidMkEntries, but the properties are the same.
+type testModuleConfigHostModule struct {
+ testModuleConfigModule
+}
+
// Properties to list in Android.bp for this module.
type tradefedProperties struct {
// Module name of the base test that we will run.
@@ -68,8 +75,9 @@
}
var (
- testModuleConfigTag = dependencyTag{name: "TestModuleConfigBase"}
- pctx = android.NewPackageContext("android/soong/tradefed_modules")
+ testModuleConfigTag = dependencyTag{name: "TestModuleConfigBase"}
+ testModuleConfigHostTag = dependencyTag{name: "TestModuleConfigHostBase"}
+ pctx = android.NewPackageContext("android/soong/tradefed_modules")
)
func (m *testModuleConfigModule) InstallInTestcases() bool {
@@ -77,6 +85,10 @@
}
func (m *testModuleConfigModule) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if m.Base == nil {
+ ctx.ModuleErrorf("'base' field must be set to a 'android_test' module.")
+ return
+ }
ctx.AddDependency(ctx.Module(), testModuleConfigTag, *m.Base)
}
@@ -143,35 +155,41 @@
//
// If we change to symlinks, this all needs to change.
func (m *testModuleConfigModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ m.validateBase(ctx, &testModuleConfigTag, "android_test", false)
+ m.generateManifestAndConfig(ctx)
- ctx.VisitDirectDepsWithTag(testModuleConfigTag, func(dep android.Module) {
- if provider, ok := android.OtherModuleProvider(ctx, dep, tradefed.BaseTestProviderKey); ok {
- m.base = dep
- m.provider = provider
- } else {
- ctx.ModuleErrorf("The base module '%s' does not provide test BaseTestProviderData. Only 'android_test' modules are supported.", dep.Name())
- return
+}
+
+// Any test suites in base should not be repeated in the derived class, except "general-tests".
+// We may restrict derived tests to only be "general-tests" as it doesn't make sense to add a slice
+// of a test to compatibility suite.
+//
+// Returns ErrorMessage, false on problems
+// Returns _, true if okay.
+func (m *testModuleConfigModule) validateTestSuites(ctx android.ModuleContext) bool {
+ if len(m.tradefedProperties.Test_suites) == 0 {
+ ctx.ModuleErrorf("At least one test-suite must be set or this won't run. Use \"general-tests\"")
+ return false
+ }
+
+ derivedSuites := make(map[string]bool)
+ // See if any suites in base is also in derived (other than general-tests)
+ for _, s := range m.tradefedProperties.Test_suites {
+ if s != "general-tests" {
+ derivedSuites[s] = true
}
- })
+ }
+ if len(derivedSuites) == 0 {
+ return true
+ }
+ for _, baseSuite := range m.provider.TestSuites {
+ if derivedSuites[baseSuite] {
+ ctx.ModuleErrorf("TestSuite %s exists in the base, do not add it here", baseSuite)
+ return false
+ }
+ }
- // 1) A manifest file listing the base.
- installDir := android.PathForModuleInstall(ctx, ctx.ModuleName())
- out := android.PathForModuleOut(ctx, "test_module_config.manifest")
- android.WriteFileRule(ctx, out, fmt.Sprintf("{%q: %q}", "base", *m.tradefedProperties.Base))
- ctx.InstallFile(installDir, out.Base(), out)
-
- // 2) Module.config / AndroidTest.xml
- // Note, there is still a "test-tag" element with base's module name, but
- // Tradefed team says its ignored anyway.
- m.testConfig = m.fixTestConfig(ctx, m.provider.TestConfig)
-
- // 3) Write ARCH/Module.apk in testcases.
- // Handled by soong_app_prebuilt and OutputFile in entries.
- // Nothing to do here.
-
- // 4) Copy base's data files.
- // Handled by soong_app_prebuilt and LOCAL_COMPATIBILITY_SUPPORT_FILES.
- // Nothing to do here.
+ return true
}
func TestModuleConfigFactory() android.Module {
@@ -184,6 +202,16 @@
return module
}
+func TestModuleConfigHostFactory() android.Module {
+ module := &testModuleConfigHostModule{}
+
+ module.AddProperties(&module.tradefedProperties)
+ android.InitAndroidMultiTargetsArchModule(module, android.HostSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
+
+ return module
+}
+
// Implements android.AndroidMkEntriesProvider
var _ android.AndroidMkEntriesProvider = (*testModuleConfigModule)(nil)
@@ -198,22 +226,102 @@
// Out update config file with extra options.
entries.SetPath("LOCAL_FULL_TEST_CONFIG", m.testConfig)
entries.SetString("LOCAL_MODULE_TAGS", "tests")
- // Required for atest to run additional tradefed testtypes
- entries.AddStrings("LOCAL_HOST_REQUIRED_MODULES", m.provider.HostRequiredModuleNames...)
-
- // Clear the JNI symbols because they belong to base not us. Either transform the names in the string
- // or clear the variable because we don't need it, we are copying bases libraries not generating
- // new ones.
- entries.SetString("LOCAL_SOONG_JNI_LIBS_SYMBOLS", "")
// Don't append to base's test-suites, only use the ones we define, so clear it before
// appending to it.
entries.SetString("LOCAL_COMPATIBILITY_SUITE", "")
- if len(m.tradefedProperties.Test_suites) > 0 {
- entries.AddCompatibilityTestSuites(m.tradefedProperties.Test_suites...)
- } else {
- entries.AddCompatibilityTestSuites("null-suite")
+ entries.AddCompatibilityTestSuites(m.tradefedProperties.Test_suites...)
+
+ if len(m.provider.HostRequiredModuleNames) > 0 {
+ entries.AddStrings("LOCAL_HOST_REQUIRED_MODULES", m.provider.HostRequiredModuleNames...)
+ }
+ if len(m.provider.RequiredModuleNames) > 0 {
+ entries.AddStrings("LOCAL_REQUIRED_MODULES", m.provider.RequiredModuleNames...)
+ }
+
+ if m.provider.IsHost == false {
+ // Not needed for jar_host_test
+ //
+ // Clear the JNI symbols because they belong to base not us. Either transform the names in the string
+ // or clear the variable because we don't need it, we are copying bases libraries not generating
+ // new ones.
+ entries.SetString("LOCAL_SOONG_JNI_LIBS_SYMBOLS", "")
}
})
return entriesList
}
+
+func (m *testModuleConfigHostModule) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if m.Base == nil {
+ ctx.ModuleErrorf("'base' field must be set to a 'java_test_host' module")
+ return
+ }
+ ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), testModuleConfigHostTag, *m.Base)
+}
+
+// File to write:
+// 1) out/host/linux-x86/testcases/derived-module/test_module_config.manifest # contains base's name.
+// 2) out/host/linux-x86/testcases/derived-module/derived-module.config # Update AnroidTest.xml
+// 3) out/host/linux-x86/testcases/derived-module/base.jar
+// - written via soong_java_prebuilt.mk
+//
+// 4) out/host/linux-x86/testcases/derived-module/* # data dependencies from base.
+// - written via soong_java_prebuilt.mk
+func (m *testModuleConfigHostModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ m.validateBase(ctx, &testModuleConfigHostTag, "java_test_host", true)
+ m.generateManifestAndConfig(ctx)
+}
+
+// Ensure the base listed is the right type by checking that we get the expected provider data.
+// Returns false on errors and the context is updated with an error indicating the baseType expected.
+func (m *testModuleConfigModule) validateBase(ctx android.ModuleContext, depTag *dependencyTag, baseType string, baseShouldBeHost bool) {
+ ctx.VisitDirectDepsWithTag(*depTag, func(dep android.Module) {
+ if provider, ok := android.OtherModuleProvider(ctx, dep, tradefed.BaseTestProviderKey); ok {
+ if baseShouldBeHost == provider.IsHost {
+ m.base = dep
+ m.provider = provider
+ } else {
+ if baseShouldBeHost {
+ ctx.ModuleErrorf("'android_test' module used as base, but 'java_test_host' expected.")
+ } else {
+ ctx.ModuleErrorf("'java_test_host' module used as base, but 'android_test' expected.")
+ }
+ }
+ } else {
+ ctx.ModuleErrorf("'%s' module used as base but it is not a '%s' module.", *m.Base, baseType)
+ }
+ })
+}
+
+// Actions to write:
+// 1. manifest file to testcases dir
+// 2. New Module.config / AndroidTest.xml file with our options.
+func (m *testModuleConfigModule) generateManifestAndConfig(ctx android.ModuleContext) {
+ // Keep before early returns.
+ android.SetProvider(ctx, android.TestOnlyProviderKey, android.TestModuleInformation{
+ TestOnly: true,
+ TopLevelTarget: true,
+ })
+
+ if !m.validateTestSuites(ctx) {
+ return
+ }
+ // Ensure the base provider is accurate
+ if m.provider.TestConfig == nil {
+ return
+ }
+
+ // 1) A manifest file listing the base, write text to a tiny file.
+ installDir := android.PathForModuleInstall(ctx, ctx.ModuleName())
+ manifest := android.PathForModuleOut(ctx, "test_module_config.manifest")
+ android.WriteFileRule(ctx, manifest, fmt.Sprintf("{%q: %q}", "base", *m.tradefedProperties.Base))
+ // build/soong/android/androidmk.go has this comment:
+ // Assume the primary install file is last
+ // so we need to Install our file last.
+ ctx.InstallFile(installDir, manifest.Base(), manifest)
+
+ // 2) Module.config / AndroidTest.xml
+ m.testConfig = m.fixTestConfig(ctx, m.provider.TestConfig)
+}
+
+var _ android.AndroidMkEntriesProvider = (*testModuleConfigHostModule)(nil)
diff --git a/tradefed_modules/test_module_config_test.go b/tradefed_modules/test_module_config_test.go
index ff53043..6997228 100644
--- a/tradefed_modules/test_module_config_test.go
+++ b/tradefed_modules/test_module_config_test.go
@@ -16,8 +16,11 @@
import (
"android/soong/android"
"android/soong/java"
+ "strconv"
"strings"
"testing"
+
+ "github.com/google/blueprint"
)
const bp = `
@@ -43,6 +46,7 @@
base: "base",
exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
include_annotations: ["android.platform.test.annotations.LargeTest"],
+ test_suites: ["general-tests"],
}
`
@@ -92,7 +96,7 @@
}
// Ensure we error for a base we don't support.
-func TestModuleConfigBadBaseShouldFail(t *testing.T) {
+func TestModuleConfigWithHostBaseShouldFailWithExplicitMessage(t *testing.T) {
badBp := `
java_test_host {
name: "base",
@@ -104,16 +108,60 @@
base: "base",
exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
include_annotations: ["android.platform.test.annotations.LargeTest"],
+ test_suites: ["general-tests"],
}`
- ctx := android.GroupFixturePreparers(
+ android.GroupFixturePreparers(
java.PrepareForTestWithJavaDefaultModules,
android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
).ExtendWithErrorHandler(
- android.FixtureExpectsAtLeastOneErrorMatchingPattern("does not provide test BaseTestProviderData")).
+ android.FixtureExpectsAtLeastOneErrorMatchingPattern("'java_test_host' module used as base, but 'android_test' expected")).
RunTestWithBp(t, badBp)
+}
- ctx.ModuleForTests("derived_test", "android_common")
+func TestModuleConfigBadBaseShouldFailWithGeneralMessage(t *testing.T) {
+ badBp := `
+ java_library {
+ name: "base",
+ srcs: ["a.java"],
+ }
+
+ test_module_config {
+ name: "derived_test",
+ base: "base",
+ exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
+ include_annotations: ["android.platform.test.annotations.LargeTest"],
+ test_suites: ["general-tests"],
+ }`
+
+ android.GroupFixturePreparers(
+ java.PrepareForTestWithJavaDefaultModules,
+ android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
+ ).ExtendWithErrorHandler(
+ android.FixtureExpectsOneErrorPattern("'base' module used as base but it is not a 'android_test' module.")).
+ RunTestWithBp(t, badBp)
+}
+
+func TestModuleConfigNoBaseShouldFail(t *testing.T) {
+ badBp := `
+ java_library {
+ name: "base",
+ srcs: ["a.java"],
+ }
+
+ test_module_config {
+ name: "derived_test",
+ exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
+ include_annotations: ["android.platform.test.annotations.LargeTest"],
+ test_suites: ["general-tests"],
+ }`
+
+ android.GroupFixturePreparers(
+ java.PrepareForTestWithJavaDefaultModules,
+ android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
+ ).ExtendWithErrorHandler(
+ android.FixtureExpectsOneErrorPattern("'base' field must be set to a 'android_test' module.")).
+ RunTestWithBp(t, badBp)
}
// Ensure we error for a base we don't support.
@@ -128,6 +176,7 @@
test_module_config {
name: "derived_test",
base: "base",
+ test_suites: ["general-tests"],
}`
ctx := android.GroupFixturePreparers(
@@ -152,12 +201,14 @@
name: "derived_test",
base: "base",
include_annotations: ["android.platform.test.annotations.LargeTest"],
+ test_suites: ["general-tests"],
}
test_module_config {
name: "another_derived_test",
base: "base",
include_annotations: ["android.platform.test.annotations.LargeTest"],
+ test_suites: ["general-tests"],
}`
ctx := android.GroupFixturePreparers(
@@ -190,6 +241,175 @@
}
}
+// Test_module_config_host rule is allowed to depend on java_test_host
+func TestModuleConfigHostBasics(t *testing.T) {
+ bp := `
+ java_test_host {
+ name: "base",
+ srcs: ["a.java"],
+ test_suites: ["suiteA", "general-tests", "suiteB"],
+ }
+
+ test_module_config_host {
+ name: "derived_test",
+ base: "base",
+ exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
+ include_annotations: ["android.platform.test.annotations.LargeTest"],
+ test_suites: ["general-tests"],
+ }`
+
+ ctx := android.GroupFixturePreparers(
+ java.PrepareForTestWithJavaDefaultModules,
+ android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
+ ).RunTestWithBp(t, bp)
+
+ variant := ctx.Config.BuildOS.String() + "_common"
+ derived := ctx.ModuleForTests("derived_test", variant)
+ mod := derived.Module().(*testModuleConfigHostModule)
+ allEntries := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)
+ entries := allEntries[0]
+ android.AssertArrayString(t, "", entries.EntryMap["LOCAL_MODULE"], []string{"derived_test"})
+
+ if !mod.Host() {
+ t.Errorf("host bit is not set for a java_test_host module.")
+ }
+ actualData, _ := strconv.ParseBool(entries.EntryMap["LOCAL_IS_UNIT_TEST"][0])
+ android.AssertBoolEquals(t, "LOCAL_IS_UNIT_TEST", true, actualData)
+
+}
+
+// When you pass an 'android_test' as base, the warning message is a bit obscure,
+// talking about variants, but it is something. Ideally we could do better.
+func TestModuleConfigHostBadBaseShouldFailWithVariantWarning(t *testing.T) {
+ badBp := `
+ android_test {
+ name: "base",
+ sdk_version: "current",
+ srcs: ["a.java"],
+ }
+
+ test_module_config_host {
+ name: "derived_test",
+ base: "base",
+ exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
+ include_annotations: ["android.platform.test.annotations.LargeTest"],
+ }`
+
+ android.GroupFixturePreparers(
+ java.PrepareForTestWithJavaDefaultModules,
+ android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
+ ).ExtendWithErrorHandler(
+ android.FixtureExpectsAtLeastOneErrorMatchingPattern("missing variant")).
+ RunTestWithBp(t, badBp)
+}
+
+func TestModuleConfigHostNeedsATestSuite(t *testing.T) {
+ badBp := `
+ java_test_host {
+ name: "base",
+ srcs: ["a.java"],
+ }
+
+ test_module_config_host {
+ name: "derived_test",
+ base: "base",
+ exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
+ include_annotations: ["android.platform.test.annotations.LargeTest"],
+ }`
+
+ android.GroupFixturePreparers(
+ java.PrepareForTestWithJavaDefaultModules,
+ android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
+ ).ExtendWithErrorHandler(
+ android.FixtureExpectsAtLeastOneErrorMatchingPattern("At least one test-suite must be set")).
+ RunTestWithBp(t, badBp)
+}
+
+func TestModuleConfigHostDuplicateTestSuitesGiveErrors(t *testing.T) {
+ badBp := `
+ java_test_host {
+ name: "base",
+ srcs: ["a.java"],
+ test_suites: ["general-tests", "some-compat"],
+ }
+
+ test_module_config_host {
+ name: "derived_test",
+ base: "base",
+ exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
+ include_annotations: ["android.platform.test.annotations.LargeTest"],
+ test_suites: ["general-tests", "some-compat"],
+ }`
+
+ android.GroupFixturePreparers(
+ java.PrepareForTestWithJavaDefaultModules,
+ android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
+ ).ExtendWithErrorHandler(
+ android.FixtureExpectsAtLeastOneErrorMatchingPattern("TestSuite some-compat exists in the base")).
+ RunTestWithBp(t, badBp)
+}
+
+func TestTestOnlyProvider(t *testing.T) {
+ t.Parallel()
+ ctx := android.GroupFixturePreparers(
+ java.PrepareForTestWithJavaDefaultModules,
+ android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
+ ).RunTestWithBp(t, `
+ // These should be test-only
+ test_module_config_host {
+ name: "host-derived-test",
+ base: "host-base",
+ exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
+ include_annotations: ["android.platform.test.annotations.LargeTest"],
+ test_suites: ["general-tests"],
+ }
+
+ test_module_config {
+ name: "derived-test",
+ base: "base",
+ exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
+ include_annotations: ["android.platform.test.annotations.LargeTest"],
+ test_suites: ["general-tests"],
+ }
+
+ android_test {
+ name: "base",
+ sdk_version: "current",
+ data: ["data/testfile"],
+ }
+
+ java_test_host {
+ name: "host-base",
+ srcs: ["a.java"],
+ test_suites: ["general-tests"],
+ }`,
+ )
+
+ // Visit all modules and ensure only the ones that should
+ // marked as test-only are marked as test-only.
+
+ actualTestOnly := []string{}
+ ctx.VisitAllModules(func(m blueprint.Module) {
+ if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, android.TestOnlyProviderKey); ok {
+ if provider.TestOnly {
+ actualTestOnly = append(actualTestOnly, m.Name())
+ }
+ }
+ })
+ expectedTestOnlyModules := []string{
+ "host-derived-test",
+ "derived-test",
+ // android_test and java_test_host are tests too.
+ "host-base",
+ "base",
+ }
+
+ notEqual, left, right := android.ListSetDifference(expectedTestOnlyModules, actualTestOnly)
+ if notEqual {
+ t.Errorf("test-only: Expected but not found: %v, Found but not expected: %v", left, right)
+ }
+}
+
// Use for situations where the entries map contains pairs: [srcPath:installedPath1, srcPath2:installedPath2]
// and we want to compare the RHS of the pairs, i.e. installedPath1, installedPath2
func assertEntryPairValues(t *testing.T, actual []string, expected []string) {
diff --git a/ui/build/androidmk_denylist.go b/ui/build/androidmk_denylist.go
index e7896ab..a29f413 100644
--- a/ui/build/androidmk_denylist.go
+++ b/ui/build/androidmk_denylist.go
@@ -23,6 +23,7 @@
"cts/",
"dalvik/",
"developers/",
+ "frameworks/",
// Do not block other directories in kernel/, see b/319658303.
"kernel/configs/",
"kernel/prebuilts/",