diff options
106 files changed, 1569 insertions, 819 deletions
@@ -13,8 +13,7 @@ on source.android.com to read how Soong is configured for testing. By design, Android.bp files are very simple. There are no conditionals or control flow statements - any complexity is handled in build logic written in Go. The syntax and semantics of Android.bp files are intentionally similar -to [Bazel BUILD files](https://www.bazel.io/versions/master/docs/be/overview.html) -when possible. +to [Bazel BUILD files](https://bazel.build/concepts/build-files) when possible. ### Modules @@ -596,14 +595,14 @@ To make `soong_build` wait for a debugger connection, install `dlv` and then start the build with `SOONG_DELVE=<listen addr>` in the environment. For example: ```bash -SOONG_DELVE=:5006 m nothing +SOONG_DELVE=5006 m nothing ``` To make `soong_ui` wait for a debugger connection, use the `SOONG_UI_DELVE` variable: ``` -SOONG_UI_DELVE=:5006 m nothing +SOONG_UI_DELVE=5006 m nothing ``` diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 1f6ecb5cd..a932a9128 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -154,6 +154,7 @@ var ( "external/zstd": Bp2BuildDefaultTrueRecursively, "frameworks/av/media/codecs": Bp2BuildDefaultTrueRecursively, + "frameworks/av/media/liberror": Bp2BuildDefaultTrueRecursively, "frameworks/av/services/minijail": Bp2BuildDefaultTrueRecursively, "frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue, "frameworks/base/startop/apps/test": Bp2BuildDefaultTrue, @@ -183,9 +184,9 @@ var ( "packages/modules/adb/pairing_connection": Bp2BuildDefaultTrueRecursively, "packages/modules/adb/proto": Bp2BuildDefaultTrueRecursively, "packages/modules/adb/tls": Bp2BuildDefaultTrueRecursively, - "packages/providers/MediaProvider/tools/dialogs": Bp2BuildDefaultTrue, + "packages/providers/MediaProvider/tools/dialogs": Bp2BuildDefaultFalse, // TODO(b/242834374) "packages/screensavers/Basic": Bp2BuildDefaultTrue, - "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultTrue, + "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultFalse, // TODO(b/242834321) "prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively, "prebuilts/runtime/mainline/platform/sdk": Bp2BuildDefaultTrueRecursively, @@ -306,6 +307,7 @@ var ( "libandroid_runtime_vm_headers", "libaudioclient_aidl_conversion_util", "libaudioutils_fixedfft", + "libbinder_aidl", "libbinder_headers", "libbinder_headers_platform_shared", "libbluetooth-types-header", @@ -327,6 +329,8 @@ var ( "libpdx_headers", "libprocpartition", "libruy_static", + "libandroidio", + "libandroidio_srcs", "libserviceutils", "libstagefright_enc_common", "libstagefright_foundation_headers", @@ -391,6 +395,13 @@ var ( //system/libhidl // needed by cc_hidl_library "libhidlbase", + + //frameworks/native + "framework_native_aidl_binder", + "framework_native_aidl_gui", + + //frameworks/native/libs/input + "inputconstants_aidl", } Bp2buildModuleTypeAlwaysConvertList = []string{ @@ -486,8 +497,6 @@ var ( "libartd-runtime-gtest", // depends on unconverted modules: libgtest_isolated, libartd-compiler, libdexfiled, libprofiled, libartbased, libartbased-art-gtest "libdebuggerd_handler", // depends on unconverted module libdebuggerd_handler_core "libdebuggerd_handler_core", "libdebuggerd_handler_fallback", // depends on unconverted module libdebuggerd - "libdexfile", // depends on unconverted modules: dexfile_operator_srcs, libartbase, libartpalette, - "libdexfile_static", // depends on unconverted modules: libartbase, libdexfile "libdexfiled", // depends on unconverted modules: dexfile_operator_srcs, libartbased, libartpalette "libfastdeploy_host", // depends on unconverted modules: libandroidfw, libusb, AdbWinApi "libgmock_main_ndk", // depends on unconverted modules: libgtest_ndk_c++ diff --git a/android/apex.go b/android/apex.go index 934cf723e..00b724137 100644 --- a/android/apex.go +++ b/android/apex.go @@ -454,7 +454,8 @@ func CheckAvailableForApex(what string, apex_available []string) bool { } return InList(what, apex_available) || (what != AvailableToPlatform && InList(AvailableToAnyApex, apex_available)) || - (what == "com.android.btservices" && InList("com.android.bluetooth", apex_available)) || + (what == "com.android.btservices" && InList("com.android.bluetooth", apex_available)) || // TODO b/243054261 + (what == "com.android.bluetooth" && InList("com.android.btservices", apex_available)) || // TODO b/243054261 (strings.HasPrefix(what, "com.android.gki.") && InList(AvailableToGkiApex, apex_available)) } @@ -711,8 +712,8 @@ type ApexContents struct { // NewApexContents creates and initializes an ApexContents that is suitable // for use with an apex module. -// * contents is a map from a module name to information about its membership within -// the apex. +// - contents is a map from a module name to information about its membership within +// the apex. func NewApexContents(contents map[string]ApexMembership) *ApexContents { return &ApexContents{ contents: contents, diff --git a/android/arch.go b/android/arch.go index b5bd2f080..a0895edf8 100644 --- a/android/arch.go +++ b/android/arch.go @@ -524,26 +524,29 @@ var DarwinUniversalVariantTag = archDepTag{name: "darwin universal binary"} // archMutator splits a module into a variant for each Target requested by the module. Target selection // for a module is in three levels, OsClass, multilib, and then Target. // OsClass selection is determined by: -// - The HostOrDeviceSupported value passed in to InitAndroidArchModule by the module type factory, which selects -// whether the module type can compile for host, device or both. -// - The host_supported and device_supported properties on the module. +// - The HostOrDeviceSupported value passed in to InitAndroidArchModule by the module type factory, which selects +// whether the module type can compile for host, device or both. +// - The host_supported and device_supported properties on the module. +// // If host is supported for the module, the Host and HostCross OsClasses are selected. If device is supported // for the module, the Device OsClass is selected. // Within each selected OsClass, the multilib selection is determined by: -// - The compile_multilib property if it set (which may be overridden by target.android.compile_multilib or -// target.host.compile_multilib). -// - The default multilib passed to InitAndroidArchModule if compile_multilib was not set. +// - The compile_multilib property if it set (which may be overridden by target.android.compile_multilib or +// target.host.compile_multilib). +// - The default multilib passed to InitAndroidArchModule if compile_multilib was not set. +// // Valid multilib values include: -// "both": compile for all Targets supported by the OsClass (generally x86_64 and x86, or arm64 and arm). -// "first": compile for only a single preferred Target supported by the OsClass. This is generally x86_64 or arm64, -// but may be arm for a 32-bit only build. -// "32": compile for only a single 32-bit Target supported by the OsClass. -// "64": compile for only a single 64-bit Target supported by the OsClass. -// "common": compile a for a single Target that will work on all Targets supported by the OsClass (for example Java). -// "common_first": compile a for a Target that will work on all Targets supported by the OsClass -// (same as "common"), plus a second Target for the preferred Target supported by the OsClass -// (same as "first"). This is used for java_binary that produces a common .jar and a wrapper -// executable script. +// +// "both": compile for all Targets supported by the OsClass (generally x86_64 and x86, or arm64 and arm). +// "first": compile for only a single preferred Target supported by the OsClass. This is generally x86_64 or arm64, +// but may be arm for a 32-bit only build. +// "32": compile for only a single 32-bit Target supported by the OsClass. +// "64": compile for only a single 64-bit Target supported by the OsClass. +// "common": compile a for a single Target that will work on all Targets supported by the OsClass (for example Java). +// "common_first": compile a for a Target that will work on all Targets supported by the OsClass +// (same as "common"), plus a second Target for the preferred Target supported by the OsClass +// (same as "first"). This is used for java_binary that produces a common .jar and a wrapper +// executable script. // // Once the list of Targets is determined, the module is split into a variant for each Target. // @@ -1215,11 +1218,13 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { // Returns the struct containing the properties specific to the given // architecture type. These look like this in Blueprint files: -// arch: { -// arm64: { -// key: value, -// }, -// }, +// +// arch: { +// arm64: { +// key: value, +// }, +// }, +// // This struct will also contain sub-structs containing to the architecture/CPU // variants and features that themselves contain properties specific to those. func getArchTypeStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) (reflect.Value, bool) { @@ -1231,11 +1236,12 @@ func getArchTypeStruct(ctx ArchVariantContext, archProperties interface{}, archT // Returns the struct containing the properties specific to a given multilib // value. These look like this in the Blueprint file: -// multilib: { -// lib32: { -// key: value, -// }, -// }, +// +// multilib: { +// lib32: { +// key: value, +// }, +// }, func getMultilibStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) (reflect.Value, bool) { archPropValues := reflect.ValueOf(archProperties).Elem() multilibProp := archPropValues.FieldByName("Multilib").Elem() @@ -2010,9 +2016,10 @@ type ConfigurationAxisToArchVariantProperties map[bazel.ConfigurationAxis]ArchVa // arch-variant properties correspond to the values of the properties of the 'propertySet' struct // that are specific to that axis/configuration. Each axis is independent, containing // non-overlapping configs that correspond to the various "arch-variant" support, at this time: -// arches (including multilib) -// oses -// arch+os combinations +// +// arches (including multilib) +// oses +// arch+os combinations // // For example, passing a struct { Foo bool, Bar string } will return an interface{} that can be // type asserted back into the same struct, containing the config-specific property value specified @@ -2165,17 +2172,21 @@ func (m *ModuleBase) GetArchVariantProperties(ctx ArchVariantContext, propertySe // Returns a struct matching the propertySet interface, containing properties specific to the targetName // For example, given these arguments: -// propertySet = BaseCompilerProperties -// targetName = "android_arm" +// +// propertySet = BaseCompilerProperties +// targetName = "android_arm" +// // And given this Android.bp fragment: -// target: -// android_arm: { -// srcs: ["foo.c"], -// } -// android_arm64: { -// srcs: ["bar.c"], -// } -// } +// +// target: +// android_arm: { +// srcs: ["foo.c"], +// } +// android_arm64: { +// srcs: ["bar.c"], +// } +// } +// // This would return a BaseCompilerProperties with BaseCompilerProperties.Srcs = ["foo.c"] func getTargetStructs(ctx ArchVariantContext, archProperties []interface{}, targetName string) []reflect.Value { var propertyStructs []reflect.Value diff --git a/android/bazel.go b/android/bazel.go index 183a2f324..aff611660 100644 --- a/android/bazel.go +++ b/android/bazel.go @@ -35,6 +35,12 @@ const ( Bp2BuildTopLevel = "." ) +// Bp2buildAidlLibrary describes a filegroup module that are converted to aidl_library +type Bp2buildAidlLibrary interface { + ShouldConvertToAidlLibrary(ctx BazelConversionPathContext) bool + GetAidlLibraryLabel(ctx BazelConversionPathContext) string +} + type BazelConversionStatus struct { // Information about _all_ bp2build targets generated by this module. Multiple targets are // supported as Soong handles some things within a single target that we may choose to split into diff --git a/android/bazel_paths.go b/android/bazel_paths.go index c030aa864..bbdae96e7 100644 --- a/android/bazel_paths.go +++ b/android/bazel_paths.go @@ -221,9 +221,13 @@ func directoryHasBlueprint(fs pathtools.FileSystem, prefix string, components [] // Transform a path (if necessary) to acknowledge package boundaries // // e.g. something like -// async_safe/include/async_safe/CHECK.h +// +// async_safe/include/async_safe/CHECK.h +// // might become -// //bionic/libc/async_safe:include/async_safe/CHECK.h +// +// //bionic/libc/async_safe:include/async_safe/CHECK.h +// // if the "async_safe" directory is actually a package and not just a directory. // // In particular, paths that extend into packages are transformed into absolute labels beginning with //. @@ -303,20 +307,21 @@ func RootToModuleRelativePaths(ctx BazelConversionPathContext, paths Paths) []ba // directory and Bazel target labels, excluding those included in the excludes argument (which // should already be expanded to resolve references to Soong-modules). Valid elements of paths // include: -// * filepath, relative to local module directory, resolves as a filepath relative to the local -// source directory -// * glob, relative to the local module directory, resolves as filepath(s), relative to the local -// module directory. Because Soong does not have a concept of crossing package boundaries, the -// glob as computed by Soong may contain paths that cross package-boundaries that would be -// unknowingly omitted if the glob were handled by Bazel. To allow identification and detect -// (within Bazel) use of paths that cross package boundaries, we expand globs within Soong rather -// than converting Soong glob syntax to Bazel glob syntax. **Invalid for excludes.** -// * other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer -// or OutputFileProducer. These resolve as a Bazel label for a target. If the Bazel target is in -// the local module directory, it will be returned relative to the current package (e.g. -// ":<target>"). Otherwise, it will be returned as an absolute Bazel label (e.g. -// "//path/to/dir:<target>"). If the reference to another module cannot be resolved,the function -// will panic. +// - filepath, relative to local module directory, resolves as a filepath relative to the local +// source directory +// - glob, relative to the local module directory, resolves as filepath(s), relative to the local +// module directory. Because Soong does not have a concept of crossing package boundaries, the +// glob as computed by Soong may contain paths that cross package-boundaries that would be +// unknowingly omitted if the glob were handled by Bazel. To allow identification and detect +// (within Bazel) use of paths that cross package boundaries, we expand globs within Soong rather +// than converting Soong glob syntax to Bazel glob syntax. **Invalid for excludes.** +// - other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer +// or OutputFileProducer. These resolve as a Bazel label for a target. If the Bazel target is in +// the local module directory, it will be returned relative to the current package (e.g. +// ":<target>"). Otherwise, it will be returned as an absolute Bazel label (e.g. +// "//path/to/dir:<target>"). If the reference to another module cannot be resolved,the function +// will panic. +// // Properties passed as the paths or excludes argument must have been annotated with struct tag // `android:"path"` so that dependencies on other modules will have already been handled by the // path_deps mutator. diff --git a/android/bazel_test.go b/android/bazel_test.go index e14649e3f..da4a9156d 100644 --- a/android/bazel_test.go +++ b/android/bazel_test.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/android/config_bp2build.go b/android/config_bp2build.go index 748be62cc..d6b2bcf97 100644 --- a/android/config_bp2build.go +++ b/android/config_bp2build.go @@ -240,10 +240,12 @@ func (m ExportedStringListDictVariables) asBazel(_ Config, _ ExportedStringVaria // ExportedVariableReferenceDictVariables is a mapping from variable names to a // dictionary which references previously defined variables. This is used to // create a Starlark output such as: -// string_var1 = "string1 -// var_ref_dict_var1 = { -// "key1": string_var1 -// } +// +// string_var1 = "string1 +// var_ref_dict_var1 = { +// "key1": string_var1 +// } +// // This type of variable collection must be expanded last so that it recognizes // previously defined variables. type ExportedVariableReferenceDictVariables map[string]map[string]string diff --git a/android/defaults.go b/android/defaults.go index 54f44bcec..03b2efbac 100644 --- a/android/defaults.go +++ b/android/defaults.go @@ -151,12 +151,12 @@ type DefaultsModuleBase struct { // retrieve the values it is necessary to iterate over properties(). E.g. to get // the commonProperties instance that have the real values: // -// d := myModule.(Defaults) -// for _, props := range d.properties() { -// if cp, ok := props.(*commonProperties); ok { -// ... access property values in cp ... -// } -// } +// d := myModule.(Defaults) +// for _, props := range d.properties() { +// if cp, ok := props.(*commonProperties); ok { +// ... access property values in cp ... +// } +// } // // The rationale is that the properties on a defaults module apply to the // defaultable modules using it, not to the defaults module itself. E.g. setting diff --git a/android/filegroup.go b/android/filegroup.go index 9e5769a82..7d3923814 100644 --- a/android/filegroup.go +++ b/android/filegroup.go @@ -15,6 +15,7 @@ package android import ( + "path/filepath" "strings" "android/soong/bazel" @@ -41,6 +42,11 @@ type bazelFilegroupAttributes struct { Srcs bazel.LabelListAttribute } +type bazelAidlLibraryAttributes struct { + Srcs bazel.LabelListAttribute + Strip_import_prefix *string +} + // ConvertWithBp2build performs bp2build conversion of filegroup func (fg *fileGroup) ConvertWithBp2build(ctx TopDownMutatorContext) { srcs := bazel.MakeLabelListAttribute( @@ -66,16 +72,33 @@ func (fg *fileGroup) ConvertWithBp2build(ctx TopDownMutatorContext) { } } - attrs := &bazelFilegroupAttributes{ - Srcs: srcs, - } + // Convert module that has only AIDL files to aidl_library + // If the module has a mixed bag of AIDL and non-AIDL files, split the filegroup manually + // and then convert + if fg.ShouldConvertToAidlLibrary(ctx) { + attrs := &bazelAidlLibraryAttributes{ + Srcs: srcs, + Strip_import_prefix: fg.properties.Path, + } - props := bazel.BazelTargetModuleProperties{ - Rule_class: "filegroup", - Bzl_load_location: "//build/bazel/rules:filegroup.bzl", - } + props := bazel.BazelTargetModuleProperties{ + Rule_class: "aidl_library", + Bzl_load_location: "//build/bazel/rules/aidl:library.bzl", + } - ctx.CreateBazelTargetModule(props, CommonAttributes{Name: fg.Name()}, attrs) + ctx.CreateBazelTargetModule(props, CommonAttributes{Name: fg.Name()}, attrs) + } else { + attrs := &bazelFilegroupAttributes{ + Srcs: srcs, + } + + props := bazel.BazelTargetModuleProperties{ + Rule_class: "filegroup", + Bzl_load_location: "//build/bazel/rules:filegroup.bzl", + } + + ctx.CreateBazelTargetModule(props, CommonAttributes{Name: fg.Name()}, attrs) + } } type fileGroupProperties struct { @@ -98,12 +121,14 @@ type fileGroupProperties struct { type fileGroup struct { ModuleBase BazelModuleBase + Bp2buildAidlLibrary properties fileGroupProperties srcs Paths } var _ MixedBuildBuildable = (*fileGroup)(nil) var _ SourceFileProducer = (*fileGroup)(nil) +var _ Bp2buildAidlLibrary = (*fileGroup)(nil) // filegroup contains a list of files that are referenced by other modules // properties (such as "srcs") using the syntax ":<name>". filegroup are @@ -164,12 +189,17 @@ func (fg *fileGroup) IsMixedBuildSupported(ctx BaseModuleContext) bool { } func (fg *fileGroup) ProcessBazelQueryResponse(ctx ModuleContext) { - fg.srcs = PathsForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs) + bazelCtx := ctx.Config().BazelContext + // This is a short-term solution because we rely on info from Android.bp to handle + // a converted module. This will block when we want to remove Android.bp for all + // converted modules at some point. + // TODO(b/242847534): Implement a long-term solution in which we don't need to rely + // on info form Android.bp for modules that are already converted to Bazel + relativeRoot := ctx.ModuleDir() if fg.properties.Path != nil { - fg.srcs = PathsWithModuleSrcSubDir(ctx, fg.srcs, String(fg.properties.Path)) + relativeRoot = filepath.Join(relativeRoot, *fg.properties.Path) } - bazelCtx := ctx.Config().BazelContext filePaths, err := bazelCtx.GetOutputFiles(fg.GetBazelLabel(ctx, fg), configKey{Common.String(), CommonOS}) if err != nil { ctx.ModuleErrorf(err.Error()) @@ -178,8 +208,27 @@ func (fg *fileGroup) ProcessBazelQueryResponse(ctx ModuleContext) { bazelOuts := make(Paths, 0, len(filePaths)) for _, p := range filePaths { - bazelOuts = append(bazelOuts, PathForBazelOutRelative(ctx, ctx.ModuleDir(), p)) + bazelOuts = append(bazelOuts, PathForBazelOutRelative(ctx, relativeRoot, p)) } - fg.srcs = bazelOuts } + +func (fg *fileGroup) ShouldConvertToAidlLibrary(ctx BazelConversionPathContext) bool { + if len(fg.properties.Srcs) == 0 || !fg.ShouldConvertWithBp2build(ctx) { + return false + } + for _, src := range fg.properties.Srcs { + if !strings.HasSuffix(src, ".aidl") { + return false + } + } + return true +} + +func (fg *fileGroup) GetAidlLibraryLabel(ctx BazelConversionPathContext) string { + if ctx.OtherModuleDir(fg.module) == ctx.ModuleDir() { + return ":" + fg.Name() + } else { + return fg.GetBazelLabel(ctx, fg) + } +} diff --git a/android/filegroup_test.go b/android/filegroup_test.go new file mode 100644 index 000000000..a7ea8054c --- /dev/null +++ b/android/filegroup_test.go @@ -0,0 +1,58 @@ +package android + +import ( + "path/filepath" + "testing" +) + +func TestFileGroupWithPathProp(t *testing.T) { + outBaseDir := "outputbase" + pathPrefix := outBaseDir + "/execroot/__main__" + expectedOutputfile := filepath.Join(pathPrefix, "a/b/c/d/test.aidl") + + testCases := []struct { + bp string + rel string + }{ + { + bp: ` + filegroup { + name: "baz", + srcs: ["a/b/c/d/test.aidl"], + path: "a/b", + bazel_module: { label: "//:baz" }, + } +`, + rel: "c/d/test.aidl", + }, + { + bp: ` + filegroup { + name: "baz", + srcs: ["a/b/c/d/test.aidl"], + bazel_module: { label: "//:baz" }, + } +`, + rel: "a/b/c/d/test.aidl", + }, + } + + for _, testCase := range testCases { + outBaseDir := "outputbase" + result := GroupFixturePreparers( + PrepareForTestWithFilegroup, + FixtureModifyConfig(func(config Config) { + config.BazelContext = MockBazelContext{ + OutputBaseDir: outBaseDir, + LabelToOutputFiles: map[string][]string{ + "//:baz": []string{"a/b/c/d/test.aidl"}, + }, + } + }), + ).RunTestWithBp(t, testCase.bp) + + fg := result.Module("baz", "").(*fileGroup) + AssertStringEquals(t, "src relativeRoot", testCase.rel, fg.srcs[0].Rel()) + AssertStringEquals(t, "src full path", expectedOutputfile, fg.srcs[0].String()) + } +} diff --git a/android/fixture.go b/android/fixture.go index 0690a5a6c..f71893571 100644 --- a/android/fixture.go +++ b/android/fixture.go @@ -420,11 +420,13 @@ type FixturePreparer interface { // instances. // // base - a list of already flattened and deduped preparers that will be applied first before -// the list of additional preparers. Any duplicates of these in the additional preparers -// will be ignored. +// +// the list of additional preparers. Any duplicates of these in the additional preparers +// will be ignored. // // preparers - a list of additional unflattened, undeduped preparers that will be applied after the -// base preparers. +// +// base preparers. // // Returns a deduped and flattened list of the preparers starting with the ones in base with any // additional ones from the preparers list added afterwards. @@ -498,10 +500,10 @@ func newSimpleFixturePreparer(preparer func(fixture *fixture)) FixturePreparer { // FixtureErrorHandler determines how to respond to errors reported by the code under test. // // Some possible responses: -// * Fail the test if any errors are reported, see FixtureExpectsNoErrors. -// * Fail the test if at least one error that matches a pattern is not reported see -// FixtureExpectsAtLeastOneErrorMatchingPattern -// * Fail the test if any unexpected errors are reported. +// - Fail the test if any errors are reported, see FixtureExpectsNoErrors. +// - Fail the test if at least one error that matches a pattern is not reported see +// FixtureExpectsAtLeastOneErrorMatchingPattern +// - Fail the test if any unexpected errors are reported. // // Although at the moment all the error handlers are implemented as simply a wrapper around a // function this is defined as an interface to allow future enhancements, e.g. provide different @@ -866,10 +868,12 @@ func (r *TestResult) NormalizePathsForTesting(paths Paths) []string { // that produced this result. // // e.g. assuming that this result was created by running: -// GroupFixturePreparers(preparer1, preparer2, preparer3).RunTest(t) +// +// GroupFixturePreparers(preparer1, preparer2, preparer3).RunTest(t) // // Then this method will be equivalent to running: -// GroupFixturePreparers(preparer1, preparer2, preparer3) +// +// GroupFixturePreparers(preparer1, preparer2, preparer3) // // This is intended for use by tests whose output is Android.bp files to verify that those files // are valid, e.g. tests of the snapshots produced by the sdk module type. diff --git a/android/module.go b/android/module.go index 450dba997..bf62080a3 100644 --- a/android/module.go +++ b/android/module.go @@ -936,6 +936,20 @@ type distProperties struct { Dists []Dist `android:"arch_variant"` } +// CommonTestOptions represents the common `test_options` properties in +// Android.bp. +type CommonTestOptions struct { + // If the test is a hostside (no device required) unittest that shall be run + // during presubmit check. + Unit_test *bool +} + +// SetAndroidMkEntries sets AndroidMkEntries according to the value of base +// `test_options`. +func (t *CommonTestOptions) SetAndroidMkEntries(entries *AndroidMkEntries) { + entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(t.Unit_test)) +} + // The key to use in TaggedDistFiles when a Dist structure does not specify a // tag property. This intentionally does not use "" as the default because that // would mean that an empty tag would have a different meaning when used in a dist @@ -1095,7 +1109,7 @@ func InitAndroidModule(m Module) { // property structs for architecture-specific versions of generic properties tagged with // `android:"arch_variant"`. // -// InitAndroidModule should not be called if InitAndroidArchModule was called. +// InitAndroidModule should not be called if InitAndroidArchModule was called. func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { InitAndroidModule(m) @@ -1336,30 +1350,30 @@ func productVariableConfigEnableLabels(ctx *topDownMutatorContext) []bazel.Label // // For example: // -// import ( -// "android/soong/android" -// ) +// import ( +// "android/soong/android" +// ) // -// type myModule struct { -// android.ModuleBase -// properties struct { -// MyProperty string -// } -// } +// type myModule struct { +// android.ModuleBase +// properties struct { +// MyProperty string +// } +// } // -// func NewMyModule() android.Module { -// m := &myModule{} -// m.AddProperties(&m.properties) -// android.InitAndroidModule(m) -// return m -// } +// func NewMyModule() android.Module { +// m := &myModule{} +// m.AddProperties(&m.properties) +// android.InitAndroidModule(m) +// return m +// } // -// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { -// // Get the CPU architecture for the current build variant. -// variantArch := ctx.Arch() +// func (m *myModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { +// // Get the CPU architecture for the current build variant. +// variantArch := ctx.Arch() // -// // ... -// } +// // ... +// } type ModuleBase struct { // Putting the curiously recurring thing pointing to the thing that contains // the thing pattern to good use. diff --git a/android/module_test.go b/android/module_test.go index 77ef14673..835ab4c7c 100644 --- a/android/module_test.go +++ b/android/module_test.go @@ -911,3 +911,45 @@ func TestSortedUniqueNamedPaths(t *testing.T) { }) } } + +func TestProcessCommonTestOptions(t *testing.T) { + tests := []struct { + name string + testOptions CommonTestOptions + expected map[string][]string + }{ + { + name: "empty", + testOptions: CommonTestOptions{}, + expected: map[string][]string{}, + }, + { + name: "is unit test", + testOptions: CommonTestOptions{ + Unit_test: boolPtr(true), + }, + expected: map[string][]string{ + "LOCAL_IS_UNIT_TEST": []string{"true"}, + }, + }, + { + name: "is not unit test", + testOptions: CommonTestOptions{ + Unit_test: boolPtr(false), + }, + expected: map[string][]string{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actualEntries := AndroidMkEntries{ + EntryMap: map[string][]string{}, + } + tt.testOptions.SetAndroidMkEntries(&actualEntries) + actual := actualEntries.EntryMap + t.Logf("actual: %v", actual) + t.Logf("expected: %v", tt.expected) + AssertDeepEquals(t, "TestProcessCommonTestOptions ", tt.expected, actual) + }) + } +} diff --git a/android/paths.go b/android/paths.go index f8e701822..74d9f13f4 100644 --- a/android/paths.go +++ b/android/paths.go @@ -387,20 +387,21 @@ func ExistentPathsForSources(ctx PathContext, paths []string) Paths { } // PathsForModuleSrc returns a Paths{} containing the resolved references in paths: -// * filepath, relative to local module directory, resolves as a filepath relative to the local -// source directory -// * glob, relative to the local module directory, resolves as filepath(s), relative to the local -// source directory. -// * other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer -// or OutputFileProducer. These resolve as a filepath to an output filepath or generated source -// filepath. +// - filepath, relative to local module directory, resolves as a filepath relative to the local +// source directory +// - glob, relative to the local module directory, resolves as filepath(s), relative to the local +// source directory. +// - other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer +// or OutputFileProducer. These resolve as a filepath to an output filepath or generated source +// filepath. +// // Properties passed as the paths argument must have been annotated with struct tag // `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the // path_deps mutator. // If a requested module is not found as a dependency: -// * if ctx.Config().AllowMissingDependencies() is true, this module to be marked as having +// - if ctx.Config().AllowMissingDependencies() is true, this module to be marked as having // missing dependencies -// * otherwise, a ModuleError is thrown. +// - otherwise, a ModuleError is thrown. func PathsForModuleSrc(ctx ModuleMissingDepsPathContext, paths []string) Paths { return PathsForModuleSrcExcludes(ctx, paths, nil) } @@ -414,21 +415,22 @@ type SourceInput struct { // PathsForModuleSrcExcludes returns a Paths{} containing the resolved references in paths, minus // those listed in excludes. Elements of paths and excludes are resolved as: -// * filepath, relative to local module directory, resolves as a filepath relative to the local -// source directory -// * glob, relative to the local module directory, resolves as filepath(s), relative to the local -// source directory. Not valid in excludes. -// * other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer -// or OutputFileProducer. These resolve as a filepath to an output filepath or generated source -// filepath. +// - filepath, relative to local module directory, resolves as a filepath relative to the local +// source directory +// - glob, relative to the local module directory, resolves as filepath(s), relative to the local +// source directory. Not valid in excludes. +// - other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer +// or OutputFileProducer. These resolve as a filepath to an output filepath or generated source +// filepath. +// // excluding the items (similarly resolved // Properties passed as the paths argument must have been annotated with struct tag // `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the // path_deps mutator. // If a requested module is not found as a dependency: -// * if ctx.Config().AllowMissingDependencies() is true, this module to be marked as having +// - if ctx.Config().AllowMissingDependencies() is true, this module to be marked as having // missing dependencies -// * otherwise, a ModuleError is thrown. +// - otherwise, a ModuleError is thrown. func PathsForModuleSrcExcludes(ctx ModuleMissingDepsPathContext, paths, excludes []string) Paths { return PathsRelativeToModuleSourceDir(SourceInput{ Context: ctx, @@ -548,13 +550,14 @@ func GetModuleFromPathDep(ctx ModuleWithDepsPathContext, moduleName, tag string) // PathsAndMissingDepsForModuleSrcExcludes returns a Paths{} containing the resolved references in // paths, minus those listed in excludes. Elements of paths and excludes are resolved as: -// * filepath, relative to local module directory, resolves as a filepath relative to the local -// source directory -// * glob, relative to the local module directory, resolves as filepath(s), relative to the local -// source directory. Not valid in excludes. -// * other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer -// or OutputFileProducer. These resolve as a filepath to an output filepath or generated source -// filepath. +// - filepath, relative to local module directory, resolves as a filepath relative to the local +// source directory +// - glob, relative to the local module directory, resolves as filepath(s), relative to the local +// source directory. Not valid in excludes. +// - other modules using the ":name{.tag}" syntax. These modules must implement SourceFileProducer +// or OutputFileProducer. These resolve as a filepath to an output filepath or generated source +// filepath. +// // and a list of the module names of missing module dependencies are returned as the second return. // Properties passed as the paths argument must have been annotated with struct tag // `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the diff --git a/android/register.go b/android/register.go index 4ff8fff97..5832b1bba 100644 --- a/android/register.go +++ b/android/register.go @@ -258,20 +258,20 @@ type RegistrationContext interface { // Used to register build components from an init() method, e.g. // -// init() { -// RegisterBuildComponents(android.InitRegistrationContext) -// } +// init() { +// RegisterBuildComponents(android.InitRegistrationContext) +// } // -// func RegisterBuildComponents(ctx android.RegistrationContext) { -// ctx.RegisterModuleType(...) -// ... -// } +// func RegisterBuildComponents(ctx android.RegistrationContext) { +// ctx.RegisterModuleType(...) +// ... +// } // // Extracting the actual registration into a separate RegisterBuildComponents(ctx) function // allows it to be used to initialize test context, e.g. // -// ctx := android.NewTestContext(config) -// RegisterBuildComponents(ctx) +// ctx := android.NewTestContext(config) +// RegisterBuildComponents(ctx) var InitRegistrationContext RegistrationContext = &initRegistrationContext{ moduleTypes: make(map[string]ModuleFactory), singletonTypes: make(map[string]SingletonFactory), diff --git a/android/rule_builder.go b/android/rule_builder.go index 11da36cc0..155fbdf71 100644 --- a/android/rule_builder.go +++ b/android/rule_builder.go @@ -1031,7 +1031,8 @@ func (c *RuleBuilderCommand) ImplicitTools(paths Paths) *RuleBuilderCommand { // be also added to the dependencies returned by RuleBuilder.Tools. // // It is equivalent to: -// cmd.Tool(ctx.Config().HostToolPath(ctx, tool)) +// +// cmd.Tool(ctx.Config().HostToolPath(ctx, tool)) func (c *RuleBuilderCommand) BuiltTool(tool string) *RuleBuilderCommand { if c.rule.ctx.Config().UseHostMusl() { // If the host is using musl, assume that the tool was built against musl libc and include @@ -1053,7 +1054,8 @@ func (c *RuleBuilderCommand) builtToolWithoutDeps(tool string) *RuleBuilderComma // dependencies returned by RuleBuilder.Tools. // // It is equivalent to: -// cmd.Tool(ctx.Config().PrebuiltBuildTool(ctx, tool)) +// +// cmd.Tool(ctx.Config().PrebuiltBuildTool(ctx, tool)) func (c *RuleBuilderCommand) PrebuiltBuildTool(ctx PathContext, tool string) *RuleBuilderCommand { return c.Tool(ctx.Config().PrebuiltBuildTool(ctx, tool)) } diff --git a/android/sdk.go b/android/sdk.go index a71f7f211..a477cbaaf 100644 --- a/android/sdk.go +++ b/android/sdk.go @@ -430,13 +430,13 @@ func (r *sdkRegistry) uniqueOnceKey() OnceKey { // required for some members but not others. Traits can cause additional information to be output // to the sdk snapshot or replace the default information exported for a member with something else. // e.g. -// * By default cc libraries only export the default image variants to the SDK. However, for some -// members it may be necessary to export specific image variants, e.g. vendor, or recovery. -// * By default cc libraries export all the configured architecture variants except for the native -// bridge architecture variants. However, for some members it may be necessary to export the -// native bridge architecture variants as well. -// * By default cc libraries export the platform variant (i.e. sdk:). However, for some members it -// may be necessary to export the sdk variant (i.e. sdk:sdk). +// - By default cc libraries only export the default image variants to the SDK. However, for some +// members it may be necessary to export specific image variants, e.g. vendor, or recovery. +// - By default cc libraries export all the configured architecture variants except for the native +// bridge architecture variants. However, for some members it may be necessary to export the +// native bridge architecture variants as well. +// - By default cc libraries export the platform variant (i.e. sdk:). However, for some members it +// may be necessary to export the sdk variant (i.e. sdk:sdk). // // A sdk can request a module to provide no traits, one trait or a collection of traits. The exact // behavior of a trait is determined by how SdkMemberType implementations handle the traits. A trait @@ -447,17 +447,17 @@ func (r *sdkRegistry) uniqueOnceKey() OnceKey { // SdkPropertyName(). Each property contains a list of modules that are required to have that trait. // e.g. something like this: // -// sdk { -// name: "sdk", -// ... -// traits: { -// recovery_image: ["module1", "module4", "module5"], -// native_bridge: ["module1", "module2"], -// native_sdk: ["module1", "module3"], -// ... -// }, -// ... -// } +// sdk { +// name: "sdk", +// ... +// traits: { +// recovery_image: ["module1", "module4", "module5"], +// native_bridge: ["module1", "module2"], +// native_sdk: ["module1", "module3"], +// ... +// }, +// ... +// } type SdkMemberTrait interface { // SdkPropertyName returns the name of the traits property on an sdk module. SdkPropertyName() string @@ -639,20 +639,19 @@ func DependencyTagForSdkMemberType(memberType SdkMemberType, export bool) SdkMem // The basic implementation should look something like this, where ModuleType is // the name of the module type being supported. // -// type moduleTypeSdkMemberType struct { -// android.SdkMemberTypeBase -// } +// type moduleTypeSdkMemberType struct { +// android.SdkMemberTypeBase +// } // -// func init() { -// android.RegisterSdkMemberType(&moduleTypeSdkMemberType{ -// SdkMemberTypeBase: android.SdkMemberTypeBase{ -// PropertyName: "module_types", -// }, -// } -// } -// -// ...methods... +// func init() { +// android.RegisterSdkMemberType(&moduleTypeSdkMemberType{ +// SdkMemberTypeBase: android.SdkMemberTypeBase{ +// PropertyName: "module_types", +// }, +// } +// } // +// ...methods... type SdkMemberType interface { // SdkPropertyName returns the name of the member type property on an sdk module. SdkPropertyName() string diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go index bd7364582..b25f24891 100644 --- a/android/soong_config_modules.go +++ b/android/soong_config_modules.go @@ -190,77 +190,78 @@ type soongConfigModuleTypeModule struct { // // Each soong_config_variable supports an additional value `conditions_default`. The properties // specified in `conditions_default` will only be used under the following conditions: -// bool variable: the variable is unspecified or not set to a true value -// value variable: the variable is unspecified -// string variable: the variable is unspecified or the variable is set to a string unused in the -// given module. For example, string variable `test` takes values: "a" and "b", -// if the module contains a property `a` and `conditions_default`, when test=b, -// the properties under `conditions_default` will be used. To specify that no -// properties should be amended for `b`, you can set `b: {},`. +// +// bool variable: the variable is unspecified or not set to a true value +// value variable: the variable is unspecified +// string variable: the variable is unspecified or the variable is set to a string unused in the +// given module. For example, string variable `test` takes values: "a" and "b", +// if the module contains a property `a` and `conditions_default`, when test=b, +// the properties under `conditions_default` will be used. To specify that no +// properties should be amended for `b`, you can set `b: {},`. // // For example, an Android.bp file could have: // -// soong_config_module_type { -// name: "acme_cc_defaults", -// module_type: "cc_defaults", -// config_namespace: "acme", -// variables: ["board"], -// bool_variables: ["feature"], -// value_variables: ["width"], -// properties: ["cflags", "srcs"], -// } +// soong_config_module_type { +// name: "acme_cc_defaults", +// module_type: "cc_defaults", +// config_namespace: "acme", +// variables: ["board"], +// bool_variables: ["feature"], +// value_variables: ["width"], +// properties: ["cflags", "srcs"], +// } // -// soong_config_string_variable { -// name: "board", -// values: ["soc_a", "soc_b"], -// } +// soong_config_string_variable { +// name: "board", +// values: ["soc_a", "soc_b"], +// } // -// acme_cc_defaults { -// name: "acme_defaults", -// cflags: ["-DGENERIC"], -// soong_config_variables: { -// board: { -// soc_a: { -// cflags: ["-DSOC_A"], -// }, -// soc_b: { -// cflags: ["-DSOC_B"], -// }, -// conditions_default: { -// cflags: ["-DSOC_DEFAULT"], -// }, -// }, -// feature: { -// cflags: ["-DFEATURE"], -// conditions_default: { -// cflags: ["-DFEATURE_DEFAULT"], -// }, -// }, -// width: { -// cflags: ["-DWIDTH=%s"], -// conditions_default: { -// cflags: ["-DWIDTH=DEFAULT"], -// }, -// }, -// }, -// } +// acme_cc_defaults { +// name: "acme_defaults", +// cflags: ["-DGENERIC"], +// soong_config_variables: { +// board: { +// soc_a: { +// cflags: ["-DSOC_A"], +// }, +// soc_b: { +// cflags: ["-DSOC_B"], +// }, +// conditions_default: { +// cflags: ["-DSOC_DEFAULT"], +// }, +// }, +// feature: { +// cflags: ["-DFEATURE"], +// conditions_default: { +// cflags: ["-DFEATURE_DEFAULT"], +// }, +// }, +// width: { +// cflags: ["-DWIDTH=%s"], +// conditions_default: { +// cflags: ["-DWIDTH=DEFAULT"], +// }, +// }, +// }, +// } // -// cc_library { -// name: "libacme_foo", -// defaults: ["acme_defaults"], -// srcs: ["*.cpp"], -// } +// cc_library { +// name: "libacme_foo", +// defaults: ["acme_defaults"], +// srcs: ["*.cpp"], +// } // // If an acme BoardConfig.mk file contained: // -// SOONG_CONFIG_NAMESPACES += acme -// SOONG_CONFIG_acme += \ -// board \ -// feature \ +// SOONG_CONFIG_NAMESPACES += acme +// SOONG_CONFIG_acme += \ +// board \ +// feature \ // -// SOONG_CONFIG_acme_board := soc_a -// SOONG_CONFIG_acme_feature := true -// SOONG_CONFIG_acme_width := 200 +// SOONG_CONFIG_acme_board := soc_a +// SOONG_CONFIG_acme_feature := true +// SOONG_CONFIG_acme_width := 200 // // Then libacme_foo would build with cflags "-DGENERIC -DSOC_A -DFEATURE". func SoongConfigModuleTypeFactory() Module { diff --git a/android/soongconfig/modules.go b/android/soongconfig/modules.go index 212b752d6..7d21b75bc 100644 --- a/android/soongconfig/modules.go +++ b/android/soongconfig/modules.go @@ -343,23 +343,26 @@ func (defs Bp2BuildSoongConfigDefinitions) String() string { // // For example, the acme_cc_defaults example above would // produce a reflect.Value whose type is: -// *struct { -// Soong_config_variables struct { -// Board struct { -// Soc_a interface{} -// Soc_b interface{} -// } -// } -// } +// +// *struct { +// Soong_config_variables struct { +// Board struct { +// Soc_a interface{} +// Soc_b interface{} +// } +// } +// } +// // And whose value is: -// &{ -// Soong_config_variables: { -// Board: { -// Soc_a: (*struct{ Cflags []string })(nil), -// Soc_b: (*struct{ Cflags []string })(nil), -// }, -// }, -// } +// +// &{ +// Soong_config_variables: { +// Board: { +// Soc_a: (*struct{ Cflags []string })(nil), +// Soc_b: (*struct{ Cflags []string })(nil), +// }, +// }, +// } func CreateProperties(factory blueprint.ModuleFactory, moduleType *ModuleType) reflect.Value { var fields []reflect.StructField diff --git a/android/testing.go b/android/testing.go index 85bdca475..b4429ca91 100644 --- a/android/testing.go +++ b/android/testing.go @@ -688,17 +688,17 @@ type TestingBuildParams struct { // // The parts of this structure which are changed are: // * BuildParams -// * Args -// * All Path, Paths, WritablePath and WritablePaths fields. +// - Args +// - All Path, Paths, WritablePath and WritablePaths fields. // // * RuleParams -// * Command -// * Depfile -// * Rspfile -// * RspfileContent -// * SymlinkOutputs -// * CommandDeps -// * CommandOrderOnly +// - Command +// - Depfile +// - Rspfile +// - RspfileContent +// - SymlinkOutputs +// - CommandDeps +// - CommandOrderOnly // // See PathRelativeToTop for more details. // diff --git a/android/variable.go b/android/variable.go index 86b8c8fb1..2d7b0bf8e 100644 --- a/android/variable.go +++ b/android/variable.go @@ -702,20 +702,20 @@ func ProductVariableProperties(ctx BazelConversionPathContext) ProductConfigProp // // If the ProductConfigProperties map contains these items, as parsed from the .bp file: // -// library_linking_strategy: { -// prefer_static: { -// static_libs: [ -// "lib_a", -// "lib_b", -// ], -// }, -// conditions_default: { -// shared_libs: [ -// "lib_a", -// "lib_b", -// ], -// }, -// }, +// library_linking_strategy: { +// prefer_static: { +// static_libs: [ +// "lib_a", +// "lib_b", +// ], +// }, +// conditions_default: { +// shared_libs: [ +// "lib_a", +// "lib_b", +// ], +// }, +// }, // // Static_libs {Library_linking_strategy ANDROID prefer_static} [lib_a lib_b] // Shared_libs {Library_linking_strategy ANDROID conditions_default} [lib_a lib_b] @@ -728,13 +728,13 @@ func ProductVariableProperties(ctx BazelConversionPathContext) ProductConfigProp // instead of putting lib_a and lib_b directly into dynamic_deps without a // select: // -// dynamic_deps = select({ -// "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": [], -// "//conditions:default": [ -// "//foo/bar:lib_a", -// "//foo/bar:lib_b", -// ], -// }), +// dynamic_deps = select({ +// "//build/bazel/product_variables:android__library_linking_strategy__prefer_static": [], +// "//conditions:default": [ +// "//foo/bar:lib_a", +// "//foo/bar:lib_b", +// ], +// }), func (props *ProductConfigProperties) zeroValuesForNamespacedVariables() { // A map of product config properties to the zero values of their respective // property value. diff --git a/androidmk/androidmk/androidmk.go b/androidmk/androidmk/androidmk.go index aaafdc758..2e8810fe8 100644 --- a/androidmk/androidmk/androidmk.go +++ b/androidmk/androidmk/androidmk.go @@ -421,9 +421,9 @@ func makeVariableToBlueprint(file *bpFile, val *mkparser.MakeString, // For example, if prefix is "foo" and name is "bar" with a value of "baz", then // the following variable will be generated: // -// foo { -// bar: "baz" -// } +// foo { +// bar: "baz" +// } // // If prefix is the empty string and name is "foo" with a value of "bar", the // following variable will be generated (if it is a property): diff --git a/androidmk/parser/make_strings.go b/androidmk/parser/make_strings.go index 8afbe7edc..be3685916 100644 --- a/androidmk/parser/make_strings.go +++ b/androidmk/parser/make_strings.go @@ -38,10 +38,10 @@ import ( // For example, "$(FOO)/bar/baz" will be represented as the // following lists: // -// { -// Strings: ["", "/bar/baz"], -// Variables: ["FOO"] -// } +// { +// Strings: ["", "/bar/baz"], +// Variables: ["FOO"] +// } type MakeString struct { StringPos Pos Strings []string diff --git a/apex/apex.go b/apex/apex.go index b391a6cca..949809ad9 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -192,6 +192,10 @@ type apexBundleProperties struct { // with the tool to sign payload contents. Custom_sign_tool *string + // Whether this is a dynamic common lib apex, if so the native shared libs will be placed + // in a special way that include the digest of the lib file under /lib(64)? + Dynamic_common_lib_apex *bool + // Canonical name of this APEX bundle. Used to determine the path to the // activated APEX on device (i.e. /apex/<apexVariationName>), and used for the // apex mutator variations. For override_apex modules, this is the name of the @@ -1472,6 +1476,11 @@ func (a *apexBundle) testOnlyShouldForceCompression() bool { return proptools.Bool(a.properties.Test_only_force_compression) } +// See the dynamic_common_lib_apex property +func (a *apexBundle) dynamic_common_lib_apex() bool { + return proptools.BoolDefault(a.properties.Dynamic_common_lib_apex, false) +} + // These functions are interfacing with cc/sanitizer.go. The entire APEX (along with all of its // members) can be sanitized, either forcibly, or by the global configuration. For some of the // sanitizers, extra dependencies can be forcibly added as well. diff --git a/apex/bp2build.go b/apex/bp2build.go index 221ab132f..d28f5122e 100644 --- a/apex/bp2build.go +++ b/apex/bp2build.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/apex/builder.go b/apex/builder.go index f1b14484e..b95b3bdfd 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -39,6 +39,7 @@ func init() { pctx.Import("android/soong/cc/config") pctx.Import("android/soong/java") pctx.HostBinToolVariable("apexer", "apexer") + pctx.HostBinToolVariable("apexer_with_DCLA_preprocessing", "apexer_with_DCLA_preprocessing") // ART minimal builds (using the master-art manifest) do not have the "frameworks/base" // projects, and hence cannot build 'aapt2'. Use the SDK prebuilt instead. hostBinToolVariableWithPrebuilt := func(name, prebuiltDir, tool string) { @@ -115,7 +116,35 @@ var ( Rspfile: "${out}.copy_commands", RspfileContent: "${copy_commands}", Description: "APEX ${image_dir} => ${out}", - }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", "opt_flags", "manifest", "payload_fs_type") + }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", + "opt_flags", "manifest") + + DCLAApexRule = pctx.StaticRule("DCLAApexRule", blueprint.RuleParams{ + Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` + + `(. ${out}.copy_commands) && ` + + `APEXER_TOOL_PATH=${tool_path} ` + + `${apexer_with_DCLA_preprocessing} ` + + `--apexer ${apexer} ` + + `--canned_fs_config ${canned_fs_config} ` + + `${image_dir} ` + + `${out} ` + + `-- ` + + `--include_build_info ` + + `--force ` + + `--payload_type image ` + + `--key ${key} ` + + `--file_contexts ${file_contexts} ` + + `--manifest ${manifest} ` + + `${opt_flags} `, + CommandDeps: []string{"${apexer_with_DCLA_preprocessing}", "${apexer}", "${avbtool}", "${e2fsdroid}", + "${merge_zips}", "${mke2fs}", "${resize2fs}", "${sefcontext_compile}", "${make_f2fs}", + "${sload_f2fs}", "${make_erofs}", "${soong_zip}", "${zipalign}", "${aapt2}", + "prebuilts/sdk/current/public/android.jar"}, + Rspfile: "${out}.copy_commands", + RspfileContent: "${copy_commands}", + Description: "APEX ${image_dir} => ${out}", + }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", + "opt_flags", "manifest", "is_DCLA") zipApexRule = pctx.StaticRule("zipApexRule", blueprint.RuleParams{ Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` + @@ -662,22 +691,41 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { optFlags = append(optFlags, "--payload_fs_type "+a.payloadFsType.string()) - ctx.Build(pctx, android.BuildParams{ - Rule: apexRule, - Implicits: implicitInputs, - Output: unsignedOutputFile, - Description: "apex (" + apexType.name() + ")", - Args: map[string]string{ - "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir, - "image_dir": imageDir.String(), - "copy_commands": strings.Join(copyCommands, " && "), - "manifest": a.manifestPbOut.String(), - "file_contexts": fileContexts.String(), - "canned_fs_config": cannedFsConfig.String(), - "key": a.privateKeyFile.String(), - "opt_flags": strings.Join(optFlags, " "), - }, - }) + if a.dynamic_common_lib_apex() { + ctx.Build(pctx, android.BuildParams{ + Rule: DCLAApexRule, + Implicits: implicitInputs, + Output: unsignedOutputFile, + Description: "apex (" + apexType.name() + ")", + Args: map[string]string{ + "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir, + "image_dir": imageDir.String(), + "copy_commands": strings.Join(copyCommands, " && "), + "manifest": a.manifestPbOut.String(), + "file_contexts": fileContexts.String(), + "canned_fs_config": cannedFsConfig.String(), + "key": a.privateKeyFile.String(), + "opt_flags": strings.Join(optFlags, " "), + }, + }) + } else { + ctx.Build(pctx, android.BuildParams{ + Rule: apexRule, + Implicits: implicitInputs, + Output: unsignedOutputFile, + Description: "apex (" + apexType.name() + ")", + Args: map[string]string{ + "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir, + "image_dir": imageDir.String(), + "copy_commands": strings.Join(copyCommands, " && "), + "manifest": a.manifestPbOut.String(), + "file_contexts": fileContexts.String(), + "canned_fs_config": cannedFsConfig.String(), + "key": a.privateKeyFile.String(), + "opt_flags": strings.Join(optFlags, " "), + }, + }) + } // TODO(jiyong): make the two rules below as separate functions apexProtoFile := android.PathForModuleOut(ctx, a.Name()+".pb"+suffix) diff --git a/apex/key.go b/apex/key.go index 9c5bb05e7..d44958928 100644 --- a/apex/key.go +++ b/apex/key.go @@ -105,7 +105,7 @@ func (m *apexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) { m.keyName = pubKeyName } -//////////////////////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////////////////// // apex_keys_text type apexKeysText struct { output android.OutputPath diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 187e0df09..172a2012d 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -364,16 +364,16 @@ func (p *prebuiltCommon) DepIsInSameApex(ctx android.BaseModuleContext, dep andr // While it may be possible to provide sufficient information to determine whether two prebuilt_apex // modules were compatible it would be a lot of work and would not provide much benefit for a couple // of reasons: -// * The number of prebuilt_apex modules that will be exporting files for the same module will be -// low as the prebuilt_apex only exports files for the direct dependencies that require it and -// very few modules are direct dependencies of multiple prebuilt_apex modules, e.g. there are a -// few com.android.art* apex files that contain the same contents and could export files for the -// same modules but only one of them needs to do so. Contrast that with source apex modules which -// need apex specific variants for every module that contributes code to the apex, whether direct -// or indirect. -// * The build cost of a prebuilt_apex variant is generally low as at worst it will involve some -// extra copying of files. Contrast that with source apex modules that has to build each variant -// from source. +// - The number of prebuilt_apex modules that will be exporting files for the same module will be +// low as the prebuilt_apex only exports files for the direct dependencies that require it and +// very few modules are direct dependencies of multiple prebuilt_apex modules, e.g. there are a +// few com.android.art* apex files that contain the same contents and could export files for the +// same modules but only one of them needs to do so. Contrast that with source apex modules which +// need apex specific variants for every module that contributes code to the apex, whether direct +// or indirect. +// - The build cost of a prebuilt_apex variant is generally low as at worst it will involve some +// extra copying of files. Contrast that with source apex modules that has to build each variant +// from source. func (p *prebuiltCommon) apexInfoMutator(mctx android.TopDownMutatorContext) { // Collect direct dependencies into contents. @@ -703,28 +703,29 @@ var _ prebuiltApexModuleCreator = (*Prebuilt)(nil) // e.g. make dex implementation jars available for java_import modules listed in exported_java_libs, // it does so as follows: // -// 1. It creates a `deapexer` module that actually extracts the files from the `.apex` file and -// makes them available for use by other modules, at both Soong and ninja levels. +// 1. It creates a `deapexer` module that actually extracts the files from the `.apex` file and +// makes them available for use by other modules, at both Soong and ninja levels. // -// 2. It adds a dependency onto those modules and creates an apex specific variant similar to what -// an `apex` module does. That ensures that code which looks for specific apex variant, e.g. -// dexpreopt, will work the same way from source and prebuilt. +// 2. It adds a dependency onto those modules and creates an apex specific variant similar to what +// an `apex` module does. That ensures that code which looks for specific apex variant, e.g. +// dexpreopt, will work the same way from source and prebuilt. // -// 3. The `deapexer` module adds a dependency from the modules that require the exported files onto -// itself so that they can retrieve the file paths to those files. +// 3. The `deapexer` module adds a dependency from the modules that require the exported files onto +// itself so that they can retrieve the file paths to those files. // // It also creates a child module `selector` that is responsible for selecting the appropriate // input apex for both the prebuilt_apex and the deapexer. That is needed for a couple of reasons: -// 1. To dedup the selection logic so it only runs in one module. -// 2. To allow the deapexer to be wired up to a different source for the input apex, e.g. an -// `apex_set`. // -// prebuilt_apex -// / | \ -// / | \ -// V V V -// selector <--- deapexer <--- exported java lib +// 1. To dedup the selection logic so it only runs in one module. // +// 2. To allow the deapexer to be wired up to a different source for the input apex, e.g. an +// `apex_set`. +// +// prebuilt_apex +// / | \ +// / | \ +// V V V +// selector <--- deapexer <--- exported java lib func (p *Prebuilt) createPrebuiltApexModules(ctx android.TopDownMutatorContext) { baseModuleName := p.BaseModuleName() diff --git a/bazel/aquery.go b/bazel/aquery.go index 418b14321..05f6ed48c 100644 --- a/bazel/aquery.go +++ b/bazel/aquery.go @@ -52,8 +52,9 @@ type KeyValuePair struct { // AqueryDepset is a depset definition from Bazel's aquery response. This is // akin to the `depSetOfFiles` in the response proto, except: -// * direct artifacts are enumerated by full path instead of by ID -// * it has a hash of the depset contents, instead of an int ID (for determinism) +// - direct artifacts are enumerated by full path instead of by ID +// - it has a hash of the depset contents, instead of an int ID (for determinism) +// // A depset is a data structure for efficient transitive handling of artifact // paths. A single depset consists of one or more artifact paths and one or // more "child" depsets. diff --git a/bazel/properties.go b/bazel/properties.go index bffd97bc5..963e27bdd 100644 --- a/bazel/properties.go +++ b/bazel/properties.go @@ -1225,15 +1225,18 @@ func (sla *StringListAttribute) SortedConfigurationAxes() []ConfigurationAxis { // DeduplicateAxesFromBase ensures no duplication of items between the no-configuration value and // configuration-specific values. For example, if we would convert this StringListAttribute as: -// ["a", "b", "c"] + select({ -// "//condition:one": ["a", "d"], -// "//conditions:default": [], -// }) +// +// ["a", "b", "c"] + select({ +// "//condition:one": ["a", "d"], +// "//conditions:default": [], +// }) +// // after this function, we would convert this StringListAttribute as: -// ["a", "b", "c"] + select({ -// "//condition:one": ["d"], -// "//conditions:default": [], -// }) +// +// ["a", "b", "c"] + select({ +// "//condition:one": ["d"], +// "//conditions:default": [], +// }) func (sla *StringListAttribute) DeduplicateAxesFromBase() { base := sla.Value for axis, configToList := range sla.ConfigurableValues { diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go index 95869dd87..1f69b5add 100644 --- a/bp2build/cc_binary_conversion_test.go +++ b/bp2build/cc_binary_conversion_test.go @@ -543,3 +543,41 @@ func TestCcBinaryConvertLex(t *testing.T) { }, }) } + +func TestCcBinaryRuntimeLibs(t *testing.T) { + runCcBinaryTests(t, ccBinaryBp2buildTestCase{ + description: "cc_binary with runtime libs", + blueprint: ` +cc_library { + name: "bar", + srcs: ["b.cc"], +} + +{rule_name} { + name: "foo", + srcs: ["a.cc"], + runtime_libs: ["bar"], +} +`, + targets: []testBazelTarget{ + {"cc_library_static", "bar_bp2build_cc_library_static", AttrNameToString{ + "local_includes": `["."]`, + "srcs": `["b.cc"]`, + "target_compatible_with": `["//build/bazel/platforms/os:android"]`, + }, + }, + {"cc_library_shared", "bar", AttrNameToString{ + "local_includes": `["."]`, + "srcs": `["b.cc"]`, + "target_compatible_with": `["//build/bazel/platforms/os:android"]`, + }, + }, + {"cc_binary", "foo", AttrNameToString{ + "local_includes": `["."]`, + "srcs": `["a.cc"]`, + "runtime_deps": `[":bar"]`, + }, + }, + }, + }) +} diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 6c56d4188..f6d50679d 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -2514,3 +2514,29 @@ func TestCcLibraryConvertLex(t *testing.T) { })...), }) } + +func TestCCLibraryRuntimeDeps(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Blueprint: `cc_library_shared { + name: "bar", +} + +cc_library { + name: "foo", + runtime_libs: ["foo"], +}`, + ExpectedBazelTargets: []string{ + makeBazelTarget("cc_library_shared", "bar", AttrNameToString{ + "local_includes": `["."]`, + }), + makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "runtime_deps": `[":foo"]`, + "local_includes": `["."]`, + }), + makeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "runtime_deps": `[":foo"]`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index 6a4786254..de57e5adc 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -624,3 +624,25 @@ func TestCCLibraryFlagSpaceSplitting(t *testing.T) { }, }) } + +func TestCCLibrarySharedRuntimeDeps(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Blueprint: `cc_library_shared { + name: "bar", +} + +cc_library_shared { + name: "foo", + runtime_libs: ["foo"], +}`, + ExpectedBazelTargets: []string{ + makeBazelTarget("cc_library_shared", "bar", AttrNameToString{ + "local_includes": `["."]`, + }), + makeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "runtime_deps": `[":foo"]`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index ddb7bf94b..1c160ec6a 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -15,12 +15,12 @@ package bp2build import ( + "fmt" + "testing" + "android/soong/android" "android/soong/cc" "android/soong/genrule" - "fmt" - - "testing" ) const ( @@ -1559,3 +1559,25 @@ func TestCcLibraryStaticStl(t *testing.T) { }) } } + +func TestCCLibraryStaticRuntimeDeps(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Blueprint: `cc_library_shared { + name: "bar", +} + +cc_library_static { + name: "foo", + runtime_libs: ["foo"], +}`, + ExpectedBazelTargets: []string{ + makeBazelTarget("cc_library_shared", "bar", AttrNameToString{ + "local_includes": `["."]`, + }), + makeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "runtime_deps": `[":foo"]`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/bp2build/cc_prebuilt_library_conversion_test.go b/bp2build/cc_prebuilt_library_conversion_test.go index 74ad0053a..32c3f4d9b 100644 --- a/bp2build/cc_prebuilt_library_conversion_test.go +++ b/bp2build/cc_prebuilt_library_conversion_test.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/bp2build/cc_prebuilt_library_static_test.go b/bp2build/cc_prebuilt_library_static_test.go index 7498e504c..489a53d75 100644 --- a/bp2build/cc_prebuilt_library_static_test.go +++ b/bp2build/cc_prebuilt_library_static_test.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/bp2build/filegroup_conversion_test.go b/bp2build/filegroup_conversion_test.go index b598b855e..de09a1787 100644 --- a/bp2build/filegroup_conversion_test.go +++ b/bp2build/filegroup_conversion_test.go @@ -56,3 +56,68 @@ filegroup { ExpectedErr: fmt.Errorf("filegroup 'foo' cannot contain a file with the same name"), }) } + +func TestFilegroupWithAidlSrcs(t *testing.T) { + testcases := []struct { + name string + bp string + expectedBazelAttrs AttrNameToString + }{ + { + name: "filegroup with only aidl srcs", + bp: ` + filegroup { + name: "foo", + srcs: ["aidl/foo.aidl"], + path: "aidl", + }`, + expectedBazelAttrs: AttrNameToString{ + "srcs": `["aidl/foo.aidl"]`, + "strip_import_prefix": `"aidl"`, + }, + }, + { + name: "filegroup without path", + bp: ` + filegroup { + name: "foo", + srcs: ["aidl/foo.aidl"], + }`, + expectedBazelAttrs: AttrNameToString{ + "srcs": `["aidl/foo.aidl"]`, + }, + }, + } + + for _, test := range testcases { + expectedBazelTargets := []string{ + MakeBazelTargetNoRestrictions("aidl_library", "foo", test.expectedBazelAttrs), + } + runFilegroupTestCase(t, Bp2buildTestCase{ + Description: test.name, + Blueprint: test.bp, + ExpectedBazelTargets: expectedBazelTargets, + }) + } +} + +func TestFilegroupWithAidlAndNonAidlSrcs(t *testing.T) { + runFilegroupTestCase(t, Bp2buildTestCase{ + Description: "filegroup with aidl and non-aidl srcs", + Filesystem: map[string]string{}, + Blueprint: ` +filegroup { + name: "foo", + srcs: [ + "aidl/foo.aidl", + "buf.proto", + ], +}`, + ExpectedBazelTargets: []string{ + MakeBazelTargetNoRestrictions("filegroup", "foo", AttrNameToString{ + "srcs": `[ + "aidl/foo.aidl", + "buf.proto", + ]`}), + }}) +} diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go index 94b28dc50..ddaa98aa3 100644 --- a/bpfix/bpfix/bpfix.go +++ b/bpfix/bpfix/bpfix.go @@ -553,7 +553,9 @@ func indicateAttributeError(mod *parser.Module, attributeName string, format str // If a variable is LOCAL_MODULE, get its value from the 'name' attribute. // This handles the statement -// LOCAL_SRC_FILES := $(LOCAL_MODULE) +// +// LOCAL_SRC_FILES := $(LOCAL_MODULE) +// // which occurs often. func resolveLocalModule(mod *parser.Module, val parser.Expression) parser.Expression { if varLocalName, ok := val.(*parser.Variable); ok { @@ -567,9 +569,9 @@ func resolveLocalModule(mod *parser.Module, val parser.Expression) parser.Expres } // etcPrebuiltModuleUpdate contains information on updating certain parts of a defined module such as: -// * changing the module type from prebuilt_etc to a different one -// * stripping the prefix of the install path based on the module type -// * appending additional boolean properties to the prebuilt module +// - changing the module type from prebuilt_etc to a different one +// - stripping the prefix of the install path based on the module type +// - appending additional boolean properties to the prebuilt module type etcPrebuiltModuleUpdate struct { // The prefix of the install path defined in local_module_path. The prefix is removed from local_module_path // before setting the 'filename' attribute. diff --git a/cc/afdo.go b/cc/afdo.go index 66e973284..fb66bbe52 100644 --- a/cc/afdo.go +++ b/cc/afdo.go @@ -66,8 +66,9 @@ func (afdo *afdo) AfdoEnabled() bool { } // Get list of profile file names, ordered by level of specialisation. For example: -// 1. libfoo_arm64.afdo -// 2. libfoo.afdo +// 1. libfoo_arm64.afdo +// 2. libfoo.afdo +// // Add more specialisation as needed. func getProfileFiles(ctx android.BaseModuleContext, moduleName string) []string { var files []string diff --git a/cc/androidmk.go b/cc/androidmk.go index 47fb919d0..779160c5d 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -411,14 +411,13 @@ func (test *testBinary) AndroidMkEntries(ctx AndroidMkContext, entries *android. entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true) } entries.AddStrings("LOCAL_TEST_MAINLINE_MODULES", test.Properties.Test_mainline_modules...) - if Bool(test.Properties.Test_options.Unit_test) { - entries.SetBool("LOCAL_IS_UNIT_TEST", true) - } entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", Bool(test.Properties.Per_testcase_directory)) if len(test.Properties.Data_bins) > 0 { entries.AddStrings("LOCAL_TEST_DATA_BINS", test.Properties.Data_bins...) } + + test.Properties.Test_options.CommonTestOptions.SetAndroidMkEntries(entries) }) AndroidMkWriteTestData(test.data, entries) diff --git a/cc/binary.go b/cc/binary.go index b2f248282..849aafaaa 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -617,6 +617,7 @@ func binaryBp2build(ctx android.TopDownMutatorContext, m *Module, typ string) { Dynamic_deps: baseAttrs.implementationDynamicDeps, Whole_archive_deps: baseAttrs.wholeArchiveDeps, System_deps: baseAttrs.systemDynamicDeps, + Runtime_deps: baseAttrs.runtimeDeps, Local_includes: baseAttrs.localIncludes, Absolute_includes: baseAttrs.absoluteIncludes, @@ -667,6 +668,7 @@ type binaryAttributes struct { Dynamic_deps bazel.LabelListAttribute Whole_archive_deps bazel.LabelListAttribute System_deps bazel.LabelListAttribute + Runtime_deps bazel.LabelListAttribute Local_includes bazel.StringListAttribute Absolute_includes bazel.StringListAttribute diff --git a/cc/bp2build.go b/cc/bp2build.go index 61a55ee69..ba9343995 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -52,6 +52,7 @@ type staticOrSharedAttributes struct { Implementation_dynamic_deps bazel.LabelListAttribute Whole_archive_deps bazel.LabelListAttribute Implementation_whole_archive_deps bazel.LabelListAttribute + Runtime_deps bazel.LabelListAttribute System_dynamic_deps bazel.LabelListAttribute @@ -710,6 +711,7 @@ type linkerAttributes struct { implementationDeps bazel.LabelListAttribute dynamicDeps bazel.LabelListAttribute implementationDynamicDeps bazel.LabelListAttribute + runtimeDeps bazel.LabelListAttribute wholeArchiveDeps bazel.LabelListAttribute implementationWholeArchiveDeps bazel.LabelListAttribute systemDynamicDeps bazel.LabelListAttribute @@ -825,6 +827,11 @@ func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversion if axisFeatures != nil { la.features.SetSelectValue(axis, config, axisFeatures) } + + runtimeDeps := android.BazelLabelForModuleDepsExcludes(ctx, props.Runtime_libs, props.Exclude_runtime_libs) + if !runtimeDeps.IsEmpty() { + la.runtimeDeps.SetSelectValue(axis, config, runtimeDeps) + } } func (la *linkerAttributes) convertStripProps(ctx android.BazelConversionPathContext, module *Module) { @@ -514,6 +514,7 @@ type ModuleContextIntf interface { getVndkExtendsModuleName() string isAfdoCompile() bool isPgoCompile() bool + isCfi() bool isNDKStubLibrary() bool useClangLld(actx ModuleContext) bool isForPlatform() bool @@ -1314,6 +1315,13 @@ func (c *Module) isPgoCompile() bool { return false } +func (c *Module) isCfi() bool { + if sanitize := c.sanitize; sanitize != nil { + return Bool(sanitize.Properties.Sanitize.Cfi) + } + return false +} + func (c *Module) isNDKStubLibrary() bool { if _, ok := c.compiler.(*stubDecorator); ok { return true @@ -1592,6 +1600,10 @@ func (ctx *moduleContextImpl) isPgoCompile() bool { return ctx.mod.isPgoCompile() } +func (ctx *moduleContextImpl) isCfi() bool { + return ctx.mod.isCfi() +} + func (ctx *moduleContextImpl) isNDKStubLibrary() bool { return ctx.mod.isNDKStubLibrary() } diff --git a/cc/fuzz.go b/cc/fuzz.go index dfc718e85..8a8c10723 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -152,10 +152,10 @@ func UnstrippedOutputFile(module android.Module) android.Path { // IsValidSharedDependency takes a module and determines if it is a unique shared library // that should be installed in the fuzz target output directories. This function // returns true, unless: -// - The module is not an installable shared library, or -// - The module is a header or stub, or -// - The module is a prebuilt and its source is available, or -// - The module is a versioned member of an SDK snapshot. +// - The module is not an installable shared library, or +// - The module is a header or stub, or +// - The module is a prebuilt and its source is available, or +// - The module is a versioned member of an SDK snapshot. func IsValidSharedDependency(dependency android.Module) bool { // TODO(b/144090547): We should be parsing these modules using // ModuleDependencyTag instead of the current brute-force checking. diff --git a/cc/genrule.go b/cc/genrule.go index 239064f1c..4ef990c35 100644 --- a/cc/genrule.go +++ b/cc/genrule.go @@ -41,13 +41,13 @@ type GenruleExtraProperties struct { // variations. The following environment variables will be set when the command // execute: // -// CC_ARCH the name of the architecture the command is being executed for +// CC_ARCH the name of the architecture the command is being executed for // -// CC_MULTILIB "lib32" if the architecture the command is being executed for is 32-bit, -// "lib64" if it is 64-bit. +// CC_MULTILIB "lib32" if the architecture the command is being executed for is 32-bit, +// "lib64" if it is 64-bit. // -// CC_NATIVE_BRIDGE the name of the subdirectory that native bridge libraries are stored in if -// the architecture has native bridge enabled, empty if it is disabled. +// CC_NATIVE_BRIDGE the name of the subdirectory that native bridge libraries are stored in if +// the architecture has native bridge enabled, empty if it is disabled. func GenRuleFactory() android.Module { module := genrule.NewGenRule() diff --git a/cc/image.go b/cc/image.go index 921b2bb13..e65a9aadb 100644 --- a/cc/image.go +++ b/cc/image.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/cc/library.go b/cc/library.go index 897b57261..621b58c33 100644 --- a/cc/library.go +++ b/cc/library.go @@ -319,6 +319,7 @@ func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) { Implementation_whole_archive_deps: linkerAttrs.implementationWholeArchiveDeps, Whole_archive_deps: *linkerAttrs.wholeArchiveDeps.Clone().Append(staticAttrs.Whole_archive_deps), System_dynamic_deps: *linkerAttrs.systemDynamicDeps.Clone().Append(staticAttrs.System_dynamic_deps), + Runtime_deps: linkerAttrs.runtimeDeps, sdkAttributes: bp2BuildParseSdkAttributes(m), } @@ -335,6 +336,7 @@ func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) { Implementation_dynamic_deps: *linkerAttrs.implementationDynamicDeps.Clone().Append(sharedAttrs.Implementation_dynamic_deps), Whole_archive_deps: *linkerAttrs.wholeArchiveDeps.Clone().Append(sharedAttrs.Whole_archive_deps), System_dynamic_deps: *linkerAttrs.systemDynamicDeps.Clone().Append(sharedAttrs.System_dynamic_deps), + Runtime_deps: linkerAttrs.runtimeDeps, sdkAttributes: bp2BuildParseSdkAttributes(m), } @@ -1048,9 +1050,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa if ctx.Module().(android.ApexModule).NotInPlatform() { flag = "--apex" } else { - // TODO(b/239274367) drop --apex when #apex is replaced with #systemapi - // in the map.txt files of platform libraries - flag = "--systemapi --apex" + flag = "--systemapi" } nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile, android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag) @@ -2552,6 +2552,7 @@ func sharedOrStaticLibraryBp2Build(ctx android.TopDownMutatorContext, module *Mo Implementation_whole_archive_deps: linkerAttrs.implementationWholeArchiveDeps, System_dynamic_deps: linkerAttrs.systemDynamicDeps, sdkAttributes: bp2BuildParseSdkAttributes(module), + Runtime_deps: linkerAttrs.runtimeDeps, } var attrs interface{} @@ -136,9 +136,16 @@ func (lto *lto) LTO(ctx BaseModuleContext) bool { } func (lto *lto) DefaultThinLTO(ctx BaseModuleContext) bool { + // LP32 has many subtle issues and less test coverage. + lib32 := ctx.Arch().ArchType.Multilib == "lib32" + // CFI enables full LTO. + cfi := ctx.isCfi() + // Performance and binary size are less important for host binaries. host := ctx.Host() - vndk := ctx.isVndk() // b/169217596 - return GlobalThinLTO(ctx) && !lto.Never() && !host && !vndk + // FIXME: ThinLTO for VNDK produces different output. + // b/169217596 + vndk := ctx.isVndk() + return GlobalThinLTO(ctx) && !lto.Never() && !lib32 && !cfi && !host && !vndk } func (lto *lto) FullLTO() bool { diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go index 56fd5fc81..ef38a064a 100644 --- a/cc/ndk_headers.go +++ b/cc/ndk_headers.go @@ -148,12 +148,12 @@ func (m *headerModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { // to the sysroot base + "usr/include" + to directory + directory component. // ndk_headers requires the license file to be specified. Example: // -// Given: -// sysroot base = "ndk/sysroot" -// from = "include/foo" -// to = "bar" -// header = "include/foo/woodly/doodly.h" -// output path = "ndk/sysroot/usr/include/bar/woodly/doodly.h" +// Given: +// sysroot base = "ndk/sysroot" +// from = "include/foo" +// to = "bar" +// header = "include/foo/woodly/doodly.h" +// output path = "ndk/sysroot/usr/include/bar/woodly/doodly.h" func ndkHeadersFactory() android.Module { module := &headerModule{} module.AddProperties(&module.properties) @@ -275,15 +275,17 @@ func versionedNdkHeadersFactory() android.Module { return module } -// preprocessed_ndk_header { -// name: "foo", -// preprocessor: "foo.sh", -// srcs: [...], -// to: "android", -// } +// preprocessed_ndk_header { +// name: "foo", +// preprocessor: "foo.sh", +// srcs: [...], +// to: "android", +// } // // Will invoke the preprocessor as: -// $preprocessor -o $SYSROOT/usr/include/android/needs_preproc.h $src +// +// $preprocessor -o $SYSROOT/usr/include/android/needs_preproc.h $src +// // For each src in srcs. type preprocessedHeadersProperties struct { // The preprocessor to run. Must be a program inside the source directory diff --git a/cc/ndk_library.go b/cc/ndk_library.go index 0879257a5..2bbfc4aee 100644 --- a/cc/ndk_library.go +++ b/cc/ndk_library.go @@ -84,12 +84,11 @@ var ( // // Example: // -// ndk_library { -// name: "libfoo", -// symbol_file: "libfoo.map.txt", -// first_version: "9", -// } -// +// ndk_library { +// name: "libfoo", +// symbol_file: "libfoo.map.txt", +// first_version: "9", +// } type libraryProperties struct { // Relative path to the symbol map. // An example file can be seen here: TODO(danalbert): Make an example. diff --git a/cc/prebuilt.go b/cc/prebuilt.go index 8c404d30f..a2d450332 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -348,10 +348,10 @@ type bazelPrebuiltLibraryStaticAttributes struct { // TODO(b/228623543): The below is not entirely true until the bug is fixed. For now, both targets are always generated // Implements bp2build for cc_prebuilt_library modules. This will generate: -// * Only a prebuilt_library_static if the shared.enabled property is set to false across all variants. -// * Only a prebuilt_library_shared if the static.enabled property is set to false across all variants -// * Both a prebuilt_library_static and prebuilt_library_shared if the aforementioned properties are not false across -// all variants +// - Only a prebuilt_library_static if the shared.enabled property is set to false across all variants. +// - Only a prebuilt_library_shared if the static.enabled property is set to false across all variants +// - Both a prebuilt_library_static and prebuilt_library_shared if the aforementioned properties are not false across +// all variants // // In all cases, prebuilt_library_static target names will be appended with "_bp2build_cc_library_static". func prebuiltLibraryBp2Build(ctx android.TopDownMutatorContext, module *Module) { diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go index 9d40ad058..792ffe364 100644 --- a/cc/snapshot_prebuilt.go +++ b/cc/snapshot_prebuilt.go @@ -4,7 +4,7 @@ // 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 +// 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, @@ -263,12 +263,12 @@ type BaseSnapshotDecoratorProperties struct { // version, snapshot arch, etc. It also adds a special suffix to Soong module name, so it doesn't // collide with source modules. e.g. the following example module, // -// vendor_snapshot_static { -// name: "libbase", -// arch: "arm64", -// version: 30, -// ... -// } +// vendor_snapshot_static { +// name: "libbase", +// arch: "arm64", +// version: 30, +// ... +// } // // will be seen as "libbase.vendor_static.30.arm64" by Soong. type BaseSnapshotDecorator struct { @@ -370,7 +370,6 @@ func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *BaseSnapshotDecorato } } -// // Module definitions for snapshots of libraries (shared, static, header). // // Modules (vendor|recovery)_snapshot_(shared|static|header) are defined here. Shared libraries and @@ -630,7 +629,6 @@ func RecoverySnapshotHeaderFactory() android.Module { var _ snapshotSanitizer = (*snapshotLibraryDecorator)(nil) -// // Module definitions for snapshots of executable binaries. // // Modules (vendor|recovery)_snapshot_binary are defined here. They have their prebuilt executable @@ -728,7 +726,6 @@ func snapshotBinaryFactory(image SnapshotImage, moduleSuffix string) android.Mod return module.Init() } -// // Module definitions for snapshots of object files (*.o). // // Modules (vendor|recovery)_snapshot_object are defined here. They have their prebuilt object diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go index de50ef50f..cf4617da3 100644 --- a/cc/snapshot_utils.go +++ b/cc/snapshot_utils.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/cc/test.go b/cc/test.go index 57035711e..f5abc454d 100644 --- a/cc/test.go +++ b/cc/test.go @@ -43,6 +43,8 @@ type TestInstallerProperties struct { // Test option struct. type TestOptions struct { + android.CommonTestOptions + // The UID that you want to run the test as on a device. Run_test_as *string @@ -52,9 +54,6 @@ type TestOptions struct { // a list of extra test configuration files that should be installed with the module. Extra_test_configs []string `android:"path,arch_variant"` - // If the test is a hostside(no device required) unittest that shall be run during presubmit check. - Unit_test *bool - // Add ShippingApiLevelModuleController to auto generated test config. If the device properties // for the shipping api level is less than the min_shipping_api_level, skip this module. Min_shipping_api_level *int64 diff --git a/cc/vendor_public_library.go b/cc/vendor_public_library.go index 65a2b0c9e..f2c8545bc 100644 --- a/cc/vendor_public_library.go +++ b/cc/vendor_public_library.go @@ -28,17 +28,16 @@ var ( // // Example: // -// vendor_public_library { -// name: "libfoo", -// symbol_file: "libfoo.map.txt", -// export_public_headers: ["libfoo_headers"], -// } -// -// cc_headers { -// name: "libfoo_headers", -// export_include_dirs: ["include"], -// } -// +// vendor_public_library { +// name: "libfoo", +// symbol_file: "libfoo.map.txt", +// export_public_headers: ["libfoo_headers"], +// } +// +// cc_headers { +// name: "libfoo_headers", +// export_include_dirs: ["include"], +// } type vendorPublicLibraryProperties struct { // Relative path to the symbol map. Symbol_file *string diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go index e7c05aca8..77e6f6ffe 100644 --- a/cc/vendor_snapshot.go +++ b/cc/vendor_snapshot.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go index 31b6d10dd..37819a4be 100644 --- a/cc/vndk_prebuilt.go +++ b/cc/vndk_prebuilt.go @@ -29,26 +29,25 @@ var ( // // Example: // -// vndk_prebuilt_shared { -// name: "libfoo", -// version: "27", -// target_arch: "arm64", -// vendor_available: true, -// product_available: true, -// vndk: { -// enabled: true, -// }, -// export_include_dirs: ["include/external/libfoo/vndk_include"], -// arch: { -// arm64: { -// srcs: ["arm/lib64/libfoo.so"], -// }, -// arm: { -// srcs: ["arm/lib/libfoo.so"], -// }, -// }, -// } -// +// vndk_prebuilt_shared { +// name: "libfoo", +// version: "27", +// target_arch: "arm64", +// vendor_available: true, +// product_available: true, +// vndk: { +// enabled: true, +// }, +// export_include_dirs: ["include/external/libfoo/vndk_include"], +// arch: { +// arm64: { +// srcs: ["arm/lib64/libfoo.so"], +// }, +// arm: { +// srcs: ["arm/lib/libfoo.so"], +// }, +// }, +// } type vndkPrebuiltProperties struct { // VNDK snapshot version. Version *string @@ -250,25 +249,25 @@ func vndkPrebuiltSharedLibrary() *Module { // vndk_prebuilt_shared installs Vendor Native Development kit (VNDK) snapshot // shared libraries for system build. Example: // -// vndk_prebuilt_shared { -// name: "libfoo", -// version: "27", -// target_arch: "arm64", -// vendor_available: true, -// product_available: true, -// vndk: { -// enabled: true, -// }, -// export_include_dirs: ["include/external/libfoo/vndk_include"], -// arch: { -// arm64: { -// srcs: ["arm/lib64/libfoo.so"], -// }, -// arm: { -// srcs: ["arm/lib/libfoo.so"], -// }, -// }, -// } +// vndk_prebuilt_shared { +// name: "libfoo", +// version: "27", +// target_arch: "arm64", +// vendor_available: true, +// product_available: true, +// vndk: { +// enabled: true, +// }, +// export_include_dirs: ["include/external/libfoo/vndk_include"], +// arch: { +// arm64: { +// srcs: ["arm/lib64/libfoo.so"], +// }, +// arm: { +// srcs: ["arm/lib/libfoo.so"], +// }, +// }, +// } func VndkPrebuiltSharedFactory() android.Module { module := vndkPrebuiltSharedLibrary() return module.Init() diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go index 4f7451d0c..91e3540dd 100644 --- a/cmd/sbox/sbox.go +++ b/cmd/sbox/sbox.go @@ -208,7 +208,6 @@ func run() error { // // returns an exec.Cmd that can be ran from within sbox context if no error, or nil if error. // caller must ensure script is cleaned up if function succeeds. -// func createCommandScript(rawCommand, scriptPath, scriptPathInSandbox string) (*exec.Cmd, error) { err := os.WriteFile(scriptPath, []byte(rawCommand), 0644) if err != nil { diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go index 7bc9ab261..afb3de38a 100644 --- a/dexpreopt/class_loader_context.go +++ b/dexpreopt/class_loader_context.go @@ -25,11 +25,11 @@ import ( ) // This comment describes the following: -// 1. the concept of class loader context (CLC) and its relation to classpath -// 2. how PackageManager constructs CLC from shared libraries and their dependencies -// 3. build-time vs. run-time CLC and why this matters for dexpreopt -// 4. manifest fixer: a tool that adds missing <uses-library> tags to the manifests -// 5. build system support for CLC +// 1. the concept of class loader context (CLC) and its relation to classpath +// 2. how PackageManager constructs CLC from shared libraries and their dependencies +// 3. build-time vs. run-time CLC and why this matters for dexpreopt +// 4. manifest fixer: a tool that adds missing <uses-library> tags to the manifests +// 5. build system support for CLC // // 1. Class loader context // ----------------------- @@ -59,15 +59,16 @@ import ( // loaders are not duplicated (at runtime there is a single class loader instance for each library). // // Example: A has <uses-library> tags B, C and D; C has <uses-library tags> B and D; -// D has <uses-library> E; B and E have no <uses-library> dependencies. The CLC is: -// A -// ├── B -// ├── C -// │ ├── B -// │ └── D -// │ └── E -// └── D -// └── E +// +// D has <uses-library> E; B and E have no <uses-library> dependencies. The CLC is: +// A +// ├── B +// ├── C +// │ ├── B +// │ └── D +// │ └── E +// └── D +// └── E // // CLC defines the lookup order of libraries when resolving Java classes used by the library/app. // The lookup order is important because libraries may contain duplicate classes, and the class is @@ -188,7 +189,6 @@ import ( // rule generation phase. // // ClassLoaderContext is a structure that represents CLC. -// type ClassLoaderContext struct { // The name of the library. Name string @@ -249,7 +249,6 @@ func (c *ClassLoaderContext) excludeLibs(excludedLibs []string) (*ClassLoaderCon // generates a build rule that includes conditional CLC for all versions, extracts the target SDK // version from the manifest, and filters the CLCs based on that version. Exact final CLC that is // passed to dex2oat is unknown to the build system, and gets known only at Ninja stage. -// type ClassLoaderContextMap map[int][]*ClassLoaderContext // Compatibility libraries. Some are optional, and some are required: this is the default that @@ -485,7 +484,6 @@ func (clcMap ClassLoaderContextMap) ExcludeLibs(excludedLibs []string) ClassLoad // constructs class loader context on device. // // TODO(b/132357300): remove "android.hidl.manager" and "android.hidl.base" for non-system apps. -// func fixClassLoaderContext(clcMap ClassLoaderContextMap) { required, optional := clcMap.UsesLibs() usesLibs := append(required, optional...) diff --git a/etc/snapshot_etc.go b/etc/snapshot_etc.go index b54a8a6ec..0d65ab6b6 100644 --- a/etc/snapshot_etc.go +++ b/etc/snapshot_etc.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/finder/finder.go b/finder/finder.go index c5196c8de..054ccd639 100644 --- a/finder/finder.go +++ b/finder/finder.go @@ -736,15 +736,15 @@ func (f *Finder) parseCacheEntry(bytes []byte) ([]dirFullInfo, error) { // because we know this separator won't appear in the json that we're parsing. // // The newline byte can only appear in a UTF-8 stream if the newline character appears, because: -// - The newline character is encoded as "0000 1010" in binary ("0a" in hex) -// - UTF-8 dictates that bytes beginning with a "0" bit are never emitted as part of a multibyte -// character. +// - The newline character is encoded as "0000 1010" in binary ("0a" in hex) +// - UTF-8 dictates that bytes beginning with a "0" bit are never emitted as part of a multibyte +// character. // // We know that the newline character will never appear in our json string, because: -// - If a newline character appears as part of a data string, then json encoding will -// emit two characters instead: '\' and 'n'. -// - The json encoder that we use doesn't emit the optional newlines between any of its -// other outputs. +// - If a newline character appears as part of a data string, then json encoding will +// emit two characters instead: '\' and 'n'. +// - The json encoder that we use doesn't emit the optional newlines between any of its +// other outputs. const lineSeparator = byte('\n') func (f *Finder) readLine(reader *bufio.Reader) ([]byte, error) { diff --git a/genrule/genrule.go b/genrule/genrule.go index b796877ef..6686c8717 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -976,9 +976,7 @@ func (m *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { var Bool = proptools.Bool var String = proptools.String -// // Defaults -// type Defaults struct { android.ModuleBase android.DefaultsModuleBase diff --git a/java/androidmk.go b/java/androidmk.go index 4cf5ee49e..75ac0e72d 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -167,9 +167,8 @@ func (j *Test) AndroidMkEntries() []android.AndroidMkEntries { entries.SetString("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", "true") } entries.AddStrings("LOCAL_TEST_MAINLINE_MODULES", j.testProperties.Test_mainline_modules...) - if Bool(j.testProperties.Test_options.Unit_test) { - entries.SetBool("LOCAL_IS_UNIT_TEST", true) - } + + j.testProperties.Test_options.CommonTestOptions.SetAndroidMkEntries(entries) }) return entriesList diff --git a/java/app_import.go b/java/app_import.go index 4bab14b32..d6dca3836 100644 --- a/java/app_import.go +++ b/java/app_import.go @@ -461,19 +461,19 @@ func createVariantGroupType(variants []string, variantGroupName string) reflect. // android_app_import imports a prebuilt apk with additional processing specified in the module. // DPI-specific apk source files can be specified using dpi_variants. Example: // -// android_app_import { -// name: "example_import", -// apk: "prebuilts/example.apk", -// dpi_variants: { -// mdpi: { -// apk: "prebuilts/example_mdpi.apk", -// }, -// xhdpi: { -// apk: "prebuilts/example_xhdpi.apk", -// }, -// }, -// presigned: true, -// } +// android_app_import { +// name: "example_import", +// apk: "prebuilts/example.apk", +// dpi_variants: { +// mdpi: { +// apk: "prebuilts/example_mdpi.apk", +// }, +// xhdpi: { +// apk: "prebuilts/example_xhdpi.apk", +// }, +// }, +// presigned: true, +// } func AndroidAppImportFactory() android.Module { module := &AndroidAppImport{} module.AddProperties(&module.properties) diff --git a/java/base.go b/java/base.go index 94daf37fc..fe92b4754 100644 --- a/java/base.go +++ b/java/base.go @@ -267,6 +267,9 @@ type DeviceProperties struct { // Only for libraries created by a sysprop_library module, SyspropPublicStub is the name of the // public stubs library. SyspropPublicStub string `blueprint:"mutated"` + + HiddenAPIPackageProperties + HiddenAPIFlagFileProperties } // Device properties that can be overridden by overriding module (e.g. override_android_app) @@ -564,6 +567,20 @@ func (j *Module) addHostAndDeviceProperties() { ) } +// provideHiddenAPIPropertyInfo populates a HiddenAPIPropertyInfo from hidden API properties and +// makes it available through the hiddenAPIPropertyInfoProvider. +func (j *Module) provideHiddenAPIPropertyInfo(ctx android.ModuleContext) { + hiddenAPIInfo := newHiddenAPIPropertyInfo() + + // Populate with flag file paths from the properties. + hiddenAPIInfo.extractFlagFilesFromProperties(ctx, &j.deviceProperties.HiddenAPIFlagFileProperties) + + // Populate with package rules from the properties. + hiddenAPIInfo.extractPackageRulesFromProperties(&j.deviceProperties.HiddenAPIPackageProperties) + + ctx.SetProvider(hiddenAPIPropertyInfoProvider, hiddenAPIInfo) +} + func (j *Module) OutputFiles(tag string) (android.Paths, error) { switch tag { case "": diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 56401b3f7..93168070e 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -128,7 +128,7 @@ type bootclasspathFragmentProperties struct { Coverage BootclasspathFragmentCoverageAffectedProperties // Hidden API related properties. - Hidden_api HiddenAPIFlagFileProperties + HiddenAPIFlagFileProperties // The list of additional stub libraries which this fragment's contents use but which are not // provided by another bootclasspath_fragment. @@ -145,7 +145,7 @@ type bootclasspathFragmentProperties struct { BootclasspathFragmentsDepsProperties } -type HiddenApiPackageProperties struct { +type HiddenAPIPackageProperties struct { Hidden_api struct { // Contains prefixes of a package hierarchy that is provided solely by this // bootclasspath_fragment. @@ -222,8 +222,8 @@ type HiddenApiPackageProperties struct { } type SourceOnlyBootclasspathProperties struct { - HiddenApiPackageProperties - Coverage HiddenApiPackageProperties + HiddenAPIPackageProperties + Coverage HiddenAPIPackageProperties } type BootclasspathFragmentModule struct { @@ -293,7 +293,7 @@ func bootclasspathFragmentFactory() android.Module { return } - err = proptools.AppendProperties(&m.sourceOnlyProperties.HiddenApiPackageProperties, &m.sourceOnlyProperties.Coverage, nil) + err = proptools.AppendProperties(&m.sourceOnlyProperties.HiddenAPIPackageProperties, &m.sourceOnlyProperties.Coverage, nil) if err != nil { ctx.PropertyErrorf("coverage", "error trying to append hidden api coverage specific properties: %s", err) return @@ -825,7 +825,12 @@ func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.Modul input.gatherStubLibInfo(ctx, contents) // Populate with flag file paths from the properties. - input.extractFlagFilesFromProperties(ctx, &b.properties.Hidden_api) + input.extractFlagFilesFromProperties(ctx, &b.properties.HiddenAPIFlagFileProperties) + + // Populate with package rules from the properties. + input.extractPackageRulesFromProperties(&b.sourceOnlyProperties.HiddenAPIPackageProperties) + + input.gatherPropertyInfo(ctx, contents) // Add the stub dex jars from this module's fragment dependencies. input.DependencyStubDexJarsByScope.addStubDexJarsByModule(dependencyHiddenApiInfo.TransitiveStubDexJarsByScope) @@ -862,9 +867,9 @@ func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleC // If the module specifies split_packages or package_prefixes then use those to generate the // signature patterns. - splitPackages := b.sourceOnlyProperties.Hidden_api.Split_packages - packagePrefixes := b.sourceOnlyProperties.Hidden_api.Package_prefixes - singlePackages := b.sourceOnlyProperties.Hidden_api.Single_packages + splitPackages := input.SplitPackages + packagePrefixes := input.PackagePrefixes + singlePackages := input.SinglePackages if splitPackages != nil || packagePrefixes != nil || singlePackages != nil { output.SignaturePatternsPath = buildRuleSignaturePatternsFile( ctx, output.AllFlagsPath, splitPackages, packagePrefixes, singlePackages) diff --git a/java/bootclasspath_fragment_test.go b/java/bootclasspath_fragment_test.go index 83beb6d23..f95c83fe7 100644 --- a/java/bootclasspath_fragment_test.go +++ b/java/bootclasspath_fragment_test.go @@ -15,6 +15,7 @@ package java import ( + "strings" "testing" "android/soong/android" @@ -285,6 +286,119 @@ func TestBootclasspathFragment_StubLibs(t *testing.T) { android.AssertPathsRelativeToTopEquals(t, "widest dex stubs jar", expectedWidestPaths, info.TransitiveStubDexJarsByScope.StubDexJarsForWidestAPIScope()) } +func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) { + result := android.GroupFixturePreparers( + prepareForTestWithBootclasspathFragment, + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("mysdklibrary", "mynewlibrary"), + FixtureConfigureApexBootJars("myapex:mybootlib", "myapex:mynewlibrary"), + android.MockFS{ + "my-blocked.txt": nil, + "my-max-target-o-low-priority.txt": nil, + "my-max-target-p.txt": nil, + "my-max-target-q.txt": nil, + "my-max-target-r-low-priority.txt": nil, + "my-removed.txt": nil, + "my-unsupported-packages.txt": nil, + "my-unsupported.txt": nil, + "my-new-max-target-q.txt": nil, + }.AddToFixture(), + android.FixtureWithRootAndroidBp(` + bootclasspath_fragment { + name: "mybootclasspathfragment", + apex_available: ["myapex"], + contents: ["mybootlib", "mynewlibrary"], + hidden_api: { + unsupported: [ + "my-unsupported.txt", + ], + removed: [ + "my-removed.txt", + ], + max_target_r_low_priority: [ + "my-max-target-r-low-priority.txt", + ], + max_target_q: [ + "my-max-target-q.txt", + ], + max_target_p: [ + "my-max-target-p.txt", + ], + max_target_o_low_priority: [ + "my-max-target-o-low-priority.txt", + ], + blocked: [ + "my-blocked.txt", + ], + unsupported_packages: [ + "my-unsupported-packages.txt", + ], + split_packages: ["sdklibrary"], + package_prefixes: ["sdklibrary.all.mine"], + single_packages: ["sdklibrary.mine"], + }, + } + + java_library { + name: "mybootlib", + apex_available: ["myapex"], + srcs: ["Test.java"], + system_modules: "none", + sdk_version: "none", + min_sdk_version: "1", + compile_dex: true, + permitted_packages: ["mybootlib"], + } + + java_sdk_library { + name: "mynewlibrary", + apex_available: ["myapex"], + srcs: ["Test.java"], + min_sdk_version: "10", + compile_dex: true, + public: {enabled: true}, + permitted_packages: ["mysdklibrary"], + hidden_api: { + max_target_q: [ + "my-new-max-target-q.txt", + ], + split_packages: ["sdklibrary", "newlibrary"], + package_prefixes: ["newlibrary.all.mine"], + single_packages: ["newlibrary.mine"], + }, + } + `), + ).RunTest(t) + + // Make sure that the library exports hidden API properties for use by the bootclasspath_fragment. + library := result.Module("mynewlibrary", "android_common") + info := result.ModuleProvider(library, hiddenAPIPropertyInfoProvider).(HiddenAPIPropertyInfo) + android.AssertArrayString(t, "split packages", []string{"sdklibrary", "newlibrary"}, info.SplitPackages) + android.AssertArrayString(t, "package prefixes", []string{"newlibrary.all.mine"}, info.PackagePrefixes) + android.AssertArrayString(t, "single packages", []string{"newlibrary.mine"}, info.SinglePackages) + for _, c := range HiddenAPIFlagFileCategories { + expectedMaxTargetQPaths := []string(nil) + if c.PropertyName == "max_target_q" { + expectedMaxTargetQPaths = []string{"my-new-max-target-q.txt"} + } + android.AssertPathsRelativeToTopEquals(t, c.PropertyName, expectedMaxTargetQPaths, info.FlagFilesByCategory[c]) + } + + // Make sure that the signature-patterns.csv is passed all the appropriate package properties + // from the bootclasspath_fragment and its contents. + fragment := result.ModuleForTests("mybootclasspathfragment", "android_common") + rule := fragment.Output("modular-hiddenapi/signature-patterns.csv") + expectedCommand := strings.Join([]string{ + "--split-package newlibrary", + "--split-package sdklibrary", + "--package-prefix newlibrary.all.mine", + "--package-prefix sdklibrary.all.mine", + "--single-package newlibrary.mine", + "--single-package sdklibrary", + }, " ") + android.AssertStringDoesContain(t, "signature patterns command", rule.RuleParams.Command, expectedCommand) +} + func TestBootclasspathFragment_Test(t *testing.T) { result := android.GroupFixturePreparers( prepareForTestWithBootclasspathFragment, diff --git a/java/classpath_element.go b/java/classpath_element.go index 753e7f888..496291678 100644 --- a/java/classpath_element.go +++ b/java/classpath_element.go @@ -97,11 +97,11 @@ type ClasspathElementContext interface { // the list with its Contents field. // // Requirements/Assumptions: -// * A fragment can be associated with more than one apex but each apex must only be associated with -// a single fragment from the fragments list. -// * All of a fragment's contents must appear as a contiguous block in the same order in the -// libraries list. -// * Each library must only appear in a single fragment. +// - A fragment can be associated with more than one apex but each apex must only be associated with +// a single fragment from the fragments list. +// - All of a fragment's contents must appear as a contiguous block in the same order in the +// libraries list. +// - Each library must only appear in a single fragment. // // The apex is used to identify which libraries belong to which fragment. First a mapping is created // from apex to fragment. Then the libraries are iterated over and any library in an apex is @@ -109,13 +109,15 @@ type ClasspathElementContext interface { // standalone and have their own element. // // e.g. Given the following input: -// libraries: com.android.art:core-oj, com.android.art:core-libart, framework, ext -// fragments: com.android.art:art-bootclasspath-fragment +// +// libraries: com.android.art:core-oj, com.android.art:core-libart, framework, ext +// fragments: com.android.art:art-bootclasspath-fragment // // Then this will return: -// ClasspathFragmentElement(art-bootclasspath-fragment, [core-oj, core-libart]), -// ClasspathLibraryElement(framework), -// ClasspathLibraryElement(ext), +// +// ClasspathFragmentElement(art-bootclasspath-fragment, [core-oj, core-libart]), +// ClasspathLibraryElement(framework), +// ClasspathLibraryElement(ext), func CreateClasspathElements(ctx ClasspathElementContext, libraries []android.Module, fragments []android.Module) ClasspathElements { // Create a map from apex name to the fragment module. This makes it easy to find the fragment // associated with a particular apex. diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index b4cd07a78..4e416fc82 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -418,7 +418,6 @@ func (image *bootImageConfig) shouldInstallInApex() bool { // // The location is passed as an argument to the ART tools like dex2oat instead of the real path. // ART tools will then reconstruct the architecture-specific real path. -// func (image *bootImageVariant) imageLocations() (imageLocationsOnHost []string, imageLocationsOnDevice []string) { if image.extends != nil { imageLocationsOnHost, imageLocationsOnDevice = image.extends.getVariant(image.target).imageLocations() diff --git a/java/droiddoc.go b/java/droiddoc.go index 96639220a..901419cba 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -158,9 +158,7 @@ type DroiddocProperties struct { Compat_config *string `android:"path"` } -// // Common flags passed down to build rule -// type droiddocBuilderFlags struct { bootClasspathArgs string classpathArgs string @@ -193,9 +191,7 @@ func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersio return false } -// // Javadoc -// type Javadoc struct { android.ModuleBase android.DefaultableModuleBase @@ -548,9 +544,7 @@ func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) { rule.Build("javadoc", "javadoc") } -// // Droiddoc -// type Droiddoc struct { Javadoc @@ -827,9 +821,7 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) { rule.Build("javadoc", desc) } -// // Exported Droiddoc Directory -// var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"} type ExportedDroiddocDirProperties struct { @@ -862,9 +854,7 @@ func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleCont d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")}) } -// // Defaults -// type DocDefaults struct { android.ModuleBase android.DefaultsModuleBase diff --git a/java/droidstubs.go b/java/droidstubs.go index 932fb19ce..12590ca50 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -42,19 +42,14 @@ func RegisterStubsBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory) } -// // Droidstubs -// type Droidstubs struct { Javadoc android.SdkBase properties DroidstubsProperties - apiFile android.WritablePath - apiXmlFile android.WritablePath - lastReleasedApiXmlFile android.WritablePath - privateApiFile android.WritablePath - removedApiFile android.WritablePath + apiFile android.Path + removedApiFile android.Path nullabilityWarningsFile android.WritablePath checkCurrentApiTimestamp android.WritablePath @@ -68,9 +63,6 @@ type Droidstubs struct { annotationsZip android.WritablePath apiVersionsXml android.WritablePath - apiFilePath android.Path - removedApiFilePath android.Path - metadataZip android.WritablePath metadataDir android.WritablePath } @@ -206,9 +198,9 @@ func (d *Droidstubs) OutputFiles(tag string) (android.Paths, error) { return android.Paths{d.docZip}, nil case ".api.txt", android.DefaultDistTag: // This is the default dist path for dist properties that have no tag property. - return android.Paths{d.apiFilePath}, nil + return android.Paths{d.apiFile}, nil case ".removed-api.txt": - return android.Paths{d.removedApiFilePath}, nil + return android.Paths{d.removedApiFile}, nil case ".annotations.zip": return android.Paths{d.annotationsZip}, nil case ".api_versions.xml": @@ -223,11 +215,11 @@ func (d *Droidstubs) AnnotationsZip() android.Path { } func (d *Droidstubs) ApiFilePath() android.Path { - return d.apiFilePath + return d.apiFile } func (d *Droidstubs) RemovedApiFilePath() android.Path { - return d.removedApiFilePath + return d.removedApiFile } func (d *Droidstubs) StubsSrcJar() android.Path { @@ -270,24 +262,24 @@ func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuil apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") || String(d.properties.Api_filename) != "" { filename := proptools.StringDefault(d.properties.Api_filename, ctx.ModuleName()+"_api.txt") - d.apiFile = android.PathForModuleOut(ctx, "metalava", filename) - cmd.FlagWithOutput("--api ", d.apiFile) - d.apiFilePath = d.apiFile + uncheckedApiFile := android.PathForModuleOut(ctx, "metalava", filename) + cmd.FlagWithOutput("--api ", uncheckedApiFile) + d.apiFile = uncheckedApiFile } else if sourceApiFile := proptools.String(d.properties.Check_api.Current.Api_file); sourceApiFile != "" { // If check api is disabled then make the source file available for export. - d.apiFilePath = android.PathForModuleSrc(ctx, sourceApiFile) + d.apiFile = android.PathForModuleSrc(ctx, sourceApiFile) } if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") || apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") || String(d.properties.Removed_api_filename) != "" { filename := proptools.StringDefault(d.properties.Removed_api_filename, ctx.ModuleName()+"_removed.txt") - d.removedApiFile = android.PathForModuleOut(ctx, "metalava", filename) - cmd.FlagWithOutput("--removed-api ", d.removedApiFile) - d.removedApiFilePath = d.removedApiFile + uncheckedRemovedFile := android.PathForModuleOut(ctx, "metalava", filename) + cmd.FlagWithOutput("--removed-api ", uncheckedRemovedFile) + d.removedApiFile = uncheckedRemovedFile } else if sourceRemovedApiFile := proptools.String(d.properties.Check_api.Current.Removed_api_file); sourceRemovedApiFile != "" { // If check api is disabled then make the source removed api file available for export. - d.removedApiFilePath = android.PathForModuleSrc(ctx, sourceRemovedApiFile) + d.removedApiFile = android.PathForModuleSrc(ctx, sourceRemovedApiFile) } if Bool(d.properties.Write_sdk_values) { @@ -697,15 +689,86 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { zipSyncCleanupCmd(rule, srcJarDir) + rule.Build("metalava", "metalava merged") + if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") { - d.generateCheckCurrentCheckedInApiIsUpToDateBuildRules(ctx) - // Make sure that whenever the API stubs are generated that the current checked in API files are - // checked to make sure that they are up-to-date. - cmd.Validation(d.checkCurrentApiTimestamp) - } + if len(d.Javadoc.properties.Out) > 0 { + ctx.PropertyErrorf("out", "out property may not be combined with check_api") + } - rule.Build("metalava", "metalava merged") + apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file)) + removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file)) + baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file) + + if baselineFile.Valid() { + ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName()) + } + + d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "metalava", "check_current_api.timestamp") + + rule := android.NewRuleBuilder(pctx, ctx) + + // Diff command line. + // -F matches the closest "opening" line, such as "package android {" + // and " public class Intent {". + diff := `diff -u -F '{ *$'` + + rule.Command().Text("( true") + rule.Command(). + Text(diff). + Input(apiFile).Input(d.apiFile) + + rule.Command(). + Text(diff). + Input(removedApiFile).Input(d.removedApiFile) + + msg := fmt.Sprintf(`\n******************************\n`+ + `You have tried to change the API from what has been previously approved.\n\n`+ + `To make these errors go away, you have two choices:\n`+ + ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+ + ` to the new methods, etc. shown in the above diff.\n\n`+ + ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+ + ` m %s-update-current-api\n\n`+ + ` To submit the revised current.txt to the main Android repository,\n`+ + ` you will need approval.\n`+ + `******************************\n`, ctx.ModuleName()) + + rule.Command(). + Text("touch").Output(d.checkCurrentApiTimestamp). + Text(") || ("). + Text("echo").Flag("-e").Flag(`"` + msg + `"`). + Text("; exit 38"). + Text(")") + + rule.Build("metalavaCurrentApiCheck", "check current API") + + d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "metalava", "update_current_api.timestamp") + + // update API rule + rule = android.NewRuleBuilder(pctx, ctx) + + rule.Command().Text("( true") + + rule.Command(). + Text("cp").Flag("-f"). + Input(d.apiFile).Flag(apiFile.String()) + + rule.Command(). + Text("cp").Flag("-f"). + Input(d.removedApiFile).Flag(removedApiFile.String()) + + msg = "failed to update public API" + + rule.Command(). + Text("touch").Output(d.updateCurrentApiTimestamp). + Text(") || ("). + Text("echo").Flag("-e").Flag(`"` + msg + `"`). + Text("; exit 38"). + Text(")") + + rule.Build("metalavaCurrentApiUpdate", "update current API") + } if String(d.properties.Check_nullability_warnings) != "" { if d.nullabilityWarningsFile == nil { @@ -743,84 +806,6 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } -func (d *Droidstubs) generateCheckCurrentCheckedInApiIsUpToDateBuildRules(ctx android.ModuleContext) { - if len(d.Javadoc.properties.Out) > 0 { - ctx.PropertyErrorf("out", "out property may not be combined with check_api") - } - - apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file)) - removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file)) - baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file) - - if baselineFile.Valid() { - ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName()) - } - - d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "metalava", "check_current_api.timestamp") - - rule := android.NewRuleBuilder(pctx, ctx) - - // Diff command line. - // -F matches the closest "opening" line, such as "package android {" - // and " public class Intent {". - diff := `diff -u -F '{ *$'` - - rule.Command().Text("( true") - rule.Command(). - Text(diff). - Input(apiFile).Input(d.apiFile) - - rule.Command(). - Text(diff). - Input(removedApiFile).Input(d.removedApiFile) - - msg := fmt.Sprintf(`\n******************************\n`+ - `You have tried to change the API from what has been previously approved.\n\n`+ - `To make these errors go away, you have two choices:\n`+ - ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+ - ` to the new methods, etc. shown in the above diff.\n\n`+ - ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+ - ` m %s-update-current-api\n\n`+ - ` To submit the revised current.txt to the main Android repository,\n`+ - ` you will need approval.\n`+ - `******************************\n`, ctx.ModuleName()) - - rule.Command(). - Text("touch").Output(d.checkCurrentApiTimestamp). - Text(") || ("). - Text("echo").Flag("-e").Flag(`"` + msg + `"`). - Text("; exit 38"). - Text(")") - - rule.Build("metalavaCurrentApiCheck", "check current API") - - d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "metalava", "update_current_api.timestamp") - - // update API rule - rule = android.NewRuleBuilder(pctx, ctx) - - rule.Command().Text("( true") - - rule.Command(). - Text("cp").Flag("-f"). - Input(d.apiFile).Flag(apiFile.String()) - - rule.Command(). - Text("cp").Flag("-f"). - Input(d.removedApiFile).Flag(removedApiFile.String()) - - msg = "failed to update public API" - - rule.Command(). - Text("touch").Output(d.updateCurrentApiTimestamp). - Text(") || ("). - Text("echo").Flag("-e").Flag(`"` + msg + `"`). - Text("; exit 38"). - Text(")") - - rule.Build("metalavaCurrentApiUpdate", "update current API") -} - func StubsDefaultsFactory() android.Module { module := &DocDefaults{} diff --git a/java/genrule.go b/java/genrule.go index 5047c412f..208e1f43b 100644 --- a/java/genrule.go +++ b/java/genrule.go @@ -43,23 +43,23 @@ func RegisterGenRuleBuildComponents(ctx android.RegistrationContext) { // // Use a java_genrule to package generated java resources: // -// java_genrule { -// name: "generated_resources", -// tools: [ -// "generator", -// "soong_zip", -// ], -// srcs: ["generator_inputs/**/*"], -// out: ["generated_android_icu4j_resources.jar"], -// cmd: "$(location generator) $(in) -o $(genDir) " + -// "&& $(location soong_zip) -o $(out) -C $(genDir)/res -D $(genDir)/res", -// } +// java_genrule { +// name: "generated_resources", +// tools: [ +// "generator", +// "soong_zip", +// ], +// srcs: ["generator_inputs/**/*"], +// out: ["generated_android_icu4j_resources.jar"], +// cmd: "$(location generator) $(in) -o $(genDir) " + +// "&& $(location soong_zip) -o $(out) -C $(genDir)/res -D $(genDir)/res", +// } // -// java_library { -// name: "lib_with_generated_resources", -// srcs: ["src/**/*.java"], -// static_libs: ["generated_resources"], -// } +// java_library { +// name: "lib_with_generated_resources", +// srcs: ["src/**/*.java"], +// static_libs: ["generated_resources"], +// } func GenRuleFactory() android.Module { module := genrule.NewGenRule() diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index c90b2ff97..7b678037c 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -378,32 +378,37 @@ func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, // with one Java package per line. All members of all classes within that package (but not nested // packages) will be updated in a property specific way. type HiddenAPIFlagFileProperties struct { - // Marks each signature in the referenced files as being unsupported. - Unsupported []string `android:"path"` + Hidden_api struct { + // Marks each signature in the referenced files as being unsupported. + Unsupported []string `android:"path"` - // Marks each signature in the referenced files as being unsupported because it has been removed. - // Any conflicts with other flags are ignored. - Removed []string `android:"path"` + // Marks each signature in the referenced files as being unsupported because it has been + // removed. Any conflicts with other flags are ignored. + Removed []string `android:"path"` - // Marks each signature in the referenced files as being supported only for targetSdkVersion <= R - // and low priority. - Max_target_r_low_priority []string `android:"path"` + // Marks each signature in the referenced files as being supported only for + // targetSdkVersion <= R and low priority. + Max_target_r_low_priority []string `android:"path"` - // Marks each signature in the referenced files as being supported only for targetSdkVersion <= Q. - Max_target_q []string `android:"path"` + // Marks each signature in the referenced files as being supported only for + // targetSdkVersion <= Q. + Max_target_q []string `android:"path"` - // Marks each signature in the referenced files as being supported only for targetSdkVersion <= P. - Max_target_p []string `android:"path"` + // Marks each signature in the referenced files as being supported only for + // targetSdkVersion <= P. + Max_target_p []string `android:"path"` - // Marks each signature in the referenced files as being supported only for targetSdkVersion <= O - // and low priority. Any conflicts with other flags are ignored. - Max_target_o_low_priority []string `android:"path"` + // Marks each signature in the referenced files as being supported only for + // targetSdkVersion <= O + // and low priority. Any conflicts with other flags are ignored. + Max_target_o_low_priority []string `android:"path"` - // Marks each signature in the referenced files as being blocked. - Blocked []string `android:"path"` + // Marks each signature in the referenced files as being blocked. + Blocked []string `android:"path"` - // Marks each signature in every package in the referenced files as being unsupported. - Unsupported_packages []string `android:"path"` + // Marks each signature in every package in the referenced files as being unsupported. + Unsupported_packages []string `android:"path"` + } } type hiddenAPIFlagFileCategory struct { @@ -428,19 +433,30 @@ var hiddenAPIRemovedFlagFileCategory = &hiddenAPIFlagFileCategory{ // See HiddenAPIFlagFileProperties.Removed PropertyName: "removed", propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string { - return properties.Removed + return properties.Hidden_api.Removed }, commandMutator: func(command *android.RuleBuilderCommand, path android.Path) { command.FlagWithInput("--unsupported ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "removed") }, } -var HiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{ +type hiddenAPIFlagFileCategories []*hiddenAPIFlagFileCategory + +func (c hiddenAPIFlagFileCategories) byProperty(name string) *hiddenAPIFlagFileCategory { + for _, category := range c { + if category.PropertyName == name { + return category + } + } + panic(fmt.Errorf("no category exists with property name %q in %v", name, c)) +} + +var HiddenAPIFlagFileCategories = hiddenAPIFlagFileCategories{ // See HiddenAPIFlagFileProperties.Unsupported { PropertyName: "unsupported", propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string { - return properties.Unsupported + return properties.Hidden_api.Unsupported }, commandMutator: func(command *android.RuleBuilderCommand, path android.Path) { command.FlagWithInput("--unsupported ", path) @@ -451,7 +467,7 @@ var HiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{ { PropertyName: "max_target_r_low_priority", propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string { - return properties.Max_target_r_low_priority + return properties.Hidden_api.Max_target_r_low_priority }, commandMutator: func(command *android.RuleBuilderCommand, path android.Path) { command.FlagWithInput("--max-target-r ", path).FlagWithArg("--tag ", "lo-prio") @@ -461,7 +477,7 @@ var HiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{ { PropertyName: "max_target_q", propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string { - return properties.Max_target_q + return properties.Hidden_api.Max_target_q }, commandMutator: func(command *android.RuleBuilderCommand, path android.Path) { command.FlagWithInput("--max-target-q ", path) @@ -471,7 +487,7 @@ var HiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{ { PropertyName: "max_target_p", propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string { - return properties.Max_target_p + return properties.Hidden_api.Max_target_p }, commandMutator: func(command *android.RuleBuilderCommand, path android.Path) { command.FlagWithInput("--max-target-p ", path) @@ -481,7 +497,7 @@ var HiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{ { PropertyName: "max_target_o_low_priority", propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string { - return properties.Max_target_o_low_priority + return properties.Hidden_api.Max_target_o_low_priority }, commandMutator: func(command *android.RuleBuilderCommand, path android.Path) { command.FlagWithInput("--max-target-o ", path).Flag("--ignore-conflicts ").FlagWithArg("--tag ", "lo-prio") @@ -491,7 +507,7 @@ var HiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{ { PropertyName: "blocked", propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string { - return properties.Blocked + return properties.Hidden_api.Blocked }, commandMutator: func(command *android.RuleBuilderCommand, path android.Path) { command.FlagWithInput("--blocked ", path) @@ -501,7 +517,7 @@ var HiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{ { PropertyName: "unsupported_packages", propertyValueReader: func(properties *HiddenAPIFlagFileProperties) []string { - return properties.Unsupported_packages + return properties.Hidden_api.Unsupported_packages }, commandMutator: func(command *android.RuleBuilderCommand, path android.Path) { command.FlagWithInput("--unsupported ", path).Flag("--packages ") @@ -512,13 +528,20 @@ var HiddenAPIFlagFileCategories = []*hiddenAPIFlagFileCategory{ // FlagFilesByCategory maps a hiddenAPIFlagFileCategory to the paths to the files in that category. type FlagFilesByCategory map[*hiddenAPIFlagFileCategory]android.Paths -// append appends the supplied flags files to the corresponding category in this map. +// append the supplied flags files to the corresponding category in this map. func (s FlagFilesByCategory) append(other FlagFilesByCategory) { for _, category := range HiddenAPIFlagFileCategories { s[category] = append(s[category], other[category]...) } } +// sort the paths for each category in this map. +func (s FlagFilesByCategory) sort() { + for category, value := range s { + s[category] = android.SortedUniquePaths(value) + } +} + // HiddenAPIInfo contains information provided by the hidden API processing. // // That includes paths resolved from HiddenAPIFlagFileProperties and also generated by hidden API @@ -686,13 +709,70 @@ func (s StubDexJarsByModule) StubDexJarsForScope(scope *HiddenAPIScope) android. return stubDexJars } -// HiddenAPIFlagInput encapsulates information obtained from a module and its dependencies that are -// needed for hidden API flag generation. -type HiddenAPIFlagInput struct { +type HiddenAPIPropertyInfo struct { // FlagFilesByCategory contains the flag files that override the initial flags that are derived // from the stub dex files. FlagFilesByCategory FlagFilesByCategory + // See HiddenAPIFlagFileProperties.Package_prefixes + PackagePrefixes []string + + // See HiddenAPIFlagFileProperties.Single_packages + SinglePackages []string + + // See HiddenAPIFlagFileProperties.Split_packages + SplitPackages []string +} + +var hiddenAPIPropertyInfoProvider = blueprint.NewProvider(HiddenAPIPropertyInfo{}) + +// newHiddenAPIPropertyInfo creates a new initialized HiddenAPIPropertyInfo struct. +func newHiddenAPIPropertyInfo() HiddenAPIPropertyInfo { + return HiddenAPIPropertyInfo{ + FlagFilesByCategory: FlagFilesByCategory{}, + } +} + +// extractFlagFilesFromProperties extracts the paths to flag files that are specified in the +// supplied properties and stores them in this struct. +func (i *HiddenAPIPropertyInfo) extractFlagFilesFromProperties(ctx android.ModuleContext, p *HiddenAPIFlagFileProperties) { + for _, category := range HiddenAPIFlagFileCategories { + paths := android.PathsForModuleSrc(ctx, category.propertyValueReader(p)) + i.FlagFilesByCategory[category] = paths + } +} + +// extractPackageRulesFromProperties extracts the package rules that are specified in the supplied +// properties and stores them in this struct. +func (i *HiddenAPIPropertyInfo) extractPackageRulesFromProperties(p *HiddenAPIPackageProperties) { + i.PackagePrefixes = p.Hidden_api.Package_prefixes + i.SinglePackages = p.Hidden_api.Single_packages + i.SplitPackages = p.Hidden_api.Split_packages +} + +func (i *HiddenAPIPropertyInfo) gatherPropertyInfo(ctx android.ModuleContext, contents []android.Module) { + for _, module := range contents { + if ctx.OtherModuleHasProvider(module, hiddenAPIPropertyInfoProvider) { + info := ctx.OtherModuleProvider(module, hiddenAPIPropertyInfoProvider).(HiddenAPIPropertyInfo) + i.FlagFilesByCategory.append(info.FlagFilesByCategory) + i.PackagePrefixes = append(i.PackagePrefixes, info.PackagePrefixes...) + i.SinglePackages = append(i.SinglePackages, info.SinglePackages...) + i.SplitPackages = append(i.SplitPackages, info.SplitPackages...) + } + } + + // Dedup and sort the information to ensure consistent builds. + i.FlagFilesByCategory.sort() + i.PackagePrefixes = android.SortedUniqueStrings(i.PackagePrefixes) + i.SinglePackages = android.SortedUniqueStrings(i.SinglePackages) + i.SplitPackages = android.SortedUniqueStrings(i.SplitPackages) +} + +// HiddenAPIFlagInput encapsulates information obtained from a module and its dependencies that are +// needed for hidden API flag generation. +type HiddenAPIFlagInput struct { + HiddenAPIPropertyInfo + // StubDexJarsByScope contains the stub dex jars for different *HiddenAPIScope and which determine // the initial flags for each dex member. StubDexJarsByScope StubDexJarsByModule @@ -714,10 +794,10 @@ type HiddenAPIFlagInput struct { RemovedTxtFiles android.Paths } -// newHiddenAPIFlagInput creates a new initialize HiddenAPIFlagInput struct. +// newHiddenAPIFlagInput creates a new initialized HiddenAPIFlagInput struct. func newHiddenAPIFlagInput() HiddenAPIFlagInput { input := HiddenAPIFlagInput{ - FlagFilesByCategory: FlagFilesByCategory{}, + HiddenAPIPropertyInfo: newHiddenAPIPropertyInfo(), StubDexJarsByScope: StubDexJarsByModule{}, DependencyStubDexJarsByScope: StubDexJarsByModule{}, AdditionalStubDexJarsByScope: StubDexJarsByModule{}, @@ -773,15 +853,6 @@ func (i *HiddenAPIFlagInput) gatherStubLibInfo(ctx android.ModuleContext, conten i.RemovedTxtFiles = android.SortedUniquePaths(i.RemovedTxtFiles) } -// extractFlagFilesFromProperties extracts the paths to flag files that are specified in the -// supplied properties and stores them in this struct. -func (i *HiddenAPIFlagInput) extractFlagFilesFromProperties(ctx android.ModuleContext, p *HiddenAPIFlagFileProperties) { - for _, category := range HiddenAPIFlagFileCategories { - paths := android.PathsForModuleSrc(ctx, category.propertyValueReader(p)) - i.FlagFilesByCategory[category] = paths - } -} - func (i *HiddenAPIFlagInput) transitiveStubDexJarsByScope() StubDexJarsByModule { transitive := i.DependencyStubDexJarsByScope transitive.addStubDexJarsByModule(i.StubDexJarsByScope) diff --git a/java/java.go b/java/java.go index 77ab40279..210b883e1 100644 --- a/java/java.go +++ b/java/java.go @@ -629,6 +629,9 @@ func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer } func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { + + j.provideHiddenAPIPropertyInfo(ctx) + j.sdkVersion = j.SdkVersion(ctx) j.minSdkVersion = j.MinSdkVersion(ctx) j.maxSdkVersion = j.MaxSdkVersion(ctx) @@ -852,11 +855,10 @@ func LibraryHostFactory() android.Module { // Test option struct. type TestOptions struct { + android.CommonTestOptions + // a list of extra test configuration files that should be installed with the module. Extra_test_configs []string `android:"path,arch_variant"` - - // If the test is a hostside(no device required) unittest that shall be run during presubmit check. - Unit_test *bool } type testProperties struct { diff --git a/java/java_test.go b/java/java_test.go index 9e5cf0cf2..bfd97eb0d 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1287,6 +1287,41 @@ func TestAidlExportIncludeDirsFromImports(t *testing.T) { } } +func TestAidlIncludeDirFromConvertedFileGroupWithPathPropInMixedBuilds(t *testing.T) { + bp := ` + filegroup { + name: "foo_aidl", + srcs: ["aidl/foo/IFoo.aidl"], + path: "aidl/foo", + bazel_module: { label: "//:foo_aidl" }, + } + java_library { + name: "foo", + srcs: [":foo_aidl"], + } +` + + outBaseDir := "out/bazel/output" + result := android.GroupFixturePreparers( + prepareForJavaTest, + android.PrepareForTestWithFilegroup, + android.FixtureModifyConfig(func(config android.Config) { + config.BazelContext = android.MockBazelContext{ + OutputBaseDir: outBaseDir, + LabelToOutputFiles: map[string][]string{ + "//:foo_aidl": []string{"aidl/foo/IFoo.aidl"}, + }, + } + }), + ).RunTestWithBp(t, bp) + + aidlCommand := result.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command + expectedAidlFlag := "-I" + outBaseDir + "/execroot/__main__/aidl/foo" + if !strings.Contains(aidlCommand, expectedAidlFlag) { + t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) + } +} + func TestAidlFlagsArePassedToTheAidlCompiler(t *testing.T) { ctx, _ := testJava(t, ` java_library { diff --git a/java/lint.go b/java/lint.go index 67746204e..931820d74 100644 --- a/java/lint.go +++ b/java/lint.go @@ -331,12 +331,18 @@ func (l *linter) lint(ctx android.ModuleContext) { if l.minSdkVersion != l.compileSdkVersion { l.extraMainlineLintErrors = append(l.extraMainlineLintErrors, updatabilityChecks...) - _, filtered := android.FilterList(l.properties.Lint.Warning_checks, updatabilityChecks) - if len(filtered) != 0 { - ctx.PropertyErrorf("lint.warning_checks", - "Can't treat %v checks as warnings if min_sdk_version is different from sdk_version.", filtered) + // Skip lint warning checks for NewApi warnings for libcore where they come from source + // files that reference the API they are adding (b/208656169). + if ctx.ModuleDir() != "libcore" { + _, filtered := android.FilterList(l.properties.Lint.Warning_checks, updatabilityChecks) + + if len(filtered) != 0 { + ctx.PropertyErrorf("lint.warning_checks", + "Can't treat %v checks as warnings if min_sdk_version is different from sdk_version.", filtered) + } } - _, filtered = android.FilterList(l.properties.Lint.Disabled_checks, updatabilityChecks) + + _, filtered := android.FilterList(l.properties.Lint.Disabled_checks, updatabilityChecks) if len(filtered) != 0 { ctx.PropertyErrorf("lint.disabled_checks", "Can't disable %v checks if min_sdk_version is different from sdk_version.", filtered) diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index 1e2723845..24f8253ae 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -62,7 +62,7 @@ type platformBootclasspathModule struct { type platformBootclasspathProperties struct { BootclasspathFragmentsDepsProperties - Hidden_api HiddenAPIFlagFileProperties + HiddenAPIFlagFileProperties } func platformBootclasspathFactory() android.SingletonModule { @@ -372,7 +372,7 @@ func (b *platformBootclasspathModule) createAndProvideMonolithicHiddenAPIInfo(ct temporaryInput := newHiddenAPIFlagInput() // Create paths to the flag files specified in the properties. - temporaryInput.extractFlagFilesFromProperties(ctx, &b.properties.Hidden_api) + temporaryInput.extractFlagFilesFromProperties(ctx, &b.properties.HiddenAPIFlagFileProperties) // Create the monolithic info, by starting with the flag files specified on this and then merging // in information from all the fragment dependencies of this. diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go index 1c4249507..655021fc4 100644 --- a/java/platform_compat_config.go +++ b/java/platform_compat_config.go @@ -280,7 +280,7 @@ func platformCompatConfigSingletonFactory() android.Singleton { return &platformCompatConfigSingleton{} } -//============== merged_compat_config ================= +// ============== merged_compat_config ================= type globalCompatConfigProperties struct { // name of the file into which the metadata will be copied. Filename *string diff --git a/java/sdk_library.go b/java/sdk_library.go index 490c03132..8f499b101 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -2129,11 +2129,12 @@ var _ SdkLibraryDependency = (*SdkLibraryImport)(nil) // The type of a structure that contains a field of type sdkLibraryScopeProperties // for each apiscope in allApiScopes, e.g. something like: -// struct { -// Public sdkLibraryScopeProperties -// System sdkLibraryScopeProperties -// ... -// } +// +// struct { +// Public sdkLibraryScopeProperties +// System sdkLibraryScopeProperties +// ... +// } var allScopeStructType = createAllScopePropertiesStructType() // Dynamically create a structure type for each apiscope in allApiScopes. @@ -2556,9 +2557,7 @@ func (module *SdkLibraryImport) RequiredFilesFromPrebuiltApex(ctx android.BaseMo return requiredFilesFromPrebuiltApexForImport(name) } -// // java_sdk_library_xml -// type sdkLibraryXml struct { android.ModuleBase android.DefaultableModuleBase diff --git a/java/sdk_library_external.go b/java/sdk_library_external.go index 0acaa13b2..4f8398194 100644 --- a/java/sdk_library_external.go +++ b/java/sdk_library_external.go @@ -49,9 +49,10 @@ func (g partitionGroup) String() string { // Get partition group of java module that can be used at inter-partition dependency check. // We currently have three groups -// (system, system_ext) => system partition group -// (vendor, odm) => vendor partition group -// (product) => product partition group +// +// (system, system_ext) => system partition group +// (vendor, odm) => vendor partition group +// (product) => product partition group func (j *Module) partitionGroup(ctx android.EarlyModuleContext) partitionGroup { // system and system_ext partition can be treated as the same in terms of inter-partition dependency. if j.Platform() || j.SystemExtSpecific() { diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go index 2707f0c5e..aa48e6377 100644 --- a/mk2rbc/mk2rbc.go +++ b/mk2rbc/mk2rbc.go @@ -14,13 +14,13 @@ // Convert makefile containing device configuration to Starlark file // The conversion can handle the following constructs in a makefile: -// * comments -// * simple variable assignments -// * $(call init-product,<file>) -// * $(call inherit-product-if-exists -// * if directives -// All other constructs are carried over to the output starlark file as comments. +// - comments +// - simple variable assignments +// - $(call init-product,<file>) +// - $(call inherit-product-if-exists +// - if directives // +// All other constructs are carried over to the output starlark file as comments. package mk2rbc import ( diff --git a/mk2rbc/soong_variables.go b/mk2rbc/soong_variables.go index de4692528..a52ec4f2a 100644 --- a/mk2rbc/soong_variables.go +++ b/mk2rbc/soong_variables.go @@ -32,8 +32,8 @@ type context struct { // Scans the makefile Soong uses to generate soong.variables file, // collecting variable names and types from the lines that look like this: -// $(call add_json_XXX, <...>, $(VAR)) // +// $(call add_json_XXX, <...>, $(VAR)) func FindSoongVariables(mkFile string, includeFileScope mkparser.Scope, registrar variableRegistrar) error { ctx := context{includeFileScope, registrar} return ctx.doFind(mkFile) diff --git a/python/androidmk.go b/python/androidmk.go index 233d8679f..7dc471397 100644 --- a/python/androidmk.go +++ b/python/androidmk.go @@ -69,7 +69,7 @@ func (p *testDecorator) AndroidMk(base *Module, entries *android.AndroidMkEntrie entries.AddStrings("LOCAL_TEST_DATA", android.AndroidMkDataPaths(p.data)...) - entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(p.testProperties.Test_options.Unit_test)) + p.testProperties.Test_options.SetAndroidMkEntries(entries) }) base.subAndroidMk(entries, p.binaryDecorator.pythonInstaller) } diff --git a/python/python.go b/python/python.go index eb0d3cad0..836416947 100644 --- a/python/python.go +++ b/python/python.go @@ -438,9 +438,9 @@ func (p *Module) anySrcHasExt(ctx android.BottomUpMutatorContext, ext string) bo } // DepsMutator mutates dependencies for this module: -// * handles proto dependencies, -// * if required, specifies launcher and adds launcher dependencies, -// * applies python version mutations to Python dependencies +// - handles proto dependencies, +// - if required, specifies launcher and adds launcher dependencies, +// - applies python version mutations to Python dependencies func (p *Module) DepsMutator(ctx android.BottomUpMutatorContext) { android.ProtoDeps(ctx, &p.protoProperties) diff --git a/python/test.go b/python/test.go index 7413782cb..b9b346549 100644 --- a/python/test.go +++ b/python/test.go @@ -32,12 +32,6 @@ func registerPythonTestComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("python_test", PythonTestFactory) } -// Test option struct. -type TestOptions struct { - // If the test is a hostside(no device required) unittest that shall be run during presubmit check. - Unit_test *bool -} - type TestProperties struct { // the name of the test configuration (for example "AndroidTest.xml") that should be // installed with the module. @@ -55,7 +49,7 @@ type TestProperties struct { Java_data []string // Test options. - Test_options TestOptions + Test_options android.CommonTestOptions } type testDecorator struct { diff --git a/rust/androidmk.go b/rust/androidmk.go index 2361e0377..32c746ed4 100644 --- a/rust/androidmk.go +++ b/rust/androidmk.go @@ -105,10 +105,11 @@ func (test *testDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidM entries.SetString("LOCAL_FULL_TEST_CONFIG", test.testConfig.String()) } entries.SetBoolIfTrue("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", !BoolDefault(test.Properties.Auto_gen_config, true)) - entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(test.Properties.Test_options.Unit_test)) if test.Properties.Data_bins != nil { entries.AddStrings("LOCAL_TEST_DATA_BINS", test.Properties.Data_bins...) } + + test.Properties.Test_options.SetAndroidMkEntries(entries) }) cc.AndroidMkWriteTestData(test.data, ret) diff --git a/rust/test.go b/rust/test.go index 6e5393595..0cc3bca6e 100644 --- a/rust/test.go +++ b/rust/test.go @@ -24,12 +24,6 @@ import ( "android/soong/tradefed" ) -// Test option struct. -type TestOptions struct { - // If the test is a hostside(no device required) unittest that shall be run during presubmit check. - Unit_test *bool -} - type TestProperties struct { // Disables the creation of a test-specific directory when used with // relative_install_path. Useful if several tests need to be in the same @@ -67,7 +61,7 @@ type TestProperties struct { Test_harness *bool // Test options. - Test_options TestOptions + Test_options android.CommonTestOptions // Add RootTargetPreparer to auto generated test config. This guarantees the test to run // with root permission. diff --git a/scripts/build_broken_logs.go b/scripts/build_broken_logs.go index 82ba7491e..bb4b9fdd9 100644 --- a/scripts/build_broken_logs.go +++ b/scripts/build_broken_logs.go @@ -19,12 +19,12 @@ // To use, download the logs.zip from one or more branches, and extract them // into subdirectories of the current directory. So for example, I have: // -// ./aosp-master/aosp_arm/std_full.log -// ./aosp-master/aosp_arm64/std_full.log -// ./aosp-master/... -// ./internal-master/aosp_arm/std_full.log -// ./internal-master/aosp_arm64/std_full.log -// ./internal-master/... +// ./aosp-master/aosp_arm/std_full.log +// ./aosp-master/aosp_arm64/std_full.log +// ./aosp-master/... +// ./internal-master/aosp_arm/std_full.log +// ./internal-master/aosp_arm64/std_full.log +// ./internal-master/... // // Then I use `go run path/to/build_broken_logs.go *` package main diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go index 13ddbe768..c93055a51 100644 --- a/sdk/bootclasspath_fragment_sdk_test.go +++ b/sdk/bootclasspath_fragment_sdk_test.go @@ -675,8 +675,8 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) { prepareForSdkTestWithJava, java.PrepareForTestWithJavaDefaultModules, java.PrepareForTestWithJavaSdkLibraryFiles, - java.FixtureWithLastReleaseApis("mysdklibrary"), - java.FixtureConfigureApexBootJars("myapex:mybootlib"), + java.FixtureWithLastReleaseApis("mysdklibrary", "mynewlibrary"), + java.FixtureConfigureApexBootJars("myapex:mybootlib", "myapex:mynewlibrary"), prepareForSdkTestWithApex, // Add a platform_bootclasspath that depends on the fragment. @@ -691,6 +691,7 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) { "my-removed.txt": nil, "my-unsupported-packages.txt": nil, "my-unsupported.txt": nil, + "my-new-max-target-q.txt": nil, }.AddToFixture(), android.FixtureWithRootAndroidBp(` sdk { @@ -708,7 +709,7 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) { bootclasspath_fragment { name: "mybootclasspathfragment", apex_available: ["myapex"], - contents: ["mybootlib"], + contents: ["mybootlib", "mynewlibrary"], api: { stub_libs: ["mysdklibrary"], }, @@ -737,7 +738,9 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) { unsupported_packages: [ "my-unsupported-packages.txt", ], - split_packages: ["*"], + split_packages: ["sdklibrary"], + package_prefixes: ["sdklibrary.all.mine"], + single_packages: ["sdklibrary.mine"], }, } @@ -759,6 +762,24 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) { public: {enabled: true}, permitted_packages: ["mysdklibrary"], } + + java_sdk_library { + name: "mynewlibrary", + apex_available: ["myapex"], + srcs: ["Test.java"], + min_sdk_version: "10", + compile_dex: true, + public: {enabled: true}, + permitted_packages: ["mysdklibrary"], + hidden_api: { + max_target_q: [ + "my-new-max-target-q.txt", + ], + split_packages: ["sdklibrary", "newlibrary"], + package_prefixes: ["newlibrary.all.mine"], + single_packages: ["newlibrary.mine"], + }, + } `), ).RunTest(t) @@ -774,7 +795,10 @@ prebuilt_bootclasspath_fragment { prefer: false, visibility: ["//visibility:public"], apex_available: ["myapex"], - contents: ["mybootlib"], + contents: [ + "mybootlib", + "mynewlibrary", + ], api: { stub_libs: ["mysdklibrary"], }, @@ -782,7 +806,10 @@ prebuilt_bootclasspath_fragment { unsupported: ["hiddenapi/my-unsupported.txt"], removed: ["hiddenapi/my-removed.txt"], max_target_r_low_priority: ["hiddenapi/my-max-target-r-low-priority.txt"], - max_target_q: ["hiddenapi/my-max-target-q.txt"], + max_target_q: [ + "hiddenapi/my-max-target-q.txt", + "hiddenapi/my-new-max-target-q.txt", + ], max_target_p: ["hiddenapi/my-max-target-p.txt"], max_target_o_low_priority: ["hiddenapi/my-max-target-o-low-priority.txt"], blocked: ["hiddenapi/my-blocked.txt"], @@ -806,6 +833,23 @@ java_import { } java_sdk_library_import { + name: "mynewlibrary", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["myapex"], + shared_library: true, + compile_dex: true, + permitted_packages: ["mysdklibrary"], + public: { + jars: ["sdk_library/public/mynewlibrary-stubs.jar"], + stub_srcs: ["sdk_library/public/mynewlibrary_stub_sources"], + current_api: "sdk_library/public/mynewlibrary.txt", + removed_api: "sdk_library/public/mynewlibrary-removed.txt", + sdk_version: "current", + }, +} + +java_sdk_library_import { name: "mysdklibrary", prefer: false, visibility: ["//visibility:public"], @@ -827,6 +871,7 @@ my-unsupported.txt -> hiddenapi/my-unsupported.txt my-removed.txt -> hiddenapi/my-removed.txt my-max-target-r-low-priority.txt -> hiddenapi/my-max-target-r-low-priority.txt my-max-target-q.txt -> hiddenapi/my-max-target-q.txt +my-new-max-target-q.txt -> hiddenapi/my-new-max-target-q.txt my-max-target-p.txt -> hiddenapi/my-max-target-p.txt my-max-target-o-low-priority.txt -> hiddenapi/my-max-target-o-low-priority.txt my-blocked.txt -> hiddenapi/my-blocked.txt @@ -838,6 +883,9 @@ my-unsupported-packages.txt -> hiddenapi/my-unsupported-packages.txt .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv .intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar +.intermediates/mynewlibrary.stubs/android_common/javac/mynewlibrary.stubs.jar -> sdk_library/public/mynewlibrary-stubs.jar +.intermediates/mynewlibrary.stubs.source/android_common/metalava/mynewlibrary.stubs.source_api.txt -> sdk_library/public/mynewlibrary.txt +.intermediates/mynewlibrary.stubs.source/android_common/metalava/mynewlibrary.stubs.source_removed.txt -> sdk_library/public/mynewlibrary-removed.txt .intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar .intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt .intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt diff --git a/sdk/build_release.go b/sdk/build_release.go index 0494a28ee..ac57a3279 100644 --- a/sdk/build_release.go +++ b/sdk/build_release.go @@ -16,6 +16,7 @@ package sdk import ( "fmt" + "math" "reflect" "strings" ) @@ -29,7 +30,10 @@ type buildRelease struct { // The name of the release, e.g. S, Tiramisu, etc. name string - // The index of this structure within the buildReleases list. + // The index of this structure within the dessertBuildReleases list. + // + // The buildReleaseCurrent does not appear in the dessertBuildReleases list as it has an ordinal value + // that is larger than the size of the dessertBuildReleases. ordinal int } @@ -56,7 +60,7 @@ func (s *buildReleaseSet) addItem(release *buildRelease) { // addRange adds all the build releases from start (inclusive) to end (inclusive). func (s *buildReleaseSet) addRange(start *buildRelease, end *buildRelease) { for i := start.ordinal; i <= end.ordinal; i += 1 { - s.addItem(buildReleases[i]) + s.addItem(dessertBuildReleases[i]) } } @@ -69,11 +73,17 @@ func (s *buildReleaseSet) contains(release *buildRelease) bool { // String returns a string representation of the set, sorted from earliest to latest release. func (s *buildReleaseSet) String() string { list := []string{} - for _, release := range buildReleases { + addRelease := func(release *buildRelease) { if _, ok := s.contents[release]; ok { list = append(list, release.name) } } + // Add the names of the build releases in this set in the order in which they were created. + for _, release := range dessertBuildReleases { + addRelease(release) + } + // Always add "current" to the list of names last if it is present in the set. + addRelease(buildReleaseCurrent) return fmt.Sprintf("[%s]", strings.Join(list, ",")) } @@ -81,30 +91,46 @@ var ( // nameToBuildRelease contains a map from name to build release. nameToBuildRelease = map[string]*buildRelease{} - // buildReleases lists all the available build releases. - buildReleases = []*buildRelease{} + // dessertBuildReleases lists all the available dessert build releases, i.e. excluding current. + dessertBuildReleases = []*buildRelease{} // allBuildReleaseSet is the set of all build releases. allBuildReleaseSet = &buildReleaseSet{contents: map[*buildRelease]struct{}{}} - // Add the build releases from oldest to newest. + // Add the dessert build releases from oldest to newest. buildReleaseS = initBuildRelease("S") buildReleaseT = initBuildRelease("Tiramisu") + + // Add the current build release which is always treated as being more recent than any other + // build release, including those added in tests. + buildReleaseCurrent = initBuildRelease("current") ) // initBuildRelease creates a new build release with the specified name. func initBuildRelease(name string) *buildRelease { - ordinal := len(nameToBuildRelease) + ordinal := len(dessertBuildReleases) + if name == "current" { + // The current build release is more recent than all other build releases, including those + // created in tests so use the max int value. It cannot just rely on being created after all + // the other build releases as some are created in tests which run after the current build + // release has been created. + ordinal = math.MaxInt + } release := &buildRelease{name: name, ordinal: ordinal} nameToBuildRelease[name] = release - buildReleases = append(buildReleases, release) allBuildReleaseSet.addItem(release) + if name != "current" { + // As the current build release has an ordinal value that does not correspond to its position + // in the dessertBuildReleases list do not add it to the list. + dessertBuildReleases = append(dessertBuildReleases, release) + } return release } -// latestBuildRelease returns the latest build release, i.e. the last one added. -func latestBuildRelease() *buildRelease { - return buildReleases[len(buildReleases)-1] +// latestDessertBuildRelease returns the latest dessert release build name, i.e. the last dessert +// release added to the list, which does not include current. +func latestDessertBuildRelease() *buildRelease { + return dessertBuildReleases[len(dessertBuildReleases)-1] } // nameToRelease maps from build release name to the corresponding build release (if it exists) or @@ -134,8 +160,10 @@ func parseBuildReleaseSet(specification string) (*buildReleaseSet, error) { if err != nil { return nil, err } - end := latestBuildRelease() + end := latestDessertBuildRelease() set.addRange(start, end) + // An open-ended range always includes the current release. + set.addItem(buildReleaseCurrent) } else if strings.Contains(specification, "-") { limits := strings.SplitN(specification, "-", 2) start, err := nameToRelease(limits[0]) @@ -369,7 +397,9 @@ func newPropertyPrunerForStructType(structType reflect.Type, selector fieldSelec // structure which are not supported by the specified target build release. // // A property is pruned if its field has a tag of the form: -// `supported_build_releases:"<build-release-set>"` +// +// `supported_build_releases:"<build-release-set>"` +// // and the resulting build release set does not contain the target build release. Properties that // have no such tag are assumed to be supported by all releases. func newPropertyPrunerByBuildRelease(propertiesStruct interface{}, targetBuildRelease *buildRelease) *propertyPruner { diff --git a/sdk/build_release_test.go b/sdk/build_release_test.go index 6f1ef9e30..13730cbca 100644 --- a/sdk/build_release_test.go +++ b/sdk/build_release_test.go @@ -42,7 +42,7 @@ func TestNameToRelease(t *testing.T) { android.AssertDeepEquals(t, "release", (*buildRelease)(nil), release) // Uses a wildcard in the error message to allow for additional build releases to be added to // the supported set without breaking this test. - android.FailIfNoMatchingErrors(t, `unknown release "A", expected one of \[S,T.*,F1,F2\]`, []error{err}) + android.FailIfNoMatchingErrors(t, `unknown release "A", expected one of \[S,Tiramisu,F1,F2,current\]`, []error{err}) }) } @@ -55,7 +55,7 @@ func TestParseBuildReleaseSet(t *testing.T) { t.Run("open range", func(t *testing.T) { set, err := parseBuildReleaseSet("F1+") android.AssertDeepEquals(t, "errors", nil, err) - android.AssertStringEquals(t, "set", "[F1,F2]", set.String()) + android.AssertStringEquals(t, "set", "[F1,F2,current]", set.String()) }) t.Run("closed range", func(t *testing.T) { set, err := parseBuildReleaseSet("S-F1") diff --git a/sdk/member_trait.go b/sdk/member_trait.go index 4229ca82b..0843306a8 100644 --- a/sdk/member_trait.go +++ b/sdk/member_trait.go @@ -68,7 +68,6 @@ func getDynamicSdkMemberTraits(key android.OnceKey, registeredTraits []android.S // A list of sdkMemberTraitListProperty instances is created, one per member trait that provides: // * a reference to the member trait. // * a getter for the corresponding field in the properties struct. -// func createDynamicSdkMemberTraits(sdkMemberTraits []android.SdkMemberTrait) *dynamicSdkMemberTraits { var listProperties []*sdkMemberTraitListProperty diff --git a/sdk/member_type.go b/sdk/member_type.go index 10669fe23..98f59820b 100644 --- a/sdk/member_type.go +++ b/sdk/member_type.go @@ -80,7 +80,6 @@ func getDynamicSdkMemberTypes(key android.OnceKey, registeredTypes []android.Sdk // * a reference to the member type. // * a getter for the corresponding field in the properties struct. // * a dependency tag that identifies the member type of a resolved dependency. -// func createDynamicSdkMemberTypes(sdkMemberTypes []android.SdkMemberType) *dynamicSdkMemberTypes { var listProperties []*sdkMemberTypeListProperty diff --git a/sdk/testing.go b/sdk/testing.go index bed11b27d..f4e2b031b 100644 --- a/sdk/testing.go +++ b/sdk/testing.go @@ -262,8 +262,7 @@ func CheckSnapshot(t *testing.T, result *android.TestResult, name string, dir st // If the generated snapshot builders not for the current release then it cannot be loaded by // the current release. - currentBuildRelease := latestBuildRelease() - if snapshotBuildInfo.targetBuildRelease != currentBuildRelease { + if snapshotBuildInfo.targetBuildRelease != buildReleaseCurrent { return } diff --git a/sdk/update.go b/sdk/update.go index c555ddc7a..5c9376b5d 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -387,12 +387,11 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) { // Always add -current to the end snapshotFileSuffix := "-current" - currentBuildRelease := latestBuildRelease() - targetBuildReleaseEnv := config.GetenvWithDefault("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE", currentBuildRelease.name) + targetBuildReleaseEnv := config.GetenvWithDefault("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE", buildReleaseCurrent.name) targetBuildRelease, err := nameToRelease(targetBuildReleaseEnv) if err != nil { ctx.ModuleErrorf("invalid SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE: %s", err) - targetBuildRelease = currentBuildRelease + targetBuildRelease = buildReleaseCurrent } builder := &snapshotBuilder{ @@ -472,7 +471,7 @@ be unnecessary as every module in the sdk already has its own licenses property. contents := bp.content.String() // If the snapshot is being generated for the current build release then check the syntax to make // sure that it is compatible. - if targetBuildRelease == currentBuildRelease { + if targetBuildRelease == buildReleaseCurrent { syntaxCheckSnapshotBpFile(ctx, contents) } diff --git a/sh/sh_binary.go b/sh/sh_binary.go index 4de01443d..96273297a 100644 --- a/sh/sh_binary.go +++ b/sh/sh_binary.go @@ -103,12 +103,6 @@ type shBinaryProperties struct { Recovery_available *bool } -// Test option struct. -type TestOptions struct { - // If the test is a hostside(no device required) unittest that shall be run during presubmit check. - Unit_test *bool -} - type TestProperties struct { // list of compatibility suites (for example "cts", "vts") that the module should be // installed into. @@ -153,7 +147,7 @@ type TestProperties struct { Per_testcase_directory *bool // Test options. - Test_options TestOptions + Test_options android.CommonTestOptions } type ShBinary struct { @@ -464,10 +458,9 @@ func (s *ShTest) AndroidMkEntries() []android.AndroidMkEntries { if s.testProperties.Data_bins != nil { entries.AddStrings("LOCAL_TEST_DATA_BINS", s.testProperties.Data_bins...) } - if Bool(s.testProperties.Test_options.Unit_test) { - entries.SetBool("LOCAL_IS_UNIT_TEST", true) - } entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", Bool(s.testProperties.Per_testcase_directory)) + + s.testProperties.Test_options.SetAndroidMkEntries(entries) }, }, }} diff --git a/shared/env.go b/shared/env.go index 152729ba0..b7d3bafb4 100644 --- a/shared/env.go +++ b/shared/env.go @@ -32,10 +32,11 @@ type envFileData []envFileEntry // // e.g. OUT_DIR = "out" // is converted to: -// { -// "Key": "OUT_DIR", -// "Value": "out", -// }, +// +// { +// "Key": "OUT_DIR", +// "Value": "out", +// }, func EnvFileContents(envDeps map[string]string) ([]byte, error) { contents := make(envFileData, 0, len(envDeps)) for key, value := range envDeps { diff --git a/snapshot/recovery_snapshot.go b/snapshot/recovery_snapshot.go index f1e31ca03..ac002be9c 100644 --- a/snapshot/recovery_snapshot.go +++ b/snapshot/recovery_snapshot.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/snapshot/snapshot.go b/snapshot/snapshot.go index 294f8b611..206ecc947 100644 --- a/snapshot/snapshot.go +++ b/snapshot/snapshot.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/snapshot/snapshot_base.go b/snapshot/snapshot_base.go index 4a14f2e03..8e5dfe4a2 100644 --- a/snapshot/snapshot_base.go +++ b/snapshot/snapshot_base.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/snapshot/util.go b/snapshot/util.go index f44705227..806ac90fa 100644 --- a/snapshot/util.go +++ b/snapshot/util.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/snapshot/vendor_snapshot.go b/snapshot/vendor_snapshot.go index 9bd26c201..8f7b8c215 100644 --- a/snapshot/vendor_snapshot.go +++ b/snapshot/vendor_snapshot.go @@ -4,7 +4,7 @@ // 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 +// 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, diff --git a/third_party/zip/reader_test.go b/third_party/zip/reader_test.go index 11c6d6e66..5f97f5c5f 100644 --- a/third_party/zip/reader_test.go +++ b/third_party/zip/reader_test.go @@ -615,7 +615,6 @@ func returnRecursiveZip() (r io.ReaderAt, size int64) { // // It's here in hex for the same reason as rZipBytes above: to avoid // problems with on-disk virus scanners or other zip processors. -// func biggestZipBytes() []byte { s := ` 0000000 50 4b 03 04 14 00 08 00 08 00 00 00 00 00 00 00 diff --git a/ui/build/soong.go b/ui/build/soong.go index 29c3b65c9..519506ed0 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -22,6 +22,7 @@ import ( "os" "path/filepath" "strconv" + "strings" "android/soong/ui/metrics" soong_metrics_proto "android/soong/ui/metrics/metrics_proto" @@ -445,6 +446,11 @@ func runSoong(ctx Context, config Config) { "-f", filepath.Join(config.SoongOutDir(), ninjaFile), } + if extra, ok := config.Environment().Get("SOONG_UI_NINJA_ARGS"); ok { + ctx.Printf(`CAUTION: arguments in $SOONG_UI_NINJA_ARGS=%q, e.g. "-n", can make soong_build FAIL or INCORRECT`, extra) + ninjaArgs = append(ninjaArgs, strings.Fields(extra)...) + } + ninjaArgs = append(ninjaArgs, targets...) cmd := Command(ctx, config, "soong "+name, config.PrebuiltBuildTool("ninja"), ninjaArgs...) diff --git a/ui/signal/signal.go b/ui/signal/signal.go index 4929a7bfe..552545d8b 100644 --- a/ui/signal/signal.go +++ b/ui/signal/signal.go @@ -31,13 +31,12 @@ import ( // same time we do. Most of the time this means we just need to ignore the signal and we'll // just see errors from all of our subprocesses. But in case that fails, when we get a signal: // -// 1. Wait two seconds to exit normally. -// 2. Call cancel() which is normally the cancellation of a Context. This will send a SIGKILL -// to any subprocesses attached to that context. -// 3. Wait two seconds to exit normally. -// 4. Call cleanup() to close the log/trace buffers, then panic. -// 5. If another two seconds passes (if cleanup got stuck, etc), then panic. -// +// 1. Wait two seconds to exit normally. +// 2. Call cancel() which is normally the cancellation of a Context. This will send a SIGKILL +// to any subprocesses attached to that context. +// 3. Wait two seconds to exit normally. +// 4. Call cleanup() to close the log/trace buffers, then panic. +// 5. If another two seconds passes (if cleanup got stuck, etc), then panic. func SetupSignals(log logger.Logger, cancel, cleanup func()) { signals := make(chan os.Signal, 5) signal.Notify(signals, os.Interrupt, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM) |