Merge "//visibility:any_partition can be used with another visibility field" into main
diff --git a/aconfig/codegen/aconfig_declarations_group.go b/aconfig/codegen/aconfig_declarations_group.go
index 203b6be..1c91bee 100644
--- a/aconfig/codegen/aconfig_declarations_group.go
+++ b/aconfig/codegen/aconfig_declarations_group.go
@@ -15,9 +15,10 @@
package codegen
import (
- "android/soong/aconfig"
- "android/soong/android"
"fmt"
+ "maps"
+
+ "android/soong/android"
"github.com/google/blueprint"
)
@@ -43,6 +44,7 @@
aconfigDeclarationNames []string
intermediateCacheOutputPaths android.Paths
javaSrcjars android.Paths
+ modeInfos map[string]android.ModeInfo
}
type AconfigDeclarationsGroupProperties struct {
@@ -76,9 +78,10 @@
}
func (adg *AconfigDeclarationsGroup) VisitDeps(ctx android.ModuleContext) {
+ adg.modeInfos = make(map[string]android.ModeInfo)
ctx.VisitDirectDeps(func(dep android.Module) {
tag := ctx.OtherModuleDependencyTag(dep)
- if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.CodegenInfoProvider); ok {
+ if provider, ok := android.OtherModuleProvider(ctx, dep, android.CodegenInfoProvider); ok {
// aconfig declaration names and cache files are collected for all aconfig library dependencies
adg.aconfigDeclarationNames = append(adg.aconfigDeclarationNames, provider.AconfigDeclarations...)
@@ -88,8 +91,14 @@
case aconfigDeclarationsGroupTag:
// Will retrieve outputs from another language codegen modules when support is added
adg.javaSrcjars = append(adg.javaSrcjars, provider.Srcjars...)
+ maps.Copy(adg.modeInfos, provider.ModeInfos)
case javaAconfigLibraryTag:
adg.javaSrcjars = append(adg.javaSrcjars, provider.Srcjars...)
+ maps.Copy(adg.modeInfos, provider.ModeInfos)
+ case ccAconfigLibraryTag:
+ maps.Copy(adg.modeInfos, provider.ModeInfos)
+ case rustAconfigLibraryTag:
+ maps.Copy(adg.modeInfos, provider.ModeInfos)
}
}
})
@@ -100,10 +109,11 @@
adg.aconfigDeclarationNames = android.FirstUniqueStrings(adg.aconfigDeclarationNames)
adg.intermediateCacheOutputPaths = android.FirstUniquePaths(adg.intermediateCacheOutputPaths)
- android.SetProvider(ctx, aconfig.CodegenInfoProvider, aconfig.CodegenInfo{
+ android.SetProvider(ctx, android.CodegenInfoProvider, android.CodegenInfo{
AconfigDeclarations: adg.aconfigDeclarationNames,
IntermediateCacheOutputPaths: adg.intermediateCacheOutputPaths,
Srcjars: adg.javaSrcjars,
+ ModeInfos: adg.modeInfos,
})
}
diff --git a/aconfig/codegen/cc_aconfig_library.go b/aconfig/codegen/cc_aconfig_library.go
index 50cd4de..80e4926 100644
--- a/aconfig/codegen/cc_aconfig_library.go
+++ b/aconfig/codegen/cc_aconfig_library.go
@@ -146,4 +146,12 @@
"mode": mode,
},
})
+
+ android.SetProvider(ctx, android.CodegenInfoProvider, android.CodegenInfo{
+ ModeInfos: map[string]android.ModeInfo{
+ ctx.ModuleName(): {
+ Container: declarations.Container,
+ Mode: mode,
+ }},
+ })
}
diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go
index 3d15ac9..1378dfe 100644
--- a/aconfig/codegen/java_aconfig_library.go
+++ b/aconfig/codegen/java_aconfig_library.go
@@ -17,7 +17,6 @@
import (
"fmt"
- "android/soong/aconfig"
"android/soong/android"
"android/soong/java"
@@ -119,10 +118,15 @@
module.AddJarJarRenameRule(declarations.Package+".FakeFeatureFlagsImpl", "")
}
- android.SetProvider(ctx, aconfig.CodegenInfoProvider, aconfig.CodegenInfo{
+ android.SetProvider(ctx, android.CodegenInfoProvider, android.CodegenInfo{
AconfigDeclarations: []string{declarationsModules[0].Name()},
IntermediateCacheOutputPaths: android.Paths{declarations.IntermediateCacheOutputPath},
Srcjars: android.Paths{srcJarPath},
+ ModeInfos: map[string]android.ModeInfo{
+ ctx.ModuleName(): {
+ Container: declarations.Container,
+ Mode: mode,
+ }},
})
return srcJarPath
diff --git a/aconfig/codegen/rust_aconfig_library.go b/aconfig/codegen/rust_aconfig_library.go
index 2ab54b6..3f7495b 100644
--- a/aconfig/codegen/rust_aconfig_library.go
+++ b/aconfig/codegen/rust_aconfig_library.go
@@ -85,6 +85,15 @@
},
})
a.BaseSourceProvider.OutputFiles = android.Paths{generatedSource}
+
+ android.SetProvider(ctx, android.CodegenInfoProvider, android.CodegenInfo{
+ ModeInfos: map[string]android.ModeInfo{
+ ctx.ModuleName(): {
+ Container: declarations.Container,
+ Mode: mode,
+ }},
+ })
+
return generatedSource
}
diff --git a/aconfig/init.go b/aconfig/init.go
index e64429f..4625128 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -20,20 +20,6 @@
"github.com/google/blueprint"
)
-type CodegenInfo struct {
- // AconfigDeclarations is the name of the aconfig_declarations modules that
- // the codegen module is associated with
- AconfigDeclarations []string
-
- // Paths to the cache files of the associated aconfig_declaration modules
- IntermediateCacheOutputPaths android.Paths
-
- // Paths to the srcjar files generated from the java_aconfig_library modules
- Srcjars android.Paths
-}
-
-var CodegenInfoProvider = blueprint.NewProvider[CodegenInfo]()
-
var (
pctx = android.NewPackageContext("android/soong/aconfig")
diff --git a/android/aconfig_providers.go b/android/aconfig_providers.go
index 74c1a5e..fcc57e1 100644
--- a/android/aconfig_providers.go
+++ b/android/aconfig_providers.go
@@ -17,6 +17,7 @@
import (
"fmt"
"io"
+ "maps"
"reflect"
"github.com/google/blueprint"
@@ -50,6 +51,35 @@
var AconfigTransitiveDeclarationsInfoProvider = blueprint.NewProvider[AconfigTransitiveDeclarationsInfo]()
+type ModeInfo struct {
+ Container string
+ Mode string
+}
+type CodegenInfo struct {
+ // AconfigDeclarations is the name of the aconfig_declarations modules that
+ // the codegen module is associated with
+ AconfigDeclarations []string
+
+ // Paths to the cache files of the associated aconfig_declaration modules
+ IntermediateCacheOutputPaths Paths
+
+ // Paths to the srcjar files generated from the java_aconfig_library modules
+ Srcjars Paths
+
+ ModeInfos map[string]ModeInfo
+}
+
+var CodegenInfoProvider = blueprint.NewProvider[CodegenInfo]()
+
+func propagateModeInfos(ctx ModuleContext, module Module, to, from map[string]ModeInfo) {
+ if len(from) > 0 {
+ depTag := ctx.OtherModuleDependencyTag(module)
+ if tag, ok := depTag.(PropagateAconfigValidationDependencyTag); ok && tag.PropagateAconfigValidation() {
+ maps.Copy(to, from)
+ }
+ }
+}
+
// CollectDependencyAconfigFiles is used by some module types to provide finer dependency graphing than
// we can do in ModuleBase.
func CollectDependencyAconfigFiles(ctx ModuleContext, mergedAconfigFiles *map[string]Paths) {
@@ -90,13 +120,40 @@
type aconfigPropagatingDeclarationsInfo struct {
AconfigFiles map[string]Paths
+ ModeInfos map[string]ModeInfo
}
var aconfigPropagatingProviderKey = blueprint.NewProvider[aconfigPropagatingDeclarationsInfo]()
+func VerifyAconfigBuildMode(ctx ModuleContext, container string, module blueprint.Module, asError bool) {
+ if dep, ok := OtherModuleProvider(ctx, module, aconfigPropagatingProviderKey); ok {
+ for k, v := range dep.ModeInfos {
+ msg := fmt.Sprintf("%s/%s depends on %s/%s/%s across containers\n",
+ module.Name(), container, k, v.Container, v.Mode)
+ if v.Container != container && v.Mode != "exported" && v.Mode != "force-read-only" {
+ if asError {
+ ctx.ModuleErrorf(msg)
+ } else {
+ fmt.Printf("WARNING: " + msg)
+ }
+ } else {
+ if !asError {
+ fmt.Printf("PASSED: " + msg)
+ }
+ }
+ }
+ }
+}
+
func aconfigUpdateAndroidBuildActions(ctx ModuleContext) {
mergedAconfigFiles := make(map[string]Paths)
+ mergedModeInfos := make(map[string]ModeInfo)
+
ctx.VisitDirectDepsIgnoreBlueprint(func(module Module) {
+ if aconfig_dep, ok := OtherModuleProvider(ctx, module, CodegenInfoProvider); ok && len(aconfig_dep.ModeInfos) > 0 {
+ maps.Copy(mergedModeInfos, aconfig_dep.ModeInfos)
+ }
+
// If any of our dependencies have aconfig declarations (directly or propagated), then merge those and provide them.
if dep, ok := OtherModuleProvider(ctx, module, AconfigDeclarationsProviderKey); ok {
mergedAconfigFiles[dep.Container] = append(mergedAconfigFiles[dep.Container], dep.IntermediateCacheOutputPath)
@@ -105,6 +162,7 @@
for container, v := range dep.AconfigFiles {
mergedAconfigFiles[container] = append(mergedAconfigFiles[container], v...)
}
+ propagateModeInfos(ctx, module, mergedModeInfos, dep.ModeInfos)
}
if dep, ok := OtherModuleProvider(ctx, module, AconfigTransitiveDeclarationsInfoProvider); ok {
for container, v := range dep.AconfigFiles {
@@ -120,6 +178,7 @@
SetProvider(ctx, aconfigPropagatingProviderKey, aconfigPropagatingDeclarationsInfo{
AconfigFiles: mergedAconfigFiles,
+ ModeInfos: mergedModeInfos,
})
}
}
diff --git a/android/apex.go b/android/apex.go
index 4d36a93..8759905 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -976,3 +976,18 @@
// Map from the apex library name (without prebuilt_ prefix) to the dex file path on host
LibraryNameToDexJarPathOnHost map[string]Path
}
+
+var PrebuiltInfoProvider = blueprint.NewProvider[PrebuiltInfo]()
+
+// contents of prebuilt_info.json
+type PrebuiltInfo struct {
+ // Name of the apex, without the prebuilt_ prefix
+ Name string
+
+ Is_prebuilt bool
+
+ // This is relative to root of the workspace.
+ // In case of mainline modules, this file contains the build_id that was used
+ // to generate the mainline module prebuilt.
+ Prebuilt_info_file_path string `json:",omitempty"`
+}
diff --git a/android/apex_contributions.go b/android/apex_contributions.go
index c388aff..c76d9c2 100644
--- a/android/apex_contributions.go
+++ b/android/apex_contributions.go
@@ -27,11 +27,13 @@
func RegisterApexContributionsBuildComponents(ctx RegistrationContext) {
ctx.RegisterModuleType("apex_contributions", apexContributionsFactory)
+ ctx.RegisterModuleType("apex_contributions_defaults", apexContributionsDefaultsFactory)
ctx.RegisterSingletonModuleType("all_apex_contributions", allApexContributionsFactory)
}
type apexContributions struct {
ModuleBase
+ DefaultableModuleBase
properties contributionProps
}
@@ -61,6 +63,7 @@
module := &apexContributions{}
module.AddProperties(&module.properties)
InitAndroidModule(module)
+ InitDefaultableModule(module)
return module
}
@@ -70,6 +73,18 @@
func (m *apexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
}
+type apexContributionsDefaults struct {
+ ModuleBase
+ DefaultsModuleBase
+}
+
+func apexContributionsDefaultsFactory() Module {
+ module := &apexContributionsDefaults{}
+ module.AddProperties(&contributionProps{})
+ InitDefaultsModule(module)
+ return module
+}
+
// A container for apex_contributions.
// Based on product_config, it will create a dependency on the selected
// apex_contributions per mainline module
diff --git a/android/base_module_context.go b/android/base_module_context.go
index b9c1153..dd38a4e 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -16,9 +16,11 @@
import (
"fmt"
- "github.com/google/blueprint"
"regexp"
"strings"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/parser"
)
// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
@@ -214,6 +216,10 @@
// getMissingDependencies returns the list of missing dependencies.
// Calling this function prevents adding new dependencies.
getMissingDependencies() []string
+
+ // EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context
+ // can be used to evaluate the final value of Configurable properties.
+ EvaluateConfiguration(parser.SelectType, string) (string, bool)
}
type baseModuleContext struct {
@@ -564,3 +570,32 @@
}
return sb.String()
}
+
+func (m *baseModuleContext) EvaluateConfiguration(ty parser.SelectType, condition string) (string, bool) {
+ switch ty {
+ case parser.SelectTypeReleaseVariable:
+ if v, ok := m.Config().productVariables.BuildFlags[condition]; ok {
+ return v, true
+ }
+ return "", false
+ case parser.SelectTypeProductVariable:
+ // TODO(b/323382414): Might add these on a case-by-case basis
+ m.ModuleErrorf("TODO(b/323382414): Product variables are not yet supported in selects")
+ return "", false
+ case parser.SelectTypeSoongConfigVariable:
+ parts := strings.Split(condition, ":")
+ namespace := parts[0]
+ variable := parts[1]
+ if n, ok := m.Config().productVariables.VendorVars[namespace]; ok {
+ if v, ok := n[variable]; ok {
+ return v, true
+ }
+ }
+ return "", false
+ case parser.SelectTypeVariant:
+ m.ModuleErrorf("TODO(b/323382414): Variants are not yet supported in selects")
+ return "", false
+ default:
+ panic("Should be unreachable")
+ }
+}
diff --git a/android/config.go b/android/config.go
index 1bb1a22..567ebd8 100644
--- a/android/config.go
+++ b/android/config.go
@@ -18,7 +18,6 @@
// product variables necessary for soong_build's operation.
import (
- "android/soong/shared"
"encoding/json"
"fmt"
"os"
@@ -30,6 +29,8 @@
"sync"
"unicode"
+ "android/soong/shared"
+
"github.com/google/blueprint"
"github.com/google/blueprint/bootstrap"
"github.com/google/blueprint/pathtools"
@@ -1938,6 +1939,10 @@
return c.config.productVariables.GenerateAidlNdkPlatformBackend
}
+func (c *deviceConfig) AconfigContainerValidation() string {
+ return c.config.productVariables.AconfigContainerValidation
+}
+
func (c *config) IgnorePrefer32OnDevice() bool {
return c.productVariables.IgnorePrefer32OnDevice
}
diff --git a/android/deptag.go b/android/deptag.go
index a15443b..c7ba4d3 100644
--- a/android/deptag.go
+++ b/android/deptag.go
@@ -43,3 +43,15 @@
}
return false
}
+
+type PropagateAconfigValidationDependencyTag interface {
+ PropagateAconfigValidation() bool
+}
+
+type AlwaysPropagateAconfigValidationDependencyTag struct{}
+
+func (p AlwaysPropagateAconfigValidationDependencyTag) PropagateAconfigValidation() bool {
+ return true
+}
+
+var _ PropagateAconfigValidationDependencyTag = AlwaysPropagateAconfigValidationDependencyTag{}
diff --git a/android/module.go b/android/module.go
index b615ff5..000476c 100644
--- a/android/module.go
+++ b/android/module.go
@@ -15,7 +15,6 @@
package android
import (
- "android/soong/bazel"
"crypto/md5"
"encoding/hex"
"encoding/json"
@@ -27,6 +26,8 @@
"sort"
"strings"
+ "android/soong/bazel"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -2087,6 +2088,7 @@
// caused by prebuilt_ prefix, or fully qualified module names.
type sourceOrOutputDependencyTag struct {
blueprint.BaseDependencyTag
+ AlwaysPropagateAconfigValidationDependencyTag
// The name of the module.
moduleName string
diff --git a/android/module_context.go b/android/module_context.go
index 3fc5d01..1cab630 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -21,7 +21,6 @@
"strings"
"github.com/google/blueprint"
- "github.com/google/blueprint/parser"
"github.com/google/blueprint/proptools"
)
@@ -213,10 +212,6 @@
// GenerateAndroidBuildActions. If it is called then the struct will be written out and included in
// the module-info.json generated by Make, and Make will not generate its own data for this module.
ModuleInfoJSON() *ModuleInfoJSON
-
- // EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context
- // can be used to evaluate the final value of Configurable properties.
- EvaluateConfiguration(parser.SelectType, string) (string, bool)
}
type moduleContext struct {
@@ -719,32 +714,3 @@
func (m *moduleContext) TargetRequiredModuleNames() []string {
return m.module.TargetRequiredModuleNames()
}
-
-func (m *moduleContext) EvaluateConfiguration(ty parser.SelectType, condition string) (string, bool) {
- switch ty {
- case parser.SelectTypeReleaseVariable:
- if v, ok := m.Config().productVariables.BuildFlags[condition]; ok {
- return v, true
- }
- return "", false
- case parser.SelectTypeProductVariable:
- // TODO: Might add these on a case-by-case basis
- m.ModuleErrorf("TODO(b/323382414): Product variables are not yet supported in selects")
- return "", false
- case parser.SelectTypeSoongConfigVariable:
- parts := strings.Split(condition, ":")
- namespace := parts[0]
- variable := parts[1]
- if n, ok := m.Config().productVariables.VendorVars[namespace]; ok {
- if v, ok := n[variable]; ok {
- return v, true
- }
- }
- return "", false
- case parser.SelectTypeVariant:
- m.ModuleErrorf("TODO(b/323382414): Variants are not yet supported in selects")
- return "", false
- default:
- panic("Should be unreachable")
- }
-}
diff --git a/android/path_properties.go b/android/path_properties.go
index bbfaa8c..ea92565 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -47,7 +47,7 @@
// tagged with `android:"path"`.
var pathProperties []string
for _, ps := range props {
- pathProperties = append(pathProperties, pathPropertiesForPropertyStruct(ps)...)
+ pathProperties = append(pathProperties, pathPropertiesForPropertyStruct(ctx, ps)...)
}
// Remove duplicates to avoid multiple dependencies.
@@ -64,7 +64,7 @@
// pathPropertiesForPropertyStruct uses the indexes of properties that are tagged with
// android:"path" to extract all their values from a property struct, returning them as a single
// slice of strings.
-func pathPropertiesForPropertyStruct(ps interface{}) []string {
+func pathPropertiesForPropertyStruct(ctx BottomUpMutatorContext, ps interface{}) []string {
v := reflect.ValueOf(ps)
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
panic(fmt.Errorf("type %s is not a pointer to a struct", v.Type()))
@@ -106,6 +106,16 @@
ret = append(ret, sv.String())
case reflect.Slice:
ret = append(ret, sv.Interface().([]string)...)
+ case reflect.Struct:
+ intf := sv.Interface()
+ if configurable, ok := intf.(proptools.Configurable[string]); ok {
+ ret = append(ret, proptools.String(configurable.Evaluate(ctx)))
+ } else if configurable, ok := intf.(proptools.Configurable[[]string]); ok {
+ ret = append(ret, proptools.Slice(configurable.Evaluate(ctx))...)
+ } else {
+ panic(fmt.Errorf(`field %s in type %s has tag android:"path" but is not a string or slice of strings, it is a %s`,
+ v.Type().FieldByIndex(i).Name, v.Type(), sv.Type()))
+ }
default:
panic(fmt.Errorf(`field %s in type %s has tag android:"path" but is not a string or slice of strings, it is a %s`,
v.Type().FieldByIndex(i).Name, v.Type(), sv.Type()))
diff --git a/android/selects_test.go b/android/selects_test.go
index dca3789..aa9c521 100644
--- a/android/selects_test.go
+++ b/android/selects_test.go
@@ -80,6 +80,36 @@
},
},
{
+ name: "basic paths",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_paths: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": ["foo.txt"],
+ "b": ["bar.txt"],
+ _: ["baz.txt"],
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ my_paths: &[]string{"baz.txt"},
+ },
+ },
+ {
+ name: "paths with module references",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_paths: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": [":a"],
+ "b": [":b"],
+ _: [":c"],
+ }),
+ }
+ `,
+ expectedError: `"foo" depends on undefined module "c"`,
+ },
+ {
name: "Differing types",
bp: `
my_module_type {
@@ -233,6 +263,7 @@
my_bool *bool
my_string *string
my_string_list *[]string
+ my_paths *[]string
}
func (p *selectsTestProvider) String() string {
@@ -248,7 +279,8 @@
my_bool: %v,
my_string: %s,
my_string_list: %s,
-}`, myBoolStr, myStringStr, p.my_string_list)
+ my_paths: %s,
+}`, myBoolStr, myStringStr, p.my_string_list, p.my_paths)
}
var selectsTestProviderKey = blueprint.NewProvider[selectsTestProvider]()
@@ -257,6 +289,7 @@
My_bool proptools.Configurable[bool]
My_string proptools.Configurable[string]
My_string_list proptools.Configurable[[]string]
+ My_paths proptools.Configurable[[]string] `android:"path"`
}
type selectsMockModule struct {
@@ -266,10 +299,11 @@
}
func (p *selectsMockModule) GenerateAndroidBuildActions(ctx ModuleContext) {
- SetProvider[selectsTestProvider](ctx, selectsTestProviderKey, selectsTestProvider{
+ SetProvider(ctx, selectsTestProviderKey, selectsTestProvider{
my_bool: p.properties.My_bool.Evaluate(ctx),
my_string: p.properties.My_string.Evaluate(ctx),
my_string_list: p.properties.My_string_list.Evaluate(ctx),
+ my_paths: p.properties.My_paths.Evaluate(ctx),
})
}
diff --git a/android/variable.go b/android/variable.go
index be3c80d..73f5bfd 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -500,6 +500,8 @@
HiddenapiExportableStubs *bool `json:",omitempty"`
ExportRuntimeApis *bool `json:",omitempty"`
+
+ AconfigContainerValidation string `json:",omitempty"`
}
type PartitionQualifiedVariablesType struct {
diff --git a/apex/aconfig_test.go b/apex/aconfig_test.go
new file mode 100644
index 0000000..be98d45
--- /dev/null
+++ b/apex/aconfig_test.go
@@ -0,0 +1,550 @@
+// 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 apex
+
+import (
+ "testing"
+
+ "android/soong/aconfig/codegen"
+ "android/soong/android"
+ "android/soong/cc"
+ "android/soong/genrule"
+ "android/soong/java"
+ "android/soong/rust"
+ "github.com/google/blueprint/proptools"
+)
+
+var withAconfigValidationError = android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.AconfigContainerValidation = "error"
+ variables.BuildId = proptools.StringPtr("TEST.BUILD_ID")
+})
+
+func TestValidationAcrossContainersExportedPass(t *testing.T) {
+ testCases := []struct {
+ name string
+ bp string
+ }{
+ {
+ name: "Java lib passes for exported containers cross",
+ bp: apex_default_bp + `
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ java_libs: [
+ "my_java_library_foo",
+ ],
+ updatable: false,
+ }
+ java_library {
+ name: "my_java_library_foo",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["my_java_aconfig_library_foo"],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["foo.aconfig"],
+ exportable: true,
+ }
+ java_aconfig_library {
+ name: "my_java_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ mode: "exported",
+ apex_available: [
+ "myapex",
+ ],
+ }`,
+ },
+ {
+ name: "Android app passes for exported containers cross",
+ bp: apex_default_bp + `
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ apps: [
+ "my_android_app_foo",
+ ],
+ updatable: false,
+ }
+ android_app {
+ name: "my_android_app_foo",
+ srcs: ["foo/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ stl: "none",
+ static_libs: ["my_java_library_bar"],
+ apex_available: [ "myapex" ],
+ }
+ java_library {
+ name: "my_java_library_bar",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["my_java_aconfig_library_bar"],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_bar",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["bar.aconfig"],
+ exportable: true,
+ }
+ java_aconfig_library {
+ name: "my_java_aconfig_library_bar",
+ aconfig_declarations: "my_aconfig_declarations_bar",
+ mode: "exported",
+ apex_available: [
+ "myapex",
+ ],
+ }`,
+ },
+ {
+ name: "Cc lib passes for exported containers cross",
+ bp: apex_default_bp + `
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ native_shared_libs: [
+ "my_cc_library_bar",
+ ],
+ binaries: [
+ "my_cc_binary_baz",
+ ],
+ updatable: false,
+ }
+ cc_library {
+ name: "my_cc_library_bar",
+ srcs: ["foo/bar/MyClass.cc"],
+ static_libs: [
+ "my_cc_aconfig_library_bar",
+ "my_cc_aconfig_library_baz",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ cc_binary {
+ name: "my_cc_binary_baz",
+ srcs: ["foo/bar/MyClass.cc"],
+ static_libs: ["my_cc_aconfig_library_baz"],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ cc_library {
+ name: "server_configurable_flags",
+ srcs: ["server_configurable_flags.cc"],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_bar",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["bar.aconfig"],
+ exportable: true,
+ }
+ cc_aconfig_library {
+ name: "my_cc_aconfig_library_bar",
+ aconfig_declarations: "my_aconfig_declarations_bar",
+ apex_available: [
+ "myapex",
+ ],
+ mode: "exported",
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_baz",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["baz.aconfig"],
+ exportable: true,
+ }
+ cc_aconfig_library {
+ name: "my_cc_aconfig_library_baz",
+ aconfig_declarations: "my_aconfig_declarations_baz",
+ apex_available: [
+ "myapex",
+ ],
+ mode: "exported",
+ }`,
+ },
+ }
+ for _, test := range testCases {
+ t.Run(test.name, func(t *testing.T) {
+ android.GroupFixturePreparers(
+ java.PrepareForTestWithJavaDefaultModules,
+ cc.PrepareForTestWithCcBuildComponents,
+ rust.PrepareForTestWithRustDefaultModules,
+ codegen.PrepareForTestWithAconfigBuildComponents,
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithMyapex,
+ withAconfigValidationError,
+ ).
+ RunTestWithBp(t, test.bp)
+ })
+ }
+}
+
+func TestValidationAcrossContainersNotExportedFail(t *testing.T) {
+ testCases := []struct {
+ name string
+ expectedError string
+ bp string
+ }{
+ {
+ name: "Java lib fails for non-exported containers cross",
+ bp: apex_default_bp + `
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ java_libs: [
+ "my_java_library_foo",
+ ],
+ updatable: false,
+ }
+ java_library {
+ name: "my_java_library_foo",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["my_java_aconfig_library_foo"],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["foo.aconfig"],
+ }
+ java_aconfig_library {
+ name: "my_java_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ apex_available: [
+ "myapex",
+ ],
+ }`,
+ expectedError: `.*my_java_library_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
+ },
+ {
+ name: "Android app fails for non-exported containers cross",
+ bp: apex_default_bp + `
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ apps: [
+ "my_android_app_foo",
+ ],
+ updatable: false,
+ }
+ android_app {
+ name: "my_android_app_foo",
+ srcs: ["foo/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ stl: "none",
+ static_libs: ["my_java_library_foo"],
+ apex_available: [ "myapex" ],
+ }
+ java_library {
+ name: "my_java_library_foo",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["my_java_aconfig_library_foo"],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["bar.aconfig"],
+ }
+ java_aconfig_library {
+ name: "my_java_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ apex_available: [
+ "myapex",
+ ],
+ }`,
+ expectedError: `.*my_android_app_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
+ },
+ {
+ name: "Cc lib fails for non-exported containers cross",
+ bp: apex_default_bp + `
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ native_shared_libs: [
+ "my_cc_library_foo",
+ ],
+ updatable: false,
+ }
+ cc_library {
+ name: "my_cc_library_foo",
+ srcs: ["foo/bar/MyClass.cc"],
+ shared_libs: [
+ "my_cc_aconfig_library_foo",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ cc_library {
+ name: "server_configurable_flags",
+ srcs: ["server_configurable_flags.cc"],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["foo.aconfig"],
+ }
+ cc_aconfig_library {
+ name: "my_cc_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ apex_available: [
+ "myapex",
+ ],
+ }`,
+ expectedError: `.*my_cc_library_foo/myapex depends on my_cc_aconfig_library_foo/otherapex/production across containers`,
+ },
+ {
+ name: "Cc binary fails for non-exported containers cross",
+ bp: apex_default_bp + `
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ binaries: [
+ "my_cc_binary_foo",
+ ],
+ updatable: false,
+ }
+ cc_library {
+ name: "my_cc_library_foo",
+ srcs: ["foo/bar/MyClass.cc"],
+ static_libs: [
+ "my_cc_aconfig_library_foo",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ cc_binary {
+ name: "my_cc_binary_foo",
+ srcs: ["foo/bar/MyClass.cc"],
+ static_libs: ["my_cc_library_foo"],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ cc_library {
+ name: "server_configurable_flags",
+ srcs: ["server_configurable_flags.cc"],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["foo.aconfig"],
+ }
+ cc_aconfig_library {
+ name: "my_cc_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ apex_available: [
+ "myapex",
+ ],
+ }`,
+ expectedError: `.*my_cc_binary_foo/myapex depends on my_cc_aconfig_library_foo/otherapex/production across containers`,
+ },
+ {
+ name: "Aconfig validation propagate along sourceOrOutputDependencyTag",
+ bp: apex_default_bp + `
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ apps: [
+ "my_android_app_foo",
+ ],
+ updatable: false,
+ }
+ android_app {
+ name: "my_android_app_foo",
+ srcs: ["foo/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ stl: "none",
+ static_libs: ["my_java_library_foo"],
+ apex_available: [ "myapex" ],
+ }
+ java_library {
+ name: "my_java_library_foo",
+ srcs: [":my_genrule_foo"],
+ sdk_version: "none",
+ system_modules: "none",
+ apex_available: [
+ "myapex",
+ ],
+ }
+ aconfig_declarations_group {
+ name: "my_aconfig_declarations_group_foo",
+ java_aconfig_libraries: [
+ "my_java_aconfig_library_foo",
+ ],
+ }
+ filegroup {
+ name: "my_filegroup_foo_srcjars",
+ srcs: [
+ ":my_aconfig_declarations_group_foo{.srcjars}",
+ ],
+ }
+ genrule {
+ name: "my_genrule_foo",
+ srcs: [":my_filegroup_foo_srcjars"],
+ cmd: "cp $(in) $(out)",
+ out: ["my_genrule_foo.srcjar"],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["bar.aconfig"],
+ }
+ java_aconfig_library {
+ name: "my_java_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ apex_available: [
+ "myapex",
+ ],
+ }`,
+ expectedError: `.*my_android_app_foo/myapex depends on my_java_aconfig_library_foo/otherapex/production across containers`,
+ },
+ }
+ for _, test := range testCases {
+ t.Run(test.name, func(t *testing.T) {
+ errorHandler := android.FixtureExpectsNoErrors
+ if test.expectedError != "" {
+ errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError)
+ }
+ android.GroupFixturePreparers(
+ java.PrepareForTestWithJavaDefaultModules,
+ cc.PrepareForTestWithCcBuildComponents,
+ rust.PrepareForTestWithRustDefaultModules,
+ codegen.PrepareForTestWithAconfigBuildComponents,
+ genrule.PrepareForIntegrationTestWithGenrule,
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithMyapex,
+ withAconfigValidationError,
+ ).
+ ExtendWithErrorHandler(errorHandler).
+ RunTestWithBp(t, test.bp)
+ })
+ }
+}
+
+func TestValidationNotPropagateAcrossShared(t *testing.T) {
+ testCases := []struct {
+ name string
+ bp string
+ }{
+ {
+ name: "Java shared lib not propagate aconfig validation",
+ bp: apex_default_bp + `
+ apex {
+ name: "myapex",
+ manifest: ":myapex.manifest",
+ androidManifest: ":myapex.androidmanifest",
+ key: "myapex.key",
+ java_libs: [
+ "my_java_library_bar",
+ ],
+ updatable: false,
+ }
+ java_library {
+ name: "my_java_library_bar",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ libs: ["my_java_library_foo"],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ java_library {
+ name: "my_java_library_foo",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ static_libs: ["my_java_aconfig_library_foo"],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ aconfig_declarations {
+ name: "my_aconfig_declarations_foo",
+ package: "com.example.package",
+ container: "otherapex",
+ srcs: ["foo.aconfig"],
+ }
+ java_aconfig_library {
+ name: "my_java_aconfig_library_foo",
+ aconfig_declarations: "my_aconfig_declarations_foo",
+ apex_available: [
+ "myapex",
+ ],
+ }`,
+ },
+ }
+ for _, test := range testCases {
+ t.Run(test.name, func(t *testing.T) {
+ android.GroupFixturePreparers(
+ java.PrepareForTestWithJavaDefaultModules,
+ cc.PrepareForTestWithCcBuildComponents,
+ rust.PrepareForTestWithRustDefaultModules,
+ codegen.PrepareForTestWithAconfigBuildComponents,
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithMyapex,
+ withAconfigValidationError,
+ ).
+ RunTestWithBp(t, test.bp)
+ })
+ }
+}
diff --git a/apex/apex.go b/apex/apex.go
index 9d7af18..32a3638 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2321,9 +2321,15 @@
}
func addAconfigFiles(vctx *visitorContext, ctx android.ModuleContext, module blueprint.Module) {
- dep, _ := android.OtherModuleProvider(ctx, module, android.AconfigTransitiveDeclarationsInfoProvider)
- if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
- vctx.aconfigFiles = append(vctx.aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
+ if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigTransitiveDeclarationsInfoProvider); ok {
+ if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
+ vctx.aconfigFiles = append(vctx.aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
+ }
+ }
+
+ validationFlag := ctx.DeviceConfig().AconfigContainerValidation()
+ if validationFlag == "error" || validationFlag == "warning" {
+ android.VerifyAconfigBuildMode(ctx, ctx.ModuleName(), module, validationFlag == "error")
}
}
@@ -2424,6 +2430,18 @@
// Set a provider for dexpreopt of bootjars
a.provideApexExportsInfo(ctx)
+
+ a.providePrebuiltInfo(ctx)
+}
+
+// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
+// with information about whether source or prebuilt of an apex was used during the build.
+func (a *apexBundle) providePrebuiltInfo(ctx android.ModuleContext) {
+ info := android.PrebuiltInfo{
+ Name: a.Name(),
+ Is_prebuilt: false,
+ }
+ android.SetProvider(ctx, android.PrebuiltInfoProvider, info)
}
// Set a provider containing information about the jars and .prof provided by the apex
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go
index 25c0cc4..e6ebff2 100644
--- a/apex/apex_singleton.go
+++ b/apex/apex_singleton.go
@@ -17,6 +17,8 @@
package apex
import (
+ "encoding/json"
+
"github.com/google/blueprint"
"android/soong/android"
@@ -129,3 +131,43 @@
// Export check result to Make. The path is added to droidcore.
ctx.Strict("APEX_ALLOWED_DEPS_CHECK", s.allowedApexDepsInfoCheckResult.String())
}
+
+func init() {
+ registerApexPrebuiltInfoComponents(android.InitRegistrationContext)
+}
+
+func registerApexPrebuiltInfoComponents(ctx android.RegistrationContext) {
+ ctx.RegisterParallelSingletonType("apex_prebuiltinfo_singleton", apexPrebuiltInfoFactory)
+}
+
+func apexPrebuiltInfoFactory() android.Singleton {
+ return &apexPrebuiltInfo{}
+}
+
+type apexPrebuiltInfo struct {
+ out android.WritablePath
+}
+
+func (a *apexPrebuiltInfo) GenerateBuildActions(ctx android.SingletonContext) {
+ prebuiltInfos := []android.PrebuiltInfo{}
+
+ ctx.VisitAllModules(func(m android.Module) {
+ prebuiltInfo, exists := android.SingletonModuleProvider(ctx, m, android.PrebuiltInfoProvider)
+ // Use prebuiltInfoProvider to filter out non apex soong modules.
+ // Use HideFromMake to filter out the unselected variants of a specific apex.
+ if exists && !m.IsHideFromMake() {
+ prebuiltInfos = append(prebuiltInfos, prebuiltInfo)
+ }
+ })
+
+ j, err := json.Marshal(prebuiltInfos)
+ if err != nil {
+ ctx.Errorf("Could not convert prebuilt info of apexes to json due to error: %v", err)
+ }
+ a.out = android.PathForOutput(ctx, "prebuilt_info.json")
+ android.WriteFileRule(ctx, a.out, string(j))
+}
+
+func (a *apexPrebuiltInfo) MakeVars(ctx android.MakeVarsContext) {
+ ctx.DistForGoal("droidcore", a.out)
+}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 54d2d08..19b9d16 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2068,7 +2068,7 @@
// Ensure that mylib links with "current" LLNDK
libFlags := names(mylib.Rule("ld").Args["libFlags"])
- ensureListContains(t, libFlags, "out/soong/.intermediates/libbar/"+vendorVariant+"_shared_current/libbar.so")
+ ensureListContains(t, libFlags, "out/soong/.intermediates/libbar/"+vendorVariant+"_shared/libbar.so")
// Ensure that mylib is targeting 29
ccRule := ctx.ModuleForTests("mylib", vendorVariant+"_static_apex29").Output("obj/mylib.o")
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index cebbae9..ea847e1 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -121,6 +121,11 @@
// List of systemserverclasspath fragments inside this prebuilt APEX bundle and for which this
// APEX bundle will create an APEX variant.
Exported_systemserverclasspath_fragments []string
+
+ // Path to the .prebuilt_info file of the prebuilt apex.
+ // In case of mainline modules, the .prebuilt_info file contains the build_id that was used to
+ // generate the prebuilt.
+ Prebuilt_info *string `android:"path"`
}
// initPrebuiltCommon initializes the prebuiltCommon structure and performs initialization of the
@@ -819,6 +824,20 @@
}
}
+// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
+// with information about whether source or prebuilt of an apex was used during the build.
+func (p *prebuiltCommon) providePrebuiltInfo(ctx android.ModuleContext) {
+ info := android.PrebuiltInfo{
+ Name: p.BaseModuleName(),
+ Is_prebuilt: true,
+ }
+ // If Prebuilt_info information is available in the soong module definition, add it to prebuilt_info.json.
+ if p.prebuiltCommonProperties.Prebuilt_info != nil {
+ info.Prebuilt_info_file_path = android.PathForModuleSrc(ctx, *p.prebuiltCommonProperties.Prebuilt_info).String()
+ }
+ android.SetProvider(ctx, android.PrebuiltInfoProvider, info)
+}
+
func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
p.apexKeysPath = writeApexKeys(ctx, p)
// TODO(jungjw): Check the key validity.
@@ -846,6 +865,8 @@
// provide info used for generating the boot image
p.provideApexExportsInfo(ctx)
+ p.providePrebuiltInfo(ctx)
+
// Save the files that need to be made available to Make.
p.initApexFilesForAndroidMk(ctx)
@@ -1068,6 +1089,8 @@
// provide info used for generating the boot image
a.provideApexExportsInfo(ctx)
+ a.providePrebuiltInfo(ctx)
+
// Save the files that need to be made available to Make.
a.initApexFilesForAndroidMk(ctx)
diff --git a/cc/cc.go b/cc/cc.go
index 2770fb2..0fa3457 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -766,6 +766,12 @@
var _ android.InstallNeededDependencyTag = libraryDependencyTag{}
+func (d libraryDependencyTag) PropagateAconfigValidation() bool {
+ return d.static()
+}
+
+var _ android.PropagateAconfigValidationDependencyTag = libraryDependencyTag{}
+
// dependencyTag is used for tagging miscellaneous dependency types that don't fit into
// libraryDependencyTag. Each tag object is created globally and reused for multiple
// dependencies (although since the object contains no references, assigning a tag to a
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 6cc500b..d1b728e 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -2680,15 +2680,13 @@
}
}
expected := []string{
- "android_vendor.29_arm64_armv8-a_shared_current",
"android_vendor.29_arm64_armv8-a_shared",
- "android_vendor.29_arm_armv7-a-neon_shared_current",
"android_vendor.29_arm_armv7-a-neon_shared",
}
android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
params := result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared").Description("generate stub")
- android.AssertSame(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"])
+ android.AssertSame(t, "use Vendor API level for default stubs", "202404", params.Args["apiLevel"])
checkExportedIncludeDirs := func(module, variant string, expectedDirs ...string) {
t.Helper()
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index 82beb29..0de9e05 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -51,6 +51,7 @@
arm64Ldflags = []string{
"-Wl,--hash-style=gnu",
"-Wl,-z,separate-code",
+ "-Wl,-z,separate-loadable-segments",
}
arm64Lldflags = arm64Ldflags
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index b97d511..12119a7 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -31,6 +31,7 @@
x86_64Ldflags = []string{
"-Wl,--hash-style=gnu",
+ "-Wl,-z,separate-loadable-segments",
}
X86_64Lldflags = x86_64Ldflags
diff --git a/cc/library.go b/cc/library.go
index e2b4d4f..5607632 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -677,18 +677,16 @@
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
if ctx.IsLlndk() {
+ vendorApiLevel := ctx.Config().VendorApiLevel()
+ if vendorApiLevel == "" {
+ // TODO(b/321892570): Some tests relying on old fixtures which
+ // doesn't set vendorApiLevel. Needs to fix them.
+ vendorApiLevel = ctx.Config().PlatformSdkVersion().String()
+ }
// This is the vendor variant of an LLNDK library, build the LLNDK stubs.
- vndkVer := ctx.Module().(*Module).VndkVersion()
- if !inList(vndkVer, ctx.Config().PlatformVersionActiveCodenames()) || vndkVer == "" {
- // For non-enforcing devices, vndkVer is empty. Use "current" in that case, too.
- vndkVer = "current"
- }
- if library.stubsVersion() != "" {
- vndkVer = library.stubsVersion()
- }
nativeAbiResult := parseNativeAbiDefinition(ctx,
String(library.Properties.Llndk.Symbol_file),
- android.ApiLevelOrPanic(ctx, vndkVer), "--llndk")
+ android.ApiLevelOrPanic(ctx, vendorApiLevel), "--llndk")
objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
if !Bool(library.Properties.Llndk.Unversioned) {
library.versionScriptPath = android.OptionalPathForPath(
@@ -1893,6 +1891,10 @@
if library.hasStubsVariants() && library.Properties.Stubs.Symbol_file != nil {
return library.Properties.Stubs.Symbol_file
}
+ // TODO(b/309880485): Distinguish platform, NDK, LLNDK, and APEX version scripts.
+ if library.baseLinker.Properties.Version_script != nil {
+ return library.baseLinker.Properties.Version_script
+ }
return nil
}
@@ -1913,12 +1915,15 @@
}
if library.hasLLNDKStubs() && ctx.Module().(*Module).InVendorOrProduct() {
- // LLNDK libraries only need a single stubs variant.
- return []string{android.FutureApiLevel.String()}
+ // LLNDK libraries only need a single stubs variant (""), which is
+ // added automatically in createVersionVariations().
+ return nil
}
// Future API level is implicitly added if there isn't
- return addCurrentVersionIfNotPresent(library.Properties.Stubs.Versions)
+ versions := addCurrentVersionIfNotPresent(library.Properties.Stubs.Versions)
+ normalizeVersions(ctx, versions)
+ return versions
}
func addCurrentVersionIfNotPresent(vers []string) []string {
@@ -2290,10 +2295,6 @@
return
}
versions := library.stubsVersions(mctx)
- if len(versions) <= 0 {
- return
- }
- normalizeVersions(mctx, versions)
if mctx.Failed() {
return
}
diff --git a/cc/ndkstubgen/test_ndkstubgen.py b/cc/ndkstubgen/test_ndkstubgen.py
index 1e0bdf3..22f31d9 100755
--- a/cc/ndkstubgen/test_ndkstubgen.py
+++ b/cc/ndkstubgen/test_ndkstubgen.py
@@ -463,6 +463,98 @@
""")
self.assertEqual(expected_version, version_file.getvalue())
+ def test_integration_with_llndk(self) -> None:
+ input_file = io.StringIO(textwrap.dedent("""\
+ VERSION_34 { # introduced=34
+ global:
+ foo;
+ bar; # llndk
+ };
+ VERSION_35 { # introduced=35
+ global:
+ wiggle;
+ waggle;
+ waggle; # llndk=202404
+ bubble; # llndk=202404
+ duddle;
+ duddle; # llndk=202504
+ } VERSION_34;
+ """))
+ f = copy(self.filter)
+ f.llndk = True
+ f.api = 202404
+ parser = symbolfile.SymbolFileParser(input_file, {}, f)
+ versions = parser.parse()
+
+ src_file = io.StringIO()
+ version_file = io.StringIO()
+ symbol_list_file = io.StringIO()
+
+ generator = ndkstubgen.Generator(src_file,
+ version_file, symbol_list_file, f)
+ generator.write(versions)
+
+ expected_src = textwrap.dedent("""\
+ void foo() {}
+ void bar() {}
+ void waggle() {}
+ void bubble() {}
+ """)
+ self.assertEqual(expected_src, src_file.getvalue())
+
+ expected_version = textwrap.dedent("""\
+ VERSION_34 {
+ global:
+ foo;
+ bar;
+ };
+ VERSION_35 {
+ global:
+ waggle;
+ bubble;
+ } VERSION_34;
+ """)
+ self.assertEqual(expected_version, version_file.getvalue())
+
+ def test_integration_with_llndk_with_single_version_block(self) -> None:
+ input_file = io.StringIO(textwrap.dedent("""\
+ LIBANDROID {
+ global:
+ foo; # introduced=34
+ bar; # introduced=35
+ bar; # llndk=202404
+ baz; # introduced=35
+ };
+ """))
+ f = copy(self.filter)
+ f.llndk = True
+ f.api = 202404
+ parser = symbolfile.SymbolFileParser(input_file, {}, f)
+ versions = parser.parse()
+
+ src_file = io.StringIO()
+ version_file = io.StringIO()
+ symbol_list_file = io.StringIO()
+
+ generator = ndkstubgen.Generator(src_file,
+ version_file, symbol_list_file, f)
+ generator.write(versions)
+
+ expected_src = textwrap.dedent("""\
+ void foo() {}
+ void bar() {}
+ """)
+ self.assertEqual(expected_src, src_file.getvalue())
+
+ expected_version = textwrap.dedent("""\
+ LIBANDROID {
+ global:
+ foo;
+ bar;
+ };
+ """)
+ self.assertEqual(expected_version, version_file.getvalue())
+
def test_empty_stub(self) -> None:
"""Tests that empty stubs can be generated.
diff --git a/cc/symbolfile/__init__.py b/cc/symbolfile/__init__.py
index 345e9f9..4553616 100644
--- a/cc/symbolfile/__init__.py
+++ b/cc/symbolfile/__init__.py
@@ -103,13 +103,24 @@
@property
def has_llndk_tags(self) -> bool:
"""Returns True if any LL-NDK tags are set."""
- return 'llndk' in self.tags
+ for tag in self.tags:
+ if tag == 'llndk' or tag.startswith('llndk='):
+ return True
+ return False
@property
def has_platform_only_tags(self) -> bool:
"""Returns True if any platform-only tags are set."""
return 'platform-only' in self.tags
+ def copy_introduced_from(self, tags: Tags) -> None:
+ """Copies introduced= or introduced-*= tags."""
+ for tag in tags:
+ if tag.startswith('introduced=') or tag.startswith('introduced-'):
+ name, _ = split_tag(tag)
+ if not any(self_tag.startswith(name + '=') for self_tag in self.tags):
+ self.tags += (tag,)
+
@dataclass
class Symbol:
@@ -147,6 +158,8 @@
"""Returns true if this tag has an API level that may need decoding."""
if tag.startswith('llndk-deprecated='):
return True
+ if tag.startswith('llndk='):
+ return True
if tag.startswith('introduced='):
return True
if tag.startswith('introduced-'):
@@ -237,15 +250,22 @@
This defines the rules shared between version tagging and symbol tagging.
"""
- # The apex and llndk tags will only exclude APIs from other modes. If in
+ # LLNDK mode/tags follow the similar filtering except that API level checking
+ # is based llndk= instead of introduced=.
+ if self.llndk:
+ if tags.has_mode_tags and not tags.has_llndk_tags:
+ return True
+ if not symbol_in_arch(tags, self.arch):
+ return True
+ if not symbol_in_llndk_api(tags, self.arch, self.api):
+ return True
+ return False
# APEX or LLNDK mode and neither tag is provided, we fall back to the
# default behavior because all NDK symbols are implicitly available to
# APEX and LLNDK.
if tags.has_mode_tags:
if self.apex and tags.has_apex_tags:
return False
- if self.llndk and tags.has_llndk_tags:
- return False
if self.systemapi and tags.has_systemapi_tags:
return False
return True
@@ -266,6 +286,10 @@
return True
if version.tags.has_platform_only_tags:
return True
+ # Include all versions when targeting LLNDK because LLNDK symbols are self-versioned.
+ # Empty version block will be handled separately.
+ if self.llndk:
+ return False
return self._should_omit_tags(version.tags)
def should_omit_symbol(self, symbol: Symbol) -> bool:
@@ -292,6 +316,14 @@
# for the tagged architectures.
return not has_arch_tags
+def symbol_in_llndk_api(tags: Iterable[Tag], arch: Arch, api: int) -> bool:
+ """Returns true if the symbol is present for the given LLNDK API level."""
+ # Check llndk= first.
+ for tag in tags:
+ if tag.startswith('llndk='):
+ return api >= int(get_tag_value(tag))
+ # If not, we keep old behavior: NDK symbols in <= 34 are LLNDK symbols.
+ return symbol_in_api(tags, arch, 34)
def symbol_in_api(tags: Iterable[Tag], arch: Arch, api: int) -> bool:
"""Returns true if the symbol is present for the given API level."""
@@ -368,6 +400,7 @@
f'Unexpected contents at top level: {self.current_line}')
self.check_no_duplicate_symbols(versions)
+ self.check_llndk_introduced(versions)
return versions
def check_no_duplicate_symbols(self, versions: Iterable[Version]) -> None:
@@ -396,6 +429,31 @@
raise MultiplyDefinedSymbolError(
sorted(list(multiply_defined_symbols)))
+ def check_llndk_introduced(self, versions: Iterable[Version]) -> None:
+ """Raises errors when llndk= is missing for new llndk symbols."""
+ if not self.filter.llndk:
+ return
+
+ def assert_llndk_with_version(tags: Tags, name: str) -> None:
+ has_llndk_introduced = False
+ for tag in tags:
+ if tag.startswith('llndk='):
+ has_llndk_introduced = True
+ break
+ if not has_llndk_introduced:
+ raise ParseError(f'{name}: missing version. `llndk=yyyymm`')
+
+ arch = self.filter.arch
+ for version in versions:
+ # llndk symbols >= introduced=35 should be tagged
+ # explicitly with llndk=yyyymm.
+ for symbol in version.symbols:
+ if not symbol.tags.has_llndk_tags:
+ continue
+ if symbol_in_api(symbol.tags, arch, 34):
+ continue
+ assert_llndk_with_version(symbol.tags, symbol.name)
+
def parse_version(self) -> Version:
"""Parses a single version section and returns a Version object."""
assert self.current_line is not None
@@ -429,7 +487,9 @@
else:
raise ParseError('Unknown visiblity label: ' + visibility)
elif global_scope and not cpp_symbols:
- symbols.append(self.parse_symbol())
+ symbol = self.parse_symbol()
+ symbol.tags.copy_introduced_from(tags)
+ symbols.append(symbol)
else:
# We're in a hidden scope or in 'extern "C++"' block. Ignore
# everything.
diff --git a/cc/symbolfile/test_symbolfile.py b/cc/symbolfile/test_symbolfile.py
index 83becc2..8b412b9 100644
--- a/cc/symbolfile/test_symbolfile.py
+++ b/cc/symbolfile/test_symbolfile.py
@@ -344,6 +344,45 @@
self.assertInclude(f_llndk, s_none)
self.assertInclude(f_llndk, s_llndk)
+ def test_omit_llndk_versioned(self) -> None:
+ f_ndk = self.filter
+ f_ndk.api = 35
+
+ f_llndk = copy(f_ndk)
+ f_llndk.llndk = True
+ f_llndk.api = 202404
+
+ s = Symbol('foo', Tags())
+ s_llndk = Symbol('foo', Tags.from_strs(['llndk']))
+ s_llndk_202404 = Symbol('foo', Tags.from_strs(['llndk=202404']))
+ s_34 = Symbol('foo', Tags.from_strs(['introduced=34']))
+ s_34_llndk = Symbol('foo', Tags.from_strs(['introduced=34', 'llndk']))
+ s_35 = Symbol('foo', Tags.from_strs(['introduced=35']))
+ s_35_llndk_202404 = Symbol('foo', Tags.from_strs(['introduced=35', 'llndk=202404']))
+ s_35_llndk_202504 = Symbol('foo', Tags.from_strs(['introduced=35', 'llndk=202504']))
+
+ # When targeting NDK, omit LLNDK tags
+ self.assertInclude(f_ndk, s)
+ self.assertOmit(f_ndk, s_llndk)
+ self.assertOmit(f_ndk, s_llndk_202404)
+ self.assertInclude(f_ndk, s_34)
+ self.assertOmit(f_ndk, s_34_llndk)
+ self.assertInclude(f_ndk, s_35)
+ self.assertOmit(f_ndk, s_35_llndk_202404)
+ self.assertOmit(f_ndk, s_35_llndk_202504)
+
+ # When targeting LLNDK, old symbols without any mode tags are included as LLNDK
+ self.assertInclude(f_llndk, s)
+ # When targeting LLNDK, old symbols with #llndk are included as LLNDK
+ self.assertInclude(f_llndk, s_llndk)
+ self.assertInclude(f_llndk, s_llndk_202404)
+ self.assertInclude(f_llndk, s_34)
+ self.assertInclude(f_llndk, s_34_llndk)
+ # When targeting LLNDK, new symbols(>=35) should be tagged with llndk-introduced=.
+ self.assertOmit(f_llndk, s_35)
+ self.assertInclude(f_llndk, s_35_llndk_202404)
+ self.assertOmit(f_llndk, s_35_llndk_202504)
+
def test_omit_apex(self) -> None:
f_none = self.filter
f_apex = copy(f_none)
@@ -451,9 +490,12 @@
self.assertIsNone(version.base)
self.assertEqual(Tags.from_strs(['weak', 'introduced=35']), version.tags)
+ # Inherit introduced= tags from version block so that
+ # should_omit_tags() can differently based on introduced API level when treating
+ # LLNDK-available symbols.
expected_symbols = [
- Symbol('baz', Tags()),
- Symbol('qux', Tags.from_strs(['apex', 'llndk'])),
+ Symbol('baz', Tags.from_strs(['introduced=35'])),
+ Symbol('qux', Tags.from_strs(['apex', 'llndk', 'introduced=35'])),
]
self.assertEqual(expected_symbols, version.symbols)
@@ -601,6 +643,19 @@
]
self.assertEqual(expected_symbols, version.symbols)
+ def test_parse_llndk_version_is_missing(self) -> None:
+ input_file = io.StringIO(textwrap.dedent("""\
+ VERSION_1 { # introduced=35
+ foo;
+ bar; # llndk
+ };
+ """))
+ f = copy(self.filter)
+ f.llndk = True
+ parser = symbolfile.SymbolFileParser(input_file, {}, f)
+ with self.assertRaises(symbolfile.ParseError):
+ parser.parse()
+
def main() -> None:
suite = unittest.TestLoader().loadTestsFromName(__name__)
diff --git a/java/app.go b/java/app.go
index 8209d4c..4f6f1f3 100755
--- a/java/app.go
+++ b/java/app.go
@@ -912,6 +912,13 @@
}
a.buildAppDependencyInfo(ctx)
+
+ providePrebuiltInfo(ctx,
+ prebuiltInfoProps{
+ baseModuleName: a.BaseModuleName(),
+ isPrebuilt: false,
+ },
+ )
}
type appDepsInterface interface {
diff --git a/java/app_import.go b/java/app_import.go
index dc84fc2..7387e16 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -150,6 +150,11 @@
// If unspecified, follows the naming convention that the source module of
// the prebuilt is Name() without "prebuilt_" prefix
Source_module_name *string
+
+ // Path to the .prebuilt_info file of the prebuilt app.
+ // In case of mainline modules, the .prebuilt_info file contains the build_id that was used
+ // to generate the prebuilt.
+ Prebuilt_info *string `android:"path"`
}
func (a *AndroidAppImport) IsInstallable() bool {
@@ -413,6 +418,14 @@
}
android.CollectDependencyAconfigFiles(ctx, &a.mergedAconfigFiles)
+ providePrebuiltInfo(ctx,
+ prebuiltInfoProps{
+ baseModuleName: a.BaseModuleName(),
+ isPrebuilt: true,
+ prebuiltInfo: a.properties.Prebuilt_info,
+ },
+ )
+
// TODO: androidmk converter jni libs
}
diff --git a/java/app_set.go b/java/app_set.go
index d2d3b06..33d3ade 100644
--- a/java/app_set.go
+++ b/java/app_set.go
@@ -48,6 +48,11 @@
// Names of modules to be overridden. Listed modules can only be other apps
// (in Make or Soong).
Overrides []string
+
+ // Path to the .prebuilt_info file of the prebuilt app.
+ // In case of mainline modules, the .prebuilt_info file contains the build_id that was used
+ // to generate the prebuilt.
+ Prebuilt_info *string `android:"path"`
}
type AndroidAppSet struct {
@@ -117,6 +122,27 @@
return result
}
+type prebuiltInfoProps struct {
+ baseModuleName string
+ isPrebuilt bool
+ prebuiltInfo *string
+}
+
+// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
+// with information about whether source or prebuilt of an apex was used during the build.
+func providePrebuiltInfo(ctx android.ModuleContext, p prebuiltInfoProps) {
+ info := android.PrebuiltInfo{
+ Name: p.baseModuleName,
+ Is_prebuilt: p.isPrebuilt,
+ }
+ // If Prebuilt_info information is available in the soong module definition, add it to prebuilt_info.json.
+ if p.prebuiltInfo != nil {
+ prebuiltInfoFile := android.PathForModuleSrc(ctx, *p.prebuiltInfo)
+ info.Prebuilt_info_file_path = prebuiltInfoFile.String()
+ }
+ android.SetProvider(ctx, android.PrebuiltInfoProvider, info)
+}
+
func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
as.primaryOutput = android.PathForModuleOut(ctx, as.BaseModuleName()+".apk")
@@ -157,6 +183,15 @@
installDir = android.PathForModuleInstall(ctx, "app", as.BaseModuleName())
}
ctx.InstallFileWithExtraFilesZip(installDir, as.BaseModuleName()+".apk", as.primaryOutput, as.packedOutput)
+
+ providePrebuiltInfo(ctx,
+ prebuiltInfoProps{
+ baseModuleName: as.BaseModuleName(),
+ isPrebuilt: true,
+ prebuiltInfo: as.properties.Prebuilt_info,
+ },
+ )
+
}
func (as *AndroidAppSet) InstallBypassMake() bool { return true }
diff --git a/java/base.go b/java/base.go
index d8ccec6..69f88be 100644
--- a/java/base.go
+++ b/java/base.go
@@ -26,7 +26,6 @@
"github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
- "android/soong/aconfig"
"android/soong/android"
"android/soong/dexpreopt"
"android/soong/java/config"
@@ -2551,7 +2550,7 @@
default:
return RenameUseExclude, "srcfile"
}
- } else if _, ok := android.OtherModuleProvider(ctx, m, aconfig.CodegenInfoProvider); ok {
+ } else if _, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok {
return RenameUseInclude, "aconfig_declarations_group"
} else {
switch tag {
diff --git a/java/builder.go b/java/builder.go
index b07a622..5d84d0b 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -120,6 +120,8 @@
`--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED ` +
`--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED ` +
`--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED ` +
+ `--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED ` +
+ `--add-exports=jdk.internal.opt/jdk.internal.opt=ALL-UNNAMED ` +
`-jar ${config.JavaKytheExtractorJar} ` +
`${config.JavacHeapFlags} ${config.CommonJdkFlags} ` +
`$processorpath $processor $javacFlags $bootClasspath $classpath ` +
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 6a66f45..aec40b3 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -21,7 +21,6 @@
"github.com/google/blueprint/proptools"
- "android/soong/aconfig"
"android/soong/android"
"android/soong/java/config"
)
@@ -414,7 +413,7 @@
case aconfigDeclarationTag:
if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey); ok {
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPath)
- } else if dep, ok := android.OtherModuleProvider(ctx, module, aconfig.CodegenInfoProvider); ok {
+ } else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
} else {
ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
diff --git a/java/java.go b/java/java.go
index 6423eeb..e606993 100644
--- a/java/java.go
+++ b/java/java.go
@@ -24,7 +24,6 @@
"sort"
"strings"
- "android/soong/aconfig"
"android/soong/remoteexec"
"android/soong/testing"
@@ -346,6 +345,12 @@
return j.kytheFiles
}
+func (d dependencyTag) PropagateAconfigValidation() bool {
+ return d.static
+}
+
+var _ android.PropagateAconfigValidationDependencyTag = dependencyTag{}
+
type dependencyTag struct {
blueprint.BaseDependencyTag
name string
@@ -355,6 +360,8 @@
// True if the dependency is a toolchain, for example an annotation processor.
toolchain bool
+
+ static bool
}
// installDependencyTag is a dependency tag that is annotated to cause the installed files of the
@@ -400,7 +407,7 @@
var (
dataNativeBinsTag = dependencyTag{name: "dataNativeBins"}
dataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"}
- staticLibTag = dependencyTag{name: "staticlib"}
+ staticLibTag = dependencyTag{name: "staticlib", static: true}
libTag = dependencyTag{name: "javalib", runtimeLinked: true}
sdkLibTag = dependencyTag{name: "sdklib", runtimeLinked: true}
java9LibTag = dependencyTag{name: "java9lib", runtimeLinked: true}
@@ -2173,7 +2180,7 @@
case aconfigDeclarationTag:
if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok {
al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPath)
- } else if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.CodegenInfoProvider); ok {
+ } else if provider, ok := android.OtherModuleProvider(ctx, dep, android.CodegenInfoProvider); ok {
al.aconfigProtoFiles = append(al.aconfigProtoFiles, provider.IntermediateCacheOutputPaths...)
} else {
ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
diff --git a/java/system_modules.go b/java/system_modules.go
index 92e31cd..8e2d5d8 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -64,6 +64,7 @@
// useful on Android, and (b) it causes errors with later versions of jlink
// when the jdk.internal.module is absent from java.base (as it is here).
` --disable-plugin system-modules && ` +
+ `rm -rf ${workDir} && ` +
`cp ${config.JrtFsJar} ${outDir}/lib/`,
CommandDeps: []string{
"${moduleInfoJavaPath}",
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 82abba4..698aaf2 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -157,12 +157,11 @@
syspropDir := android.GenPathWithExt(ctx, "sysprop", syspropFile, "srcrust")
outputDir := syspropDir.Join(ctx, "src")
libPath := syspropDir.Join(ctx, "src", "lib.rs")
- parsersPath := syspropDir.Join(ctx, "src", "gen_parsers_and_formatters.rs")
ctx.Build(pctx, android.BuildParams{
Rule: syspropRust,
Description: "sysprop_rust " + syspropFile.Rel(),
- Outputs: android.WritablePaths{libPath, parsersPath},
+ Outputs: android.WritablePaths{libPath},
Input: syspropFile,
Implicit: checkApiFileTimeStamp,
Args: map[string]string{
@@ -171,7 +170,7 @@
},
})
- g.genSrcs = append(g.genSrcs, libPath, parsersPath)
+ g.genSrcs = append(g.genSrcs, libPath)
}
}
diff --git a/ui/build/config.go b/ui/build/config.go
index 3143b6b..7426a78 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -1386,7 +1386,9 @@
}
func (c *configImpl) rbeSockAddr(dir string) (string, error) {
- maxNameLen := len(syscall.RawSockaddrUnix{}.Path)
+ // Absolute path socket addresses have a prefix of //. This should
+ // be included in the length limit.
+ maxNameLen := len(syscall.RawSockaddrUnix{}.Path) - 2
base := fmt.Sprintf("reproxy_%v.sock", rbeRandPrefix)
name := filepath.Join(dir, base)
diff --git a/ui/status/ninja.go b/ui/status/ninja.go
index f4e3fb8..8c3ff29 100644
--- a/ui/status/ninja.go
+++ b/ui/status/ninja.go
@@ -206,10 +206,11 @@
}
if msg.EdgeStarted != nil {
action := &Action{
- Description: msg.EdgeStarted.GetDesc(),
- Outputs: msg.EdgeStarted.Outputs,
- Inputs: msg.EdgeStarted.Inputs,
- Command: msg.EdgeStarted.GetCommand(),
+ Description: msg.EdgeStarted.GetDesc(),
+ Outputs: msg.EdgeStarted.Outputs,
+ Inputs: msg.EdgeStarted.Inputs,
+ Command: msg.EdgeStarted.GetCommand(),
+ ChangedInputs: msg.EdgeStarted.ChangedInputs,
}
n.status.StartAction(action)
running[msg.EdgeStarted.GetId()] = action
diff --git a/ui/status/ninja_frontend/frontend.pb.go b/ui/status/ninja_frontend/frontend.pb.go
index d8344c8..fce7ca2 100644
--- a/ui/status/ninja_frontend/frontend.pb.go
+++ b/ui/status/ninja_frontend/frontend.pb.go
@@ -363,6 +363,8 @@
Command *string `protobuf:"bytes,6,opt,name=command" json:"command,omitempty"`
// Edge uses console.
Console *bool `protobuf:"varint,7,opt,name=console" json:"console,omitempty"`
+ // Changed inputs.
+ ChangedInputs []string `protobuf:"bytes,8,rep,name=changed_inputs,json=changedInputs" json:"changed_inputs,omitempty"`
}
func (x *Status_EdgeStarted) Reset() {
@@ -446,6 +448,13 @@
return false
}
+func (x *Status_EdgeStarted) GetChangedInputs() []string {
+ if x != nil {
+ return x.ChangedInputs
+ }
+ return nil
+}
+
type Status_EdgeFinished struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -678,7 +687,7 @@
var file_frontend_proto_rawDesc = []byte{
0x0a, 0x0e, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x12, 0x05, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x22, 0xa9, 0x0b, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74,
+ 0x12, 0x05, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x22, 0xdb, 0x0b, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74,
0x75, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x65, 0x64, 0x67, 0x65,
0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x2e,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x45, 0x64, 0x67, 0x65,
@@ -717,7 +726,7 @@
0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x65, 0x73, 0x74, 0x69,
0x6d, 0x61, 0x74, 0x65, 0x64, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0x0f,
0x0a, 0x0d, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x1a,
- 0xb6, 0x01, 0x0a, 0x0b, 0x45, 0x64, 0x67, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12,
+ 0xe8, 0x01, 0x0a, 0x0b, 0x45, 0x64, 0x67, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12,
0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16,
@@ -728,50 +737,54 @@
0x64, 0x65, 0x73, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18,
0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x18,
0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52,
- 0x07, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x1a, 0xf3, 0x03, 0x0a, 0x0c, 0x45, 0x64, 0x67,
- 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x65, 0x6e, 0x64,
- 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x65, 0x6e, 0x64,
- 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03,
- 0x20, 0x01, 0x28, 0x11, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06,
- 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75,
- 0x74, 0x70, 0x75, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74, 0x69, 0x6d,
- 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x54, 0x69, 0x6d,
- 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x69, 0x6d, 0x65,
- 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x69,
- 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x73, 0x73, 0x5f, 0x6b, 0x62,
- 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x52, 0x73, 0x73, 0x4b, 0x62,
- 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66,
- 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x69, 0x6e,
- 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x11,
- 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74,
- 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x50, 0x61,
- 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x69, 0x6f, 0x5f, 0x69,
- 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x69,
- 0x6f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x69, 0x6f, 0x5f, 0x6f,
- 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a,
- 0x69, 0x6f, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x3c, 0x0a, 0x1a, 0x76, 0x6f,
- 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f,
- 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x18,
- 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74,
- 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x1c, 0x69, 0x6e, 0x76, 0x6f,
- 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f,
- 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1a,
- 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65,
- 0x78, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61,
- 0x67, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x1a, 0x92,
- 0x01, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x37, 0x0a, 0x05, 0x6c, 0x65,
- 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6e, 0x69, 0x6e, 0x6a,
- 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
- 0x2e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x52, 0x05, 0x6c, 0x65,
- 0x76, 0x65, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x34, 0x0a,
- 0x05, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x00,
- 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a,
- 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55,
- 0x47, 0x10, 0x03, 0x42, 0x2a, 0x48, 0x03, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
- 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
- 0x2f, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64,
+ 0x07, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x68, 0x61, 0x6e,
+ 0x67, 0x65, 0x64, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73,
+ 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x53,
+ 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x1a, 0xf3, 0x03, 0x0a, 0x0c, 0x45,
+ 0x64, 0x67, 0x65, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69,
+ 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x65,
+ 0x6e, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x65,
+ 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16,
+ 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
+ 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x74,
+ 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x54,
+ 0x69, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x69,
+ 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
+ 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x73, 0x73, 0x5f,
+ 0x6b, 0x62, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x52, 0x73, 0x73,
+ 0x4b, 0x62, 0x12, 0x2a, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65,
+ 0x5f, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d,
+ 0x69, 0x6e, 0x6f, 0x72, 0x50, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x2a,
+ 0x0a, 0x11, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x66, 0x61, 0x75,
+ 0x6c, 0x74, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x6d, 0x61, 0x6a, 0x6f, 0x72,
+ 0x50, 0x61, 0x67, 0x65, 0x46, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x69, 0x6f,
+ 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52,
+ 0x09, 0x69, 0x6f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x20, 0x0a, 0x0c, 0x69, 0x6f,
+ 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6b, 0x62, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04,
+ 0x52, 0x0a, 0x69, 0x6f, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4b, 0x62, 0x12, 0x3c, 0x0a, 0x1a,
+ 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78,
+ 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04,
+ 0x52, 0x18, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65,
+ 0x78, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x40, 0x0a, 0x1c, 0x69, 0x6e,
+ 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78,
+ 0x74, 0x5f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04,
+ 0x52, 0x1a, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e,
+ 0x74, 0x65, 0x78, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04,
+ 0x74, 0x61, 0x67, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73,
+ 0x1a, 0x92, 0x01, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x37, 0x0a, 0x05,
+ 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6e, 0x69,
+ 0x6e, 0x6a, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61,
+ 0x67, 0x65, 0x2e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x52, 0x05,
+ 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22,
+ 0x34, 0x0a, 0x05, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f,
+ 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12,
+ 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45,
+ 0x42, 0x55, 0x47, 0x10, 0x03, 0x42, 0x2a, 0x48, 0x03, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f,
+ 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x73, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x2f, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x5f, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e,
+ 0x64,
}
var (
diff --git a/ui/status/ninja_frontend/frontend.proto b/ui/status/ninja_frontend/frontend.proto
index 42b251b..faa0d34 100644
--- a/ui/status/ninja_frontend/frontend.proto
+++ b/ui/status/ninja_frontend/frontend.proto
@@ -54,6 +54,8 @@
optional string command = 6;
// Edge uses console.
optional bool console = 7;
+ // Changed inputs since last build.
+ repeated string changed_inputs = 8;
}
message EdgeFinished {
diff --git a/ui/status/status.go b/ui/status/status.go
index da78994..52ed56a 100644
--- a/ui/status/status.go
+++ b/ui/status/status.go
@@ -41,6 +41,10 @@
// It's optional, but one of either Description or Command should be
// set.
Command string
+
+ // ChangedInputs is the (optional) list of inputs that have changed
+ // since last time this action was run.
+ ChangedInputs []string
}
// ActionResult describes the result of running an Action.
diff --git a/ui/tracer/status.go b/ui/tracer/status.go
index f973613..8acf561 100644
--- a/ui/tracer/status.go
+++ b/ui/tracer/status.go
@@ -15,9 +15,10 @@
package tracer
import (
- "android/soong/ui/status"
"strings"
"time"
+
+ "android/soong/ui/status"
)
func (t *tracerImpl) StatusTracer() status.StatusOutput {
@@ -110,6 +111,7 @@
VoluntaryContextSwitches: result.Stats.VoluntaryContextSwitches,
InvoluntaryContextSwitches: result.Stats.InvoluntaryContextSwitches,
Tags: s.parseTags(result.Stats.Tags),
+ ChangedInputs: result.Action.ChangedInputs,
},
})
}
@@ -125,6 +127,7 @@
VoluntaryContextSwitches uint64 `json:"voluntary_context_switches"`
InvoluntaryContextSwitches uint64 `json:"involuntary_context_switches"`
Tags map[string]string `json:"tags"`
+ ChangedInputs []string `json:"changed_inputs"`
}
func (s *statusOutput) Flush() {}