diff options
29 files changed, 1255 insertions, 168 deletions
diff --git a/aidl_library/aidl_library.go b/aidl_library/aidl_library.go index 9b5f0a814..8a84e6bfa 100644 --- a/aidl_library/aidl_library.go +++ b/aidl_library/aidl_library.go @@ -22,6 +22,10 @@ import ( "github.com/google/blueprint/proptools" ) +var PrepareForTestWithAidlLibrary = android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + registerAidlLibraryBuildComponents(ctx) +}) + func init() { registerAidlLibraryBuildComponents(android.InitRegistrationContext) } diff --git a/aidl_library/aidl_library_test.go b/aidl_library/aidl_library_test.go index 42fa5367e..d9b410acc 100644 --- a/aidl_library/aidl_library_test.go +++ b/aidl_library/aidl_library_test.go @@ -19,10 +19,6 @@ import ( "testing" ) -var PrepareForTestWithAidlLibrary = android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { - registerAidlLibraryBuildComponents(ctx) -}) - func TestAidlLibrary(t *testing.T) { t.Parallel() ctx := android.GroupFixturePreparers( diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 5b7f11789..9700f8bb9 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -85,6 +85,7 @@ var ( "development/apps/DevelopmentSettings": Bp2BuildDefaultTrue, "development/apps/Fallback": Bp2BuildDefaultTrue, "development/apps/WidgetPreview": Bp2BuildDefaultTrue, + "development/python-packages/adb": Bp2BuildDefaultTrueRecursively, "development/samples/BasicGLSurfaceView": Bp2BuildDefaultTrue, "development/samples/BluetoothChat": Bp2BuildDefaultTrue, "development/samples/BrokenKeyDerivation": Bp2BuildDefaultTrue, @@ -211,6 +212,7 @@ var ( "frameworks/av/media/module/minijail": Bp2BuildDefaultTrueRecursively, "frameworks/av/services/minijail": Bp2BuildDefaultTrueRecursively, "frameworks/base/libs/androidfw": Bp2BuildDefaultTrue, + "frameworks/base/libs/services": Bp2BuildDefaultTrue, "frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue, "frameworks/base/proto": Bp2BuildDefaultTrue, "frameworks/base/services/tests/servicestests/aidl": Bp2BuildDefaultTrue, @@ -570,6 +572,9 @@ var ( //external/fec "libfec_rs", + //frameworks/base/core/java + "IDropBoxManagerService_aidl", + //system/core/libsparse "libsparse", @@ -751,6 +756,10 @@ var ( "CaptivePortalLogin", "libstagefright_headers", + + // aidl + "aidl", + "libaidl-common", } Bp2buildModuleTypeAlwaysConvertList = []string{ diff --git a/android/bazel_handler.go b/android/bazel_handler.go index 5291ecae9..10cf60a0a 100644 --- a/android/bazel_handler.go +++ b/android/bazel_handler.go @@ -29,6 +29,7 @@ import ( "android/soong/bazel/cquery" "android/soong/shared" "android/soong/starlark_fmt" + "github.com/google/blueprint" "github.com/google/blueprint/metrics" @@ -700,9 +701,6 @@ func (context *mixedBuildBazelContext) createBazelCommand(config Config, runName // We don't need to set --host_platforms because it's set in bazelrc files // that the bazel shell script wrapper passes - // Explicitly disable downloading rules (such as canonical C++ and Java rules) from the network. - "--experimental_repository_disable_download", - // Suppress noise "--ui_event_filters=-INFO", "--noshow_progress", diff --git a/android/config.go b/android/config.go index 9e94e0517..acadb3ff3 100644 --- a/android/config.go +++ b/android/config.go @@ -183,6 +183,16 @@ func (c Config) MaxPageSizeSupported() string { return String(c.config.productVariables.DeviceMaxPageSizeSupported) } +// The release version passed to aconfig, derived from RELEASE_VERSION +func (c Config) ReleaseVersion() string { + return c.config.productVariables.ReleaseVersion +} + +// The flag values files passed to aconfig, derived from RELEASE_VERSION +func (c Config) ReleaseDeviceConfigValueSets() []string { + return c.config.productVariables.ReleaseDeviceConfigValueSets +} + // A DeviceConfig object represents the configuration for a particular device // being built. For now there will only be one of these, but in the future there // may be multiple devices being built. diff --git a/android/variable.go b/android/variable.go index bf66135b5..97171e7b9 100644 --- a/android/variable.go +++ b/android/variable.go @@ -473,6 +473,9 @@ type productVariables struct { ProductManufacturer string `json:",omitempty"` ProductBrand string `json:",omitempty"` BuildVersionTags []string `json:",omitempty"` + + ReleaseVersion string `json:",omitempty"` + ReleaseDeviceConfigValueSets []string `json:",omitempty"` } func boolPtr(v bool) *bool { diff --git a/apex/apex.go b/apex/apex.go index 026734eee..ff7ee35c0 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -404,7 +404,7 @@ type apexBundle struct { /////////////////////////////////////////////////////////////////////////////////////////// // Inputs - // Keys for apex_paylaod.img + // Keys for apex_payload.img publicKeyFile android.Path privateKeyFile android.Path @@ -2606,8 +2606,45 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) }) vctx.normalizeFileInfo(ctx) if a.privateKeyFile == nil { - ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key)) - return + if ctx.Config().AllowMissingDependencies() { + // TODO(b/266099037): a better approach for slim manifests. + ctx.AddMissingDependencies([]string{String(a.overridableProperties.Key)}) + // Create placeholder paths for later stages that expect to see those paths, + // though they won't be used. + var unusedPath = android.PathForModuleOut(ctx, "nonexistentprivatekey") + ctx.Build(pctx, android.BuildParams{ + Rule: android.ErrorRule, + Output: unusedPath, + Args: map[string]string{ + "error": "Private key not available", + }, + }) + a.privateKeyFile = unusedPath + } else { + ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key)) + return + } + } + + if a.publicKeyFile == nil { + if ctx.Config().AllowMissingDependencies() { + // TODO(b/266099037): a better approach for slim manifests. + ctx.AddMissingDependencies([]string{String(a.overridableProperties.Key)}) + // Create placeholder paths for later stages that expect to see those paths, + // though they won't be used. + var unusedPath = android.PathForModuleOut(ctx, "nonexistentpublickey") + ctx.Build(pctx, android.BuildParams{ + Rule: android.ErrorRule, + Output: unusedPath, + Args: map[string]string{ + "error": "Public key not available", + }, + }) + a.publicKeyFile = unusedPath + } else { + ctx.PropertyErrorf("key", "public_key for %q could not be found", String(a.overridableProperties.Key)) + return + } } //////////////////////////////////////////////////////////////////////////////////////////// diff --git a/apex/apex_test.go b/apex/apex_test.go index 6ca5afb84..c1d80a39f 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -1368,6 +1368,8 @@ func TestApexWithRuntimeLibsDependency(t *testing.T) { cc_library { name: "mylib", srcs: ["mylib.cpp"], + static_libs: ["libstatic"], + shared_libs: ["libshared"], runtime_libs: ["libfoo", "libbar"], system_shared_libs: [], stl: "none", @@ -1392,6 +1394,39 @@ func TestApexWithRuntimeLibsDependency(t *testing.T) { apex_available: [ "myapex" ], } + cc_library { + name: "libstatic", + srcs: ["mylib.cpp"], + system_shared_libs: [], + stl: "none", + apex_available: [ "myapex" ], + runtime_libs: ["libstatic_to_runtime"], + } + + cc_library { + name: "libshared", + srcs: ["mylib.cpp"], + system_shared_libs: [], + stl: "none", + apex_available: [ "myapex" ], + runtime_libs: ["libshared_to_runtime"], + } + + cc_library { + name: "libstatic_to_runtime", + srcs: ["mylib.cpp"], + system_shared_libs: [], + stl: "none", + apex_available: [ "myapex" ], + } + + cc_library { + name: "libshared_to_runtime", + srcs: ["mylib.cpp"], + system_shared_libs: [], + stl: "none", + apex_available: [ "myapex" ], + } `) apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule") @@ -1405,11 +1440,14 @@ func TestApexWithRuntimeLibsDependency(t *testing.T) { // Ensure that runtime_libs dep in included ensureContains(t, copyCmds, "image.apex/lib64/libbar.so") + ensureContains(t, copyCmds, "image.apex/lib64/libshared.so") + ensureContains(t, copyCmds, "image.apex/lib64/libshared_to_runtime.so") + + ensureNotContains(t, copyCmds, "image.apex/lib64/libstatic_to_runtime.so") apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule") ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"])) ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.so") - } var prepareForTestOfRuntimeApexWithHwasan = android.GroupFixturePreparers( @@ -6541,6 +6579,72 @@ func TestApexAvailable_IndirectDep(t *testing.T) { }`) } +func TestApexAvailable_IndirectStaticDep(t *testing.T) { + testApex(t, ` + apex { + name: "myapex", + key: "myapex.key", + native_shared_libs: ["libfoo"], + updatable: false, + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "libfoo", + stl: "none", + static_libs: ["libbar"], + system_shared_libs: [], + apex_available: ["myapex"], + } + + cc_library { + name: "libbar", + stl: "none", + shared_libs: ["libbaz"], + system_shared_libs: [], + apex_available: ["myapex"], + } + + cc_library { + name: "libbaz", + stl: "none", + system_shared_libs: [], + }`) + + testApexError(t, `requires "libbar" that doesn't list the APEX under 'apex_available'.`, ` + apex { + name: "myapex", + key: "myapex.key", + native_shared_libs: ["libfoo"], + updatable: false, + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "libfoo", + stl: "none", + static_libs: ["libbar"], + system_shared_libs: [], + apex_available: ["myapex"], + } + + cc_library { + name: "libbar", + stl: "none", + system_shared_libs: [], + }`) +} + func TestApexAvailable_InvalidApexName(t *testing.T) { testApexError(t, "\"otherapex\" is not a valid module name", ` apex { diff --git a/bazel/configurability.go b/bazel/configurability.go index d042fe8b8..8f63ec45b 100644 --- a/bazel/configurability.go +++ b/bazel/configurability.go @@ -31,11 +31,11 @@ const ( // OsType names in arch.go OsAndroid = "android" - osDarwin = "darwin" - osLinux = "linux_glibc" + OsDarwin = "darwin" + OsLinux = "linux_glibc" osLinuxMusl = "linux_musl" osLinuxBionic = "linux_bionic" - osWindows = "windows" + OsWindows = "windows" // Targets in arch.go osArchAndroidArm = "android_arm" @@ -156,11 +156,11 @@ var ( // constraint_value for the @platforms//os:os constraint_setting platformOsMap = map[string]string{ OsAndroid: "//build/bazel/platforms/os:android", - osDarwin: "//build/bazel/platforms/os:darwin", - osLinux: "//build/bazel/platforms/os:linux_glibc", + OsDarwin: "//build/bazel/platforms/os:darwin", + OsLinux: "//build/bazel/platforms/os:linux_glibc", osLinuxMusl: "//build/bazel/platforms/os:linux_musl", osLinuxBionic: "//build/bazel/platforms/os:linux_bionic", - osWindows: "//build/bazel/platforms/os:windows", + OsWindows: "//build/bazel/platforms/os:windows", ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map. } @@ -192,22 +192,22 @@ var ( // in a cyclic dependency. osToArchMap = map[string][]string{ OsAndroid: {archArm, archArm64, archRiscv64, archX86, archX86_64}, - osLinux: {archX86, archX86_64}, + OsLinux: {archX86, archX86_64}, osLinuxMusl: {archX86, archX86_64}, - osDarwin: {archArm64, archX86_64}, + OsDarwin: {archArm64, archX86_64}, osLinuxBionic: {archArm64, archX86_64}, // TODO(cparsons): According to arch.go, this should contain archArm, archArm64, as well. - osWindows: {archX86, archX86_64}, + OsWindows: {archX86, archX86_64}, } osAndInApexMap = map[string]string{ AndroidAndInApex: "//build/bazel/rules/apex:android-in_apex", AndroidPlatform: "//build/bazel/rules/apex:system", - osDarwin: "//build/bazel/platforms/os:darwin", - osLinux: "//build/bazel/platforms/os:linux_glibc", + OsDarwin: "//build/bazel/platforms/os:darwin", + OsLinux: "//build/bazel/platforms/os:linux_glibc", osLinuxMusl: "//build/bazel/platforms/os:linux_musl", osLinuxBionic: "//build/bazel/platforms/os:linux_bionic", - osWindows: "//build/bazel/platforms/os:windows", + OsWindows: "//build/bazel/platforms/os:windows", ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, } diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go index 89eac8a00..6ec37031b 100644 --- a/bp2build/cc_binary_conversion_test.go +++ b/bp2build/cc_binary_conversion_test.go @@ -644,10 +644,7 @@ func TestCcBinaryWithInstructionSet(t *testing.T) { targets: []testBazelTarget{ {"cc_binary", "foo", AttrNameToString{ "features": `select({ - "//build/bazel/platforms/arch:arm": [ - "arm_isa_arm", - "-arm_isa_thumb", - ], + "//build/bazel/platforms/arch:arm": ["arm_isa_arm"], "//conditions:default": [], })`, "local_includes": `["."]`, diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 1b681efb0..0e8705b54 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -18,6 +18,7 @@ import ( "fmt" "testing" + "android/soong/aidl_library" "android/soong/android" "android/soong/cc" ) @@ -63,6 +64,7 @@ func registerCcLibraryModuleTypes(ctx android.RegistrationContext) { ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory) ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory) ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory) + ctx.RegisterModuleType("aidl_library", aidl_library.AidlLibraryFactory) } func TestCcLibrarySimple(t *testing.T) { @@ -3219,10 +3221,7 @@ func TestCcLibraryWithInstructionSet(t *testing.T) { `, ExpectedBazelTargets: makeCcLibraryTargets("foo", AttrNameToString{ "features": `select({ - "//build/bazel/platforms/arch:arm": [ - "arm_isa_arm", - "-arm_isa_thumb", - ], + "//build/bazel/platforms/arch:arm": ["arm_isa_arm"], "//conditions:default": [], })`, "local_includes": `["."]`, @@ -3315,6 +3314,51 @@ func TestCcLibraryArchVariantSuffix(t *testing.T) { }) } +func TestCcLibraryWithAidlLibrary(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library with aidl_library", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +aidl_library { + name: "A_aidl", + srcs: ["aidl/A.aidl"], + hdrs: ["aidl/Header.aidl"], + strip_import_prefix: "aidl", +} +cc_library { + name: "foo", + aidl: { + libs: ["A_aidl"], + }, + export_include_dirs: ["include"], +}`, + ExpectedBazelTargets: []string{ + MakeBazelTargetNoRestrictions("aidl_library", "A_aidl", AttrNameToString{ + "srcs": `["aidl/A.aidl"]`, + "hdrs": `["aidl/Header.aidl"]`, + "strip_import_prefix": `"aidl"`, + "tags": `["apex_available=//apex_available:anyapex"]`, + }), + MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{ + "deps": `[":A_aidl"]`, + "local_includes": `["."]`, + "export_includes": `["include"]`, + }), + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`, + "local_includes": `["."]`, + "export_includes": `["include"]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`, + "local_includes": `["."]`, + "export_includes": `["include"]`, + }), + }, + }) +} + func TestCcLibraryWithAidlSrcs(t *testing.T) { runCcLibraryTestCase(t, Bp2buildTestCase{ Description: "cc_library with aidl srcs", @@ -3343,6 +3387,7 @@ cc_library { "srcs": `["B.aidl"]`, }), MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{ + "local_includes": `["."]`, "deps": `[ ":A_aidl", ":foo_aidl_library", @@ -3382,7 +3427,8 @@ cc_library { }`, ExpectedBazelTargets: []string{ MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{ - "deps": `["//path/to/A:A_aidl"]`, + "local_includes": `["."]`, + "deps": `["//path/to/A:A_aidl"]`, }), MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ "implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`, @@ -3397,37 +3443,78 @@ cc_library { } func TestCcLibraryWithExportAidlHeaders(t *testing.T) { - runCcLibraryTestCase(t, Bp2buildTestCase{ - Description: "cc_library with export aidl headers", - ModuleTypeUnderTest: "cc_library", - ModuleTypeUnderTestFactory: cc.LibraryFactory, - Blueprint: ` -cc_library { - name: "foo", - srcs: [ - "Foo.aidl", - ], - aidl: { - export_aidl_headers: true, - } -}`, - ExpectedBazelTargets: []string{ - MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{ - "srcs": `["Foo.aidl"]`, - }), - MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{ - "deps": `[":foo_aidl_library"]`, - }), - MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ - "whole_archive_deps": `[":foo_cc_aidl_library"]`, - "local_includes": `["."]`, - }), - MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ - "whole_archive_deps": `[":foo_cc_aidl_library"]`, - "local_includes": `["."]`, - }), + t.Parallel() + + expectedBazelTargets := []string{ + MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{ + "local_includes": `["."]`, + "deps": `[":foo_aidl_library"]`, + }), + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "whole_archive_deps": `[":foo_cc_aidl_library"]`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "whole_archive_deps": `[":foo_cc_aidl_library"]`, + "local_includes": `["."]`, + }), + } + testCases := []struct { + description string + bp string + expectedBazelTargets []string + }{ + { + description: "cc_library with aidl srcs and aidl.export_aidl_headers set", + bp: ` + cc_library { + name: "foo", + srcs: [ + "Foo.aidl", + ], + aidl: { + export_aidl_headers: true, + } + }`, + expectedBazelTargets: append( + expectedBazelTargets, + MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{ + "srcs": `["Foo.aidl"]`, + })), }, - }) + { + description: "cc_library with aidl.libs and aidl.export_aidl_headers set", + bp: ` + aidl_library { + name: "foo_aidl_library", + srcs: ["Foo.aidl"], + } + cc_library { + name: "foo", + aidl: { + libs: ["foo_aidl_library"], + export_aidl_headers: true, + } + }`, + expectedBazelTargets: append( + expectedBazelTargets, + MakeBazelTargetNoRestrictions("aidl_library", "foo_aidl_library", AttrNameToString{ + "srcs": `["Foo.aidl"]`, + "tags": `["apex_available=//apex_available:anyapex"]`, + }), + ), + }, + } + + for _, testCase := range testCases { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library with export aidl headers", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: testCase.bp, + ExpectedBazelTargets: testCase.expectedBazelTargets, + }) + } } func TestCcLibraryWithTargetApex(t *testing.T) { @@ -3642,7 +3729,8 @@ cc_library_static { "srcs": `["Foo.aidl"]`, }), MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{ - "deps": `[":foo_aidl_library"]`, + "local_includes": `["."]`, + "deps": `[":foo_aidl_library"]`, "implementation_deps": `[ ":baz-static", ":bar-static", @@ -4519,3 +4607,105 @@ func TestCcLibraryCppFlagsInProductVariables(t *testing.T) { }, ) } + +func TestCcLibraryYaccConversion(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library is built from .y/.yy files", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: soongCcLibraryPreamble + `cc_library { + name: "a", + srcs: [ + "a.cpp", + "a.yy", + ], + shared_libs: ["sharedlib"], + static_libs: ["staticlib"], + yacc: { + flags: ["someYaccFlag"], + gen_location_hh: true, + gen_position_hh: true, + }, +} +cc_library_static { + name: "staticlib", + bazel_module: { bp2build_available: false }, +} +cc_library { + name: "sharedlib", + bazel_module: { bp2build_available: false }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_yacc_static_library", "a_yacc", AttrNameToString{ + "src": `"a.yy"`, + "implementation_deps": `[":staticlib"]`, + "implementation_dynamic_deps": `[":sharedlib"]`, + "flags": `["someYaccFlag"]`, + "gen_location_hh": "True", + "gen_position_hh": "True", + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "a", AttrNameToString{ + "srcs": `["a.cpp"]`, + "implementation_deps": `[":staticlib"]`, + "implementation_dynamic_deps": `[":sharedlib"]`, + "implementation_whole_archive_deps": `[":a_yacc"]`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{ + "srcs": `["a.cpp"]`, + "implementation_deps": `[":staticlib"]`, + "implementation_dynamic_deps": `[":sharedlib"]`, + "implementation_whole_archive_deps": `[":a_yacc"]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryHostLdLibs(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_binary linker flags for host_ldlibs", + ModuleTypeUnderTest: "cc_binary", + ModuleTypeUnderTestFactory: cc.BinaryFactory, + Blueprint: soongCcLibraryPreamble + `cc_binary { + name: "a", + host_supported: true, + ldflags: ["-lcommon"], + target: { + linux: { + host_ldlibs: [ + "-llinux", + ], + }, + darwin: { + ldflags: ["-ldarwinadditional"], + host_ldlibs: [ + "-ldarwin", + ], + }, + windows: { + host_ldlibs: [ + "-lwindows", + ], + }, + }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTargetNoRestrictions("cc_binary", "a", AttrNameToString{ + "linkopts": `["-lcommon"] + select({ + "//build/bazel/platforms/os:darwin": [ + "-ldarwinadditional", + "-ldarwin", + ], + "//build/bazel/platforms/os:linux_glibc": ["-llinux"], + "//build/bazel/platforms/os:windows": ["-lwindows"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/cc/Android.bp b/cc/Android.bp index be2cc5a34..f49dc1a9e 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -9,6 +9,7 @@ bootstrap_go_package { "blueprint", "blueprint-pathtools", "soong", + "soong-aidl-library", "soong-android", "soong-bazel", "soong-cc-config", @@ -22,7 +23,6 @@ bootstrap_go_package { srcs: [ "afdo.go", "fdo_profile.go", - "androidmk.go", "api_level.go", "bp2build.go", diff --git a/cc/bp2build.go b/cc/bp2build.go index cf5f74d4d..fa98df4cd 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -38,6 +38,7 @@ const ( protoSrcPartition = "proto" aidlSrcPartition = "aidl" syspropSrcPartition = "sysprop" + yaccSrcPartition = "yacc" stubsSuffix = "_stub_libs_current" ) @@ -154,6 +155,7 @@ func groupSrcsByExtension(ctx android.BazelConversionPathContext, srcs bazel.Lab // know the language of these sources until the genrule is executed. cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true}, syspropSrcPartition: bazel.LabelPartition{Extensions: []string{".sysprop"}}, + yaccSrcPartition: bazel.LabelPartition{Extensions: []string{".y", "yy"}}, } return bazel.PartitionLabelListAttribute(ctx, &srcs, labels) @@ -404,6 +406,12 @@ type compilerAttributes struct { // Sysprop sources syspropSrcs bazel.LabelListAttribute + // Yacc sources + yaccSrc *bazel.LabelAttribute + yaccFlags bazel.StringListAttribute + yaccGenLocationHeader bazel.BoolAttribute + yaccGenPositionHeader bazel.BoolAttribute + hdrs bazel.LabelListAttribute rtti bazel.BoolAttribute @@ -492,7 +500,7 @@ func (ca *compilerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversi instructionSet := proptools.StringDefault(props.Instruction_set, "") if instructionSet == "arm" { - ca.features.SetSelectValue(axis, config, []string{"arm_isa_arm", "-arm_isa_thumb"}) + ca.features.SetSelectValue(axis, config, []string{"arm_isa_arm"}) } else if instructionSet != "" && instructionSet != "thumb" { ctx.ModuleErrorf("Unknown value for instruction_set: %s", instructionSet) } @@ -566,6 +574,12 @@ func (ca *compilerAttributes) finalize(ctx android.BazelConversionPathContext, i ca.asmSrcs = partitionedSrcs[asmSrcPartition] ca.lSrcs = partitionedSrcs[lSrcPartition] ca.llSrcs = partitionedSrcs[llSrcPartition] + if yacc := partitionedSrcs[yaccSrcPartition]; !yacc.IsEmpty() { + if len(yacc.Value.Includes) > 1 { + ctx.PropertyErrorf("srcs", "Found multiple yacc (.y/.yy) files in library") + } + ca.yaccSrc = bazel.MakeLabelAttribute(yacc.Value.Includes[0].Label) + } ca.syspropSrcs = partitionedSrcs[syspropSrcPartition] ca.absoluteIncludes.DeduplicateAxesFromBase() @@ -728,6 +742,8 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) compilerAttrs := compilerAttributes{} linkerAttrs := linkerAttributes{} + var aidlLibs bazel.LabelList + // Iterate through these axes in a deterministic order. This is required // because processing certain dependencies may result in concatenating // elements along other axes. (For example, processing NoConfig may result @@ -742,7 +758,13 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) if baseCompilerProps.Lex != nil { compilerAttrs.lexopts.SetSelectValue(axis, cfg, baseCompilerProps.Lex.Flags) } + if baseCompilerProps.Yacc != nil { + compilerAttrs.yaccFlags.SetSelectValue(axis, cfg, baseCompilerProps.Yacc.Flags) + compilerAttrs.yaccGenLocationHeader.SetSelectValue(axis, cfg, baseCompilerProps.Yacc.Gen_location_hh) + compilerAttrs.yaccGenPositionHeader.SetSelectValue(axis, cfg, baseCompilerProps.Yacc.Gen_position_hh) + } (&compilerAttrs).bp2buildForAxisAndConfig(ctx, axis, cfg, baseCompilerProps) + aidlLibs.Append(android.BazelLabelForModuleDeps(ctx, baseCompilerProps.Aidl.Libs)) } var exportHdrs []string @@ -815,7 +837,15 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) (&linkerAttrs).wholeArchiveDeps.Add(protoDep.wholeStaticLib) (&linkerAttrs).implementationWholeArchiveDeps.Add(protoDep.implementationWholeStaticLib) - aidlDep := bp2buildCcAidlLibrary(ctx, module, compilerAttrs.aidlSrcs, linkerAttrs) + aidlDep := bp2buildCcAidlLibrary( + ctx, module, + compilerAttrs.aidlSrcs, + bazel.LabelListAttribute{ + Value: aidlLibs, + }, + linkerAttrs, + compilerAttrs, + ) if aidlDep != nil { if lib, ok := module.linker.(*libraryDecorator); ok { if proptools.Bool(lib.Properties.Aidl.Export_aidl_headers) { @@ -826,6 +856,12 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) } } + // Create a cc_yacc_static_library if srcs contains .y/.yy files + // This internal target will produce an .a file that will be statically linked to the parent library + if yaccDep := bp2buildCcYaccLibrary(ctx, compilerAttrs, linkerAttrs); yaccDep != nil { + (&linkerAttrs).implementationWholeArchiveDeps.Add(yaccDep) + } + convertedLSrcs := bp2BuildLex(ctx, module.Name(), compilerAttrs) (&compilerAttrs).srcs.Add(&convertedLSrcs.srcName) (&compilerAttrs).cSrcs.Add(&convertedLSrcs.cSrcName) @@ -864,6 +900,48 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) } } +type ccYaccLibraryAttributes struct { + Src bazel.LabelAttribute + Flags bazel.StringListAttribute + Gen_location_hh bazel.BoolAttribute + Gen_position_hh bazel.BoolAttribute + Local_includes bazel.StringListAttribute + Implementation_deps bazel.LabelListAttribute + Implementation_dynamic_deps bazel.LabelListAttribute +} + +func bp2buildCcYaccLibrary(ctx android.Bp2buildMutatorContext, ca compilerAttributes, la linkerAttributes) *bazel.LabelAttribute { + if ca.yaccSrc == nil { + return nil + } + yaccLibraryLabel := ctx.Module().Name() + "_yacc" + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "cc_yacc_static_library", + Bzl_load_location: "//build/bazel/rules/cc:cc_yacc_library.bzl", + }, + android.CommonAttributes{ + Name: yaccLibraryLabel, + }, + &ccYaccLibraryAttributes{ + Src: *ca.yaccSrc, + Flags: ca.yaccFlags, + Gen_location_hh: ca.yaccGenLocationHeader, + Gen_position_hh: ca.yaccGenPositionHeader, + Local_includes: ca.localIncludes, + Implementation_deps: la.implementationDeps, + Implementation_dynamic_deps: la.implementationDynamicDeps, + }, + ) + + yaccLibrary := &bazel.LabelAttribute{ + Value: &bazel.Label{ + Label: ":" + yaccLibraryLabel, + }, + } + return yaccLibrary +} + // As a workaround for b/261657184, we are manually adding the default value // of system_dynamic_deps for the linux_musl os. // TODO: Solve this properly @@ -912,11 +990,16 @@ func bp2buildFdoProfile( func bp2buildCcAidlLibrary( ctx android.Bp2buildMutatorContext, m *Module, - aidlLabelList bazel.LabelListAttribute, + aidlSrcs bazel.LabelListAttribute, + aidlLibs bazel.LabelListAttribute, linkerAttrs linkerAttributes, + compilerAttrs compilerAttributes, ) *bazel.LabelAttribute { - if !aidlLabelList.IsEmpty() { - aidlLibs, aidlSrcs := aidlLabelList.Partition(func(src bazel.Label) bool { + var aidlLibsFromSrcs, aidlFiles bazel.LabelListAttribute + apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.TopDownMutatorContext), ctx.Module()) + + if !aidlSrcs.IsEmpty() { + aidlLibsFromSrcs, aidlFiles = aidlSrcs.Partition(func(src bazel.Label) bool { if fg, ok := android.ToFileGroupAsLibrary(ctx, src.OriginalModuleName); ok && fg.ShouldConvertToAidlLibrary(ctx) { return true @@ -924,55 +1007,69 @@ func bp2buildCcAidlLibrary( return false }) - apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.TopDownMutatorContext), ctx.Module()) - sdkAttrs := bp2BuildParseSdkAttributes(m) - - if !aidlSrcs.IsEmpty() { + if !aidlFiles.IsEmpty() { aidlLibName := m.Name() + "_aidl_library" ctx.CreateBazelTargetModule( bazel.BazelTargetModuleProperties{ Rule_class: "aidl_library", Bzl_load_location: "//build/bazel/rules/aidl:aidl_library.bzl", }, - android.CommonAttributes{Name: aidlLibName}, - &aidlLibraryAttributes{ - Srcs: aidlSrcs, + android.CommonAttributes{ + Name: aidlLibName, Tags: apexAvailableTags, }, + &aidlLibraryAttributes{ + Srcs: aidlFiles, + }, ) - aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}}) + aidlLibsFromSrcs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}}) } + } - if !aidlLibs.IsEmpty() { - ccAidlLibrarylabel := m.Name() + "_cc_aidl_library" - // Since parent cc_library already has these dependencies, we can add them as implementation - // deps so that they don't re-export - implementationDeps := linkerAttrs.deps.Clone() - implementationDeps.Append(linkerAttrs.implementationDeps) - implementationDynamicDeps := linkerAttrs.dynamicDeps.Clone() - implementationDynamicDeps.Append(linkerAttrs.implementationDynamicDeps) + allAidlLibs := aidlLibs.Clone() + allAidlLibs.Append(aidlLibsFromSrcs) - ctx.CreateBazelTargetModule( - bazel.BazelTargetModuleProperties{ - Rule_class: "cc_aidl_library", - Bzl_load_location: "//build/bazel/rules/cc:cc_aidl_library.bzl", - }, - android.CommonAttributes{Name: ccAidlLibrarylabel}, - &ccAidlLibraryAttributes{ - Deps: aidlLibs, - Implementation_deps: *implementationDeps, - Implementation_dynamic_deps: *implementationDynamicDeps, - Tags: apexAvailableTags, - sdkAttributes: sdkAttrs, - }, - ) - label := &bazel.LabelAttribute{ - Value: &bazel.Label{ - Label: ":" + ccAidlLibrarylabel, - }, - } - return label + if !allAidlLibs.IsEmpty() { + ccAidlLibrarylabel := m.Name() + "_cc_aidl_library" + // Since parent cc_library already has these dependencies, we can add them as implementation + // deps so that they don't re-export + implementationDeps := linkerAttrs.deps.Clone() + implementationDeps.Append(linkerAttrs.implementationDeps) + implementationDynamicDeps := linkerAttrs.dynamicDeps.Clone() + implementationDynamicDeps.Append(linkerAttrs.implementationDynamicDeps) + + sdkAttrs := bp2BuildParseSdkAttributes(m) + + exportedIncludes := bp2BuildParseExportedIncludes(ctx, m, &compilerAttrs.includes) + includeAttrs := includesAttributes{ + Export_includes: exportedIncludes.Includes, + Export_absolute_includes: exportedIncludes.AbsoluteIncludes, + Export_system_includes: exportedIncludes.SystemIncludes, + Local_includes: compilerAttrs.localIncludes, + Absolute_includes: compilerAttrs.absoluteIncludes, } + + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "cc_aidl_library", + Bzl_load_location: "//build/bazel/rules/cc:cc_aidl_library.bzl", + }, + android.CommonAttributes{Name: ccAidlLibrarylabel}, + &ccAidlLibraryAttributes{ + Deps: *allAidlLibs, + Implementation_deps: *implementationDeps, + Implementation_dynamic_deps: *implementationDynamicDeps, + Tags: apexAvailableTags, + sdkAttributes: sdkAttrs, + includesAttributes: includeAttrs, + }, + ) + label := &bazel.LabelAttribute{ + Value: &bazel.Label{ + Label: ":" + ccAidlLibrarylabel, + }, + } + return label } return nil @@ -1169,6 +1266,9 @@ func (la *linkerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversion } la.additionalLinkerInputs.SetSelectValue(axis, config, additionalLinkerInputs) + if axis == bazel.OsConfigurationAxis && (config == bazel.OsDarwin || config == bazel.OsLinux || config == bazel.OsWindows) { + linkerFlags = append(linkerFlags, props.Host_ldlibs...) + } la.linkopts.SetSelectValue(axis, config, linkerFlags) if axisFeatures != nil { @@ -27,6 +27,7 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/proptools" + "android/soong/aidl_library" "android/soong/android" "android/soong/bazel/cquery" "android/soong/cc/config" @@ -110,6 +111,9 @@ type Deps struct { // Used by DepsMutator to pass system_shared_libs information to check_elf_file.py. SystemSharedLibs []string + // Used by DepMutator to pass aidl_library modules to aidl compiler + AidlLibs []string + // If true, statically link the unwinder into native libraries/binaries. StaticUnwinderIfLegacy bool @@ -182,6 +186,9 @@ type PathDeps struct { // For Darwin builds, the path to the second architecture's output that should // be combined with this architectures's output into a FAT MachO file. DarwinSecondArchOutput android.OptionalPath + + // Paths to direct srcs and transitive include dirs from direct aidl_library deps + AidlLibraryInfos []aidl_library.AidlLibraryInfo } // LocalOrGlobalFlags contains flags that need to have values set globally by the build system or locally by the module @@ -765,6 +772,7 @@ var ( stubImplDepTag = dependencyTag{name: "stub_impl"} JniFuzzLibTag = dependencyTag{name: "jni_fuzz_lib_tag"} FdoProfileTag = dependencyTag{name: "fdo_profile"} + aidlLibraryTag = dependencyTag{name: "aidl_library"} ) func IsSharedDepTag(depTag blueprint.DependencyTag) bool { @@ -2751,6 +2759,14 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { } } + if len(deps.AidlLibs) > 0 { + actx.AddDependency( + c, + aidlLibraryTag, + deps.AidlLibs..., + ) + } + updateImportedLibraryDependency(ctx) } @@ -3055,6 +3071,17 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { return } + if depTag == aidlLibraryTag { + if ctx.OtherModuleHasProvider(dep, aidl_library.AidlLibraryProvider) { + depPaths.AidlLibraryInfos = append( + depPaths.AidlLibraryInfos, + ctx.OtherModuleProvider( + dep, + aidl_library.AidlLibraryProvider).(aidl_library.AidlLibraryInfo), + ) + } + } + ccDep, ok := dep.(LinkableInterface) if !ok { diff --git a/cc/cc_test.go b/cc/cc_test.go index f9e661ff2..422df7310 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -24,6 +24,7 @@ import ( "strings" "testing" + "android/soong/aidl_library" "android/soong/android" "android/soong/bazel/cquery" ) @@ -38,6 +39,7 @@ func TestMain(m *testing.M) { var prepareForCcTest = android.GroupFixturePreparers( PrepareForTestWithCcIncludeVndk, + aidl_library.PrepareForTestWithAidlLibrary, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { variables.DeviceVndkVersion = StringPtr("current") variables.ProductVndkVersion = StringPtr("current") @@ -4418,9 +4420,65 @@ func TestStubsLibReexportsHeaders(t *testing.T) { } } +func TestAidlLibraryWithHeader(t *testing.T) { + t.Parallel() + ctx := android.GroupFixturePreparers( + prepareForCcTest, + aidl_library.PrepareForTestWithAidlLibrary, + android.MockFS{ + "package_bar/Android.bp": []byte(` + aidl_library { + name: "bar", + srcs: ["x/y/Bar.aidl"], + strip_import_prefix: "x", + } + `)}.AddToFixture(), + android.MockFS{ + "package_foo/Android.bp": []byte(` + aidl_library { + name: "foo", + srcs: ["a/b/Foo.aidl"], + strip_import_prefix: "a", + deps: ["bar"], + } + cc_library { + name: "libfoo", + aidl: { + libs: ["foo"], + } + } + `), + }.AddToFixture(), + ).RunTest(t).TestContext + + libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static") + manifest := android.RuleBuilderSboxProtoForTests(t, libfoo.Output("aidl.sbox.textproto")) + aidlCommand := manifest.Commands[0].GetCommand() + + expectedAidlFlags := "-Ipackage_foo/a -Ipackage_bar/x" + if !strings.Contains(aidlCommand, expectedAidlFlags) { + t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlags) + } + + outputs := strings.Join(libfoo.AllOutputs(), " ") + + android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl/b/BpFoo.h") + android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl/b/BnFoo.h") + android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl/b/Foo.h") + android.AssertStringDoesContain(t, "aidl-generated cpp", outputs, "b/Foo.cpp") + // Confirm that the aidl header doesn't get compiled to cpp and h files + android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl/y/BpBar.h") + android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl/y/BnBar.h") + android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl/y/Bar.h") + android.AssertStringDoesNotContain(t, "aidl-generated cpp", outputs, "y/Bar.cpp") +} + func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) { t.Parallel() - ctx := testCc(t, ` + ctx := android.GroupFixturePreparers( + prepareForCcTest, + aidl_library.PrepareForTestWithAidlLibrary, + ).RunTestWithBp(t, ` cc_library { name: "libfoo", srcs: ["a/Foo.aidl"], @@ -4705,7 +4763,15 @@ func TestIncludeDirsExporting(t *testing.T) { }) t.Run("ensure only aidl headers are exported", func(t *testing.T) { - ctx := testCc(t, genRuleModules+` + ctx := android.GroupFixturePreparers( + prepareForCcTest, + aidl_library.PrepareForTestWithAidlLibrary, + ).RunTestWithBp(t, ` + aidl_library { + name: "libfoo_aidl", + srcs: ["x/y/Bar.aidl"], + strip_import_prefix: "x", + } cc_library_shared { name: "libfoo", srcs: [ @@ -4714,10 +4780,11 @@ func TestIncludeDirsExporting(t *testing.T) { "a.proto", ], aidl: { + libs: ["libfoo_aidl"], export_aidl_headers: true, } } - `) + `).TestContext foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() checkIncludeDirs(t, ctx, foo, expectedIncludeDirs(` @@ -4728,11 +4795,17 @@ func TestIncludeDirsExporting(t *testing.T) { .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h + .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/Bar.h + .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/BnBar.h + .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/BpBar.h `), expectedOrderOnlyDeps(` .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h + .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/Bar.h + .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/BnBar.h + .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/BpBar.h `), ) }) diff --git a/cc/compiler.go b/cc/compiler.go index 88985b6f9..5da745e02 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -120,6 +120,9 @@ type BaseCompilerProperties struct { Lex *LexProperties Aidl struct { + // List of aidl_library modules + Libs []string + // list of directories that will be added to the aidl include paths. Include_dirs []string @@ -272,6 +275,7 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps { deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...) deps.GeneratedSources = removeListFromList(deps.GeneratedSources, compiler.Properties.Exclude_generated_sources) deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...) + deps.AidlLibs = append(deps.AidlLibs, compiler.Properties.Aidl.Libs...) android.ProtoDeps(ctx, &compiler.Proto) if compiler.hasSrcExt(".proto") { @@ -561,7 +565,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps "-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String()) } - if compiler.hasSrcExt(".aidl") { + if compiler.hasAidl(deps) { flags.aidlFlags = append(flags.aidlFlags, compiler.Properties.Aidl.Flags...) if len(compiler.Properties.Aidl.Local_include_dirs) > 0 { localAidlIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Aidl.Local_include_dirs) @@ -572,6 +576,14 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs)) } + var rootAidlIncludeDirs android.Paths + for _, aidlLibraryInfo := range deps.AidlLibraryInfos { + rootAidlIncludeDirs = append(rootAidlIncludeDirs, aidlLibraryInfo.IncludeDirs.ToList()...) + } + if len(rootAidlIncludeDirs) > 0 { + flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs)) + } + if proptools.BoolDefault(compiler.Properties.Aidl.Generate_traces, true) { flags.aidlFlags = append(flags.aidlFlags, "-t") } @@ -660,6 +672,10 @@ func ndkPathDeps(ctx ModuleContext) android.Paths { return nil } +func (compiler *baseCompiler) hasAidl(deps PathDeps) bool { + return len(deps.AidlLibraryInfos) > 0 || compiler.hasSrcExt(".aidl") +} + func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { pathDeps := deps.GeneratedDeps pathDeps = append(pathDeps, ndkPathDeps(ctx)...) @@ -668,7 +684,7 @@ func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathD srcs := append(android.Paths(nil), compiler.srcsBeforeGen...) - srcs, genDeps, info := genSources(ctx, srcs, buildFlags) + srcs, genDeps, info := genSources(ctx, deps.AidlLibraryInfos, srcs, buildFlags) pathDeps = append(pathDeps, genDeps...) compiler.pathDeps = pathDeps diff --git a/cc/config/global.go b/cc/config/global.go index e5ce48ebe..d4106eb18 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -354,14 +354,14 @@ func init() { // Automatically initialize any uninitialized stack variables. // Prefer zero-init if multiple options are set. if ctx.Config().IsEnvTrue("AUTO_ZERO_INITIALIZE") { - flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang -Wno-unused-command-line-argument") + flags = append(flags, "-ftrivial-auto-var-init=zero") } else if ctx.Config().IsEnvTrue("AUTO_PATTERN_INITIALIZE") { flags = append(flags, "-ftrivial-auto-var-init=pattern") } else if ctx.Config().IsEnvTrue("AUTO_UNINITIALIZE") { flags = append(flags, "-ftrivial-auto-var-init=uninitialized") } else { // Default to zero initialization. - flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang -Wno-unused-command-line-argument") + flags = append(flags, "-ftrivial-auto-var-init=zero") } // Workaround for ccache with clang. @@ -18,7 +18,9 @@ import ( "path/filepath" "strings" + "android/soong/aidl_library" "android/soong/bazel" + "github.com/google/blueprint" "android/soong/android" @@ -124,11 +126,6 @@ func genAidl(ctx android.ModuleContext, rule *android.RuleBuilder, aidlFile andr headerBn := outDir.Join(ctx, aidlPackage, "Bn"+shortName+".h") headerBp := outDir.Join(ctx, aidlPackage, "Bp"+shortName+".h") - baseDir := strings.TrimSuffix(aidlFile.String(), aidlFile.Rel()) - if baseDir != "" { - aidlFlags += " -I" + baseDir - } - cmd := rule.Command() cmd.BuiltTool("aidl-cpp"). FlagWithDepFile("-d", depFile). @@ -282,7 +279,10 @@ type generatedSourceInfo struct { syspropOrderOnlyDeps android.Paths } -func genSources(ctx android.ModuleContext, srcFiles android.Paths, +func genSources( + ctx android.ModuleContext, + aidlLibraryInfos []aidl_library.AidlLibraryInfo, + srcFiles android.Paths, buildFlags builderFlags) (android.Paths, android.Paths, generatedSourceInfo) { var info generatedSourceInfo @@ -330,7 +330,8 @@ func genSources(ctx android.ModuleContext, srcFiles android.Paths, aidlRule = android.NewRuleBuilder(pctx, ctx).Sbox(android.PathForModuleGen(ctx, "aidl"), android.PathForModuleGen(ctx, "aidl.sbox.textproto")) } - cppFile, aidlHeaders := genAidl(ctx, aidlRule, srcFile, buildFlags.aidlFlags) + baseDir := strings.TrimSuffix(srcFile.String(), srcFile.Rel()) + cppFile, aidlHeaders := genAidl(ctx, aidlRule, srcFile, buildFlags.aidlFlags+" -I"+baseDir) srcFiles[i] = cppFile info.aidlHeaders = append(info.aidlHeaders, aidlHeaders...) @@ -352,6 +353,24 @@ func genSources(ctx android.ModuleContext, srcFiles android.Paths, } } + for _, aidlLibraryInfo := range aidlLibraryInfos { + for _, aidlSrc := range aidlLibraryInfo.Srcs { + if aidlRule == nil { + // TODO(b/279960133): Sandbox inputs to ensure aidl headers are explicitly specified + aidlRule = android.NewRuleBuilder(pctx, ctx).Sbox(android.PathForModuleGen(ctx, "aidl"), + android.PathForModuleGen(ctx, "aidl.sbox.textproto")) + } + cppFile, aidlHeaders := genAidl(ctx, aidlRule, aidlSrc, buildFlags.aidlFlags) + + srcFiles = append(srcFiles, cppFile) + info.aidlHeaders = append(info.aidlHeaders, aidlHeaders...) + // Use the generated headers as order only deps to ensure that they are up to date when + // needed. + // TODO: Reduce the size of the ninja file by using one order only dep for the whole rule + info.aidlOrderOnlyDeps = append(info.aidlOrderOnlyDeps, aidlHeaders...) + } + } + if aidlRule != nil { aidlRule.Build("aidl", "gen aidl") } diff --git a/cc/library.go b/cc/library.go index 13b333a12..09a7253ab 100644 --- a/cc/library.go +++ b/cc/library.go @@ -271,7 +271,9 @@ type ccAidlLibraryAttributes struct { Implementation_deps bazel.LabelListAttribute Implementation_dynamic_deps bazel.LabelListAttribute Tags bazel.StringListAttribute + sdkAttributes + includesAttributes } type stripAttributes struct { @@ -335,6 +337,14 @@ func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) { Native_coverage: baseAttributes.Native_coverage, } + includeAttrs := includesAttributes{ + Export_includes: exportedIncludes.Includes, + Export_absolute_includes: exportedIncludes.AbsoluteIncludes, + Export_system_includes: exportedIncludes.SystemIncludes, + Local_includes: compilerAttrs.localIncludes, + Absolute_includes: compilerAttrs.absoluteIncludes, + } + sharedCommonAttrs := staticOrSharedAttributes{ Srcs: *srcs.Clone().Append(sharedAttrs.Srcs), Srcs_c: *compilerAttrs.cSrcs.Clone().Append(sharedAttrs.Srcs_c), @@ -356,41 +366,34 @@ func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) { staticTargetAttrs := &bazelCcLibraryStaticAttributes{ staticOrSharedAttributes: staticCommonAttrs, + includesAttributes: includeAttrs, Cppflags: compilerAttrs.cppFlags, Conlyflags: compilerAttrs.conlyFlags, Asflags: asFlags, - Export_includes: exportedIncludes.Includes, - Export_absolute_includes: exportedIncludes.AbsoluteIncludes, - Export_system_includes: exportedIncludes.SystemIncludes, - Local_includes: compilerAttrs.localIncludes, - Absolute_includes: compilerAttrs.absoluteIncludes, - Rtti: compilerAttrs.rtti, - Stl: compilerAttrs.stl, - Cpp_std: compilerAttrs.cppStd, - C_std: compilerAttrs.cStd, + Rtti: compilerAttrs.rtti, + Stl: compilerAttrs.stl, + Cpp_std: compilerAttrs.cppStd, + C_std: compilerAttrs.cStd, Features: *staticFeatures, } sharedTargetAttrs := &bazelCcLibrarySharedAttributes{ staticOrSharedAttributes: sharedCommonAttrs, - Cppflags: compilerAttrs.cppFlags, - Conlyflags: compilerAttrs.conlyFlags, - Asflags: asFlags, + includesAttributes: includeAttrs, - Export_includes: exportedIncludes.Includes, - Export_absolute_includes: exportedIncludes.AbsoluteIncludes, - Export_system_includes: exportedIncludes.SystemIncludes, - Local_includes: compilerAttrs.localIncludes, - Absolute_includes: compilerAttrs.absoluteIncludes, - Linkopts: linkerAttrs.linkopts, - Rtti: compilerAttrs.rtti, - Stl: compilerAttrs.stl, - Cpp_std: compilerAttrs.cppStd, - C_std: compilerAttrs.cStd, - Use_version_lib: linkerAttrs.useVersionLib, + Cppflags: compilerAttrs.cppFlags, + Conlyflags: compilerAttrs.conlyFlags, + Asflags: asFlags, + + Linkopts: linkerAttrs.linkopts, + Rtti: compilerAttrs.rtti, + Stl: compilerAttrs.stl, + Cpp_std: compilerAttrs.cppStd, + C_std: compilerAttrs.cStd, + Use_version_lib: linkerAttrs.useVersionLib, Additional_linker_inputs: linkerAttrs.additionalLinkerInputs, @@ -2114,7 +2117,7 @@ func (library *libraryDecorator) link(ctx ModuleContext, // Optionally export aidl headers. if Bool(library.Properties.Aidl.Export_aidl_headers) { - if library.baseCompiler.hasSrcExt(".aidl") { + if library.baseCompiler.hasAidl(deps) { dir := android.PathForModuleGen(ctx, "aidl") library.reexportDirs(dir) @@ -2880,6 +2883,13 @@ func sharedOrStaticLibraryBp2Build(ctx android.TopDownMutatorContext, module *Mo linkerAttrs := baseAttributes.linkerAttributes exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, &compilerAttrs.includes) + includeAttrs := includesAttributes{ + Export_includes: exportedIncludes.Includes, + Export_absolute_includes: exportedIncludes.AbsoluteIncludes, + Export_system_includes: exportedIncludes.SystemIncludes, + Local_includes: compilerAttrs.localIncludes, + Absolute_includes: compilerAttrs.absoluteIncludes, + } // Append shared/static{} stanza properties. These won't be specified on // cc_library_* itself, but may be specified in cc_defaults that this module @@ -2937,11 +2947,7 @@ func sharedOrStaticLibraryBp2Build(ctx android.TopDownMutatorContext, module *Mo Cpp_std: compilerAttrs.cppStd, C_std: compilerAttrs.cStd, - Export_includes: exportedIncludes.Includes, - Export_absolute_includes: exportedIncludes.AbsoluteIncludes, - Export_system_includes: exportedIncludes.SystemIncludes, - Local_includes: compilerAttrs.localIncludes, - Absolute_includes: compilerAttrs.absoluteIncludes, + includesAttributes: includeAttrs, Cppflags: compilerAttrs.cppFlags, Conlyflags: compilerAttrs.conlyFlags, @@ -2967,11 +2973,8 @@ func sharedOrStaticLibraryBp2Build(ctx android.TopDownMutatorContext, module *Mo Cpp_std: compilerAttrs.cppStd, C_std: compilerAttrs.cStd, - Export_includes: exportedIncludes.Includes, - Export_absolute_includes: exportedIncludes.AbsoluteIncludes, - Export_system_includes: exportedIncludes.SystemIncludes, - Local_includes: compilerAttrs.localIncludes, - Absolute_includes: compilerAttrs.absoluteIncludes, + includesAttributes: includeAttrs, + Additional_linker_inputs: linkerAttrs.additionalLinkerInputs, Strip: stripAttrsFromLinkerAttrs(&linkerAttrs), @@ -3007,9 +3010,18 @@ func sharedOrStaticLibraryBp2Build(ctx android.TopDownMutatorContext, module *Mo ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name(), Tags: tags}, attrs) } +type includesAttributes struct { + Export_includes bazel.StringListAttribute + Export_absolute_includes bazel.StringListAttribute + Export_system_includes bazel.StringListAttribute + Local_includes bazel.StringListAttribute + Absolute_includes bazel.StringListAttribute +} + // TODO(b/199902614): Can this be factored to share with the other Attributes? type bazelCcLibraryStaticAttributes struct { staticOrSharedAttributes + includesAttributes Use_version_lib bazel.BoolAttribute Rtti bazel.BoolAttribute @@ -3017,12 +3029,7 @@ type bazelCcLibraryStaticAttributes struct { Cpp_std *string C_std *string - Export_includes bazel.StringListAttribute - Export_absolute_includes bazel.StringListAttribute - Export_system_includes bazel.StringListAttribute - Local_includes bazel.StringListAttribute - Absolute_includes bazel.StringListAttribute - Hdrs bazel.LabelListAttribute + Hdrs bazel.LabelListAttribute Cppflags bazel.StringListAttribute Conlyflags bazel.StringListAttribute @@ -3034,6 +3041,7 @@ type bazelCcLibraryStaticAttributes struct { // TODO(b/199902614): Can this be factored to share with the other Attributes? type bazelCcLibrarySharedAttributes struct { staticOrSharedAttributes + includesAttributes Linkopts bazel.StringListAttribute Use_version_lib bazel.BoolAttribute @@ -3043,12 +3051,7 @@ type bazelCcLibrarySharedAttributes struct { Cpp_std *string C_std *string - Export_includes bazel.StringListAttribute - Export_absolute_includes bazel.StringListAttribute - Export_system_includes bazel.StringListAttribute - Local_includes bazel.StringListAttribute - Absolute_includes bazel.StringListAttribute - Hdrs bazel.LabelListAttribute + Hdrs bazel.LabelListAttribute Strip stripAttributes Additional_linker_inputs bazel.LabelListAttribute @@ -91,6 +91,11 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { return flags } + // TODO(b/254713216): LTO doesn't work on riscv64 yet. + if ctx.Arch().ArchType == android.Riscv64 { + return flags + } + if lto.LTO(ctx) { var ltoCFlag string var ltoLdFlag string diff --git a/cc/sanitize.go b/cc/sanitize.go index df96b89c8..7fddc1b83 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -653,6 +653,12 @@ func (sanitize *sanitize) begin(ctx BaseModuleContext) { s.Integer_overflow = nil } + // TODO(b/254713216): CFI doesn't work for riscv64 yet because LTO doesn't work. + if ctx.Arch().ArchType == android.Riscv64 { + s.Cfi = nil + s.Diag.Cfi = nil + } + // Disable CFI for musl if ctx.toolchain().Musl() { s.Cfi = nil diff --git a/device_config/Android.bp b/device_config/Android.bp new file mode 100644 index 000000000..360b3898a --- /dev/null +++ b/device_config/Android.bp @@ -0,0 +1,30 @@ +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +bootstrap_go_package { + name: "soong-device_config", + pkgPath: "android/soong/device_config", + deps: [ + "blueprint", + "blueprint-pathtools", + "sbox_proto", + "soong", + "soong-android", + "soong-bazel", + "soong-shared", + ], + srcs: [ + "device_config_definitions.go", + "device_config_values.go", + "device_config_value_set.go", + "init.go", + //"testing.go" + ], + /* + testSrcs: [ + "device_config_test.go", + ], + */ + pluginFor: ["soong_build"], +} diff --git a/device_config/device_config_definitions.go b/device_config/device_config_definitions.go new file mode 100644 index 000000000..c5657666c --- /dev/null +++ b/device_config/device_config_definitions.go @@ -0,0 +1,150 @@ +// Copyright 2023 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package device_config + +import ( + "android/soong/android" + "fmt" + "github.com/google/blueprint" + "strings" +) + +type DefinitionsModule struct { + android.ModuleBase + android.DefaultableModuleBase + + // Properties for "device_config_definitions" + properties struct { + // aconfig files, relative to this Android.bp file + Srcs []string `android:"path"` + + // Release config flag namespace + Namespace string + + // Values from TARGET_RELEASE / RELEASE_DEVICE_CONFIG_VALUE_SETS + Values []string `blueprint:"mutated"` + } + + intermediatePath android.WritablePath + srcJarPath android.WritablePath +} + +func DefinitionsFactory() android.Module { + module := &DefinitionsModule{} + + android.InitAndroidModule(module) + android.InitDefaultableModule(module) + module.AddProperties(&module.properties) + // TODO: bp2build + //android.InitBazelModule(module) + + return module +} + +type implicitValuesTagType struct { + blueprint.BaseDependencyTag +} + +var implicitValuesTag = implicitValuesTagType{} + +func (module *DefinitionsModule) DepsMutator(ctx android.BottomUpMutatorContext) { + // Validate Properties + if len(module.properties.Srcs) == 0 { + ctx.PropertyErrorf("srcs", "missing source files") + return + } + if len(module.properties.Namespace) == 0 { + ctx.PropertyErrorf("namespace", "missing namespace property") + } + + // Add a dependency on the device_config_value_sets defined in + // RELEASE_DEVICE_CONFIG_VALUE_SETS, and add any device_config_values that + // match our namespace. + valuesFromConfig := ctx.Config().ReleaseDeviceConfigValueSets() + ctx.AddDependency(ctx.Module(), implicitValuesTag, valuesFromConfig...) +} + +func (module *DefinitionsModule) OutputFiles(tag string) (android.Paths, error) { + switch tag { + case ".srcjar": + return []android.Path{module.srcJarPath}, nil + case "": + // The default output of this module is the intermediates format, which is + // not installable and in a private format that no other rules can handle + // correctly. + return []android.Path{module.intermediatePath}, nil + default: + return nil, fmt.Errorf("unsupported device_config_definitions module reference tag %q", tag) + } +} + +func joinAndPrefix(prefix string, values []string) string { + var sb strings.Builder + for _, v := range values { + sb.WriteString(prefix) + sb.WriteString(v) + } + return sb.String() +} + +func (module *DefinitionsModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + // Get the values that came from the global RELEASE_DEVICE_CONFIG_VALUE_SETS flag + ctx.VisitDirectDeps(func(dep android.Module) { + if !ctx.OtherModuleHasProvider(dep, valueSetProviderKey) { + // Other modules get injected as dependencies too, for example the license modules + return + } + depData := ctx.OtherModuleProvider(dep, valueSetProviderKey).(valueSetProviderData) + valuesFiles, ok := depData.AvailableNamespaces[module.properties.Namespace] + if ok { + for _, path := range valuesFiles { + module.properties.Values = append(module.properties.Values, path.String()) + } + } + }) + + // Intermediate format + inputFiles := android.PathsForModuleSrc(ctx, module.properties.Srcs) + module.intermediatePath = android.PathForModuleOut(ctx, "intermediate.json") + ctx.Build(pctx, android.BuildParams{ + Rule: aconfigRule, + Inputs: inputFiles, + Output: module.intermediatePath, + Description: "device_config_definitions", + Args: map[string]string{ + "release_version": ctx.Config().ReleaseVersion(), + "namespace": module.properties.Namespace, + "values": joinAndPrefix(" --values ", module.properties.Values), + }, + }) + + // Generated java inside a srcjar + module.srcJarPath = android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar") + ctx.Build(pctx, android.BuildParams{ + Rule: srcJarRule, + Input: module.intermediatePath, + Output: module.srcJarPath, + Description: "device_config.srcjar", + }) + + // TODO: C++ + + // Phony target for debugging convenience + ctx.Build(pctx, android.BuildParams{ + Rule: blueprint.Phony, + Output: android.PathForPhony(ctx, ctx.ModuleName()), + Inputs: []android.Path{module.srcJarPath}, // TODO: C++ + }) +} diff --git a/device_config/device_config_test.go b/device_config/device_config_test.go new file mode 100644 index 000000000..91a06a781 --- /dev/null +++ b/device_config/device_config_test.go @@ -0,0 +1,61 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package device_config + +import ( + "os" + "testing" + + "android/soong/android" + "android/soong/java" +) + +func TestMain(m *testing.M) { + os.Exit(m.Run()) +} + +func test(t *testing.T, bp string) *android.TestResult { + t.Helper() + + mockFS := android.MockFS{ + "config.aconfig": nil, + } + + result := android.GroupFixturePreparers( + java.PrepareForTestWithJavaDefaultModules, + PrepareForTestWithSyspropBuildComponents, + // TODO: Consider values files, although maybe in its own test + // android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + // variables.ReleaseConfigValuesBasePaths = ... + //}) + mockFS.AddToFixture(), + android.FixtureWithRootAndroidBp(bp), + ).RunTest(t) + + return result +} + +func TestOutputs(t *testing.T) { + /*result := */ test(t, ` + device_config { + name: "my_device_config", + srcs: ["config.aconfig"], + } + `) + + // TODO: Make sure it exports a .srcjar, which is used by java libraries + // TODO: Make sure it exports an intermediates file + // TODO: Make sure the intermediates file is propagated to the Android.mk file +} diff --git a/device_config/device_config_value_set.go b/device_config/device_config_value_set.go new file mode 100644 index 000000000..e406d20e0 --- /dev/null +++ b/device_config/device_config_value_set.go @@ -0,0 +1,92 @@ +// Copyright 2023 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package device_config + +import ( + "android/soong/android" + "github.com/google/blueprint" +) + +// Properties for "device_config_value_set" +type ValueSetModule struct { + android.ModuleBase + android.DefaultableModuleBase + + properties struct { + // device_config_values modules + Values []string + } +} + +func ValueSetFactory() android.Module { + module := &ValueSetModule{} + + android.InitAndroidModule(module) + android.InitDefaultableModule(module) + module.AddProperties(&module.properties) + // TODO: bp2build + //android.InitBazelModule(module) + + return module +} + +// Dependency tag for values property +type valueSetType struct { + blueprint.BaseDependencyTag +} + +var valueSetTag = valueSetType{} + +// Provider published by device_config_value_set +type valueSetProviderData struct { + // The namespace of each of the + // (map of namespace --> device_config_module) + AvailableNamespaces map[string]android.Paths +} + +var valueSetProviderKey = blueprint.NewProvider(valueSetProviderData{}) + +func (module *ValueSetModule) DepsMutator(ctx android.BottomUpMutatorContext) { + deps := ctx.AddDependency(ctx.Module(), valueSetTag, module.properties.Values...) + for _, dep := range deps { + _, ok := dep.(*ValuesModule) + if !ok { + ctx.PropertyErrorf("values", "values must be a device_config_values module") + return + } + } +} + +func (module *ValueSetModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + // Accumulate the namespaces of the values modules listed, and set that as an + // valueSetProviderKey provider that device_config modules can read and use + // to append values to their aconfig actions. + namespaces := make(map[string]android.Paths) + ctx.VisitDirectDeps(func(dep android.Module) { + if !ctx.OtherModuleHasProvider(dep, valuesProviderKey) { + // Other modules get injected as dependencies too, for example the license modules + return + } + depData := ctx.OtherModuleProvider(dep, valuesProviderKey).(valuesProviderData) + + srcs := make([]android.Path, len(depData.Values)) + copy(srcs, depData.Values) + namespaces[depData.Namespace] = srcs + + }) + ctx.SetProvider(valueSetProviderKey, valueSetProviderData{ + AvailableNamespaces: namespaces, + }) +} diff --git a/device_config/device_config_values.go b/device_config/device_config_values.go new file mode 100644 index 000000000..110f12a1c --- /dev/null +++ b/device_config/device_config_values.go @@ -0,0 +1,70 @@ +// Copyright 2023 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package device_config + +import ( + "android/soong/android" + "github.com/google/blueprint" +) + +// Properties for "device_config_value" +type ValuesModule struct { + android.ModuleBase + android.DefaultableModuleBase + + properties struct { + // aconfig files, relative to this Android.bp file + Srcs []string `android:"path"` + + // Release config flag namespace + Namespace string + } +} + +func ValuesFactory() android.Module { + module := &ValuesModule{} + + android.InitAndroidModule(module) + android.InitDefaultableModule(module) + module.AddProperties(&module.properties) + // TODO: bp2build + //android.InitBazelModule(module) + + return module +} + +// Provider published by device_config_value_set +type valuesProviderData struct { + // The namespace that this values module values + Namespace string + + // The values aconfig files, relative to the root of the tree + Values android.Paths +} + +var valuesProviderKey = blueprint.NewProvider(valuesProviderData{}) + +func (module *ValuesModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + if len(module.properties.Namespace) == 0 { + ctx.PropertyErrorf("namespace", "missing namespace property") + } + + // Provide the our source files list to the device_config_value_set as a list of files + providerData := valuesProviderData{ + Namespace: module.properties.Namespace, + Values: android.PathsForModuleSrc(ctx, module.properties.Srcs), + } + ctx.SetProvider(valuesProviderKey, providerData) +} diff --git a/device_config/init.go b/device_config/init.go new file mode 100644 index 000000000..0a4645b2b --- /dev/null +++ b/device_config/init.go @@ -0,0 +1,70 @@ +// Copyright 2023 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package device_config + +import ( + "android/soong/android" + "github.com/google/blueprint" +) + +var ( + pctx = android.NewPackageContext("android/soong/device_config") + + // For device_config_definitions: Generate cache file + // TODO: Restat + aconfigRule = pctx.AndroidStaticRule("aconfig", + blueprint.RuleParams{ + Command: `${aconfig} create-cache` + + ` --namespace ${namespace}` + + ` --declarations ${in}` + + ` ${values}` + + ` --cache ${out}.tmp` + + ` && ( if cmp -s ${out}.tmp ; then rm ${out}.tmp ; else mv ${out}.tmp ${out} ; fi )`, + // ` --build-id ${release_version}` + + CommandDeps: []string{ + "${aconfig}", + }, + Restat: true, + }, "release_version", "namespace", "values") + + // For device_config_definitions: Generate java file + srcJarRule = pctx.AndroidStaticRule("aconfig_srcjar", + blueprint.RuleParams{ + Command: `rm -rf ${out}.tmp` + + ` && mkdir -p ${out}.tmp` + + ` && ${aconfig} create-java-lib` + + ` --cache ${in}` + + ` --out ${out}.tmp` + + ` && $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` + + ` && rm -rf ${out}.tmp`, + CommandDeps: []string{ + "$aconfig", + "$soong_zip", + }, + Restat: true, + }) +) + +func init() { + registerBuildComponents(android.InitRegistrationContext) +} + +func registerBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("device_config_definitions", DefinitionsFactory) + ctx.RegisterModuleType("device_config_values", ValuesFactory) + ctx.RegisterModuleType("device_config_value_set", ValueSetFactory) + pctx.HostBinToolVariable("aconfig", "aconfig") + pctx.HostBinToolVariable("soong_zip", "soong_zip") +} diff --git a/device_config/testing.go b/device_config/testing.go new file mode 100644 index 000000000..f0544766b --- /dev/null +++ b/device_config/testing.go @@ -0,0 +1,19 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package device_config + +import "android/soong/android" + +var PrepareForTestWithSyspropBuildComponents = android.FixtureRegisterWithContext(registerBuildComponents) diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go index 6817dcef0..3e1bbded6 100644 --- a/etc/prebuilt_etc.go +++ b/etc/prebuilt_etc.go @@ -652,9 +652,7 @@ func generatePrebuiltSnapshot(s snapshot.SnapshotSingleton, ctx android.Singleto prop := snapshot.SnapshotJsonFlags{} propOut := snapshotLibOut + ".json" prop.InitBaseSnapshotProps(m) - if m.subdirProperties.Relative_install_path != nil { - prop.RelativeInstallPath = *m.subdirProperties.Relative_install_path - } + prop.RelativeInstallPath = m.SubDir() if m.properties.Filename != nil { prop.Filename = *m.properties.Filename |