Merge "Install apex symlinks in m --soong-only" into main
diff --git a/aconfig/Android.bp b/aconfig/Android.bp
index 402cf16..1505ba5 100644
--- a/aconfig/Android.bp
+++ b/aconfig/Android.bp
@@ -25,7 +25,16 @@
"aconfig_declarations_test.go",
"aconfig_values_test.go",
"aconfig_value_set_test.go",
- "all_aconfig_declarations_test.go",
],
pluginFor: ["soong_build"],
}
+
+all_aconfig_declarations {
+ name: "all_aconfig_declarations",
+ api_files: [
+ ":frameworks-base-api-current.txt",
+ ":frameworks-base-api-system-current.txt",
+ ":frameworks-base-api-system-server-current.txt",
+ ":frameworks-base-api-module-lib-current.txt",
+ ],
+}
diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go
index 3262493..9086c93 100644
--- a/aconfig/all_aconfig_declarations.go
+++ b/aconfig/all_aconfig_declarations.go
@@ -19,6 +19,8 @@
"slices"
"android/soong/android"
+
+ "github.com/google/blueprint/proptools"
)
// A singleton module that collects all of the aconfig flags declared in the
@@ -28,8 +30,11 @@
// Note that this is ALL aconfig_declarations modules present in the tree, not just
// ones that are relevant to the product currently being built, so that that infra
// doesn't need to pull from multiple builds and merge them.
-func AllAconfigDeclarationsFactory() android.Singleton {
- return &allAconfigDeclarationsSingleton{releaseMap: make(map[string]allAconfigReleaseDeclarationsSingleton)}
+func AllAconfigDeclarationsFactory() android.SingletonModule {
+ module := &allAconfigDeclarationsSingleton{releaseMap: make(map[string]allAconfigReleaseDeclarationsSingleton)}
+ module.AddProperties(&module.properties)
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ return module
}
type allAconfigReleaseDeclarationsSingleton struct {
@@ -37,8 +42,15 @@
intermediateTextProtoPath android.OutputPath
}
+type allAconfigReleaseDeclarationsProperties struct {
+ Api_files proptools.Configurable[[]string] `android:"arch_variant,path"`
+}
+
type allAconfigDeclarationsSingleton struct {
+ android.SingletonModuleBase
+
releaseMap map[string]allAconfigReleaseDeclarationsSingleton
+ properties allAconfigReleaseDeclarationsProperties
}
func (this *allAconfigDeclarationsSingleton) sortedConfigNames() []string {
@@ -50,7 +62,30 @@
return names
}
-func (this *allAconfigDeclarationsSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+func (this *allAconfigDeclarationsSingleton) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ apiFiles := android.Paths{}
+ for _, apiFile := range this.properties.Api_files.GetOrDefault(ctx, nil) {
+ if path := android.PathForModuleSrc(ctx, apiFile); path != nil {
+ apiFiles = append(apiFiles, path)
+ }
+ }
+ flagFile := android.PathForIntermediates(ctx, "all_aconfig_declarations.pb")
+
+ output := android.PathForIntermediates(ctx, "finalized-flags.txt")
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: RecordFinalizedFlagsRule,
+ Inputs: append(apiFiles, flagFile),
+ Output: output,
+ Args: map[string]string{
+ "api_files": android.JoinPathsWithPrefix(apiFiles, "--api-file "),
+ "flag_file": "--flag-file " + flagFile.String(),
+ },
+ })
+ ctx.Phony("all_aconfig_declarations", output)
+}
+
+func (this *allAconfigDeclarationsSingleton) GenerateSingletonBuildActions(ctx android.SingletonContext) {
for _, rcName := range append([]string{""}, ctx.Config().ReleaseAconfigExtraReleaseConfigs()...) {
// Find all of the aconfig_declarations modules
var packages = make(map[string]int)
@@ -116,4 +151,5 @@
ctx.DistForGoalWithFilename(goal, this.releaseMap[rcName].intermediateTextProtoPath, assembleFileName(rcName, "flags.textproto"))
}
}
+ ctx.DistForGoalWithFilename("sdk", android.PathForIntermediates(ctx, "finalized-flags.txt"), "finalized-flags.txt")
}
diff --git a/aconfig/all_aconfig_declarations_test.go b/aconfig/all_aconfig_declarations_test.go
deleted file mode 100644
index 0b2021e..0000000
--- a/aconfig/all_aconfig_declarations_test.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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 aconfig
-
-import (
- "testing"
-
- "android/soong/android"
-)
-
-func TestTwoAconfigDeclarationsPerPackage(t *testing.T) {
- bp := `
- aconfig_declarations {
- name: "module_name.foo",
- package: "com.example.package",
- container: "com.android.foo",
- srcs: [
- "foo.aconfig",
- ],
- }
-
- aconfig_declarations {
- name: "module_name.bar",
- package: "com.example.package",
- container: "com.android.foo",
- srcs: [
- "bar.aconfig",
- ],
- }
- `
- errMsg := "Only one aconfig_declarations allowed for each package."
- android.GroupFixturePreparers(
- PrepareForTestWithAconfigBuildComponents).
- ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(errMsg)).
- RunTestWithBp(t, bp)
-}
diff --git a/aconfig/codegen/init.go b/aconfig/codegen/init.go
index 34fdca3..385fa49 100644
--- a/aconfig/codegen/init.go
+++ b/aconfig/codegen/init.go
@@ -26,6 +26,7 @@
// For java_aconfig_library: Generate java library
javaRule = pctx.AndroidStaticRule("java_aconfig_library",
blueprint.RuleParams{
+ // LINT.IfChange
Command: `rm -rf ${out}.tmp` +
` && mkdir -p ${out}.tmp` +
` && ${aconfig} create-java-lib` +
@@ -34,14 +35,16 @@
` --out ${out}.tmp` +
` --allow-instrumentation ${debug}` +
` --new-exported ${new_exported}` +
+ ` --check-api-level ${check_api_level}` +
` && $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` +
` && rm -rf ${out}.tmp`,
+ // LINT.ThenChange(/aconfig/init.go)
CommandDeps: []string{
"$aconfig",
"$soong_zip",
},
Restat: true,
- }, "mode", "debug", "new_exported")
+ }, "mode", "debug", "new_exported", "check_api_level")
// For cc_aconfig_library: Generate C++ library
cppRule = pctx.AndroidStaticRule("cc_aconfig_library",
diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go
index cd1767b..7b9da8e 100644
--- a/aconfig/codegen/java_aconfig_library.go
+++ b/aconfig/codegen/java_aconfig_library.go
@@ -112,9 +112,10 @@
Output: srcJarPath,
Description: "aconfig.srcjar",
Args: map[string]string{
- "mode": mode,
- "debug": strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorage()),
- "new_exported": strconv.FormatBool(newExported),
+ "mode": mode,
+ "debug": strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorage()),
+ "new_exported": strconv.FormatBool(newExported),
+ "check_api_level": strconv.FormatBool(ctx.Config().ReleaseAconfigCheckApiLevel()),
},
})
diff --git a/aconfig/exported_java_aconfig_library.go b/aconfig/exported_java_aconfig_library.go
index f7e6dcf..dd068d1 100644
--- a/aconfig/exported_java_aconfig_library.go
+++ b/aconfig/exported_java_aconfig_library.go
@@ -59,6 +59,7 @@
"cache_files": android.JoinPathsWithPrefix(cacheFiles, " "),
"use_new_storage": strconv.FormatBool(newStorage),
"use_new_exported": strconv.FormatBool(newExported),
+ "check_api_level": strconv.FormatBool(ctx.Config().ReleaseAconfigCheckApiLevel()),
},
})
ctx.Phony("exported_java_aconfig_library", this.intermediatePath)
diff --git a/aconfig/init.go b/aconfig/init.go
index ab6ee46..3d7b20d 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -70,6 +70,13 @@
"${aconfig}",
},
}, "cache_files")
+ RecordFinalizedFlagsRule = pctx.AndroidStaticRule("RecordFinalizedFlagsRule",
+ blueprint.RuleParams{
+ Command: `${record-finalized-flags} ${flag_file} ${api_files} > ${out}`,
+ CommandDeps: []string{
+ "${record-finalized-flags}",
+ },
+ }, "api_files", "flag_file")
CreateStorageRule = pctx.AndroidStaticRule("aconfig_create_storage",
blueprint.RuleParams{
@@ -88,6 +95,7 @@
// exported flags (only). Finally collect all generated code
// into the ${out} JAR file.
blueprint.RuleParams{
+ // LINT.IfChange
Command: `rm -rf ${out}.tmp` +
`&& for cache in ${cache_files}; do ` +
` if [ -n "$$(${aconfig} dump-cache --dedup --cache $$cache --filter=is_exported:true --format='{fully_qualified_name}')" ]; then ` +
@@ -96,28 +104,31 @@
` --mode=exported` +
` --allow-instrumentation ${use_new_storage}` +
` --new-exported ${use_new_exported}` +
+ ` --check-api-level ${check_api_level}` +
` --out ${out}.tmp; ` +
` fi ` +
`done` +
`&& $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` +
`&& rm -rf ${out}.tmp`,
+ // LINT.ThenChange(/aconfig/codegen/init.go)
CommandDeps: []string{
"$aconfig",
"$soong_zip",
},
- }, "cache_files", "use_new_storage", "use_new_exported")
+ }, "cache_files", "use_new_storage", "use_new_exported", "check_api_level")
)
func init() {
RegisterBuildComponents(android.InitRegistrationContext)
pctx.HostBinToolVariable("aconfig", "aconfig")
pctx.HostBinToolVariable("soong_zip", "soong_zip")
+ pctx.HostBinToolVariable("record-finalized-flags", "record-finalized-flags")
}
func RegisterBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("aconfig_declarations", DeclarationsFactory)
ctx.RegisterModuleType("aconfig_values", ValuesFactory)
ctx.RegisterModuleType("aconfig_value_set", ValueSetFactory)
- ctx.RegisterParallelSingletonType("all_aconfig_declarations", AllAconfigDeclarationsFactory)
+ ctx.RegisterSingletonModuleType("all_aconfig_declarations", AllAconfigDeclarationsFactory)
ctx.RegisterParallelSingletonType("exported_java_aconfig_library", ExportedJavaDeclarationsLibraryFactory)
}
diff --git a/android/androidmk.go b/android/androidmk.go
index 87a93e3..6f094e5 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -741,8 +741,36 @@
// defined through the androidmk mechanisms, so this function is an alternate implementation of
// the androidmk singleton that just focuses on getting the dist contributions
func (c *androidMkSingleton) soongOnlyBuildActions(ctx SingletonContext, mods []blueprint.Module) {
- allDistContributions := getDistContributionsFromMods(ctx, mods)
+ allDistContributions, moduleInfoJSONs := getSoongOnlyDataFromMods(ctx, mods)
+ // Build module-info.json. Only in builds with HasDeviceProduct(), as we need a named
+ // device to have a TARGET_OUT folder.
+ if ctx.Config().HasDeviceProduct() {
+ preMergePath := PathForOutput(ctx, "module_info_pre_merging.json")
+ moduleInfoJSONPath := pathForInstall(ctx, Android, X86_64, "", "module-info.json")
+ if err := writeModuleInfoJSON(ctx, moduleInfoJSONs, preMergePath); err != nil {
+ ctx.Errorf("%s", err)
+ }
+ builder := NewRuleBuilder(pctx, ctx)
+ builder.Command().
+ BuiltTool("merge_module_info_json").
+ FlagWithOutput("-o ", moduleInfoJSONPath).
+ Input(preMergePath)
+ builder.Build("merge_module_info_json", "merge module info json")
+ ctx.Phony("module-info", moduleInfoJSONPath)
+ ctx.Phony("droidcore-unbundled", moduleInfoJSONPath)
+ allDistContributions = append(allDistContributions, distContributions{
+ copiesForGoals: []*copiesForGoals{{
+ goals: "general-tests droidcore-unbundled",
+ copies: []distCopy{{
+ from: moduleInfoJSONPath,
+ dest: "module-info.json",
+ }},
+ }},
+ })
+ }
+
+ // Build dist.mk for the packaging step to read and generate dist targets
distMkFile := absolutePath(filepath.Join(ctx.Config().katiPackageMkDir(), "dist.mk"))
var goalOutputPairs []string
@@ -793,8 +821,11 @@
}
}
-func getDistContributionsFromMods(ctx fillInEntriesContext, mods []blueprint.Module) []distContributions {
+// getSoongOnlyDataFromMods gathers data from the given modules needed in soong-only builds.
+// Currently, this is the dist contributions, and the module-info.json contents.
+func getSoongOnlyDataFromMods(ctx fillInEntriesContext, mods []blueprint.Module) ([]distContributions, []*ModuleInfoJSON) {
var allDistContributions []distContributions
+ var moduleInfoJSONs []*ModuleInfoJSON
for _, mod := range mods {
if amod, ok := mod.(Module); ok && shouldSkipAndroidMkProcessing(ctx, amod.base()) {
continue
@@ -806,6 +837,9 @@
if info.PrimaryInfo.disabled() {
continue
}
+ if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
+ moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON)
+ }
if contribution := info.PrimaryInfo.getDistContributions(ctx, mod); contribution != nil {
allDistContributions = append(allDistContributions, *contribution)
}
@@ -831,6 +865,9 @@
if data.Entries.disabled() {
continue
}
+ if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
+ moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON)
+ }
if contribution := data.Entries.getDistContributions(mod); contribution != nil {
allDistContributions = append(allDistContributions, *contribution)
}
@@ -841,6 +878,9 @@
if entries.disabled() {
continue
}
+ if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
+ moduleInfoJSONs = append(moduleInfoJSONs, moduleInfoJSON)
+ }
if contribution := entries.getDistContributions(mod); contribution != nil {
allDistContributions = append(allDistContributions, *contribution)
}
@@ -850,7 +890,7 @@
}
}
}
- return allDistContributions
+ return allDistContributions, moduleInfoJSONs
}
func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []blueprint.Module) error {
diff --git a/android/config.go b/android/config.go
index c22c332..eda8e71 100644
--- a/android/config.go
+++ b/android/config.go
@@ -294,6 +294,10 @@
return c.config.productVariables.GetBuildFlagBool("RELEASE_FINGERPRINT_ACONFIG_PACKAGES")
}
+func (c Config) ReleaseAconfigCheckApiLevel() bool {
+ return c.config.productVariables.GetBuildFlagBool("RELEASE_ACONFIG_CHECK_API_LEVEL")
+}
+
// A DeviceConfig object represents the configuration for a particular device
// being built. For now there will only be one of these, but in the future there
// may be multiple devices being built.
@@ -2175,6 +2179,10 @@
return c.productVariables.GetBuildFlagBool("RELEASE_USE_TRANSITIVE_JARS_IN_CLASSPATH")
}
+func (c *config) UseR8FullModeByDefault() bool {
+ return c.productVariables.GetBuildFlagBool("RELEASE_R8_FULL_MODE_BY_DEFAULT")
+}
+
func (c *config) UseR8OnlyRuntimeVisibleAnnotations() bool {
return c.productVariables.GetBuildFlagBool("RELEASE_R8_ONLY_RUNTIME_VISIBLE_ANNOTATIONS")
}
diff --git a/android/license.go b/android/license.go
index 5bffc25..ffda58b 100644
--- a/android/license.go
+++ b/android/license.go
@@ -18,6 +18,16 @@
"github.com/google/blueprint"
)
+type LicenseInfo struct {
+ EffectiveLicenses []string
+ PackageName *string
+ EffectiveLicenseText NamedPaths
+ EffectiveLicenseKinds []string
+ EffectiveLicenseConditions []string
+}
+
+var LicenseInfoProvider = blueprint.NewProvider[LicenseInfo]()
+
type licenseKindDependencyTag struct {
blueprint.BaseDependencyTag
}
@@ -71,14 +81,22 @@
// license modules have no licenses, but license_kinds must refer to license_kind modules
mergeStringProps(&m.base().commonProperties.Effective_licenses, ctx.ModuleName())
namePathProps(&m.base().commonProperties.Effective_license_text, m.properties.Package_name, PathsForModuleSrc(ctx, m.properties.License_text)...)
- for _, module := range ctx.GetDirectDepsWithTag(licenseKindTag) {
- if lk, ok := module.(*licenseKindModule); ok {
- mergeStringProps(&m.base().commonProperties.Effective_license_conditions, lk.properties.Conditions...)
+ for _, module := range ctx.GetDirectDepsProxyWithTag(licenseKindTag) {
+ if lk, ok := OtherModuleProvider(ctx, module, LicenseKindInfoProvider); ok {
+ mergeStringProps(&m.base().commonProperties.Effective_license_conditions, lk.Conditions...)
mergeStringProps(&m.base().commonProperties.Effective_license_kinds, ctx.OtherModuleName(module))
} else {
ctx.ModuleErrorf("license_kinds property %q is not a license_kind module", ctx.OtherModuleName(module))
}
}
+
+ SetProvider(ctx, LicenseInfoProvider, LicenseInfo{
+ EffectiveLicenses: m.base().commonProperties.Effective_licenses,
+ PackageName: m.properties.Package_name,
+ EffectiveLicenseText: m.base().commonProperties.Effective_license_text,
+ EffectiveLicenseKinds: m.base().commonProperties.Effective_license_kinds,
+ EffectiveLicenseConditions: m.base().commonProperties.Effective_license_conditions,
+ })
}
func LicenseFactory() Module {
diff --git a/android/license_kind.go b/android/license_kind.go
index 838dedd..1ca6954 100644
--- a/android/license_kind.go
+++ b/android/license_kind.go
@@ -14,6 +14,14 @@
package android
+import "github.com/google/blueprint"
+
+type LicenseKindInfo struct {
+ Conditions []string
+}
+
+var LicenseKindInfoProvider = blueprint.NewProvider[LicenseKindInfo]()
+
func init() {
RegisterLicenseKindBuildComponents(InitRegistrationContext)
}
@@ -43,8 +51,10 @@
// Nothing to do.
}
-func (m *licenseKindModule) GenerateAndroidBuildActions(ModuleContext) {
- // Nothing to do.
+func (m *licenseKindModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ SetProvider(ctx, LicenseKindInfoProvider, LicenseKindInfo{
+ Conditions: m.properties.Conditions,
+ })
}
func LicenseKindFactory() Module {
diff --git a/android/licenses.go b/android/licenses.go
index 53d0555..77f563f 100644
--- a/android/licenses.go
+++ b/android/licenses.go
@@ -227,16 +227,16 @@
}
var licenses []string
- for _, module := range ctx.GetDirectDepsWithTag(licensesTag) {
- if l, ok := module.(*licenseModule); ok {
+ for _, module := range ctx.GetDirectDepsProxyWithTag(licensesTag) {
+ if l, ok := OtherModuleProvider(ctx, module, LicenseInfoProvider); ok {
licenses = append(licenses, ctx.OtherModuleName(module))
- if m.base().commonProperties.Effective_package_name == nil && l.properties.Package_name != nil {
- m.base().commonProperties.Effective_package_name = l.properties.Package_name
+ if m.base().commonProperties.Effective_package_name == nil && l.PackageName != nil {
+ m.base().commonProperties.Effective_package_name = l.PackageName
}
- mergeStringProps(&m.base().commonProperties.Effective_licenses, module.base().commonProperties.Effective_licenses...)
- mergeNamedPathProps(&m.base().commonProperties.Effective_license_text, module.base().commonProperties.Effective_license_text...)
- mergeStringProps(&m.base().commonProperties.Effective_license_kinds, module.base().commonProperties.Effective_license_kinds...)
- mergeStringProps(&m.base().commonProperties.Effective_license_conditions, module.base().commonProperties.Effective_license_conditions...)
+ mergeStringProps(&m.base().commonProperties.Effective_licenses, l.EffectiveLicenses...)
+ mergeNamedPathProps(&m.base().commonProperties.Effective_license_text, l.EffectiveLicenseText...)
+ mergeStringProps(&m.base().commonProperties.Effective_license_kinds, l.EffectiveLicenseKinds...)
+ mergeStringProps(&m.base().commonProperties.Effective_license_conditions, l.EffectiveLicenseConditions...)
} else {
propertyName := "licenses"
primaryProperty := m.base().primaryLicensesProperty
@@ -248,10 +248,10 @@
}
// Make the license information available for other modules.
- licenseInfo := LicenseInfo{
+ licenseInfo := LicensesInfo{
Licenses: licenses,
}
- SetProvider(ctx, LicenseInfoProvider, licenseInfo)
+ SetProvider(ctx, LicensesInfoProvider, licenseInfo)
}
// Update a property string array with a distinct union of its values and a list of new values.
@@ -336,14 +336,14 @@
return true
}
-// LicenseInfo contains information about licenses for a specific module.
-type LicenseInfo struct {
+// LicensesInfo contains information about licenses for a specific module.
+type LicensesInfo struct {
// The list of license modules this depends upon, either explicitly or through default package
// configuration.
Licenses []string
}
-var LicenseInfoProvider = blueprint.NewProvider[LicenseInfo]()
+var LicensesInfoProvider = blueprint.NewProvider[LicensesInfo]()
func init() {
RegisterMakeVarsProvider(pctx, licensesMakeVarsProvider)
diff --git a/android/module.go b/android/module.go
index b9489b4..c81380e 100644
--- a/android/module.go
+++ b/android/module.go
@@ -990,8 +990,9 @@
// 2. `boot_signer` is `required` by modules like `build_image` which is explicitly list as
// the top-level build goal (in the shell file that invokes Soong).
// 3. `boot_signer` depends on `bouncycastle-unbundled` which is in the missing git project.
- // 4. aosp_kernel-build-tools invokes soong with `--skip-make`. Therefore, the absence of
- // ALLOW_MISSING_DEPENDENCIES didn't cause a problem.
+ // 4. aosp_kernel-build-tools invokes soong with `--soong-only`. Therefore, the absence of
+ // ALLOW_MISSING_DEPENDENCIES didn't cause a problem, as previously only make processed required
+ // dependencies.
// 5. Now, since Soong understands `required` deps, it tries to build `boot_signer` and the
// absence of external/bouncycastle fails the build.
//
@@ -1654,6 +1655,7 @@
func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) {
var allInstalledFiles InstallPaths
var allCheckbuildTargets Paths
+ var alloutputFiles Paths
ctx.VisitAllModuleVariantProxies(func(module ModuleProxy) {
var checkbuildTarget Path
var uncheckedModule bool
@@ -1670,6 +1672,9 @@
uncheckedModule = info.UncheckedModule
skipAndroidMkProcessing = OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).SkipAndroidMkProcessing
}
+ if outputFiles, err := outputFilesForModule(ctx, module, ""); err == nil {
+ alloutputFiles = append(alloutputFiles, outputFiles...)
+ }
// A module's -checkbuild phony targets should
// not be created if the module is not exported to make.
// Those could depend on the build target and fail to compile
@@ -1701,6 +1706,12 @@
deps = append(deps, PathForPhony(ctx, name))
}
+ if len(alloutputFiles) > 0 {
+ name := namespacePrefix + ctx.ModuleName() + "-outputs"
+ ctx.Phony(name, alloutputFiles...)
+ deps = append(deps, PathForPhony(ctx, name))
+ }
+
if len(deps) > 0 {
suffix := ""
if ctx.Config().KatiEnabled() {
diff --git a/android/variable.go b/android/variable.go
index 08bcedf..3e637fe 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -555,6 +555,7 @@
type PartitionQualifiedVariablesType struct {
BuildingImage bool `json:",omitempty"`
+ PrebuiltImage bool `json:",omitempty"`
BoardErofsCompressor string `json:",omitempty"`
BoardErofsCompressHints string `json:",omitempty"`
BoardErofsPclusterSize string `json:",omitempty"`
@@ -623,6 +624,8 @@
VendorDlkmSecurityPatch string `json:",omitempty"`
OdmDlkmSecurityPatch string `json:",omitempty"`
+ BuildingSystemOtherImage bool `json:",omitempty"`
+
// Boot image stuff
BuildingRamdiskImage bool `json:",omitempty"`
ProductBuildBootImage bool `json:",omitempty"`
diff --git a/android/vintf_data.go b/android/vintf_data.go
index 401f4d2..2909817 100644
--- a/android/vintf_data.go
+++ b/android/vintf_data.go
@@ -140,6 +140,7 @@
// Process vintf fragment source file with assemble_vintf tool
builder.Command().
+ Implicits(inputPaths).
Flags(assembleVintfEnvs).
BuiltTool("assemble_vintf").
FlagWithArg("-i ", strings.Join(inputPaths.Strings(), ":")).
diff --git a/apex/apex.go b/apex/apex.go
index 428d57e..d98cfae 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2570,7 +2570,7 @@
fromName := ctx.OtherModuleName(from)
toName := ctx.OtherModuleName(to)
- // The dynamic linker and crash_dump tool in the runtime APEX is the only
+ // The dynamic linker and crash_dump tool in the runtime APEX is an
// exception to this rule. It can't make the static dependencies dynamic
// because it can't do the dynamic linking for itself.
// Same rule should be applied to linkerconfig, because it should be executed
@@ -2579,6 +2579,15 @@
return false
}
+ // b/389067742 adds libz as an exception to this check. Although libz is
+ // a part of NDK and thus provides a stable interface, it never was the
+ // intention because the upstream zlib provides neither ABI- nor behavior-
+ // stability. Therefore, we want to allow portable components like APEXes to
+ // bundle libz by statically linking to it.
+ if toName == "libz" {
+ return false
+ }
+
isStubLibraryFromOtherApex := info.HasStubsVariants && !librariesDirectlyInApex[toName]
if isStubLibraryFromOtherApex && !externalDep {
ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+
diff --git a/bin/mm b/bin/mm
index 6461b1e..6f1c934 100755
--- a/bin/mm
+++ b/bin/mm
@@ -19,6 +19,6 @@
require_top
-_wrap_build "$TOP/build/soong/soong_ui.bash" --build-mode --modules-in-a-dir-no-deps --dir="$(pwd)" "$@"
+_wrap_build "$TOP/build/soong/soong_ui.bash" --build-mode --modules-in-a-dir --dir="$(pwd)" "$@"
exit $?
diff --git a/bin/mmm b/bin/mmm
index ab3a632..d9190e5 100755
--- a/bin/mmm
+++ b/bin/mmm
@@ -19,6 +19,6 @@
require_top
-_wrap_build "$TOP/build/soong/soong_ui.bash" --build-mode --modules-in-dirs-no-deps --dir="$(pwd)" "$@"
+_wrap_build "$TOP/build/soong/soong_ui.bash" --build-mode --modules-in-dirs --dir="$(pwd)" "$@"
exit $?
diff --git a/cc/strip.go b/cc/strip.go
index b1f34bb..36c0c48 100644
--- a/cc/strip.go
+++ b/cc/strip.go
@@ -52,11 +52,7 @@
// NeedsStrip determines if stripping is required for a module.
func (stripper *Stripper) NeedsStrip(actx android.ModuleContext) bool {
forceDisable := Bool(stripper.StripProperties.Strip.None)
- defaultEnable := (!actx.Config().KatiEnabled() || actx.Device())
- forceEnable := Bool(stripper.StripProperties.Strip.All) ||
- Bool(stripper.StripProperties.Strip.Keep_symbols) ||
- Bool(stripper.StripProperties.Strip.Keep_symbols_and_debug_frame)
- return !forceDisable && (forceEnable || defaultEnable)
+ return !forceDisable
}
func (stripper *Stripper) strip(actx android.ModuleContext, in android.Path, out android.ModuleOutPath,
diff --git a/cc/test.go b/cc/test.go
index abf9162..32b1551 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -29,8 +29,8 @@
// if set, build against the gtest library. Defaults to true.
Gtest *bool
- // if set, use the isolated gtest runner. Defaults to true if gtest is also true and the arch is Windows, false
- // otherwise.
+ // if set, use the isolated gtest runner. Defaults to false.
+ // Isolation is not supported on Windows.
Isolated *bool
}
@@ -198,8 +198,8 @@
return BoolDefault(test.LinkerProperties.Gtest, true)
}
-func (test *testDecorator) isolated(ctx android.EarlyModuleContext) bool {
- return BoolDefault(test.LinkerProperties.Isolated, false)
+func (test *testDecorator) isolated(ctx android.BaseModuleContext) bool {
+ return BoolDefault(test.LinkerProperties.Isolated, false) && !ctx.Windows()
}
// NOTE: Keep this in sync with cc/cc_test.bzl#gtest_copts
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 7926292..a884964 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -471,20 +471,6 @@
description: "Build action: build from the top of the source tree.",
action: build.BUILD_MODULES,
}, {
- // This is redirecting to mma build command behaviour. Once it has soaked for a
- // while, the build command is deleted from here once it has been removed from the
- // envsetup.sh.
- name: "modules-in-a-dir-no-deps",
- description: "Build action: builds all of the modules in the current directory without their dependencies.",
- action: build.BUILD_MODULES_IN_A_DIRECTORY,
- }, {
- // This is redirecting to mmma build command behaviour. Once it has soaked for a
- // while, the build command is deleted from here once it has been removed from the
- // envsetup.sh.
- name: "modules-in-dirs-no-deps",
- description: "Build action: builds all of the modules in the supplied directories without their dependencies.",
- action: build.BUILD_MODULES_IN_DIRECTORIES,
- }, {
name: "modules-in-a-dir",
description: "Build action: builds all of the modules in the current directory and their dependencies.",
action: build.BUILD_MODULES_IN_A_DIRECTORY,
diff --git a/filesystem/Android.bp b/filesystem/Android.bp
index 986b72e..cb76df2 100644
--- a/filesystem/Android.bp
+++ b/filesystem/Android.bp
@@ -28,6 +28,7 @@
"raw_binary.go",
"super_image.go",
"system_image.go",
+ "system_other.go",
"vbmeta.go",
"testing.go",
],
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 98af479..6d6c15c 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -99,6 +99,9 @@
// The index used to prevent rollback of the image on device.
Avb_rollback_index *int64
+ // Rollback index location of this image. Must be 0, 1, 2, etc.
+ Avb_rollback_index_location *int64
+
// The security patch passed to as the com.android.build.<type>.security_patch avb property.
// Replacement for the make variables BOOT_SECURITY_PATCH / INIT_BOOT_SECURITY_PATCH.
Security_patch *string
@@ -237,6 +240,27 @@
Bootconfig: b.getBootconfigPath(ctx),
Output: output,
})
+
+ extractedPublicKey := android.PathForModuleOut(ctx, b.partitionName()+".avbpubkey")
+ if b.properties.Avb_private_key != nil {
+ key := android.PathForModuleSrc(ctx, proptools.String(b.properties.Avb_private_key))
+ ctx.Build(pctx, android.BuildParams{
+ Rule: extractPublicKeyRule,
+ Input: key,
+ Output: extractedPublicKey,
+ })
+ }
+ var ril int
+ if b.properties.Avb_rollback_index_location != nil {
+ ril = proptools.Int(b.properties.Avb_rollback_index_location)
+ }
+
+ android.SetProvider(ctx, vbmetaPartitionProvider, vbmetaPartitionInfo{
+ Name: b.bootImageType.String(),
+ RollbackIndexLocation: ril,
+ PublicKey: extractedPublicKey,
+ Output: output,
+ })
}
var BootimgInfoProvider = blueprint.NewProvider[BootimgInfo]()
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index ad19cc6..357ec32 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -20,6 +20,7 @@
"io"
"path/filepath"
"slices"
+ "sort"
"strconv"
"strings"
@@ -130,6 +131,9 @@
// The index used to prevent rollback of the image. Only used if use_avb is true.
Rollback_index *int64
+ // Rollback index location of this image. Must be 0, 1, 2, etc.
+ Rollback_index_location *int64
+
// Name of the partition stored in vbmeta desc. Defaults to the name of this module.
Partition_name *string
@@ -378,6 +382,13 @@
// Name of the module that produced this FilesystemInfo origionally. (though it may be
// re-exported by super images or boot images)
ModuleName string
+ // The property file generated by this module and passed to build_image.
+ // It's exported here so that system_other can reuse system's property file.
+ BuildImagePropFile android.Path
+ // Paths to all the tools referenced inside of the build image property file.
+ BuildImagePropFileDeps android.Paths
+ // Packaging specs to be installed on the system_other image, for the initial boot's dexpreopt.
+ SpecsForSystemOther map[string]android.PackagingSpec
}
var FilesystemProvider = blueprint.NewProvider[FilesystemInfo]()
@@ -484,9 +495,11 @@
var mapFile android.Path
var outputHermetic android.Path
+ var buildImagePropFile android.Path
+ var buildImagePropFileDeps android.Paths
switch f.fsType(ctx) {
case ext4Type, erofsType, f2fsType:
- f.output, outputHermetic = f.buildImageUsingBuildImage(ctx, builder, rootDir, rebasedDir)
+ f.output, outputHermetic, buildImagePropFile, buildImagePropFileDeps = f.buildImageUsingBuildImage(ctx, builder, rootDir, rebasedDir)
mapFile = f.getMapFile(ctx)
case compressedCpioType:
f.output = f.buildCpioImage(ctx, builder, rootDir, true)
@@ -508,17 +521,16 @@
android.WriteFileRule(ctx, fileListFile, f.installedFilesList())
fsInfo := FilesystemInfo{
- Output: f.output,
- FileListFile: fileListFile,
- RootDir: rootDir,
- RebasedDir: rebasedDir,
- ModuleName: ctx.ModuleName(),
- }
- if mapFile != nil {
- fsInfo.MapFile = mapFile
- }
- if outputHermetic != nil {
- fsInfo.OutputHermetic = outputHermetic
+ Output: f.output,
+ OutputHermetic: outputHermetic,
+ FileListFile: fileListFile,
+ RootDir: rootDir,
+ RebasedDir: rebasedDir,
+ MapFile: mapFile,
+ ModuleName: ctx.ModuleName(),
+ BuildImagePropFile: buildImagePropFile,
+ BuildImagePropFileDeps: buildImagePropFileDeps,
+ SpecsForSystemOther: f.systemOtherFiles(ctx),
}
android.SetProvider(ctx, FilesystemProvider, fsInfo)
@@ -528,6 +540,33 @@
if proptools.Bool(f.properties.Unchecked_module) {
ctx.UncheckedModule()
}
+
+ f.setVbmetaPartitionProvider(ctx)
+}
+
+func (f *filesystem) setVbmetaPartitionProvider(ctx android.ModuleContext) {
+ var extractedPublicKey android.ModuleOutPath
+ if f.properties.Avb_private_key != nil {
+ key := android.PathForModuleSrc(ctx, proptools.String(f.properties.Avb_private_key))
+ extractedPublicKey = android.PathForModuleOut(ctx, f.partitionName()+".avbpubkey")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: extractPublicKeyRule,
+ Input: key,
+ Output: extractedPublicKey,
+ })
+ }
+
+ var ril int
+ if f.properties.Rollback_index_location != nil {
+ ril = proptools.Int(f.properties.Rollback_index_location)
+ }
+
+ android.SetProvider(ctx, vbmetaPartitionProvider, vbmetaPartitionInfo{
+ Name: f.partitionName(),
+ RollbackIndexLocation: ril,
+ PublicKey: extractedPublicKey,
+ Output: f.output,
+ })
}
func (f *filesystem) getMapFile(ctx android.ModuleContext) android.WritablePath {
@@ -670,7 +709,7 @@
builder *android.RuleBuilder,
rootDir android.OutputPath,
rebasedDir android.OutputPath,
-) (android.Path, android.Path) {
+) (android.Path, android.Path, android.Path, android.Paths) {
// run host_init_verifier
// Ideally we should have a concept of pluggable linters that verify the generated image.
// While such concept is not implement this will do.
@@ -701,7 +740,9 @@
// Add an additional cmd to create a hermetic img file. This will contain pinned timestamps e.g.
propFilePinnedTimestamp := android.PathForModuleOut(ctx, "for_target_files", "prop")
- builder.Command().Textf("cat").Input(propFile).Flag(">").Output(propFilePinnedTimestamp).Textf(" && echo use_fixed_timestamp=true >> %s", propFilePinnedTimestamp)
+ builder.Command().Textf("cat").Input(propFile).Flag(">").Output(propFilePinnedTimestamp).
+ Textf(" && echo use_fixed_timestamp=true >> %s", propFilePinnedTimestamp).
+ Textf(" && echo block_list=%s >> %s", f.getMapFile(ctx).String(), propFilePinnedTimestamp) // mapfile will be an implicit output
outputHermetic := android.PathForModuleOut(ctx, "for_target_files", f.installFileName())
builder.Command().
@@ -721,7 +762,7 @@
// rootDir is not deleted. Might be useful for quick inspection.
builder.Build("build_filesystem_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName()))
- return output, outputHermetic
+ return output, outputHermetic, propFile, toolDeps
}
func (f *filesystem) buildFileContexts(ctx android.ModuleContext) android.Path {
@@ -736,12 +777,9 @@
func (f *filesystem) buildPropFile(ctx android.ModuleContext) (android.Path, android.Paths) {
var deps android.Paths
- var propFileString strings.Builder
+ var lines []string
addStr := func(name string, value string) {
- propFileString.WriteString(name)
- propFileString.WriteRune('=')
- propFileString.WriteString(value)
- propFileString.WriteRune('\n')
+ lines = append(lines, fmt.Sprintf("%s=%s", name, value))
}
addPath := func(name string, path android.Path) {
addStr(name, path.String())
@@ -761,7 +799,6 @@
}
panic(fmt.Errorf("unsupported fs type %v", t))
}
- addStr("block_list", f.getMapFile(ctx).String()) // This will be an implicit output
addStr("fs_type", fsTypeStr(f.fsType(ctx)))
addStr("mount_point", proptools.StringDefault(f.properties.Mount_point, "/"))
@@ -871,8 +908,10 @@
addStr("needs_compress", "1")
}
+ sort.Strings(lines)
+
propFilePreProcessing := android.PathForModuleOut(ctx, "prop_pre_processing")
- android.WriteFileRuleVerbatim(ctx, propFilePreProcessing, propFileString.String())
+ android.WriteFileRule(ctx, propFilePreProcessing, strings.Join(lines, "\n"))
propFile := android.PathForModuleOut(ctx, "prop")
ctx.Build(pctx, android.BuildParams{
Rule: textFileProcessorRule,
@@ -1065,8 +1104,21 @@
// Note that "apex" module installs its contents to "apex"(fake partition) as well
// for symbol lookup by imitating "activated" paths.
func (f *filesystem) gatherFilteredPackagingSpecs(ctx android.ModuleContext) map[string]android.PackagingSpec {
- specs := f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, f.filesystemBuilder.FilterPackagingSpec, f.filesystemBuilder.ModifyPackagingSpec)
- return specs
+ return f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, f.filesystemBuilder.FilterPackagingSpec, f.filesystemBuilder.ModifyPackagingSpec)
+}
+
+// Dexpreopt files are installed to system_other. Collect the packaingSpecs for the dexpreopt files
+// from this partition to export to the system_other partition later.
+func (f *filesystem) systemOtherFiles(ctx android.ModuleContext) map[string]android.PackagingSpec {
+ filter := func(spec android.PackagingSpec) bool {
+ // For some reason system_other packaging specs don't set the partition field.
+ return strings.HasPrefix(spec.RelPathInPackage(), "system_other/")
+ }
+ modifier := func(spec *android.PackagingSpec) {
+ spec.SetRelPathInPackage(strings.TrimPrefix(spec.RelPathInPackage(), "system_other/"))
+ spec.SetPartition("system_other")
+ }
+ return f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, filter, modifier)
}
func sha1sum(values []string) string {
diff --git a/filesystem/super_image.go b/filesystem/super_image.go
index 4419a2f..5332462 100644
--- a/filesystem/super_image.go
+++ b/filesystem/super_image.go
@@ -18,6 +18,7 @@
"fmt"
"path/filepath"
"regexp"
+ "slices"
"strconv"
"strings"
@@ -55,6 +56,9 @@
Sparse *bool
// information about how partitions within the super partition are grouped together
Partition_groups []PartitionGroupsInfo
+ // Name of the system_other partition filesystem module. This module will be installed to
+ // the "b" slot of the system partition in a/b partition builds.
+ System_other_partition *string
// whether dynamic partitions is used
Use_dynamic_partitions *bool
Virtual_ab struct {
@@ -127,6 +131,12 @@
var subImageDepTag superImageDepTagType
+type systemOtherDepTagType struct {
+ blueprint.BaseDependencyTag
+}
+
+var systemOtherDepTag systemOtherDepTagType
+
func (s *superImage) DepsMutator(ctx android.BottomUpMutatorContext) {
addDependencyIfDefined := func(dep *string) {
if dep != nil {
@@ -143,6 +153,9 @@
addDependencyIfDefined(s.partitionProps.Vendor_dlkm_partition)
addDependencyIfDefined(s.partitionProps.Odm_partition)
addDependencyIfDefined(s.partitionProps.Odm_dlkm_partition)
+ if s.properties.System_other_partition != nil {
+ ctx.AddDependency(ctx.Module(), systemOtherDepTag, *s.properties.System_other_partition)
+ }
}
func (s *superImage) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -299,6 +312,20 @@
}
}
+ if s.properties.System_other_partition != nil {
+ if !slices.Contains(partitionList, "system") {
+ ctx.PropertyErrorf("system_other_partition", "Must have a system partition to use a system_other partition")
+ }
+ systemOther := ctx.GetDirectDepProxyWithTag(*s.properties.System_other_partition, systemOtherDepTag)
+ systemOtherFiles := android.OutputFilesForModule(ctx, systemOther, "")
+ if len(systemOtherFiles) != 1 {
+ ctx.PropertyErrorf("system_other_partition", "Expected 1 output file from module %q", *&s.properties.System_other_partition)
+ } else {
+ addStr("system_other_image", systemOtherFiles[0].String())
+ deps = append(deps, systemOtherFiles[0])
+ }
+ }
+
// Delay the error message until execution time because on aosp-main-future-without-vendor,
// BUILDING_VENDOR_IMAGE is false so we don't get the vendor image, but it's still listed in
// BOARD_GOOGLE_DYNAMIC_PARTITIONS_PARTITION_LIST.
diff --git a/filesystem/system_other.go b/filesystem/system_other.go
new file mode 100644
index 0000000..28fe1ce
--- /dev/null
+++ b/filesystem/system_other.go
@@ -0,0 +1,137 @@
+// 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 (
+ "android/soong/android"
+ "path/filepath"
+ "strings"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+)
+
+type SystemOtherImageProperties struct {
+ // The system_other image always requires a reference to the system image. The system_other
+ // partition gets built into the system partition's "b" slot in a/b partition builds. Thus, it
+ // copies most of its configuration from the system image, such as filesystem type, avb signing
+ // info, etc. Including it here does not automatically mean that it will pick up the system
+ // image's dexpropt files, it must also be listed in Preinstall_dexpreopt_files_from for that.
+ System_image *string
+
+ // This system_other partition will include all the dexpreopt files from the apps on these
+ // partitions.
+ Preinstall_dexpreopt_files_from []string
+}
+
+type systemOtherImage struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+ properties SystemOtherImageProperties
+}
+
+// The system_other image is the default contents of the "b" slot of the system image.
+// It contains the dexpreopt files of all the apps on the device, for a faster first boot.
+// Afterwards, at runtime, it will be used as a regular b slot for OTA updates, and the initial
+// dexpreopt files will be deleted.
+func SystemOtherImageFactory() android.Module {
+ module := &systemOtherImage{}
+ module.AddProperties(&module.properties)
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
+ return module
+}
+
+type systemImageDeptag struct {
+ blueprint.BaseDependencyTag
+}
+
+var systemImageDependencyTag = systemImageDeptag{}
+
+type dexpreoptDeptag struct {
+ blueprint.BaseDependencyTag
+}
+
+var dexpreoptDependencyTag = dexpreoptDeptag{}
+
+func (m *systemOtherImage) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if proptools.String(m.properties.System_image) == "" {
+ ctx.ModuleErrorf("system_image property must be set")
+ return
+ }
+ ctx.AddDependency(ctx.Module(), systemImageDependencyTag, *m.properties.System_image)
+ ctx.AddDependency(ctx.Module(), dexpreoptDependencyTag, m.properties.Preinstall_dexpreopt_files_from...)
+}
+
+func (m *systemOtherImage) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ systemImage := ctx.GetDirectDepProxyWithTag(*m.properties.System_image, systemImageDependencyTag)
+ systemInfo, ok := android.OtherModuleProvider(ctx, systemImage, FilesystemProvider)
+ if !ok {
+ ctx.PropertyErrorf("system_image", "Expected system_image module to provide FilesystemProvider")
+ return
+ }
+
+ output := android.PathForModuleOut(ctx, "system_other.img")
+ stagingDir := android.PathForModuleOut(ctx, "staging_dir")
+
+ builder := android.NewRuleBuilder(pctx, ctx)
+ builder.Command().Textf("rm -rf %s && mkdir -p %s", stagingDir, stagingDir)
+
+ specs := make(map[string]android.PackagingSpec)
+ for _, otherPartition := range m.properties.Preinstall_dexpreopt_files_from {
+ dexModule := ctx.GetDirectDepProxyWithTag(otherPartition, dexpreoptDependencyTag)
+ fsInfo, ok := android.OtherModuleProvider(ctx, dexModule, FilesystemProvider)
+ if !ok {
+ ctx.PropertyErrorf("preinstall_dexpreopt_files_from", "Expected module %q to provide FilesystemProvider", otherPartition)
+ return
+ }
+ // Merge all the packaging specs into 1 map
+ for k := range fsInfo.SpecsForSystemOther {
+ if _, ok := specs[k]; ok {
+ ctx.ModuleErrorf("Packaging spec %s given by two different partitions", k)
+ continue
+ }
+ specs[k] = fsInfo.SpecsForSystemOther[k]
+ }
+ }
+
+ // TOOD: CopySpecsToDir only exists on PackagingBase, but doesn't use any fields from it. Clean this up.
+ (&android.PackagingBase{}).CopySpecsToDir(ctx, builder, specs, stagingDir)
+
+ if len(m.properties.Preinstall_dexpreopt_files_from) > 0 {
+ builder.Command().Textf("touch %s", filepath.Join(stagingDir.String(), "system-other-odex-marker"))
+ }
+
+ // Most of the time, if build_image were to call a host tool, it accepts the path to the
+ // host tool in a field in the prop file. However, it doesn't have that option for fec, which
+ // it expects to just be on the PATH. Add fec to the PATH.
+ fec := ctx.Config().HostToolPath(ctx, "fec")
+ pathToolDirs := []string{filepath.Dir(fec.String())}
+
+ builder.Command().
+ Textf("PATH=%s:$PATH", strings.Join(pathToolDirs, ":")).
+ BuiltTool("build_image").
+ Text(stagingDir.String()). // input directory
+ Input(systemInfo.BuildImagePropFile).
+ Implicits(systemInfo.BuildImagePropFileDeps).
+ Implicit(fec).
+ Output(output).
+ Text(stagingDir.String())
+
+ builder.Build("build_system_other", "build system other")
+
+ ctx.SetOutputFiles(android.Paths{output}, "")
+ ctx.CheckbuildFile(output)
+}
diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go
index b7f312c..91826b2 100644
--- a/filesystem/vbmeta.go
+++ b/filesystem/vbmeta.go
@@ -148,8 +148,8 @@
var vbmetaChainedPartitionDep = chainedPartitionDep{}
func (v *vbmeta) DepsMutator(ctx android.BottomUpMutatorContext) {
- ctx.AddDependency(ctx.Module(), vbmetaPartitionDep, v.properties.Partitions.GetOrDefault(ctx, nil)...)
- ctx.AddDependency(ctx.Module(), vbmetaChainedPartitionDep, v.properties.Chained_partitions...)
+ ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), vbmetaPartitionDep, v.properties.Partitions.GetOrDefault(ctx, nil)...)
+ ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), vbmetaChainedPartitionDep, v.properties.Chained_partitions...)
}
func (v *vbmeta) installFileName() string {
diff --git a/fsgen/boot_imgs.go b/fsgen/boot_imgs.go
index 889a4c2..58ebcc4 100644
--- a/fsgen/boot_imgs.go
+++ b/fsgen/boot_imgs.go
@@ -69,23 +69,26 @@
ctx.CreateModule(
filesystem.BootimgFactory,
&filesystem.BootimgProperties{
- Kernel_prebuilt: proptools.StringPtr(":" + kernelFilegroupName),
- Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
- Partition_size: partitionSize,
- Use_avb: avbInfo.avbEnable,
- Avb_mode: avbInfo.avbMode,
- Avb_private_key: avbInfo.avbkeyFilegroup,
- Avb_rollback_index: avbInfo.avbRollbackIndex,
- Avb_algorithm: avbInfo.avbAlgorithm,
- Security_patch: securityPatch,
- Dtb_prebuilt: dtbPrebuilt,
- Cmdline: cmdline,
- Stem: proptools.StringPtr("boot.img"),
+ Kernel_prebuilt: proptools.StringPtr(":" + kernelFilegroupName),
+ Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
+ Partition_size: partitionSize,
+ Use_avb: avbInfo.avbEnable,
+ Avb_mode: avbInfo.avbMode,
+ Avb_private_key: avbInfo.avbkeyFilegroup,
+ Avb_rollback_index: avbInfo.avbRollbackIndex,
+ Avb_rollback_index_location: avbInfo.avbRollbackIndexLocation,
+ Avb_algorithm: avbInfo.avbAlgorithm,
+ Security_patch: securityPatch,
+ Dtb_prebuilt: dtbPrebuilt,
+ Cmdline: cmdline,
+ Stem: proptools.StringPtr("boot.img"),
},
&struct {
- Name *string
+ Name *string
+ Visibility []string
}{
- Name: proptools.StringPtr(bootImageName),
+ Name: proptools.StringPtr(bootImageName),
+ Visibility: []string{"//visibility:public"},
},
)
return true
@@ -123,23 +126,26 @@
ctx.CreateModule(
filesystem.BootimgFactory,
&filesystem.BootimgProperties{
- Boot_image_type: proptools.StringPtr("vendor_boot"),
- Ramdisk_module: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_ramdisk")),
- Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
- Partition_size: partitionSize,
- Use_avb: avbInfo.avbEnable,
- Avb_mode: avbInfo.avbMode,
- Avb_private_key: avbInfo.avbkeyFilegroup,
- Avb_rollback_index: avbInfo.avbRollbackIndex,
- Dtb_prebuilt: dtbPrebuilt,
- Cmdline: cmdline,
- Bootconfig: vendorBootConfigImg,
- Stem: proptools.StringPtr("vendor_boot.img"),
+ Boot_image_type: proptools.StringPtr("vendor_boot"),
+ Ramdisk_module: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_ramdisk")),
+ Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
+ Partition_size: partitionSize,
+ Use_avb: avbInfo.avbEnable,
+ Avb_mode: avbInfo.avbMode,
+ Avb_private_key: avbInfo.avbkeyFilegroup,
+ Avb_rollback_index: avbInfo.avbRollbackIndex,
+ Avb_rollback_index_location: avbInfo.avbRollbackIndexLocation,
+ Dtb_prebuilt: dtbPrebuilt,
+ Cmdline: cmdline,
+ Bootconfig: vendorBootConfigImg,
+ Stem: proptools.StringPtr("vendor_boot.img"),
},
&struct {
- Name *string
+ Name *string
+ Visibility []string
}{
- Name: proptools.StringPtr(bootImageName),
+ Name: proptools.StringPtr(bootImageName),
+ Visibility: []string{"//visibility:public"},
},
)
return true
@@ -172,22 +178,25 @@
ctx.CreateModule(
filesystem.BootimgFactory,
&filesystem.BootimgProperties{
- Boot_image_type: proptools.StringPtr("init_boot"),
- Ramdisk_module: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "ramdisk")),
- Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
- Security_patch: securityPatch,
- Partition_size: partitionSize,
- Use_avb: avbInfo.avbEnable,
- Avb_mode: avbInfo.avbMode,
- Avb_private_key: avbInfo.avbkeyFilegroup,
- Avb_rollback_index: avbInfo.avbRollbackIndex,
- Avb_algorithm: avbInfo.avbAlgorithm,
- Stem: proptools.StringPtr("init_boot.img"),
+ Boot_image_type: proptools.StringPtr("init_boot"),
+ Ramdisk_module: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "ramdisk")),
+ Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
+ Security_patch: securityPatch,
+ Partition_size: partitionSize,
+ Use_avb: avbInfo.avbEnable,
+ Avb_mode: avbInfo.avbMode,
+ Avb_private_key: avbInfo.avbkeyFilegroup,
+ Avb_rollback_index: avbInfo.avbRollbackIndex,
+ Avb_rollback_index_location: avbInfo.avbRollbackIndexLocation,
+ Avb_algorithm: avbInfo.avbAlgorithm,
+ Stem: proptools.StringPtr("init_boot.img"),
},
&struct {
- Name *string
+ Name *string
+ Visibility []string
}{
- Name: proptools.StringPtr(bootImageName),
+ Name: proptools.StringPtr(bootImageName),
+ Visibility: []string{"//visibility:public"},
},
)
return true
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index 7f5a068..ebcc68b 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -128,6 +128,10 @@
f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, partitionType)
}
}
+ finalSoongGeneratedPartitionNames := make([]string, 0, len(finalSoongGeneratedPartitions))
+ for _, partitionType := range finalSoongGeneratedPartitions {
+ finalSoongGeneratedPartitionNames = append(finalSoongGeneratedPartitionNames, generatedModuleNameForPartition(ctx.Config(), partitionType))
+ }
// Create android_info.prop
f.createAndroidInfo(ctx)
@@ -156,14 +160,32 @@
}
}
- for _, x := range createVbmetaPartitions(ctx, finalSoongGeneratedPartitions) {
+ var systemOtherImageName string
+ if buildingSystemOtherImage(partitionVars) {
+ systemModule := generatedModuleNameForPartition(ctx.Config(), "system")
+ systemOtherImageName = generatedModuleNameForPartition(ctx.Config(), "system_other")
+ ctx.CreateModule(
+ filesystem.SystemOtherImageFactory,
+ &filesystem.SystemOtherImageProperties{
+ System_image: &systemModule,
+ Preinstall_dexpreopt_files_from: finalSoongGeneratedPartitionNames,
+ },
+ &struct {
+ Name *string
+ }{
+ Name: proptools.StringPtr(systemOtherImageName),
+ },
+ )
+ }
+
+ for _, x := range f.createVbmetaPartitions(ctx, finalSoongGeneratedPartitions) {
f.properties.Vbmeta_module_names = append(f.properties.Vbmeta_module_names, x.moduleName)
f.properties.Vbmeta_partition_names = append(f.properties.Vbmeta_partition_names, x.partitionName)
}
var superImageSubpartitions []string
if buildingSuperImage(partitionVars) {
- superImageSubpartitions = createSuperImage(ctx, finalSoongGeneratedPartitions, partitionVars)
+ superImageSubpartitions = createSuperImage(ctx, finalSoongGeneratedPartitions, partitionVars, systemOtherImageName)
f.properties.Super_image = ":" + generatedModuleNameForPartition(ctx.Config(), "super")
}
@@ -183,6 +205,12 @@
return generatedModuleName(cfg, fmt.Sprintf("%s_image", partitionType))
}
+func buildingSystemOtherImage(partitionVars android.PartitionVariables) bool {
+ // TODO: Recreate this logic from make instead of just depending on the final result variable:
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/board_config.mk;l=429;drc=15a0df840e7093f65518003ab80cf24a3d9e8e6a
+ return partitionVars.BuildingSystemOtherImage
+}
+
func (f *filesystemCreator) createBootloaderFilegroup(ctx android.LoadHookContext) (string, bool) {
bootloaderPath := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.PrebuiltBootloader
if len(bootloaderPath) == 0 {
@@ -837,6 +865,8 @@
fsProps.Avb_algorithm = avbInfo.avbAlgorithm
// BOARD_AVB_SYSTEM_ROLLBACK_INDEX
fsProps.Rollback_index = avbInfo.avbRollbackIndex
+ // BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION
+ fsProps.Rollback_index_location = avbInfo.avbRollbackIndexLocation
fsProps.Avb_hash_algorithm = avbInfo.avbHashAlgorithm
fsProps.Partition_name = proptools.StringPtr(partitionType)
@@ -865,13 +895,14 @@
}
type avbInfo struct {
- avbEnable *bool
- avbKeyPath *string
- avbkeyFilegroup *string
- avbAlgorithm *string
- avbRollbackIndex *int64
- avbMode *string
- avbHashAlgorithm *string
+ avbEnable *bool
+ avbKeyPath *string
+ avbkeyFilegroup *string
+ avbAlgorithm *string
+ avbRollbackIndex *int64
+ avbRollbackIndexLocation *int64
+ avbMode *string
+ avbHashAlgorithm *string
}
func getAvbInfo(config android.Config, partitionType string) avbInfo {
@@ -918,6 +949,13 @@
}
result.avbRollbackIndex = &parsed
}
+ if specificPartitionVars.BoardAvbRollbackIndexLocation != "" {
+ parsed, err := strconv.ParseInt(specificPartitionVars.BoardAvbRollbackIndexLocation, 10, 64)
+ if err != nil {
+ panic(fmt.Sprintf("Rollback index location must be an int, got %s", specificPartitionVars.BoardAvbRollbackIndexLocation))
+ }
+ result.avbRollbackIndexLocation = &parsed
+ }
// Make allows you to pass arbitrary arguments to avbtool via this variable, but in practice
// it's only used for --hash_algorithm. The soong module has a dedicated property for the
diff --git a/fsgen/super_img.go b/fsgen/super_img.go
index 5c23868..e353688 100644
--- a/fsgen/super_img.go
+++ b/fsgen/super_img.go
@@ -27,7 +27,12 @@
return partitionVars.ProductBuildSuperPartition
}
-func createSuperImage(ctx android.LoadHookContext, partitions []string, partitionVars android.PartitionVariables) []string {
+func createSuperImage(
+ ctx android.LoadHookContext,
+ partitions []string,
+ partitionVars android.PartitionVariables,
+ systemOtherImageName string,
+) []string {
baseProps := &struct {
Name *string
}{
@@ -79,6 +84,10 @@
}
superImageProps.Partition_groups = partitionGroupsInfo
+ if systemOtherImageName != "" {
+ superImageProps.System_other_partition = proptools.StringPtr(systemOtherImageName)
+ }
+
var superImageSubpartitions []string
partitionNameProps := &filesystem.SuperImagePartitionNameProperties{}
if android.InList("system", partitions) {
diff --git a/fsgen/vbmeta_partitions.go b/fsgen/vbmeta_partitions.go
index e3dc416..be738ea 100644
--- a/fsgen/vbmeta_partitions.go
+++ b/fsgen/vbmeta_partitions.go
@@ -19,7 +19,6 @@
"android/soong/filesystem"
"slices"
"strconv"
- "strings"
"github.com/google/blueprint/proptools"
)
@@ -32,6 +31,27 @@
partitionName string
}
+// https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=4849;drc=62e20f0d218f60bae563b4ee742d88cca1fc1901
+var avbPartitions = []string{
+ "boot",
+ "init_boot",
+ "vendor_boot",
+ "vendor_kernel_boot",
+ "system",
+ "vendor",
+ "product",
+ "system_ext",
+ "odm",
+ "vendor_dlkm",
+ "odm_dlkm",
+ "system_dlkm",
+ "dtbo",
+ "pvmfw",
+ "recovery",
+ "vbmeta_system",
+ "vbmeta_vendor",
+}
+
// Creates the vbmeta partition and the chained vbmeta partitions. Returns the list of module names
// that the function created. May return nil if the product isn't using avb.
//
@@ -43,7 +63,7 @@
// like vbmeta_system might contain the avb metadata for just a few products. In cuttlefish
// vbmeta_system contains metadata about product, system, and system_ext. Using chained partitions,
// that group of partitions can be updated independently from the other signed partitions.
-func createVbmetaPartitions(ctx android.LoadHookContext, generatedPartitionTypes []string) []vbmetaModuleInfo {
+func (f *filesystemCreator) createVbmetaPartitions(ctx android.LoadHookContext, generatedPartitionTypes []string) []vbmetaModuleInfo {
partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
// Some products seem to have BuildingVbmetaImage as true even when BoardAvbEnable is false
if !partitionVars.BuildingVbmetaImage || !partitionVars.BoardAvbEnable {
@@ -52,14 +72,16 @@
var result []vbmetaModuleInfo
- var chainedPartitions []string
- var partitionTypesHandledByChainedPartitions []string
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=4593;drc=62e20f0d218f60bae563b4ee742d88cca1fc1901
+ var internalAvbPartitionsInChainedVbmetaImages []string
+ var chainedPartitionTypes []string
for _, chainedName := range android.SortedKeys(partitionVars.ChainedVbmetaPartitions) {
props := partitionVars.ChainedVbmetaPartitions[chainedName]
chainedName = "vbmeta_" + chainedName
if len(props.Partitions) == 0 {
continue
}
+ internalAvbPartitionsInChainedVbmetaImages = append(internalAvbPartitionsInChainedVbmetaImages, props.Partitions...)
if len(props.Key) == 0 {
ctx.ModuleErrorf("No key found for chained avb partition %q", chainedName)
continue
@@ -92,7 +114,6 @@
var partitionModules []string
for _, partition := range props.Partitions {
- partitionTypesHandledByChainedPartitions = append(partitionTypesHandledByChainedPartitions, partition)
if !slices.Contains(generatedPartitionTypes, partition) {
// The partition is probably unsupported.
continue
@@ -100,7 +121,7 @@
partitionModules = append(partitionModules, generatedModuleNameForPartition(ctx.Config(), partition))
}
- name := generatedModuleName(ctx.Config(), chainedName)
+ name := generatedModuleNameForPartition(ctx.Config(), chainedName)
ctx.CreateModuleInDirectory(
filesystem.VbmetaFactory,
".", // Create in the root directory for now so its easy to get the key
@@ -119,15 +140,15 @@
},
).HideFromMake()
- chainedPartitions = append(chainedPartitions, name)
-
result = append(result, vbmetaModuleInfo{
moduleName: name,
partitionName: chainedName,
})
+
+ chainedPartitionTypes = append(chainedPartitionTypes, chainedName)
}
- vbmetaModuleName := generatedModuleName(ctx.Config(), "vbmeta")
+ vbmetaModuleName := generatedModuleNameForPartition(ctx.Config(), "vbmeta")
var algorithm *string
var ri *int64
@@ -148,20 +169,79 @@
ri = &parsedRi
}
- var partitionModules []string
- for _, partitionType := range generatedPartitionTypes {
- if slices.Contains(partitionTypesHandledByChainedPartitions, partitionType) {
- // Already handled by a chained vbmeta partition
+ // --chain_partition argument is only set for partitions that set
+ // `BOARD_AVB_<partition name>_KEY_PATH` value and is not "recovery"
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=4823;drc=62e20f0d218f60bae563b4ee742d88cca1fc1901
+ includeAsChainedPartitionInVbmeta := func(partition string) bool {
+ val, ok := partitionVars.PartitionQualifiedVariables[partition]
+ return ok && len(val.BoardAvbKeyPath) > 0 && partition != "recovery"
+ }
+
+ // --include_descriptors_from_image is passed if both conditions are met:
+ // - `BOARD_AVB_<partition name>_KEY_PATH` value is not set
+ // - not included in INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES
+ // for partitions that set INSTALLED_<partition name>IMAGE_TARGET
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=4827;drc=62e20f0d218f60bae563b4ee742d88cca1fc1901
+ includeAsIncludedPartitionInVbmeta := func(partition string) bool {
+ if android.InList(partition, internalAvbPartitionsInChainedVbmetaImages) {
+ // Already handled by chained vbmeta partitions
+ return false
+ }
+ partitionQualifiedVars := partitionVars.PartitionQualifiedVariables[partition]
+
+ // The return logic in the switch cases below are identical to
+ // ifdef INSTALLED_<partition name>IMAGE_TARGET
+ switch partition {
+ case "boot":
+ return partitionQualifiedVars.BuildingImage || partitionQualifiedVars.PrebuiltImage || partitionVars.BoardUsesRecoveryAsBoot
+ case "vendor_kernel_boot", "dtbo":
+ return partitionQualifiedVars.PrebuiltImage
+ case "system":
+ return partitionQualifiedVars.BuildingImage
+ case "init_boot", "vendor_boot", "vendor", "product", "system_ext", "odm", "vendor_dlkm", "odm_dlkm", "system_dlkm":
+ return partitionQualifiedVars.BuildingImage || partitionQualifiedVars.PrebuiltImage
+ // TODO: Import BOARD_USES_PVMFWIMAGE
+ // ifeq ($(BOARD_USES_PVMFWIMAGE),true)
+ // case "pvmfw":
+ case "recovery":
+ // ifdef INSTALLED_RECOVERYIMAGE_TARGET
+ return !ctx.DeviceConfig().BoardUsesRecoveryAsBoot() && !ctx.DeviceConfig().BoardMoveRecoveryResourcesToVendorBoot()
+ // Technically these partitions are determined based on len(BOARD_AVB_VBMETA_SYSTEM) and
+ // len(BOARD_AVB_VBMETA_VENDOR) but if these are non empty these partitions are
+ // already included in the chained partitions.
+ case "vbmeta_system", "vbmeta_vendor":
+ return false
+ default:
+ return false
+ }
+ }
+
+ var chainedPartitionModules []string
+ var includePartitionModules []string
+ allGeneratedPartitionTypes := append(generatedPartitionTypes,
+ chainedPartitionTypes...,
+ )
+ if len(f.properties.Boot_image) > 0 {
+ allGeneratedPartitionTypes = append(allGeneratedPartitionTypes, "boot")
+ }
+ if len(f.properties.Init_boot_image) > 0 {
+ allGeneratedPartitionTypes = append(allGeneratedPartitionTypes, "init_boot")
+ }
+ if len(f.properties.Vendor_boot_image) > 0 {
+ allGeneratedPartitionTypes = append(allGeneratedPartitionTypes, "vendor_boot")
+ }
+
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=4919;drc=62e20f0d218f60bae563b4ee742d88cca1fc1901
+ for _, partitionType := range android.SortedUniqueStrings(append(avbPartitions, chainedPartitionTypes...)) {
+ if !android.InList(partitionType, allGeneratedPartitionTypes) {
+ // Skip if the partition is not auto generated
continue
}
- if strings.Contains(partitionType, "ramdisk") || strings.Contains(partitionType, "boot") || partitionType == "userdata" || partitionType == "recovery" {
- // ramdisk and userdata are never signed with avb information
- // recovery partition is skipped in adding the partition descriptor into vbmeta.img.
- // boot partitions just have the avb footer, and don't have a corresponding vbmeta
- // partition.
- continue
+ if includeAsChainedPartitionInVbmeta(partitionType) {
+ chainedPartitionModules = append(chainedPartitionModules, generatedModuleNameForPartition(ctx.Config(), partitionType))
+ } else if includeAsIncludedPartitionInVbmeta(partitionType) {
+ includePartitionModules = append(includePartitionModules, generatedModuleNameForPartition(ctx.Config(), partitionType))
}
- partitionModules = append(partitionModules, generatedModuleNameForPartition(ctx.Config(), partitionType))
}
ctx.CreateModuleInDirectory(
@@ -172,8 +252,8 @@
Algorithm: algorithm,
Private_key: key,
Rollback_index: ri,
- Chained_partitions: chainedPartitions,
- Partitions: proptools.NewSimpleConfigurable(partitionModules),
+ Chained_partitions: chainedPartitionModules,
+ Partitions: proptools.NewSimpleConfigurable(includePartitionModules),
Partition_name: proptools.StringPtr("vbmeta"),
}, &struct {
Name *string
diff --git a/java/app.go b/java/app.go
index 34a172e..557ba28 100644
--- a/java/app.go
+++ b/java/app.go
@@ -70,6 +70,8 @@
// EmbeddedJNILibs is the list of paths to JNI libraries that were embedded in the APK.
EmbeddedJNILibs android.Paths
+
+ MergedManifestFile android.Path
}
var AppInfoProvider = blueprint.NewProvider[*AppInfo]()
@@ -419,9 +421,10 @@
}
}
android.SetProvider(ctx, AppInfoProvider, &AppInfo{
- Updatable: Bool(a.appProperties.Updatable),
- TestHelperApp: false,
- EmbeddedJNILibs: embeddedJniLibs,
+ Updatable: Bool(a.appProperties.Updatable),
+ TestHelperApp: false,
+ EmbeddedJNILibs: embeddedJniLibs,
+ MergedManifestFile: a.mergedManifest,
})
a.requiredModuleNames = a.getRequiredModuleNames(ctx)
@@ -707,7 +710,7 @@
return android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
}
-func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path) {
+func (a *AndroidApp) dexBuildActions(ctx android.ModuleContext) (android.Path, android.Path, *JavaInfo) {
a.dexpreopter.installPath = a.installPath(ctx)
a.dexpreopter.isApp = true
if a.dexProperties.Uncompress_dex == nil {
@@ -753,12 +756,8 @@
packageResources = binaryResources
}
}
- if javaInfo != nil {
- setExtraJavaInfo(ctx, a, javaInfo)
- android.SetProvider(ctx, JavaInfoProvider, javaInfo)
- }
- return a.dexJarFile.PathOrNil(), packageResources
+ return a.dexJarFile.PathOrNil(), packageResources, javaInfo
}
func (a *AndroidApp) jniBuildActions(jniLibs []jniLib, prebuiltJniPackages android.Paths, ctx android.ModuleContext) android.WritablePath {
@@ -965,7 +964,7 @@
a.linter.resources = a.aapt.resourceFiles
a.linter.buildModuleReportZip = ctx.Config().UnbundledBuildApps()
- dexJarFile, packageResources := a.dexBuildActions(ctx)
+ dexJarFile, packageResources, javaInfo := a.dexBuildActions(ctx)
// No need to check the SDK version of the JNI deps unless we embed them
checkNativeSdkVersion := a.shouldEmbedJnis(ctx) && !Bool(a.appProperties.Jni_uses_platform_apis)
@@ -1081,6 +1080,12 @@
},
)
+ if javaInfo != nil {
+ javaInfo.OutputFile = a.outputFile
+ setExtraJavaInfo(ctx, a, javaInfo)
+ android.SetProvider(ctx, JavaInfoProvider, javaInfo)
+ }
+
a.setOutputFiles(ctx)
}
diff --git a/java/app_import_test.go b/java/app_import_test.go
index a28c28b..2ec7ed4 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -59,6 +59,45 @@
android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"])
}
+func TestAndroidAppImportWithDefaults(t *testing.T) {
+ ctx, _ := testJava(t, `
+ android_app_import {
+ name: "foo",
+ defaults: ["foo_defaults"],
+ }
+
+ java_defaults {
+ name: "foo_defaults",
+ apk: "prebuilts/apk/app.apk",
+ certificate: "platform",
+ dex_preopt: {
+ enabled: true,
+ },
+ }
+ `)
+
+ variant := ctx.ModuleForTests("foo", "android_common")
+
+ // Check dexpreopt outputs.
+ if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil ||
+ variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil {
+ t.Errorf("can't find dexpreopt outputs")
+ }
+
+ // Check cert signing flag.
+ signedApk := variant.Output("signed/foo.apk")
+ signingFlag := signedApk.Args["certificates"]
+ expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
+ if expected != signingFlag {
+ t.Errorf("Incorrect signing flags, expected: %q, got: %q", expected, signingFlag)
+ }
+ rule := variant.Rule("genProvenanceMetaData")
+ android.AssertStringEquals(t, "Invalid input", "prebuilts/apk/app.apk", rule.Inputs[0].String())
+ android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/foo/provenance_metadata.textproto", rule.Output.String())
+ android.AssertStringEquals(t, "Invalid args", "foo", rule.Args["module_name"])
+ android.AssertStringEquals(t, "Invalid args", "/system/app/foo/foo.apk", rule.Args["install_path"])
+}
+
func TestAndroidAppImport_NoDexPreopt(t *testing.T) {
ctx, _ := testJava(t, `
android_app_import {
diff --git a/java/base.go b/java/base.go
index 0b896d8..d89c324 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1336,14 +1336,24 @@
kotlincFlags := j.properties.Kotlincflags
CheckKotlincFlags(ctx, kotlincFlags)
- kotlin_lang_version := proptools.StringDefault(j.properties.Kotlin_lang_version, "1.9")
- if kotlin_lang_version == "1.9" {
+ // Available kotlin versions can be found at
+ // https://github.com/JetBrains/kotlin/blob/master/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt#L560
+ // in the `LanguageVersion` class.
+ // For now, avoid targeting language versions directly, as we'd like to kee our source
+ // code version aligned as much as possible. Ideally, after defaulting to "2", we
+ // can remove the "1.9" option entirely, or at least make it emit a warning.
+ kotlin_default_lang_version := "1.9"
+ if build_flag_lang_version, ok := ctx.Config().GetBuildFlag("RELEASE_KOTLIN_LANG_VERSION"); ok {
+ kotlin_default_lang_version = build_flag_lang_version
+ }
+ kotlin_lang_version := proptools.StringDefault(j.properties.Kotlin_lang_version, kotlin_default_lang_version)
+ switch kotlin_lang_version {
+ case "1.9":
kotlincFlags = append(kotlincFlags, "-language-version 1.9")
- } else if kotlin_lang_version == "2" {
+ case "2":
kotlincFlags = append(kotlincFlags, "-Xsuppress-version-warnings", "-Xconsistent-data-class-copy-visibility")
- } else {
+ default:
ctx.PropertyErrorf("kotlin_lang_version", "Must be one of `1.9` or `2`")
-
}
// Workaround for KT-46512
@@ -1970,6 +1980,7 @@
StubsLinkType: j.stubsLinkType,
AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles,
SdkVersion: j.SdkVersion(ctx),
+ OutputFile: j.outputFile,
}
}
@@ -2219,6 +2230,8 @@
func (j *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) {
if j.expandJarjarRules != nil {
dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
+ }
+ if j.headerJarFile != nil {
// Add the header jar so that the rdeps can be resolved to the repackaged classes.
dpInfo.Jars = append(dpInfo.Jars, j.headerJarFile.String())
}
diff --git a/java/dex.go b/java/dex.go
index bc14290..00a0537 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -378,7 +378,7 @@
r8Flags = append(r8Flags, "--keep-runtime-invisible-annotations")
}
- if BoolDefault(opt.Proguard_compatibility, true) {
+ if BoolDefault(opt.Proguard_compatibility, !ctx.Config().UseR8FullModeByDefault()) {
r8Flags = append(r8Flags, "--force-proguard-compatibility")
}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index efca913..24e5f50 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -204,7 +204,7 @@
}
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
psi := android.PrebuiltSelectionInfoMap{}
- ctx.VisitDirectDeps(func(am android.Module) {
+ ctx.VisitDirectDepsProxy(func(am android.ModuleProxy) {
if prebuiltSelectionInfo, ok := android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider); ok {
psi = prebuiltSelectionInfo
}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index ac1a007..e0c2e63 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -635,18 +635,12 @@
cmd.Implicit(dep)
} else if depBase == AndroidPlusUpdatableJar && d.properties.Extensions_info_file != nil {
// The output api-versions.xml has been requested to include information on SDK
- // extensions. That means it also needs to include
- // so
- // The module-lib and system-server directories should use `android-plus-updatable.jar`
- // instead of `android.jar`. See AndroidPlusUpdatableJar for more information.
- cmd.Implicit(dep)
- } else if filename != "android.jar" && depBase == "android.jar" {
- // Metalava implicitly searches these patterns:
- // prebuilts/tools/common/api-versions/android-{version:level}/android.jar
- // prebuilts/sdk/{version:level}/public/android.jar
- // Add android.jar files from the api_levels_annotations_dirs directories to try
- // to satisfy these patterns. If Metalava can't find a match for an API level
- // between 1 and 28 in at least one pattern it will fail.
+ // extensions, i.e. updatable Apis. That means it also needs to include the history of
+ // those updatable APIs. Usually, they would be included in the `android.jar` file but
+ // unfortunately, the `module-lib` and `system-server` cannot as it would lead to build
+ // cycles. So, the module-lib and system-server directories contain an
+ // `android-plus-updatable.jar` that should be used instead of `android.jar`. See
+ // AndroidPlusUpdatableJar for more information.
cmd.Implicit(dep)
}
}
@@ -663,7 +657,7 @@
for _, sdkDir := range sdkDirs {
for _, dir := range dirs {
addPattern := func(jarFilename string) {
- cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:level}/%s/%s", dir, sdkDir, jarFilename))
+ cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:major.minor?}/%s/%s", dir, sdkDir, jarFilename))
}
if sdkDir == "module-lib" || sdkDir == "system-server" {
@@ -678,6 +672,10 @@
addPattern(filename)
}
+
+ if extensions_dir != "" {
+ cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:extension}/%s/{module}.jar", extensions_dir, sdkDir))
+ }
}
if d.properties.Extensions_info_file != nil {
@@ -686,7 +684,6 @@
}
info_file := android.PathForModuleSrc(ctx, *d.properties.Extensions_info_file)
cmd.Implicit(info_file)
- cmd.FlagWithArg("--sdk-extensions-root ", extensions_dir)
cmd.FlagWithArg("--sdk-extensions-info ", info_file.String())
}
}
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index 37740ae..75a0a31 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -88,7 +88,7 @@
cmdline := String(sboxProto.Commands[0].Command)
android.AssertStringContainsEquals(t, "api-versions generation flag", cmdline, "--generate-api-levels", c.generate_xml)
if c.expectedJarFilename != "" {
- expected := "--android-jar-pattern ./{version:level}/public/" + c.expectedJarFilename
+ expected := "--android-jar-pattern ./{version:major.minor?}/public/" + c.expectedJarFilename
if !strings.Contains(cmdline, expected) {
t.Errorf("For %q, expected metalava argument %q, but was not found %q", c.moduleName, expected, cmdline)
}
@@ -142,8 +142,8 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "public")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/{version:level}/public/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar",
}, patterns)
}
@@ -151,10 +151,10 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "system")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/{version:level}/system/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/system/android.jar",
- "--android-jar-pattern somedir/{version:level}/public/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar",
}, patterns)
}
@@ -162,12 +162,12 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "module-lib")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/{version:level}/module-lib/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/module-lib/android.jar",
- "--android-jar-pattern somedir/{version:level}/system/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/system/android.jar",
- "--android-jar-pattern somedir/{version:level}/public/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/module-lib/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/module-lib/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar",
}, patterns)
}
@@ -175,14 +175,14 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "system-server")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/{version:level}/system-server/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/system-server/android.jar",
- "--android-jar-pattern somedir/{version:level}/module-lib/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/module-lib/android.jar",
- "--android-jar-pattern somedir/{version:level}/system/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/system/android.jar",
- "--android-jar-pattern somedir/{version:level}/public/android.jar",
- "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/system-server/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/system-server/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/module-lib/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/module-lib/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/system/android.jar",
+ "--android-jar-pattern somedir/{version:major.minor?}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:major.minor?}/public/android.jar",
}, patterns)
}
@@ -303,7 +303,7 @@
m := ctx.ModuleForTests("baz-stubs", "android_common")
manifest := m.Output("metalava.sbox.textproto")
cmdline := String(android.RuleBuilderSboxProtoForTests(t, ctx, manifest).Commands[0].Command)
- android.AssertStringDoesContain(t, "sdk-extensions-root present", cmdline, "--sdk-extensions-root sdk/extensions")
+ android.AssertStringDoesContain(t, "android-jar-pattern present", cmdline, "--android-jar-pattern sdk/extensions/{version:extension}/public/{module}.jar")
android.AssertStringDoesContain(t, "sdk-extensions-info present", cmdline, "--sdk-extensions-info sdk/extensions/info.txt")
}
diff --git a/java/java.go b/java/java.go
index b2d8b72..fafe9f9 100644
--- a/java/java.go
+++ b/java/java.go
@@ -360,6 +360,9 @@
SdkVersion android.SdkSpec
+ // output file of the module, which may be a classes jar or a dex jar
+ OutputFile android.Path
+
AndroidLibraryDependencyInfo *AndroidLibraryDependencyInfo
UsesLibraryDependencyInfo *UsesLibraryDependencyInfo
@@ -1658,17 +1661,17 @@
j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs)
- ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(dataNativeBinsTag, func(dep android.ModuleProxy) {
j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
})
- ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(dataDeviceBinsTag, func(dep android.ModuleProxy) {
j.data = append(j.data, android.OutputFileForModule(ctx, dep, ""))
})
var directImplementationDeps android.Paths
var transitiveImplementationDeps []depset.DepSet[android.Path]
- ctx.VisitDirectDepsWithTag(jniLibTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(jniLibTag, func(dep android.ModuleProxy) {
sharedLibInfo, _ := android.OtherModuleProvider(ctx, dep, cc.SharedLibraryInfoProvider)
if sharedLibInfo.SharedLibrary != nil {
// Copy to an intermediate output directory to append "lib[64]" to the path,
@@ -3358,6 +3361,8 @@
&bootclasspathFragmentProperties{},
&SourceOnlyBootclasspathProperties{},
&ravenwoodTestProperties{},
+ &AndroidAppImportProperties{},
+ &UsesLibraryProperties{},
)
android.InitDefaultsModule(module)
diff --git a/java/ravenwood.go b/java/ravenwood.go
index 84d6a9f..8c8d8e9 100644
--- a/java/ravenwood.go
+++ b/java/ravenwood.go
@@ -185,26 +185,24 @@
// All JNI libraries included in the runtime
var runtimeJniModuleNames map[string]bool
- if utils := ctx.GetDirectDepsWithTag(ravenwoodUtilsTag)[0]; utils != nil {
- for _, installFile := range android.OtherModuleProviderOrDefault(
- ctx, utils, android.InstallFilesProvider).InstallFiles {
- installDeps = append(installDeps, installFile)
- }
- jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider)
- if ok {
- runtimeJniModuleNames = jniDeps.names
- }
+ utils := ctx.GetDirectDepsProxyWithTag(ravenwoodUtilsTag)[0]
+ for _, installFile := range android.OtherModuleProviderOrDefault(
+ ctx, utils, android.InstallFilesProvider).InstallFiles {
+ installDeps = append(installDeps, installFile)
+ }
+ jniDeps, ok := android.OtherModuleProvider(ctx, utils, ravenwoodLibgroupJniDepProvider)
+ if ok {
+ runtimeJniModuleNames = jniDeps.names
}
- if runtime := ctx.GetDirectDepsWithTag(ravenwoodRuntimeTag)[0]; runtime != nil {
- for _, installFile := range android.OtherModuleProviderOrDefault(
- ctx, runtime, android.InstallFilesProvider).InstallFiles {
- installDeps = append(installDeps, installFile)
- }
- jniDeps, ok := android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider)
- if ok {
- runtimeJniModuleNames = jniDeps.names
- }
+ runtime := ctx.GetDirectDepsProxyWithTag(ravenwoodRuntimeTag)[0]
+ for _, installFile := range android.OtherModuleProviderOrDefault(
+ ctx, runtime, android.InstallFilesProvider).InstallFiles {
+ installDeps = append(installDeps, installFile)
+ }
+ jniDeps, ok = android.OtherModuleProvider(ctx, runtime, ravenwoodLibgroupJniDepProvider)
+ if ok {
+ runtimeJniModuleNames = jniDeps.names
}
// Also remember what JNI libs are in the runtime.
@@ -228,7 +226,7 @@
resApkInstallPath := installPath.Join(ctx, "ravenwood-res-apks")
copyResApk := func(tag blueprint.DependencyTag, toFileName string) {
- if resApk := ctx.GetDirectDepsWithTag(tag); len(resApk) > 0 {
+ if resApk := ctx.GetDirectDepsProxyWithTag(tag); len(resApk) > 0 {
installFile := android.OutputFileForModule(ctx, resApk[0], "")
installResApk := ctx.InstallFile(resApkInstallPath, toFileName, installFile)
installDeps = append(installDeps, installResApk)
@@ -345,7 +343,7 @@
// Install our runtime into expected location for packaging
installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
for _, lib := range r.ravenwoodLibgroupProperties.Libs {
- libModule := ctx.GetDirectDepWithTag(lib, ravenwoodLibContentTag)
+ libModule := ctx.GetDirectDepProxyWithTag(lib, ravenwoodLibContentTag)
if libModule == nil {
if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{lib})
diff --git a/java/robolectric.go b/java/robolectric.go
index 6c74d08..ff0c850 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -29,6 +29,12 @@
RegisterRobolectricBuildComponents(android.InitRegistrationContext)
}
+type RobolectricRuntimesInfo struct {
+ Runtimes []android.InstallPath
+}
+
+var RobolectricRuntimesInfoProvider = blueprint.NewProvider[RobolectricRuntimesInfo]()
+
type roboRuntimeOnlyDependencyTag struct {
blueprint.BaseDependencyTag
}
@@ -141,7 +147,7 @@
var options []tradefed.Option
options = append(options, tradefed.Option{Name: "java-flags", Value: "-Drobolectric=true"})
if proptools.BoolDefault(r.robolectricProperties.Strict_mode, true) {
- options = append(options, tradefed.Option{Name: "java-flags", Value: "-Drobolectric.strict.mode=true"})
+ options = append(options, tradefed.Option{Name: "java-flags", Value: "-Drobolectric.strict.mode=true"})
}
r.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
@@ -159,25 +165,27 @@
r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_first_prefer32_data)...)
var ok bool
- var instrumentedApp *AndroidApp
+ var instrumentedApp *JavaInfo
+ var appInfo *AppInfo
// TODO: this inserts paths to built files into the test, it should really be inserting the contents.
- instrumented := ctx.GetDirectDepsWithTag(instrumentationForTag)
+ instrumented := ctx.GetDirectDepsProxyWithTag(instrumentationForTag)
if len(instrumented) == 1 {
- instrumentedApp, ok = instrumented[0].(*AndroidApp)
+ appInfo, ok = android.OtherModuleProvider(ctx, instrumented[0], AppInfoProvider)
if !ok {
ctx.PropertyErrorf("instrumentation_for", "dependency must be an android_app")
}
+ instrumentedApp = android.OtherModuleProviderOrDefault(ctx, instrumented[0], JavaInfoProvider)
} else if !ctx.Config().AllowMissingDependencies() {
panic(fmt.Errorf("expected exactly 1 instrumented dependency, got %d", len(instrumented)))
}
var resourceApk android.Path
var manifest android.Path
- if instrumentedApp != nil {
- manifest = instrumentedApp.mergedManifestFile
- resourceApk = instrumentedApp.outputFile
+ if appInfo != nil {
+ manifest = appInfo.MergedManifestFile
+ resourceApk = instrumentedApp.OutputFile
}
roboTestConfigJar := android.PathForModuleOut(ctx, "robolectric_samedir", "samedir_config.jar")
@@ -185,7 +193,7 @@
extraCombinedJars := android.Paths{roboTestConfigJar}
- handleLibDeps := func(dep android.Module) {
+ handleLibDeps := func(dep android.ModuleProxy) {
if !android.InList(ctx.OtherModuleName(dep), config.FrameworkLibraries) {
if m, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider); ok {
extraCombinedJars = append(extraCombinedJars, m.ImplementationAndResourcesJars...)
@@ -193,19 +201,19 @@
}
}
- for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
+ for _, dep := range ctx.GetDirectDepsProxyWithTag(libTag) {
handleLibDeps(dep)
}
- for _, dep := range ctx.GetDirectDepsWithTag(sdkLibTag) {
+ for _, dep := range ctx.GetDirectDepsProxyWithTag(sdkLibTag) {
handleLibDeps(dep)
}
// handle the runtimeOnly tag for strict_mode
- for _, dep := range ctx.GetDirectDepsWithTag(roboRuntimeOnlyDepTag) {
+ for _, dep := range ctx.GetDirectDepsProxyWithTag(roboRuntimeOnlyDepTag) {
handleLibDeps(dep)
}
- if instrumentedApp != nil {
- extraCombinedJars = append(extraCombinedJars, instrumentedApp.implementationAndResourcesJar)
+ if appInfo != nil {
+ extraCombinedJars = append(extraCombinedJars, instrumentedApp.ImplementationAndResourcesJars...)
}
r.stem = proptools.StringDefault(r.overridableProperties.Stem, ctx.ModuleName())
@@ -233,8 +241,8 @@
installDeps = append(installDeps, installedResourceApk)
}
- runtimes := ctx.GetDirectDepWithTag("robolectric-android-all-prebuilts", roboRuntimesTag)
- for _, runtime := range runtimes.(*robolectricRuntimes).runtimes {
+ runtimes := ctx.GetDirectDepProxyWithTag("robolectric-android-all-prebuilts", roboRuntimesTag)
+ for _, runtime := range android.OtherModuleProviderOrDefault(ctx, runtimes, RobolectricRuntimesInfoProvider).Runtimes {
installDeps = append(installDeps, runtime)
}
@@ -368,7 +376,7 @@
}
if !ctx.Config().AlwaysUsePrebuiltSdks() && r.props.Lib != nil {
- runtimeFromSourceModule := ctx.GetDirectDepWithTag(String(r.props.Lib), libTag)
+ runtimeFromSourceModule := ctx.GetDirectDepProxyWithTag(String(r.props.Lib), libTag)
if runtimeFromSourceModule == nil {
if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{String(r.props.Lib)})
@@ -386,6 +394,10 @@
installedRuntime := ctx.InstallFile(androidAllDir, runtimeName, runtimeFromSourceJar)
r.runtimes = append(r.runtimes, installedRuntime)
}
+
+ android.SetProvider(ctx, RobolectricRuntimesInfoProvider, RobolectricRuntimesInfo{
+ Runtimes: r.runtimes,
+ })
}
func (r *robolectricRuntimes) InstallInTestcases() bool { return true }
diff --git a/python/binary.go b/python/binary.go
index 5f60761..a3acb34 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -22,8 +22,14 @@
"strings"
"android/soong/android"
+ "android/soong/cc"
+ "github.com/google/blueprint"
)
+type PythonBinaryInfo struct{}
+
+var PythonBinaryInfoProvider = blueprint.NewProvider[PythonBinaryInfo]()
+
func init() {
registerPythonBinaryComponents(android.InitRegistrationContext)
}
@@ -103,6 +109,9 @@
p.buildBinary(ctx)
p.installedDest = ctx.InstallFile(installDir(ctx, "bin", "", ""),
p.installSource.Base(), p.installSource)
+
+ android.SetProvider(ctx, PythonBinaryInfoProvider, PythonBinaryInfo{})
+
ctx.SetOutputFiles(android.Paths{p.installSource}, "")
}
@@ -116,13 +125,13 @@
var launcherPath android.OptionalPath
if embeddedLauncher {
- ctx.VisitDirectDepsWithTag(launcherTag, func(m android.Module) {
- if provider, ok := m.(IntermPathProvider); ok {
+ ctx.VisitDirectDepsProxyWithTag(launcherTag, func(m android.ModuleProxy) {
+ if provider, ok := android.OtherModuleProvider(ctx, m, cc.LinkableInfoProvider); ok {
if launcherPath.Valid() {
panic(fmt.Errorf("launcher path was found before: %q",
launcherPath))
}
- launcherPath = provider.IntermPathForModuleOut()
+ launcherPath = provider.OutputFile
}
})
}
@@ -140,7 +149,7 @@
var sharedLibs []string
// if embedded launcher is enabled, we need to collect the shared library dependencies of the
// launcher
- for _, dep := range ctx.GetDirectDepsWithTag(launcherSharedLibTag) {
+ for _, dep := range ctx.GetDirectDepsProxyWithTag(launcherSharedLibTag) {
sharedLibs = append(sharedLibs, ctx.OtherModuleName(dep))
}
p.androidMkSharedLibs = sharedLibs
diff --git a/python/python.go b/python/python.go
index 914b77e..09af62e 100644
--- a/python/python.go
+++ b/python/python.go
@@ -22,12 +22,23 @@
"regexp"
"strings"
+ "android/soong/cc"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
)
+type PythonLibraryInfo struct {
+ SrcsPathMappings []pathMapping
+ DataPathMappings []pathMapping
+ SrcsZip android.Path
+ PrecompiledSrcsZip android.Path
+ PkgPath string
+}
+
+var PythonLibraryInfoProvider = blueprint.NewProvider[PythonLibraryInfo]()
+
func init() {
registerPythonMutators(android.InitRegistrationContext)
}
@@ -173,16 +184,6 @@
}
}
-// interface implemented by Python modules to provide source and data mappings and zip to python
-// modules that depend on it
-type pythonDependency interface {
- getSrcsPathMappings() []pathMapping
- getDataPathMappings() []pathMapping
- getSrcsZip() android.Path
- getPrecompiledSrcsZip() android.Path
- getPkgPath() string
-}
-
// getSrcsPathMappings gets this module's path mapping of src source path : runfiles destination
func (p *PythonLibraryModule) getSrcsPathMappings() []pathMapping {
return p.srcsPathMappings
@@ -212,8 +213,6 @@
return &p.properties
}
-var _ pythonDependency = (*PythonLibraryModule)(nil)
-
func (p *PythonLibraryModule) init() android.Module {
p.AddProperties(&p.properties, &p.protoProperties, &p.sourceProperties)
android.InitAndroidArchModule(p, p.hod, p.multilib)
@@ -464,7 +463,7 @@
expandedData = append(expandedData, android.PathsForModuleSrc(ctx, p.properties.Device_first_data)...)
// Emulate the data property for java_data dependencies.
- for _, javaData := range ctx.GetDirectDepsWithTag(javaDataTag) {
+ for _, javaData := range ctx.GetDirectDepsProxyWithTag(javaDataTag) {
expandedData = append(expandedData, android.OutputFilesForModule(ctx, javaData, "")...)
}
@@ -492,6 +491,14 @@
// generate the zipfile of all source and data files
p.srcsZip = p.createSrcsZip(ctx, pkgPath)
p.precompiledSrcsZip = p.precompileSrcs(ctx)
+
+ android.SetProvider(ctx, PythonLibraryInfoProvider, PythonLibraryInfo{
+ SrcsPathMappings: p.getSrcsPathMappings(),
+ DataPathMappings: p.getDataPathMappings(),
+ SrcsZip: p.getSrcsZip(),
+ PkgPath: p.getPkgPath(),
+ PrecompiledSrcsZip: p.getPrecompiledSrcsZip(),
+ })
}
func isValidPythonPath(path string) error {
@@ -657,16 +664,16 @@
stdLib = p.srcsZip
stdLibPkg = p.getPkgPath()
} else {
- ctx.VisitDirectDepsWithTag(hostStdLibTag, func(module android.Module) {
- if dep, ok := module.(pythonDependency); ok {
- stdLib = dep.getPrecompiledSrcsZip()
- stdLibPkg = dep.getPkgPath()
+ ctx.VisitDirectDepsProxyWithTag(hostStdLibTag, func(module android.ModuleProxy) {
+ if dep, ok := android.OtherModuleProvider(ctx, module, PythonLibraryInfoProvider); ok {
+ stdLib = dep.PrecompiledSrcsZip
+ stdLibPkg = dep.PkgPath
}
})
}
- ctx.VisitDirectDepsWithTag(hostLauncherTag, func(module android.Module) {
- if dep, ok := module.(IntermPathProvider); ok {
- optionalLauncher := dep.IntermPathForModuleOut()
+ ctx.VisitDirectDepsProxyWithTag(hostLauncherTag, func(module android.ModuleProxy) {
+ if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok {
+ optionalLauncher := dep.OutputFile
if optionalLauncher.Valid() {
launcher = optionalLauncher.Path()
}
@@ -674,9 +681,9 @@
})
var launcherSharedLibs android.Paths
var ldLibraryPath []string
- ctx.VisitDirectDepsWithTag(hostlauncherSharedLibTag, func(module android.Module) {
- if dep, ok := module.(IntermPathProvider); ok {
- optionalPath := dep.IntermPathForModuleOut()
+ ctx.VisitDirectDepsProxyWithTag(hostlauncherSharedLibTag, func(module android.ModuleProxy) {
+ if dep, ok := android.OtherModuleProvider(ctx, module, cc.LinkableInfoProvider); ok {
+ optionalPath := dep.OutputFile
if optionalPath.Valid() {
launcherSharedLibs = append(launcherSharedLibs, optionalPath.Path())
ldLibraryPath = append(ldLibraryPath, filepath.Dir(optionalPath.Path().String()))
@@ -707,16 +714,6 @@
return out
}
-// isPythonLibModule returns whether the given module is a Python library PythonLibraryModule or not
-func isPythonLibModule(module blueprint.Module) bool {
- if _, ok := module.(*PythonLibraryModule); ok {
- if _, ok := module.(*PythonBinaryModule); !ok {
- return true
- }
- }
- return false
-}
-
// collectPathsFromTransitiveDeps checks for source/data files for duplicate paths
// for module and its transitive dependencies and collects list of data/source file
// zips for transitive dependencies.
@@ -737,7 +734,7 @@
var result android.Paths
// visit all its dependencies in depth first.
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ ctx.WalkDepsProxy(func(child, _ android.ModuleProxy) bool {
// we only collect dependencies tagged as python library deps
if ctx.OtherModuleDependencyTag(child) != pythonLibTag {
return false
@@ -747,27 +744,29 @@
}
seen[child] = true
// Python modules only can depend on Python libraries.
- if !isPythonLibModule(child) {
+ dep, isLibrary := android.OtherModuleProvider(ctx, child, PythonLibraryInfoProvider)
+ _, isBinary := android.OtherModuleProvider(ctx, child, PythonBinaryInfoProvider)
+ if !isLibrary || isBinary {
ctx.PropertyErrorf("libs",
"the dependency %q of module %q is not Python library!",
ctx.OtherModuleName(child), ctx.ModuleName())
}
// collect source and data paths, checking that there are no duplicate output file conflicts
- if dep, ok := child.(pythonDependency); ok {
- srcs := dep.getSrcsPathMappings()
+ if isLibrary {
+ srcs := dep.SrcsPathMappings
for _, path := range srcs {
checkForDuplicateOutputPath(ctx, destToPySrcs,
path.dest, path.src.String(), ctx.ModuleName(), ctx.OtherModuleName(child))
}
- data := dep.getDataPathMappings()
+ data := dep.DataPathMappings
for _, path := range data {
checkForDuplicateOutputPath(ctx, destToPyData,
path.dest, path.src.String(), ctx.ModuleName(), ctx.OtherModuleName(child))
}
if precompiled {
- result = append(result, dep.getPrecompiledSrcsZip())
+ result = append(result, dep.PrecompiledSrcsZip)
} else {
- result = append(result, dep.getSrcsZip())
+ result = append(result, dep.SrcsZip)
}
}
return true
diff --git a/python/test.go b/python/test.go
index 37947dd..c780a6f 100644
--- a/python/test.go
+++ b/python/test.go
@@ -199,13 +199,13 @@
}
if p.isTestHost() && len(p.testProperties.Data_device_bins_both) > 0 {
- ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) {
+ ctx.VisitDirectDepsProxyWithTag(dataDeviceBinsTag, func(dep android.ModuleProxy) {
p.data = append(p.data, android.DataPath{SrcPath: android.OutputFileForModule(ctx, dep, "")})
})
}
// Emulate the data property for java_data dependencies.
- for _, javaData := range ctx.GetDirectDepsWithTag(javaDataTag) {
+ for _, javaData := range ctx.GetDirectDepsProxyWithTag(javaDataTag) {
for _, javaDataSrcPath := range android.OutputFilesForModule(ctx, javaData, "") {
p.data = append(p.data, android.DataPath{SrcPath: javaDataSrcPath})
}
diff --git a/scripts/gen_build_prop.py b/scripts/gen_build_prop.py
index 430e613..355f33d 100644
--- a/scripts/gen_build_prop.py
+++ b/scripts/gen_build_prop.py
@@ -308,7 +308,15 @@
props.append(f"ro.sanitize.{sanitize_target}=true")
# Sets the default value of ro.postinstall.fstab.prefix to /system.
- # Device board config should override the value to /product when needed by:
+ #
+ # Device board configs can override this to /product to use a
+ # product-specific fstab.postinstall file (installed to
+ # /product/etc/fstab.postinstall). If not overridden, the
+ # system/extras/cppreopts/fstab.postinstall file (installed to
+ # /system/etc/fstab.postinstall) will be used.
+ # Note: The default fstab.postinstall is generic and may be slower
+ # because it tries different mount options line by line to ensure
+ # compatibility across various devices.
#
# PRODUCT_PRODUCT_PROPERTIES += ro.postinstall.fstab.prefix=/product
#
diff --git a/scripts/run-soong-tests-with-go-tools.sh b/scripts/run-soong-tests-with-go-tools.sh
index 1fbb1fc..82efaa0 100755
--- a/scripts/run-soong-tests-with-go-tools.sh
+++ b/scripts/run-soong-tests-with-go-tools.sh
@@ -38,6 +38,11 @@
CLANG_VERSION=$(build/soong/scripts/get_clang_version.py)
export CC="${TOP}/prebuilts/clang/host/${OS}-x86/${CLANG_VERSION}/bin/clang"
export CXX="${TOP}/prebuilts/clang/host/${OS}-x86/${CLANG_VERSION}/bin/clang++"
+ glibc_dir="${TOP}/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8"
+ export CGO_CFLAGS="--sysroot ${glibc_dir}/sysroot/"
+ export CGO_CPPFLAGS="--sysroot ${glibc_dir}/sysroot/"
+ export CGO_CXXFLAGS="--sysroot ${glibc_dir}/sysroot/"
+ export CGO_LDFLAGS="--sysroot ${glibc_dir}/sysroot/ -B ${glibc_dir}/lib/gcc/x86_64-linux/4.8.3 -L ${glibc_dir}/lib/gcc/x86_64-linux/4.8.3 -L ${glibc_dir}/x86_64-linux/lib64"
fi
# androidmk_test.go gets confused if ANDROID_BUILD_TOP is set.
diff --git a/sdk/update.go b/sdk/update.go
index 5a899a2..00352cb 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -1145,7 +1145,7 @@
// The licenses are the same for all variants.
mctx := s.ctx
- licenseInfo, _ := android.OtherModuleProvider(mctx, variant, android.LicenseInfoProvider)
+ licenseInfo, _ := android.OtherModuleProvider(mctx, variant, android.LicensesInfoProvider)
if len(licenseInfo.Licenses) > 0 {
m.AddPropertyWithTag("licenses", licenseInfo.Licenses, s.OptionalSdkMemberReferencePropertyTag())
}
diff --git a/ui/build/build.go b/ui/build/build.go
index 26f5969..ea86782 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -33,26 +33,13 @@
ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "CleanSpec.mk"))
ensureEmptyDirectoriesExist(ctx, config.TempDir())
- // Potentially write a marker file for whether kati is enabled. This is used by soong_build to
- // potentially run the AndroidMk singleton and postinstall commands.
- // Note that the absence of the file does not not preclude running Kati for product
- // configuration purposes.
- katiEnabledMarker := filepath.Join(config.SoongOutDir(), ".soong.kati_enabled")
- if config.SkipKatiNinja() {
- os.Remove(katiEnabledMarker)
- // Note that we can not remove the file for SkipKati builds yet -- some continuous builds
- // --skip-make builds rely on kati targets being defined.
- } else if !config.SkipKati() {
- ensureEmptyFileExists(ctx, katiEnabledMarker)
- }
-
// The ninja_build file is used by our buildbots to understand that the output
// can be parsed as ninja output.
ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "ninja_build"))
ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), ".out-dir"))
if buildDateTimeFile, ok := config.environ.Get("BUILD_DATETIME_FILE"); ok {
- err := ioutil.WriteFile(buildDateTimeFile, []byte(config.buildDateTime), 0666) // a+rw
+ err := os.WriteFile(buildDateTimeFile, []byte(config.buildDateTime), 0666) // a+rw
if err != nil {
ctx.Fatalln("Failed to write BUILD_DATETIME to file:", err)
}
@@ -100,6 +87,21 @@
writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_hostname.txt", hostname)
}
+// SetupKatiEnabledMarker creates or delets a file that tells soong_build if we're running with
+// kati.
+func SetupKatiEnabledMarker(ctx Context, config Config) {
+ // Potentially write a marker file for whether kati is enabled. This is used by soong_build to
+ // potentially run the AndroidMk singleton and postinstall commands.
+ // Note that the absence of the file does not preclude running Kati for product
+ // configuration purposes.
+ katiEnabledMarker := filepath.Join(config.SoongOutDir(), ".soong.kati_enabled")
+ if config.SkipKati() || config.SkipKatiNinja() {
+ os.Remove(katiEnabledMarker)
+ } else {
+ ensureEmptyFileExists(ctx, katiEnabledMarker)
+ }
+}
+
var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
builddir = {{.OutDir}}
{{if .UseRemoteBuild }}pool local_pool
@@ -329,10 +331,16 @@
if what&RunProductConfig != 0 {
runMakeProductConfig(ctx, config)
+
+ // Re-evaluate what to run because there are product variables that control how
+ // soong and make are run.
+ what = evaluateWhatToRun(config, ctx.Verboseln)
}
// Everything below here depends on product config.
+ SetupKatiEnabledMarker(ctx, config)
+
if inList("installclean", config.Arguments()) ||
inList("install-clean", config.Arguments()) {
logArgsOtherThan("installclean", "install-clean")
diff --git a/ui/build/config.go b/ui/build/config.go
index 4f2d213..84e4005 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -63,6 +63,7 @@
NINJA_NINJA
NINJA_N2
NINJA_SISO
+ NINJA_NINJAGO
)
type Config struct{ *configImpl }
@@ -77,26 +78,27 @@
logsPrefix string
// From the arguments
- parallel int
- keepGoing int
- verbose bool
- checkbuild bool
- dist bool
- jsonModuleGraph bool
- reportMkMetrics bool // Collect and report mk2bp migration progress metrics.
- soongDocs bool
- skipConfig bool
- skipKati bool
- skipKatiNinja bool
- skipSoong bool
- skipNinja bool
- skipSoongTests bool
- searchApiDir bool // Scan the Android.bp files generated in out/api_surfaces
- skipMetricsUpload bool
- buildStartedTime int64 // For metrics-upload-only - manually specify a build-started time
- buildFromSourceStub bool
- incrementalBuildActions bool
- ensureAllowlistIntegrity bool // For CI builds - make sure modules are mixed-built
+ parallel int
+ keepGoing int
+ verbose bool
+ checkbuild bool
+ dist bool
+ jsonModuleGraph bool
+ reportMkMetrics bool // Collect and report mk2bp migration progress metrics.
+ soongDocs bool
+ skipConfig bool
+ skipKati bool
+ skipKatiControlledByFlags bool
+ skipKatiNinja bool
+ skipSoong bool
+ skipNinja bool
+ skipSoongTests bool
+ searchApiDir bool // Scan the Android.bp files generated in out/api_surfaces
+ skipMetricsUpload bool
+ buildStartedTime int64 // For metrics-upload-only - manually specify a build-started time
+ buildFromSourceStub bool
+ incrementalBuildActions bool
+ ensureAllowlistIntegrity bool // For CI builds - make sure modules are mixed-built
// From the product config
katiArgs []string
@@ -323,6 +325,8 @@
ret.ninjaCommand = NINJA_N2
case "siso":
ret.ninjaCommand = NINJA_SISO
+ case "ninjago":
+ ret.ninjaCommand = NINJA_NINJAGO
default:
if os.Getenv("SOONG_USE_N2") == "true" {
ret.ninjaCommand = NINJA_N2
@@ -843,15 +847,20 @@
c.emptyNinjaFile = true
} else if arg == "--skip-ninja" {
c.skipNinja = true
- } else if arg == "--skip-make" {
- // TODO(ccross): deprecate this, it has confusing behaviors. It doesn't run kati,
- // but it does run a Kati ninja file if the .kati_enabled marker file was created
- // by a previous build.
- c.skipConfig = true
- c.skipKati = true
} else if arg == "--soong-only" {
+ if c.skipKatiControlledByFlags {
+ ctx.Fatalf("Cannot specify both --soong-only and --no-soong-only")
+ }
+ c.skipKatiControlledByFlags = true
c.skipKati = true
c.skipKatiNinja = true
+ } else if arg == "--no-soong-only" {
+ if c.skipKatiControlledByFlags {
+ ctx.Fatalf("Cannot specify both --soong-only and --no-soong-only")
+ }
+ c.skipKatiControlledByFlags = true
+ c.skipKati = false
+ c.skipKatiNinja = false
} else if arg == "--config-only" {
c.skipKati = true
c.skipKatiNinja = true
@@ -1339,6 +1348,10 @@
}
func (c *configImpl) UseABFS() bool {
+ if c.ninjaCommand == NINJA_NINJAGO {
+ return true
+ }
+
if v, ok := c.environ.Get("NO_ABFS"); ok {
v = strings.ToLower(strings.TrimSpace(v))
if v == "true" || v == "1" {
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index b592f11..d5aab54 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -246,6 +246,8 @@
// `true` will relegate missing outputs to warnings.
"BUILD_BROKEN_MISSING_OUTPUTS",
+ "PRODUCT_SOONG_ONLY",
+
// Not used, but useful to be in the soong.log
"TARGET_BUILD_TYPE",
"HOST_ARCH",
@@ -314,4 +316,11 @@
config.SetBuildBrokenNinjaUsesEnvVars(strings.Fields(makeVars["BUILD_BROKEN_NINJA_USES_ENV_VARS"]))
config.SetSourceRootDirs(strings.Fields(makeVars["PRODUCT_SOURCE_ROOT_DIRS"]))
config.SetBuildBrokenMissingOutputs(makeVars["BUILD_BROKEN_MISSING_OUTPUTS"] == "true")
+
+ if !config.skipKatiControlledByFlags {
+ if makeVars["PRODUCT_SOONG_ONLY"] == "true" {
+ config.skipKati = true
+ config.skipKatiNinja = true
+ }
+ }
}
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index b0c9c07..1d4285f 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -76,7 +76,7 @@
//"--frontend-file", fifo,
}
default:
- // NINJA_NINJA is the default.
+ // NINJA_NINJA or NINJA_NINJAGO.
executable = config.NinjaBin()
args = []string{
"-d", "keepdepfile",
@@ -351,12 +351,18 @@
}
// Constructs and runs the Ninja command line to get the inputs of a goal.
-// For now, this will always run ninja, because ninjago, n2 and siso don't have the
+// For n2 and siso, this will always run ninja, because they don't have the
// `-t inputs` command. This command will use the inputs command's -d option,
// to use the dep file iff ninja was the executor. For other executors, the
// results will be wrong.
func runNinjaInputs(ctx Context, config Config, goal string) ([]string, error) {
- executable := config.PrebuiltBuildTool("ninja")
+ var executable string
+ switch config.ninjaCommand {
+ case NINJA_N2, NINJA_SISO:
+ executable = config.PrebuiltBuildTool("ninja")
+ default:
+ executable = config.NinjaBin()
+ }
args := []string{
"-f",
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 6c9a1eb..110ddee 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -42,7 +42,7 @@
}
// This tool is specifically disallowed and calling it will result in an
-// "executable no found" error.
+// "executable not found" error.
var Forbidden = PathConfig{
Symlink: false,
Log: true,
@@ -122,6 +122,10 @@
"ld.bfd": Forbidden,
"ld.gold": Forbidden,
"pkg-config": Forbidden,
+ "python": Forbidden,
+ "python2": Forbidden,
+ "python2.7": Forbidden,
+ "python3": Forbidden,
// These are toybox tools that only work on Linux.
"pgrep": LinuxOnlyPrebuilt,