Merge "Validate aconfig libs are built with the correct modes." into main
diff --git a/android/Android.bp b/android/Android.bp
index e73f355..03619f4 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -16,7 +16,6 @@
"soong-remoteexec",
"soong-response",
"soong-shared",
- "soong-starlark",
"soong-starlark-format",
"soong-ui-metrics_proto",
"soong-android-allowlists",
@@ -135,6 +134,7 @@
"rule_builder_test.go",
"sdk_version_test.go",
"sdk_test.go",
+ "selects_test.go",
"singleton_module_test.go",
"soong_config_modules_test.go",
"util_test.go",
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/api_levels.go b/android/api_levels.go
index 6fa4a0e..1130c3e 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -15,7 +15,6 @@
package android
import (
- "android/soong/starlark_import"
"encoding/json"
"fmt"
"strconv"
@@ -440,7 +439,28 @@
}
func getApiLevelsMapReleasedVersions() (map[string]int, error) {
- return starlark_import.GetStarlarkValue[map[string]int]("api_levels_released_versions")
+ return map[string]int{
+ "G": 9,
+ "I": 14,
+ "J": 16,
+ "J-MR1": 17,
+ "J-MR2": 18,
+ "K": 19,
+ "L": 21,
+ "L-MR1": 22,
+ "M": 23,
+ "N": 24,
+ "N-MR1": 25,
+ "O": 26,
+ "O-MR1": 27,
+ "P": 28,
+ "Q": 29,
+ "R": 30,
+ "S": 31,
+ "S-V2": 32,
+ "Tiramisu": 33,
+ "UpsideDownCake": 34,
+ }, nil
}
var finalCodenamesMapKey = NewOnceKey("FinalCodenamesMap")
diff --git a/android/config.go b/android/config.go
index 951aed1..567ebd8 100644
--- a/android/config.go
+++ b/android/config.go
@@ -639,9 +639,12 @@
"framework-adservices": {},
"framework-appsearch": {},
"framework-bluetooth": {},
+ "framework-configinfrastructure": {},
"framework-connectivity": {},
"framework-connectivity-t": {},
+ "framework-devicelock": {},
"framework-graphics": {},
+ "framework-healthfitness": {},
"framework-location": {},
"framework-media": {},
"framework-mediaprovider": {},
@@ -1343,13 +1346,16 @@
panic(fmt.Errorf("Cannot parse vendor API level %s to an integer: %s",
c.VendorApiLevel(), err))
}
- if vendorApiLevel < 202404 || vendorApiLevel%100 != 4 {
- panic("Unknown vendor API level " + c.VendorApiLevel())
- }
// The version before trunk stable is 34.
if vendorApiLevel == 202404 {
return "34"
}
+ if vendorApiLevel >= 1 && vendorApiLevel <= 34 {
+ return strconv.Itoa(vendorApiLevel - 1)
+ }
+ if vendorApiLevel < 202404 || vendorApiLevel%100 != 4 {
+ panic("Unknown vendor API level " + c.VendorApiLevel())
+ }
return strconv.Itoa(vendorApiLevel - 100)
}
diff --git a/android/module_context.go b/android/module_context.go
index 1cab630..3fc5d01 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -21,6 +21,7 @@
"strings"
"github.com/google/blueprint"
+ "github.com/google/blueprint/parser"
"github.com/google/blueprint/proptools"
)
@@ -212,6 +213,10 @@
// 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 {
@@ -714,3 +719,32 @@
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/ninja_deps.go b/android/ninja_deps.go
index 1d50a47..bdf465e 100644
--- a/android/ninja_deps.go
+++ b/android/ninja_deps.go
@@ -15,7 +15,6 @@
package android
import (
- "android/soong/starlark_import"
"sort"
)
@@ -43,11 +42,4 @@
func (ninjaDepsSingleton) GenerateBuildActions(ctx SingletonContext) {
ctx.AddNinjaFileDeps(ctx.Config().ninjaFileDeps()...)
-
- deps, err := starlark_import.GetNinjaDeps()
- if err != nil {
- ctx.Errorf("Error running starlark code: %s", err)
- } else {
- ctx.AddNinjaFileDeps(deps...)
- }
}
diff --git a/android/selects_test.go b/android/selects_test.go
new file mode 100644
index 0000000..dca3789
--- /dev/null
+++ b/android/selects_test.go
@@ -0,0 +1,282 @@
+// Copyright 2024 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "fmt"
+ "reflect"
+ "testing"
+
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+)
+
+func TestSelects(t *testing.T) {
+ testCases := []struct {
+ name string
+ bp string
+ provider selectsTestProvider
+ vendorVars map[string]map[string]string
+ expectedError string
+ }{
+ {
+ name: "basic string list",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string_list: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": ["a.cpp"],
+ "b": ["b.cpp"],
+ _: ["c.cpp"],
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string_list: &[]string{"c.cpp"},
+ },
+ },
+ {
+ name: "basic string",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": "a.cpp",
+ "b": "b.cpp",
+ _: "c.cpp",
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("c.cpp"),
+ },
+ },
+ {
+ name: "basic bool",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_bool: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": true,
+ "b": false,
+ _: true,
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ my_bool: proptools.BoolPtr(true),
+ },
+ },
+ {
+ name: "Differing types",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": "a.cpp",
+ "b": true,
+ _: "c.cpp",
+ }),
+ }
+ `,
+ expectedError: `can't assign bool value to string property "my_string\[1\]"`,
+ },
+ {
+ name: "String list non-default",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string_list: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": ["a.cpp"],
+ "b": ["b.cpp"],
+ _: ["c.cpp"],
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string_list: &[]string{"a.cpp"},
+ },
+ vendorVars: map[string]map[string]string{
+ "my_namespace": {
+ "my_variable": "a",
+ },
+ },
+ },
+ {
+ name: "String list append",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string_list: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": ["a.cpp"],
+ "b": ["b.cpp"],
+ _: ["c.cpp"],
+ }) + select(soong_config_variable("my_namespace", "my_variable_2"), {
+ "a2": ["a2.cpp"],
+ "b2": ["b2.cpp"],
+ _: ["c2.cpp"],
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string_list: &[]string{"a.cpp", "c2.cpp"},
+ },
+ vendorVars: map[string]map[string]string{
+ "my_namespace": {
+ "my_variable": "a",
+ },
+ },
+ },
+ {
+ name: "String list prepend literal",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string_list: ["literal.cpp"] + select(soong_config_variable("my_namespace", "my_variable"), {
+ "a2": ["a2.cpp"],
+ "b2": ["b2.cpp"],
+ _: ["c2.cpp"],
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string_list: &[]string{"literal.cpp", "c2.cpp"},
+ },
+ },
+ {
+ name: "String list append literal",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string_list: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a2": ["a2.cpp"],
+ "b2": ["b2.cpp"],
+ _: ["c2.cpp"],
+ }) + ["literal.cpp"],
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string_list: &[]string{"c2.cpp", "literal.cpp"},
+ },
+ },
+ {
+ name: "Can't append bools",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_bool: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": true,
+ "b": false,
+ _: true,
+ }) + false,
+ }
+ `,
+ expectedError: "my_bool: Cannot append bools",
+ },
+ {
+ name: "Append string",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(soong_config_variable("my_namespace", "my_variable"), {
+ "a": "a",
+ "b": "b",
+ _: "c",
+ }) + ".cpp",
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("c.cpp"),
+ },
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ fixtures := GroupFixturePreparers(
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.RegisterModuleType("my_module_type", newSelectsMockModule)
+ }),
+ FixtureModifyProductVariables(func(variables FixtureProductVariables) {
+ variables.VendorVars = tc.vendorVars
+ }),
+ )
+ if tc.expectedError != "" {
+ fixtures = fixtures.ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(tc.expectedError))
+ }
+ result := fixtures.RunTestWithBp(t, tc.bp)
+
+ if tc.expectedError == "" {
+ m := result.ModuleForTests("foo", "")
+ p, _ := OtherModuleProvider[selectsTestProvider](result.testContext.OtherModuleProviderAdaptor(), m.Module(), selectsTestProviderKey)
+ if !reflect.DeepEqual(p, tc.provider) {
+ t.Errorf("Expected:\n %q\ngot:\n %q", tc.provider.String(), p.String())
+ }
+ }
+ })
+ }
+}
+
+type selectsTestProvider struct {
+ my_bool *bool
+ my_string *string
+ my_string_list *[]string
+}
+
+func (p *selectsTestProvider) String() string {
+ myBoolStr := "nil"
+ if p.my_bool != nil {
+ myBoolStr = fmt.Sprintf("%t", *p.my_bool)
+ }
+ myStringStr := "nil"
+ if p.my_string != nil {
+ myStringStr = *p.my_string
+ }
+ return fmt.Sprintf(`selectsTestProvider {
+ my_bool: %v,
+ my_string: %s,
+ my_string_list: %s,
+}`, myBoolStr, myStringStr, p.my_string_list)
+}
+
+var selectsTestProviderKey = blueprint.NewProvider[selectsTestProvider]()
+
+type selectsMockModuleProperties struct {
+ My_bool proptools.Configurable[bool]
+ My_string proptools.Configurable[string]
+ My_string_list proptools.Configurable[[]string]
+}
+
+type selectsMockModule struct {
+ ModuleBase
+ DefaultableModuleBase
+ properties selectsMockModuleProperties
+}
+
+func (p *selectsMockModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ SetProvider[selectsTestProvider](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),
+ })
+}
+
+func newSelectsMockModule() Module {
+ m := &selectsMockModule{}
+ m.AddProperties(&m.properties)
+ InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon)
+ InitDefaultableModule(m)
+ return m
+}
diff --git a/android/updatable_modules.go b/android/updatable_modules.go
index 6d0eeb7..1548170 100644
--- a/android/updatable_modules.go
+++ b/android/updatable_modules.go
@@ -33,4 +33,4 @@
// * AOSP - xx9990000
// * x-mainline-prod - xx9990000
// * master - 990090000
-const DefaultUpdatableModuleVersion = "340090000"
+const DefaultUpdatableModuleVersion = "990090000"
diff --git a/apex/apex.go b/apex/apex.go
index d0b3986..7c6fb89 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2430,6 +2430,33 @@
// Set a provider for dexpreopt of bootjars
a.provideApexExportsInfo(ctx)
+
+ a.providePrebuiltInfo(ctx)
+}
+
+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"`
+}
+
+// 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 := prebuiltInfo{
+ Name: a.Name(),
+ Is_prebuilt: false,
+ }
+ android.SetProvider(ctx, 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..8aaddbe 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 := []prebuiltInfo{}
+
+ ctx.VisitAllModules(func(m android.Module) {
+ prebuiltInfo, exists := android.SingletonModuleProvider(ctx, m, 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..34dfc46 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 := prebuiltInfo{
+ Name: p.BaseModuleName(), // BaseModuleName ensures that this will not contain the prebuilt_ prefix.
+ 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, 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_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/cmd/soong_build/queryview.go b/cmd/soong_build/queryview.go
index 5c2316a..eafd67a 100644
--- a/cmd/soong_build/queryview.go
+++ b/cmd/soong_build/queryview.go
@@ -22,7 +22,6 @@
"android/soong/android"
"android/soong/bp2build"
- "android/soong/starlark_import"
)
// A helper function to generate a Read-only Bazel workspace in outDir
@@ -47,14 +46,6 @@
}
}
- // Add starlark deps here, so that they apply to both queryview and apibp2build which
- // both run this function.
- starlarkDeps, err2 := starlark_import.GetNinjaDeps()
- if err2 != nil {
- return err2
- }
- ctx.AddNinjaFileDeps(starlarkDeps...)
-
return nil
}
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 6612a6f..795a0aa 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -311,18 +311,16 @@
}
func (f *filesystem) buildPropFile(ctx android.ModuleContext) (propFile android.OutputPath, toolDeps android.Paths) {
- type prop struct {
- name string
- value string
- }
-
- var props []prop
var deps android.Paths
+ var propFileString strings.Builder
addStr := func(name string, value string) {
- props = append(props, prop{name, value})
+ propFileString.WriteString(name)
+ propFileString.WriteRune('=')
+ propFileString.WriteString(value)
+ propFileString.WriteRune('\n')
}
addPath := func(name string, path android.Path) {
- props = append(props, prop{name, path.String()})
+ addStr(name, path.String())
deps = append(deps, path)
}
@@ -376,15 +374,7 @@
addStr("hash_seed", uuid)
}
propFile = android.PathForModuleOut(ctx, "prop").OutputPath
- builder := android.NewRuleBuilder(pctx, ctx)
- builder.Command().Text("rm").Flag("-rf").Output(propFile)
- for _, p := range props {
- builder.Command().
- Text("echo").
- Flag(`"` + p.name + "=" + p.value + `"`).
- Text(">>").Output(propFile)
- }
- builder.Build("build_filesystem_prop", fmt.Sprintf("Creating filesystem props for %s", f.BaseModuleName()))
+ android.WriteFileRuleVerbatim(ctx, propFile, propFileString.String())
return propFile, deps
}
diff --git a/java/aapt2.go b/java/aapt2.go
index 445e912..f704fc6 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -309,7 +309,8 @@
var aapt2ConvertRule = pctx.AndroidStaticRule("aapt2Convert",
blueprint.RuleParams{
- Command: `${config.Aapt2Cmd} convert --output-format $format $in -o $out`,
+ Command: `${config.Aapt2Cmd} convert --enable-compact-entries ` +
+ `--output-format $format $in -o $out`,
CommandDeps: []string{"${config.Aapt2Cmd}"},
}, "format",
)
diff --git a/java/aar.go b/java/aar.go
index 7cb362a..27dd38b 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -204,6 +204,8 @@
// Flags specified in Android.bp
linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
+ linkFlags = append(linkFlags, "--enable-compact-entries")
+
// Find implicit or explicit asset and resource dirs
assets := android.PathsRelativeToModuleSourceDir(android.SourceInput{
Context: ctx,
@@ -453,6 +455,11 @@
// as imports. The resources from dependencies will not be merged into this module's package-res.apk, and
// instead modules depending on this module will reference package-res.apk from all transitive static
// dependencies.
+ for _, sharedDep := range sharedDeps {
+ if sharedDep.usedResourceProcessor {
+ transitiveRJars = append(transitiveRJars, sharedDep.rJar)
+ }
+ }
for _, staticDep := range staticDeps {
linkDeps = append(linkDeps, staticDep.resPackage)
linkFlags = append(linkFlags, "-I "+staticDep.resPackage.String())
@@ -460,11 +467,6 @@
transitiveRJars = append(transitiveRJars, staticDep.rJar)
}
}
- for _, sharedDep := range sharedDeps {
- if sharedDep.usedResourceProcessor {
- transitiveRJars = append(transitiveRJars, sharedDep.rJar)
- }
- }
} else {
// When building an app or building a library without ResourceProcessorBusyBox enabled all static
// dependencies are compiled into this module's package-res.apk as overlays.
@@ -554,6 +556,10 @@
transitiveAaptResourcePackagesFile := android.PathForModuleOut(ctx, "transitive-res-packages")
android.WriteFileRule(ctx, transitiveAaptResourcePackagesFile, strings.Join(transitiveAaptResourcePackages, "\n"))
+ // Reverse the list of R.jar files so that the current module comes first, and direct dependencies come before
+ // transitive dependencies.
+ transitiveRJars = android.ReversePaths(transitiveRJars)
+
a.aaptSrcJar = srcJar
a.transitiveAaptRJars = transitiveRJars
a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile
diff --git a/java/app_test.go b/java/app_test.go
index 28bea0a..5d7b048 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -948,10 +948,10 @@
directSrcJars: nil,
directClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
- "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
- "out/soong/.intermediates/transitive/android_common/busybox/R.jar",
"out/soong/.intermediates/direct/android_common/busybox/R.jar",
+ "out/soong/.intermediates/transitive/android_common/busybox/R.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
+ "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
},
@@ -981,9 +981,9 @@
sharedSrcJars: nil,
sharedClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
+ "out/soong/.intermediates/shared/android_common/busybox/R.jar",
"out/soong/.intermediates/shared_transitive_static/android_common/busybox/R.jar",
"out/soong/.intermediates/shared_transitive_shared/android_common/busybox/R.jar",
- "out/soong/.intermediates/shared/android_common/busybox/R.jar",
"out/soong/.intermediates/shared_transitive_shared/android_common/turbine-combined/shared_transitive_shared.jar",
"out/soong/.intermediates/shared_transitive_static/android_common/turbine-combined/shared_transitive_static.jar",
},
@@ -1094,9 +1094,9 @@
directSrcJars: nil,
directClasspath: []string{
"out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar",
- "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
- "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
"out/soong/.intermediates/direct/android_common/busybox/R.jar",
+ "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar",
+ "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar",
"out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar",
"out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar",
},
diff --git a/java/base.go b/java/base.go
index c5f22d2..69f88be 100644
--- a/java/base.go
+++ b/java/base.go
@@ -94,6 +94,9 @@
// if not blank, used as prefix to generate repackage rule
Jarjar_prefix *string
+ // if set to true, skip the jarjar repackaging
+ Skip_jarjar_repackage *bool
+
// If not blank, set the java version passed to javac as -source and -target
Java_version *string
@@ -1100,11 +1103,13 @@
jarjarProviderData := j.collectJarJarRules(ctx)
if jarjarProviderData != nil {
android.SetProvider(ctx, JarJarProvider, *jarjarProviderData)
- text := getJarJarRuleText(jarjarProviderData)
- if text != "" {
- ruleTextFile := android.PathForModuleOut(ctx, "repackaged-jarjar", "repackaging.txt")
- android.WriteFileRule(ctx, ruleTextFile, text)
- j.repackageJarjarRules = ruleTextFile
+ if !proptools.Bool(j.properties.Skip_jarjar_repackage) {
+ text := getJarJarRuleText(jarjarProviderData)
+ if text != "" {
+ ruleTextFile := android.PathForModuleOut(ctx, "repackaged-jarjar", "repackaging.txt")
+ android.WriteFileRule(ctx, ruleTextFile, text)
+ j.repackageJarjarRules = ruleTextFile
+ }
}
}
diff --git a/java/config/config.go b/java/config/config.go
index 6a945ac..d720046 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -131,12 +131,7 @@
if override := ctx.Config().Getenv("OVERRIDE_JLINK_VERSION_NUMBER"); override != "" {
return override
}
- switch ctx.Config().Getenv("EXPERIMENTAL_USE_OPENJDK21_TOOLCHAIN") {
- case "true":
- return "21"
- default:
- return "17"
- }
+ return "21"
})
pctx.SourcePathVariable("JavaToolchain", "${JavaHome}/bin")
diff --git a/java/config/droidstubs.go b/java/config/droidstubs.go
index f46c893..39eec44 100644
--- a/java/config/droidstubs.go
+++ b/java/config/droidstubs.go
@@ -23,7 +23,6 @@
"--format=v2",
"--repeat-errors-max 10",
"--hide UnresolvedImport",
- "--hide InvalidNullabilityOverride",
// Force metalava to ignore classes on the classpath when an API file contains missing classes.
// See b/285140653 for more information.
@@ -49,9 +48,6 @@
// TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
"--hide HiddenTypedefConstant",
"--hide SuperfluousPrefix",
- "--hide AnnotationExtraction",
- // b/222738070
- "--hide BannedThrow",
}
MetalavaAnnotationsWarningsFlags = strings.Join(metalavaAnnotationsWarningsFlags, " ")
diff --git a/java/java.go b/java/java.go
index 4b99672..e606993 100644
--- a/java/java.go
+++ b/java/java.go
@@ -687,10 +687,11 @@
return true
}
- // Store uncompressed dex files that are preopted on /system.
- if !dexpreopter.dexpreoptDisabled(ctx, libName) && (ctx.Host() || !dexpreopter.odexOnSystemOther(ctx, libName, dexpreopter.installPath)) {
+ // Store uncompressed dex files that are preopted on /system or /system_other.
+ if !dexpreopter.dexpreoptDisabled(ctx, libName) {
return true
}
+
if ctx.Config().UncompressPrivAppDex() &&
inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) {
return true
diff --git a/mk2rbc/test/version_defaults.mk.test b/mk2rbc/test/version_defaults.mk.test
index 1666392..3ce60bc 100644
--- a/mk2rbc/test/version_defaults.mk.test
+++ b/mk2rbc/test/version_defaults.mk.test
@@ -3,8 +3,8 @@
include $(INTERNAL_BUILD_ID_MAKEFILE)
endif
-DEFAULT_PLATFORM_VERSION := TP1A
-.KATI_READONLY := DEFAULT_PLATFORM_VERSION
+RELEASE_PLATFORM_VERSION := TP1A
+.KATI_READONLY := RELEASE_PLATFORM_VERSION
MIN_PLATFORM_VERSION := TP1A
MAX_PLATFORM_VERSION := TP1A
PLATFORM_VERSION_LAST_STABLE := 12
diff --git a/sdk/update.go b/sdk/update.go
index 095e0c2..a731414 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -89,19 +89,6 @@
indentLevel int
}
-// generatedFile abstracts operations for writing contents into a file and emit a build rule
-// for the file.
-type generatedFile struct {
- generatedContents
- path android.OutputPath
-}
-
-func newGeneratedFile(ctx android.ModuleContext, path ...string) *generatedFile {
- return &generatedFile{
- path: android.PathForModuleOut(ctx, path...).OutputPath,
- }
-}
-
func (gc *generatedContents) Indent() {
gc.indentLevel++
}
@@ -122,26 +109,6 @@
_, _ = fmt.Fprintf(&(gc.content), format, args...)
}
-func (gf *generatedFile) build(pctx android.PackageContext, ctx android.BuilderContext, implicits android.Paths) {
- rb := android.NewRuleBuilder(pctx, ctx)
-
- content := gf.content.String()
-
- // ninja consumes newline characters in rspfile_content. Prevent it by
- // escaping the backslash in the newline character. The extra backslash
- // is removed when the rspfile is written to the actual script file
- content = strings.ReplaceAll(content, "\n", "\\n")
-
- rb.Command().
- Implicits(implicits).
- Text("echo -n").Text(proptools.ShellEscape(content)).
- // convert \\n to \n
- Text("| sed 's/\\\\n/\\n/g' >").Output(gf.path)
- rb.Command().
- Text("chmod a+x").Output(gf.path)
- rb.Build(gf.path.Base(), "Build "+gf.path.Base())
-}
-
// Collect all the members.
//
// Updates the sdk module with a list of sdkMemberVariantDep instances and details as to which
@@ -170,7 +137,7 @@
var container android.Module
if parent != ctx.Module() {
- container = parent.(android.Module)
+ container = parent
}
minApiLevel := android.MinApiLevelForSdkSnapshot(ctx, child)
@@ -179,7 +146,7 @@
s.memberVariantDeps = append(s.memberVariantDeps, sdkMemberVariantDep{
sdkVariant: s,
memberType: memberType,
- variant: child.(android.Module),
+ variant: child,
minApiLevel: minApiLevel,
container: container,
export: export,
@@ -375,7 +342,7 @@
snapshotDir := android.PathForModuleOut(ctx, "snapshot")
- bp := newGeneratedFile(ctx, "snapshot", "Android.bp")
+ bp := android.PathForModuleOut(ctx, "snapshot", "Android.bp")
bpFile := &bpFile{
modules: make(map[string]*bpModule),
@@ -389,7 +356,7 @@
sdk: s,
snapshotDir: snapshotDir.OutputPath,
copies: make(map[string]string),
- filesToZip: []android.Path{bp.path},
+ filesToZip: []android.Path{bp},
bpFile: bpFile,
prebuiltModules: make(map[string]*bpModule),
allMembersByName: allMembersByName,
@@ -463,17 +430,14 @@
}
// generate Android.bp
- bp = newGeneratedFile(ctx, "snapshot", "Android.bp")
- generateBpContents(&bp.generatedContents, bpFile)
-
- contents := bp.content.String()
+ contents := generateBpContents(bpFile)
// If the snapshot is being generated for the current build release then check the syntax to make
// sure that it is compatible.
if targetBuildRelease == buildReleaseCurrent {
syntaxCheckSnapshotBpFile(ctx, contents)
}
- bp.build(pctx, ctx, nil)
+ android.WriteFileRuleVerbatim(ctx, bp, contents)
// Copy the build number file into the snapshot.
builder.CopyToSnapshot(ctx.Config().BuildNumberFile(ctx), BUILD_NUMBER_FILE)
@@ -522,16 +486,14 @@
modules := s.generateInfoData(ctx, memberVariantDeps)
// Output the modules information as pretty printed JSON.
- info := newGeneratedFile(ctx, fmt.Sprintf("%s%s.info", ctx.ModuleName(), snapshotFileSuffix))
+ info := android.PathForModuleOut(ctx, fmt.Sprintf("%s%s.info", ctx.ModuleName(), snapshotFileSuffix))
output, err := json.MarshalIndent(modules, "", " ")
if err != nil {
ctx.ModuleErrorf("error generating %q: %s", info, err)
}
builder.infoContents = string(output)
- info.generatedContents.UnindentedPrintf("%s", output)
- info.build(pctx, ctx, nil)
- infoPath := info.path
- installedInfo := ctx.InstallFile(android.PathForMainlineSdksInstall(ctx), infoPath.Base(), infoPath)
+ android.WriteFileRuleVerbatim(ctx, info, builder.infoContents)
+ installedInfo := ctx.InstallFile(android.PathForMainlineSdksInstall(ctx), info.Base(), info)
s.infoFile = android.OptionalPathForPath(installedInfo)
// Install the zip, making sure that the info file has been installed as well.
@@ -718,105 +680,6 @@
}
}
-// snapshotModuleStaticProperties contains snapshot static (i.e. not dynamically generated) properties.
-type snapshotModuleStaticProperties struct {
- Compile_multilib string `android:"arch_variant"`
-}
-
-// combinedSnapshotModuleProperties are the properties that are associated with the snapshot module.
-type combinedSnapshotModuleProperties struct {
- // The sdk variant from which this information was collected.
- sdkVariant *sdk
-
- // Static snapshot module properties.
- staticProperties *snapshotModuleStaticProperties
-
- // The dynamically generated member list properties.
- dynamicProperties interface{}
-}
-
-// collateSnapshotModuleInfo collates all the snapshot module info from supplied sdk variants.
-func (s *sdk) collateSnapshotModuleInfo(ctx android.BaseModuleContext, sdkVariants []*sdk, memberVariantDeps []sdkMemberVariantDep) []*combinedSnapshotModuleProperties {
- sdkVariantToCombinedProperties := map[*sdk]*combinedSnapshotModuleProperties{}
- var list []*combinedSnapshotModuleProperties
- for _, sdkVariant := range sdkVariants {
- staticProperties := &snapshotModuleStaticProperties{
- Compile_multilib: sdkVariant.multilibUsages.String(),
- }
- dynamicProperties := s.dynamicSdkMemberTypes.createMemberTypeListProperties()
-
- combinedProperties := &combinedSnapshotModuleProperties{
- sdkVariant: sdkVariant,
- staticProperties: staticProperties,
- dynamicProperties: dynamicProperties,
- }
- sdkVariantToCombinedProperties[sdkVariant] = combinedProperties
-
- list = append(list, combinedProperties)
- }
-
- for _, memberVariantDep := range memberVariantDeps {
- // If the member dependency is internal then do not add the dependency to the snapshot member
- // list properties.
- if !memberVariantDep.export {
- continue
- }
-
- combined := sdkVariantToCombinedProperties[memberVariantDep.sdkVariant]
- memberListProperty := s.memberTypeListProperty(memberVariantDep.memberType)
- memberName := ctx.OtherModuleName(memberVariantDep.variant)
-
- if memberListProperty.getter == nil {
- continue
- }
-
- // Append the member to the appropriate list, if it is not already present in the list.
- memberList := memberListProperty.getter(combined.dynamicProperties)
- if !android.InList(memberName, memberList) {
- memberList = append(memberList, memberName)
- }
- memberListProperty.setter(combined.dynamicProperties, memberList)
- }
-
- return list
-}
-
-func (s *sdk) optimizeSnapshotModuleProperties(ctx android.ModuleContext, list []*combinedSnapshotModuleProperties) *combinedSnapshotModuleProperties {
-
- // Extract the dynamic properties and add them to a list of propertiesContainer.
- propertyContainers := []propertiesContainer{}
- for _, i := range list {
- propertyContainers = append(propertyContainers, sdkVariantPropertiesContainer{
- sdkVariant: i.sdkVariant,
- properties: i.dynamicProperties,
- })
- }
-
- // Extract the common members, removing them from the original properties.
- commonDynamicProperties := s.dynamicSdkMemberTypes.createMemberTypeListProperties()
- extractor := newCommonValueExtractor(commonDynamicProperties)
- extractCommonProperties(ctx, extractor, commonDynamicProperties, propertyContainers)
-
- // Extract the static properties and add them to a list of propertiesContainer.
- propertyContainers = []propertiesContainer{}
- for _, i := range list {
- propertyContainers = append(propertyContainers, sdkVariantPropertiesContainer{
- sdkVariant: i.sdkVariant,
- properties: i.staticProperties,
- })
- }
-
- commonStaticProperties := &snapshotModuleStaticProperties{}
- extractor = newCommonValueExtractor(commonStaticProperties)
- extractCommonProperties(ctx, extractor, &commonStaticProperties, propertyContainers)
-
- return &combinedSnapshotModuleProperties{
- sdkVariant: nil,
- staticProperties: commonStaticProperties,
- dynamicProperties: commonDynamicProperties,
- }
-}
-
type propertyTag struct {
name string
}
@@ -885,7 +748,8 @@
}
}
-func generateBpContents(contents *generatedContents, bpFile *bpFile) {
+func generateBpContents(bpFile *bpFile) string {
+ contents := &generatedContents{}
contents.IndentedPrintf("// This is auto-generated. DO NOT EDIT.\n")
for _, bpModule := range bpFile.order {
contents.IndentedPrintf("\n")
@@ -893,6 +757,7 @@
outputPropertySet(contents, bpModule.bpPropertySet)
contents.IndentedPrintf("}\n")
}
+ return contents.content.String()
}
func outputPropertySet(contents *generatedContents, set *bpPropertySet) {
@@ -1007,7 +872,7 @@
contents.IndentedPrintf("}")
default:
- panic(fmt.Errorf("Unknown type: %T of value %#v", value, value))
+ panic(fmt.Errorf("unknown type: %T of value %#v", value, value))
}
}
@@ -1018,9 +883,7 @@
}
func (s *sdk) GetAndroidBpContentsForTests() string {
- contents := &generatedContents{}
- generateBpContents(contents, s.builderForTests.bpFile)
- return contents.content.String()
+ return generateBpContents(s.builderForTests.bpFile)
}
func (s *sdk) GetInfoContentsForTests() string {
@@ -1334,7 +1197,7 @@
case "lib64":
return m | multilib64
default:
- panic(fmt.Errorf("Unknown Multilib field in ArchType, expected 'lib32' or 'lib64', found %q", multilib))
+ panic(fmt.Errorf("unknown Multilib field in ArchType, expected 'lib32' or 'lib64', found %q", multilib))
}
}
@@ -1349,7 +1212,7 @@
case multilibBoth:
return "both"
default:
- panic(fmt.Errorf("Unknown multilib value, found %b, expected one of %b, %b, %b or %b",
+ panic(fmt.Errorf("unknown multilib value, found %b, expected one of %b, %b, %b or %b",
m, multilibNone, multilib32, multilib64, multilibBoth))
}
}
@@ -2302,20 +2165,6 @@
optimizableProperties() interface{}
}
-// A wrapper for sdk variant related properties to allow them to be optimized.
-type sdkVariantPropertiesContainer struct {
- sdkVariant *sdk
- properties interface{}
-}
-
-func (c sdkVariantPropertiesContainer) optimizableProperties() interface{} {
- return c.properties
-}
-
-func (c sdkVariantPropertiesContainer) String() string {
- return c.sdkVariant.String()
-}
-
// Extract common properties from a slice of property structures of the same type.
//
// All the property structures must be of the same type.
diff --git a/starlark_import/Android.bp b/starlark_import/Android.bp
deleted file mode 100644
index b43217b..0000000
--- a/starlark_import/Android.bp
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2023 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-bootstrap_go_package {
- name: "soong-starlark",
- pkgPath: "android/soong/starlark_import",
- srcs: [
- "starlark_import.go",
- "unmarshal.go",
- ],
- testSrcs: [
- "starlark_import_test.go",
- "unmarshal_test.go",
- ],
- deps: [
- "go-starlark-starlark",
- "go-starlark-starlarkstruct",
- "go-starlark-starlarkjson",
- "go-starlark-starlarktest",
- ],
-}
diff --git a/starlark_import/README.md b/starlark_import/README.md
deleted file mode 100644
index e444759..0000000
--- a/starlark_import/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# starlark_import package
-
-This allows soong to read constant information from starlark files. At package initialization
-time, soong will read `build/bazel/constants_exported_to_soong.bzl`, and then make the
-variables from that file available via `starlark_import.GetStarlarkValue()`. So to import
-a new variable, it must be added to `constants_exported_to_soong.bzl` and then it can
-be accessed by name.
-
-Only constant information can be read, since this is not a full bazel execution but a
-standalone starlark interpreter. This means you can't use bazel contructs like `rule`,
-`provider`, `select`, `glob`, etc.
-
-All starlark files that were loaded must be added as ninja deps that cause soong to rerun.
-The loaded files can be retrieved via `starlark_import.GetNinjaDeps()`.
diff --git a/starlark_import/starlark_import.go b/starlark_import/starlark_import.go
deleted file mode 100644
index ebe4247..0000000
--- a/starlark_import/starlark_import.go
+++ /dev/null
@@ -1,306 +0,0 @@
-// Copyright 2023 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 starlark_import
-
-import (
- "fmt"
- "os"
- "path/filepath"
- "sort"
- "strings"
- "sync"
- "time"
-
- "go.starlark.net/starlark"
- "go.starlark.net/starlarkjson"
- "go.starlark.net/starlarkstruct"
-)
-
-func init() {
- go func() {
- startTime := time.Now()
- v, d, err := runStarlarkFile("//build/bazel/constants_exported_to_soong.bzl")
- endTime := time.Now()
- //fmt.Fprintf(os.Stderr, "starlark run time: %s\n", endTime.Sub(startTime).String())
- globalResult.Set(starlarkResult{
- values: v,
- ninjaDeps: d,
- err: err,
- startTime: startTime,
- endTime: endTime,
- })
- }()
-}
-
-type starlarkResult struct {
- values starlark.StringDict
- ninjaDeps []string
- err error
- startTime time.Time
- endTime time.Time
-}
-
-// setOnce wraps a value and exposes Set() and Get() accessors for it.
-// The Get() calls will block until a Set() has been called.
-// A second call to Set() will panic.
-// setOnce must be created using newSetOnce()
-type setOnce[T any] struct {
- value T
- lock sync.Mutex
- wg sync.WaitGroup
- isSet bool
-}
-
-func (o *setOnce[T]) Set(value T) {
- o.lock.Lock()
- defer o.lock.Unlock()
- if o.isSet {
- panic("Value already set")
- }
-
- o.value = value
- o.isSet = true
- o.wg.Done()
-}
-
-func (o *setOnce[T]) Get() T {
- if !o.isSet {
- o.wg.Wait()
- }
- return o.value
-}
-
-func newSetOnce[T any]() *setOnce[T] {
- result := &setOnce[T]{}
- result.wg.Add(1)
- return result
-}
-
-var globalResult = newSetOnce[starlarkResult]()
-
-func GetStarlarkValue[T any](key string) (T, error) {
- result := globalResult.Get()
- if result.err != nil {
- var zero T
- return zero, result.err
- }
- if !result.values.Has(key) {
- var zero T
- return zero, fmt.Errorf("a starlark variable by that name wasn't found, did you update //build/bazel/constants_exported_to_soong.bzl?")
- }
- return Unmarshal[T](result.values[key])
-}
-
-func GetNinjaDeps() ([]string, error) {
- result := globalResult.Get()
- if result.err != nil {
- return nil, result.err
- }
- return result.ninjaDeps, nil
-}
-
-func getTopDir() (string, error) {
- // It's hard to communicate the top dir to this package in any other way than reading the
- // arguments directly, because we need to know this at package initialization time. Many
- // soong constants that we'd like to read from starlark are initialized during package
- // initialization.
- for i, arg := range os.Args {
- if arg == "--top" {
- if i < len(os.Args)-1 && os.Args[i+1] != "" {
- return os.Args[i+1], nil
- }
- }
- }
-
- // When running tests, --top is not passed. Instead, search for the top dir manually
- cwd, err := os.Getwd()
- if err != nil {
- return "", err
- }
- for cwd != "/" {
- if _, err := os.Stat(filepath.Join(cwd, "build/soong/soong_ui.bash")); err == nil {
- return cwd, nil
- }
- cwd = filepath.Dir(cwd)
- }
- return "", fmt.Errorf("could not find top dir")
-}
-
-const callerDirKey = "callerDir"
-
-type modentry struct {
- globals starlark.StringDict
- err error
-}
-
-func unsupportedMethod(t *starlark.Thread, fn *starlark.Builtin, _ starlark.Tuple, _ []starlark.Tuple) (starlark.Value, error) {
- return nil, fmt.Errorf("%sthis file is read by soong, and must therefore be pure starlark and include only constant information. %q is not allowed", t.CallStack().String(), fn.Name())
-}
-
-var builtins = starlark.StringDict{
- "aspect": starlark.NewBuiltin("aspect", unsupportedMethod),
- "glob": starlark.NewBuiltin("glob", unsupportedMethod),
- "json": starlarkjson.Module,
- "provider": starlark.NewBuiltin("provider", unsupportedMethod),
- "rule": starlark.NewBuiltin("rule", unsupportedMethod),
- "struct": starlark.NewBuiltin("struct", starlarkstruct.Make),
- "select": starlark.NewBuiltin("select", unsupportedMethod),
- "transition": starlark.NewBuiltin("transition", unsupportedMethod),
-}
-
-// Takes a module name (the first argument to the load() function) and returns the path
-// it's trying to load, stripping out leading //, and handling leading :s.
-func cleanModuleName(moduleName string, callerDir string) (string, error) {
- if strings.Count(moduleName, ":") > 1 {
- return "", fmt.Errorf("at most 1 colon must be present in starlark path: %s", moduleName)
- }
-
- // We don't have full support for external repositories, but at least support skylib's dicts.
- if moduleName == "@bazel_skylib//lib:dicts.bzl" {
- return "external/bazel-skylib/lib/dicts.bzl", nil
- }
-
- localLoad := false
- if strings.HasPrefix(moduleName, "@//") {
- moduleName = moduleName[3:]
- } else if strings.HasPrefix(moduleName, "//") {
- moduleName = moduleName[2:]
- } else if strings.HasPrefix(moduleName, ":") {
- moduleName = moduleName[1:]
- localLoad = true
- } else {
- return "", fmt.Errorf("load path must start with // or :")
- }
-
- if ix := strings.LastIndex(moduleName, ":"); ix >= 0 {
- moduleName = moduleName[:ix] + string(os.PathSeparator) + moduleName[ix+1:]
- }
-
- if filepath.Clean(moduleName) != moduleName {
- return "", fmt.Errorf("load path must be clean, found: %s, expected: %s", moduleName, filepath.Clean(moduleName))
- }
- if strings.HasPrefix(moduleName, "../") {
- return "", fmt.Errorf("load path must not start with ../: %s", moduleName)
- }
- if strings.HasPrefix(moduleName, "/") {
- return "", fmt.Errorf("load path starts with /, use // for a absolute path: %s", moduleName)
- }
-
- if localLoad {
- return filepath.Join(callerDir, moduleName), nil
- }
-
- return moduleName, nil
-}
-
-// loader implements load statement. The format of the loaded module URI is
-//
-// [//path]:base
-//
-// The file path is $ROOT/path/base if path is present, <caller_dir>/base otherwise.
-func loader(thread *starlark.Thread, module string, topDir string, moduleCache map[string]*modentry, moduleCacheLock *sync.Mutex, filesystem map[string]string) (starlark.StringDict, error) {
- modulePath, err := cleanModuleName(module, thread.Local(callerDirKey).(string))
- if err != nil {
- return nil, err
- }
- moduleCacheLock.Lock()
- e, ok := moduleCache[modulePath]
- if e == nil {
- if ok {
- moduleCacheLock.Unlock()
- return nil, fmt.Errorf("cycle in load graph")
- }
-
- // Add a placeholder to indicate "load in progress".
- moduleCache[modulePath] = nil
- moduleCacheLock.Unlock()
-
- childThread := &starlark.Thread{Name: "exec " + module, Load: thread.Load}
-
- // Cheating for the sake of testing:
- // propagate starlarktest's Reporter key, otherwise testing
- // the load function may cause panic in starlarktest code.
- const testReporterKey = "Reporter"
- if v := thread.Local(testReporterKey); v != nil {
- childThread.SetLocal(testReporterKey, v)
- }
-
- childThread.SetLocal(callerDirKey, filepath.Dir(modulePath))
-
- if filesystem != nil {
- globals, err := starlark.ExecFile(childThread, filepath.Join(topDir, modulePath), filesystem[modulePath], builtins)
- e = &modentry{globals, err}
- } else {
- globals, err := starlark.ExecFile(childThread, filepath.Join(topDir, modulePath), nil, builtins)
- e = &modentry{globals, err}
- }
-
- // Update the cache.
- moduleCacheLock.Lock()
- moduleCache[modulePath] = e
- }
- moduleCacheLock.Unlock()
- return e.globals, e.err
-}
-
-// Run runs the given starlark file and returns its global variables and a list of all starlark
-// files that were loaded. The top dir for starlark's // is found via getTopDir().
-func runStarlarkFile(filename string) (starlark.StringDict, []string, error) {
- topDir, err := getTopDir()
- if err != nil {
- return nil, nil, err
- }
- return runStarlarkFileWithFilesystem(filename, topDir, nil)
-}
-
-func runStarlarkFileWithFilesystem(filename string, topDir string, filesystem map[string]string) (starlark.StringDict, []string, error) {
- if !strings.HasPrefix(filename, "//") && !strings.HasPrefix(filename, ":") {
- filename = "//" + filename
- }
- filename, err := cleanModuleName(filename, "")
- if err != nil {
- return nil, nil, err
- }
- moduleCache := make(map[string]*modentry)
- moduleCache[filename] = nil
- moduleCacheLock := &sync.Mutex{}
- mainThread := &starlark.Thread{
- Name: "main",
- Print: func(_ *starlark.Thread, msg string) {
- // Ignore prints
- },
- Load: func(thread *starlark.Thread, module string) (starlark.StringDict, error) {
- return loader(thread, module, topDir, moduleCache, moduleCacheLock, filesystem)
- },
- }
- mainThread.SetLocal(callerDirKey, filepath.Dir(filename))
-
- var result starlark.StringDict
- if filesystem != nil {
- result, err = starlark.ExecFile(mainThread, filepath.Join(topDir, filename), filesystem[filename], builtins)
- } else {
- result, err = starlark.ExecFile(mainThread, filepath.Join(topDir, filename), nil, builtins)
- }
- return result, sortedStringKeys(moduleCache), err
-}
-
-func sortedStringKeys(m map[string]*modentry) []string {
- s := make([]string, 0, len(m))
- for k := range m {
- s = append(s, k)
- }
- sort.Strings(s)
- return s
-}
diff --git a/starlark_import/starlark_import_test.go b/starlark_import/starlark_import_test.go
deleted file mode 100644
index 8a58e3b..0000000
--- a/starlark_import/starlark_import_test.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2023 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 starlark_import
-
-import (
- "strings"
- "testing"
-
- "go.starlark.net/starlark"
-)
-
-func TestBasic(t *testing.T) {
- globals, _, err := runStarlarkFileWithFilesystem("a.bzl", "", map[string]string{
- "a.bzl": `
-my_string = "hello, world!"
-`})
- if err != nil {
- t.Error(err)
- return
- }
-
- if globals["my_string"].(starlark.String) != "hello, world!" {
- t.Errorf("Expected %q, got %q", "hello, world!", globals["my_string"].String())
- }
-}
-
-func TestLoad(t *testing.T) {
- globals, _, err := runStarlarkFileWithFilesystem("a.bzl", "", map[string]string{
- "a.bzl": `
-load("//b.bzl", _b_string = "my_string")
-my_string = "hello, " + _b_string
-`,
- "b.bzl": `
-my_string = "world!"
-`})
- if err != nil {
- t.Error(err)
- return
- }
-
- if globals["my_string"].(starlark.String) != "hello, world!" {
- t.Errorf("Expected %q, got %q", "hello, world!", globals["my_string"].String())
- }
-}
-
-func TestLoadRelative(t *testing.T) {
- globals, ninjaDeps, err := runStarlarkFileWithFilesystem("a.bzl", "", map[string]string{
- "a.bzl": `
-load(":b.bzl", _b_string = "my_string")
-load("//foo/c.bzl", _c_string = "my_string")
-my_string = "hello, " + _b_string
-c_string = _c_string
-`,
- "b.bzl": `
-my_string = "world!"
-`,
- "foo/c.bzl": `
-load(":d.bzl", _d_string = "my_string")
-my_string = "hello, " + _d_string
-`,
- "foo/d.bzl": `
-my_string = "world!"
-`})
- if err != nil {
- t.Error(err)
- return
- }
-
- if globals["my_string"].(starlark.String) != "hello, world!" {
- t.Errorf("Expected %q, got %q", "hello, world!", globals["my_string"].String())
- }
-
- expectedNinjaDeps := []string{
- "a.bzl",
- "b.bzl",
- "foo/c.bzl",
- "foo/d.bzl",
- }
- if !slicesEqual(ninjaDeps, expectedNinjaDeps) {
- t.Errorf("Expected %v ninja deps, got %v", expectedNinjaDeps, ninjaDeps)
- }
-}
-
-func TestLoadCycle(t *testing.T) {
- _, _, err := runStarlarkFileWithFilesystem("a.bzl", "", map[string]string{
- "a.bzl": `
-load(":b.bzl", _b_string = "my_string")
-my_string = "hello, " + _b_string
-`,
- "b.bzl": `
-load(":a.bzl", _a_string = "my_string")
-my_string = "hello, " + _a_string
-`})
- if err == nil || !strings.Contains(err.Error(), "cycle in load graph") {
- t.Errorf("Expected cycle in load graph, got: %v", err)
- return
- }
-}
-
-func slicesEqual[T comparable](a []T, b []T) bool {
- if len(a) != len(b) {
- return false
- }
- for i := range a {
- if a[i] != b[i] {
- return false
- }
- }
- return true
-}
diff --git a/starlark_import/unmarshal.go b/starlark_import/unmarshal.go
deleted file mode 100644
index b243471..0000000
--- a/starlark_import/unmarshal.go
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright 2023 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 starlark_import
-
-import (
- "fmt"
- "math"
- "reflect"
- "unsafe"
-
- "go.starlark.net/starlark"
- "go.starlark.net/starlarkstruct"
-)
-
-func Unmarshal[T any](value starlark.Value) (T, error) {
- x, err := UnmarshalReflect(value, reflect.TypeOf((*T)(nil)).Elem())
- return x.Interface().(T), err
-}
-
-func UnmarshalReflect(value starlark.Value, ty reflect.Type) (reflect.Value, error) {
- if ty == reflect.TypeOf((*starlark.Value)(nil)).Elem() {
- return reflect.ValueOf(value), nil
- }
- zero := reflect.Zero(ty)
- if value == nil {
- panic("nil value")
- }
- var result reflect.Value
- if ty.Kind() == reflect.Interface {
- var err error
- ty, err = typeOfStarlarkValue(value)
- if err != nil {
- return zero, err
- }
- }
- if ty.Kind() == reflect.Map {
- result = reflect.MakeMap(ty)
- } else {
- result = reflect.Indirect(reflect.New(ty))
- }
-
- switch v := value.(type) {
- case starlark.String:
- if result.Type().Kind() != reflect.String {
- return zero, fmt.Errorf("starlark type was %s, but %s requested", v.Type(), result.Type().Kind().String())
- }
- result.SetString(v.GoString())
- case starlark.Int:
- signedValue, signedOk := v.Int64()
- unsignedValue, unsignedOk := v.Uint64()
- switch result.Type().Kind() {
- case reflect.Int64:
- if !signedOk {
- return zero, fmt.Errorf("starlark int didn't fit in go int64")
- }
- result.SetInt(signedValue)
- case reflect.Int32:
- if !signedOk || signedValue > math.MaxInt32 || signedValue < math.MinInt32 {
- return zero, fmt.Errorf("starlark int didn't fit in go int32")
- }
- result.SetInt(signedValue)
- case reflect.Int16:
- if !signedOk || signedValue > math.MaxInt16 || signedValue < math.MinInt16 {
- return zero, fmt.Errorf("starlark int didn't fit in go int16")
- }
- result.SetInt(signedValue)
- case reflect.Int8:
- if !signedOk || signedValue > math.MaxInt8 || signedValue < math.MinInt8 {
- return zero, fmt.Errorf("starlark int didn't fit in go int8")
- }
- result.SetInt(signedValue)
- case reflect.Int:
- if !signedOk || signedValue > math.MaxInt || signedValue < math.MinInt {
- return zero, fmt.Errorf("starlark int didn't fit in go int")
- }
- result.SetInt(signedValue)
- case reflect.Uint64:
- if !unsignedOk {
- return zero, fmt.Errorf("starlark int didn't fit in go uint64")
- }
- result.SetUint(unsignedValue)
- case reflect.Uint32:
- if !unsignedOk || unsignedValue > math.MaxUint32 {
- return zero, fmt.Errorf("starlark int didn't fit in go uint32")
- }
- result.SetUint(unsignedValue)
- case reflect.Uint16:
- if !unsignedOk || unsignedValue > math.MaxUint16 {
- return zero, fmt.Errorf("starlark int didn't fit in go uint16")
- }
- result.SetUint(unsignedValue)
- case reflect.Uint8:
- if !unsignedOk || unsignedValue > math.MaxUint8 {
- return zero, fmt.Errorf("starlark int didn't fit in go uint8")
- }
- result.SetUint(unsignedValue)
- case reflect.Uint:
- if !unsignedOk || unsignedValue > math.MaxUint {
- return zero, fmt.Errorf("starlark int didn't fit in go uint")
- }
- result.SetUint(unsignedValue)
- default:
- return zero, fmt.Errorf("starlark type was %s, but %s requested", v.Type(), result.Type().Kind().String())
- }
- case starlark.Float:
- f := float64(v)
- switch result.Type().Kind() {
- case reflect.Float64:
- result.SetFloat(f)
- case reflect.Float32:
- if f > math.MaxFloat32 || f < -math.MaxFloat32 {
- return zero, fmt.Errorf("starlark float didn't fit in go float32")
- }
- result.SetFloat(f)
- default:
- return zero, fmt.Errorf("starlark type was %s, but %s requested", v.Type(), result.Type().Kind().String())
- }
- case starlark.Bool:
- if result.Type().Kind() != reflect.Bool {
- return zero, fmt.Errorf("starlark type was %s, but %s requested", v.Type(), result.Type().Kind().String())
- }
- result.SetBool(bool(v))
- case starlark.Tuple:
- if result.Type().Kind() != reflect.Slice {
- return zero, fmt.Errorf("starlark type was %s, but %s requested", v.Type(), result.Type().Kind().String())
- }
- elemType := result.Type().Elem()
- // TODO: Add this grow call when we're on go 1.20
- //result.Grow(v.Len())
- for i := 0; i < v.Len(); i++ {
- elem, err := UnmarshalReflect(v.Index(i), elemType)
- if err != nil {
- return zero, err
- }
- result = reflect.Append(result, elem)
- }
- case *starlark.List:
- if result.Type().Kind() != reflect.Slice {
- return zero, fmt.Errorf("starlark type was %s, but %s requested", v.Type(), result.Type().Kind().String())
- }
- elemType := result.Type().Elem()
- // TODO: Add this grow call when we're on go 1.20
- //result.Grow(v.Len())
- for i := 0; i < v.Len(); i++ {
- elem, err := UnmarshalReflect(v.Index(i), elemType)
- if err != nil {
- return zero, err
- }
- result = reflect.Append(result, elem)
- }
- case *starlark.Dict:
- if result.Type().Kind() != reflect.Map {
- return zero, fmt.Errorf("starlark type was %s, but %s requested", v.Type(), result.Type().Kind().String())
- }
- keyType := result.Type().Key()
- valueType := result.Type().Elem()
- for _, pair := range v.Items() {
- key := pair.Index(0)
- value := pair.Index(1)
-
- unmarshalledKey, err := UnmarshalReflect(key, keyType)
- if err != nil {
- return zero, err
- }
- unmarshalledValue, err := UnmarshalReflect(value, valueType)
- if err != nil {
- return zero, err
- }
-
- result.SetMapIndex(unmarshalledKey, unmarshalledValue)
- }
- case *starlarkstruct.Struct:
- if result.Type().Kind() != reflect.Struct {
- return zero, fmt.Errorf("starlark type was %s, but %s requested", v.Type(), result.Type().Kind().String())
- }
- if result.NumField() != len(v.AttrNames()) {
- return zero, fmt.Errorf("starlark struct and go struct have different number of fields (%d and %d)", len(v.AttrNames()), result.NumField())
- }
- for _, attrName := range v.AttrNames() {
- attr, err := v.Attr(attrName)
- if err != nil {
- return zero, err
- }
-
- // TODO(b/279787235): this should probably support tags to rename the field
- resultField := result.FieldByName(attrName)
- if resultField == (reflect.Value{}) {
- return zero, fmt.Errorf("starlark struct had field %s, but requested struct type did not", attrName)
- }
- // This hack allows us to change unexported fields
- resultField = reflect.NewAt(resultField.Type(), unsafe.Pointer(resultField.UnsafeAddr())).Elem()
- x, err := UnmarshalReflect(attr, resultField.Type())
- if err != nil {
- return zero, err
- }
- resultField.Set(x)
- }
- default:
- return zero, fmt.Errorf("unimplemented starlark type: %s", value.Type())
- }
-
- return result, nil
-}
-
-func typeOfStarlarkValue(value starlark.Value) (reflect.Type, error) {
- var err error
- switch v := value.(type) {
- case starlark.String:
- return reflect.TypeOf(""), nil
- case *starlark.List:
- innerType := reflect.TypeOf("")
- if v.Len() > 0 {
- innerType, err = typeOfStarlarkValue(v.Index(0))
- if err != nil {
- return nil, err
- }
- }
- for i := 1; i < v.Len(); i++ {
- innerTypeI, err := typeOfStarlarkValue(v.Index(i))
- if err != nil {
- return nil, err
- }
- if innerType != innerTypeI {
- return nil, fmt.Errorf("List must contain elements of entirely the same type, found %v and %v", innerType, innerTypeI)
- }
- }
- return reflect.SliceOf(innerType), nil
- case *starlark.Dict:
- keyType := reflect.TypeOf("")
- valueType := reflect.TypeOf("")
- keys := v.Keys()
- if v.Len() > 0 {
- firstKey := keys[0]
- keyType, err = typeOfStarlarkValue(firstKey)
- if err != nil {
- return nil, err
- }
- firstValue, found, err := v.Get(firstKey)
- if !found {
- err = fmt.Errorf("value not found")
- }
- if err != nil {
- return nil, err
- }
- valueType, err = typeOfStarlarkValue(firstValue)
- if err != nil {
- return nil, err
- }
- }
- for _, key := range keys {
- keyTypeI, err := typeOfStarlarkValue(key)
- if err != nil {
- return nil, err
- }
- if keyType != keyTypeI {
- return nil, fmt.Errorf("dict must contain elements of entirely the same type, found %v and %v", keyType, keyTypeI)
- }
- value, found, err := v.Get(key)
- if !found {
- err = fmt.Errorf("value not found")
- }
- if err != nil {
- return nil, err
- }
- valueTypeI, err := typeOfStarlarkValue(value)
- if valueType.Kind() != reflect.Interface && valueTypeI != valueType {
- // If we see conflicting value types, change the result value type to an empty interface
- valueType = reflect.TypeOf([]interface{}{}).Elem()
- }
- }
- return reflect.MapOf(keyType, valueType), nil
- case starlark.Int:
- return reflect.TypeOf(0), nil
- case starlark.Float:
- return reflect.TypeOf(0.0), nil
- case starlark.Bool:
- return reflect.TypeOf(true), nil
- default:
- return nil, fmt.Errorf("unimplemented starlark type: %s", value.Type())
- }
-}
-
-// UnmarshalNoneable is like Unmarshal, but it will accept None as the top level (but not nested)
-// starlark value. If the value is None, a nil pointer will be returned, otherwise a pointer
-// to the result of Unmarshal will be returned.
-func UnmarshalNoneable[T any](value starlark.Value) (*T, error) {
- if _, ok := value.(starlark.NoneType); ok {
- return nil, nil
- }
- ret, err := Unmarshal[T](value)
- return &ret, err
-}
diff --git a/starlark_import/unmarshal_test.go b/starlark_import/unmarshal_test.go
deleted file mode 100644
index bc0ea4c..0000000
--- a/starlark_import/unmarshal_test.go
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2023 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 starlark_import
-
-import (
- "reflect"
- "testing"
-
- "go.starlark.net/starlark"
-)
-
-func createStarlarkValue(t *testing.T, code string) starlark.Value {
- t.Helper()
- result, err := starlark.ExecFile(&starlark.Thread{}, "main.bzl", "x = "+code, builtins)
- if err != nil {
- panic(err)
- }
- return result["x"]
-}
-
-func TestUnmarshalConcreteType(t *testing.T) {
- x, err := Unmarshal[string](createStarlarkValue(t, `"foo"`))
- if err != nil {
- t.Error(err)
- return
- }
- if x != "foo" {
- t.Errorf(`Expected "foo", got %q`, x)
- }
-}
-
-func TestUnmarshalConcreteTypeWithInterfaces(t *testing.T) {
- x, err := Unmarshal[map[string]map[string]interface{}](createStarlarkValue(t,
- `{"foo": {"foo2": "foo3"}, "bar": {"bar2": ["bar3"]}}`))
- if err != nil {
- t.Error(err)
- return
- }
- expected := map[string]map[string]interface{}{
- "foo": {"foo2": "foo3"},
- "bar": {"bar2": []string{"bar3"}},
- }
- if !reflect.DeepEqual(x, expected) {
- t.Errorf(`Expected %v, got %v`, expected, x)
- }
-}
-
-func TestUnmarshalToStarlarkValue(t *testing.T) {
- x, err := Unmarshal[map[string]starlark.Value](createStarlarkValue(t,
- `{"foo": "Hi", "bar": None}`))
- if err != nil {
- t.Error(err)
- return
- }
- if x["foo"].(starlark.String).GoString() != "Hi" {
- t.Errorf("Expected \"Hi\", got: %q", x["foo"].(starlark.String).GoString())
- }
- if x["bar"].Type() != "NoneType" {
- t.Errorf("Expected \"NoneType\", got: %q", x["bar"].Type())
- }
-}
-
-func TestUnmarshal(t *testing.T) {
- testCases := []struct {
- input string
- expected interface{}
- }{
- {
- input: `"foo"`,
- expected: "foo",
- },
- {
- input: `5`,
- expected: 5,
- },
- {
- input: `["foo", "bar"]`,
- expected: []string{"foo", "bar"},
- },
- {
- input: `("foo", "bar")`,
- expected: []string{"foo", "bar"},
- },
- {
- input: `("foo",5)`,
- expected: []interface{}{"foo", 5},
- },
- {
- input: `{"foo": 5, "bar": 10}`,
- expected: map[string]int{"foo": 5, "bar": 10},
- },
- {
- input: `{"foo": ["qux"], "bar": []}`,
- expected: map[string][]string{"foo": {"qux"}, "bar": nil},
- },
- {
- input: `struct(Foo="foo", Bar=5)`,
- expected: struct {
- Foo string
- Bar int
- }{Foo: "foo", Bar: 5},
- },
- {
- // Unexported fields version of the above
- input: `struct(foo="foo", bar=5)`,
- expected: struct {
- foo string
- bar int
- }{foo: "foo", bar: 5},
- },
- {
- input: `{"foo": "foo2", "bar": ["bar2"], "baz": 5, "qux": {"qux2": "qux3"}, "quux": {"quux2": "quux3", "quux4": 5}}`,
- expected: map[string]interface{}{
- "foo": "foo2",
- "bar": []string{"bar2"},
- "baz": 5,
- "qux": map[string]string{"qux2": "qux3"},
- "quux": map[string]interface{}{
- "quux2": "quux3",
- "quux4": 5,
- },
- },
- },
- }
-
- for _, tc := range testCases {
- x, err := UnmarshalReflect(createStarlarkValue(t, tc.input), reflect.TypeOf(tc.expected))
- if err != nil {
- t.Error(err)
- continue
- }
- if !reflect.DeepEqual(x.Interface(), tc.expected) {
- t.Errorf(`Expected %#v, got %#v`, tc.expected, x.Interface())
- }
- }
-}
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 2258232..698aaf2 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -154,15 +154,14 @@
})
for _, syspropFile := range android.PathsForModuleSrc(ctx, g.properties.Srcs) {
- syspropDir := strings.TrimSuffix(syspropFile.String(), syspropFile.Ext())
- outputDir := android.PathForModuleGen(ctx, syspropDir, "src")
- libPath := android.PathForModuleGen(ctx, syspropDir, "src", "lib.rs")
- parsersPath := android.PathForModuleGen(ctx, syspropDir, "src", "gen_parsers_and_formatters.rs")
+ syspropDir := android.GenPathWithExt(ctx, "sysprop", syspropFile, "srcrust")
+ outputDir := syspropDir.Join(ctx, "src")
+ libPath := syspropDir.Join(ctx, "src", "lib.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 1a25397..7426a78 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -386,22 +386,21 @@
// Configure Java-related variables, including adding it to $PATH
java8Home := filepath.Join("prebuilts/jdk/jdk8", ret.HostPrebuiltTag())
- java17Home := filepath.Join("prebuilts/jdk/jdk17", ret.HostPrebuiltTag())
java21Home := filepath.Join("prebuilts/jdk/jdk21", ret.HostPrebuiltTag())
javaHome := func() string {
if override, ok := ret.environ.Get("OVERRIDE_ANDROID_JAVA_HOME"); ok {
return override
}
- if ret.environ.IsEnvTrue("EXPERIMENTAL_USE_OPENJDK21_TOOLCHAIN") {
- return java21Home
- }
if toolchain11, ok := ret.environ.Get("EXPERIMENTAL_USE_OPENJDK11_TOOLCHAIN"); ok && toolchain11 != "true" {
- ctx.Fatalln("The environment variable EXPERIMENTAL_USE_OPENJDK11_TOOLCHAIN is no longer supported. An OpenJDK 11 toolchain is now the global default.")
+ ctx.Fatalln("The environment variable EXPERIMENTAL_USE_OPENJDK11_TOOLCHAIN is no longer supported. An OpenJDK 21 toolchain is now the global default.")
}
if toolchain17, ok := ret.environ.Get("EXPERIMENTAL_USE_OPENJDK17_TOOLCHAIN"); ok && toolchain17 != "true" {
- ctx.Fatalln("The environment variable EXPERIMENTAL_USE_OPENJDK17_TOOLCHAIN is no longer supported. An OpenJDK 17 toolchain is now the global default.")
+ ctx.Fatalln("The environment variable EXPERIMENTAL_USE_OPENJDK17_TOOLCHAIN is no longer supported. An OpenJDK 21 toolchain is now the global default.")
}
- return java17Home
+ if toolchain21, ok := ret.environ.Get("EXPERIMENTAL_USE_OPENJDK21_TOOLCHAIN"); ok && toolchain21 != "true" {
+ ctx.Fatalln("The environment variable EXPERIMENTAL_USE_OPENJDK21_TOOLCHAIN is no longer supported. An OpenJDK 21 toolchain is now the global default.")
+ }
+ return java21Home
}()
absJavaHome := absPath(ctx, javaHome)
@@ -1387,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/build/rbe.go b/ui/build/rbe.go
index fa04207..5142a41 100644
--- a/ui/build/rbe.go
+++ b/ui/build/rbe.go
@@ -163,7 +163,7 @@
return
}
fmt.Fprintln(ctx.Writer, "")
- fmt.Fprintln(ctx.Writer, "\033[33mWARNING: Missing LOAS credentials, please run `gcert`. This will result in failing builds in the future, see go/rbe-android-default-announcement.\033[0m")
+ fmt.Fprintln(ctx.Writer, "\033[33mWARNING: Missing LOAS credentials, please run `gcert`. This is required for a successful build execution. See go/rbe-android-default-announcement for more information.\033[0m")
fmt.Fprintln(ctx.Writer, "")
}
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() {}