From ac0c87311d6671cf442120ff56e24c40418de441 Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Wed, 14 Feb 2024 10:25:55 +0000 Subject: [PATCH] Revert^2 "Integrate Rust-specific System Properties into rules generation." This reverts commit be3ea4f149c8688a8b76c4587a4c5f6813d567c1. Reason for revert: Reland Change-Id: Ic003c52a1477da9a6a70b82e4d4ae4a55edc584f --- rust/testing.go | 1 + sysprop/Android.bp | 1 + sysprop/sysprop_library.go | 125 +++++++++++++++++++++++++++++++++++++ sysprop/sysprop_test.go | 36 +++++++---- 4 files changed, 151 insertions(+), 12 deletions(-) diff --git a/rust/testing.go b/rust/testing.go index 3fe751e17..713a7448c 100644 --- a/rust/testing.go +++ b/rust/testing.go @@ -75,6 +75,7 @@ func GatherRequiredDepsForTest() string { apex_available: ["//apex_available:platform", "//apex_available:anyapex"], min_sdk_version: "29", vendor_available: true, + host_supported: true, recovery_available: true, llndk: { symbol_file: "liblog.map.txt", diff --git a/sysprop/Android.bp b/sysprop/Android.bp index e5263fec4..d601fac31 100644 --- a/sysprop/Android.bp +++ b/sysprop/Android.bp @@ -12,6 +12,7 @@ bootstrap_go_package { "soong-bp2build", "soong-cc", "soong-java", + "soong-rust", ], srcs: [ "sysprop_library.go", diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go index a2c0fb731..2927e2b3e 100644 --- a/sysprop/sysprop_library.go +++ b/sysprop/sysprop_library.go @@ -21,6 +21,7 @@ import ( "io" "os" "path" + "strings" "sync" "android/soong/bazel" @@ -31,6 +32,7 @@ import ( "android/soong/android" "android/soong/cc" "android/soong/java" + "android/soong/rust" ) type dependencyTag struct { @@ -53,7 +55,16 @@ type syspropJavaGenRule struct { genSrcjars android.Paths } +type syspropRustGenRule struct { + android.ModuleBase + + properties syspropGenProperties + + genSrcs android.Paths +} + var _ android.OutputFileProducer = (*syspropJavaGenRule)(nil) +var _ android.OutputFileProducer = (*syspropRustGenRule)(nil) var ( syspropJava = pctx.AndroidStaticRule("syspropJava", @@ -66,11 +77,20 @@ var ( "$soongZipCmd", }, }, "scope") + syspropRust = pctx.AndroidStaticRule("syspropRust", + blueprint.RuleParams{ + Command: `rm -rf $out_dir && mkdir -p $out_dir && ` + + `$syspropRustCmd --scope $scope --rust-output-dir $out_dir $in`, + CommandDeps: []string{ + "$syspropRustCmd", + }, + }, "scope", "out_dir") ) func init() { pctx.HostBinToolVariable("soongZipCmd", "soong_zip") pctx.HostBinToolVariable("syspropJavaCmd", "sysprop_java") + pctx.HostBinToolVariable("syspropRustCmd", "sysprop_rust") } // syspropJavaGenRule module generates srcjar containing generated java APIs. @@ -124,6 +144,56 @@ func syspropJavaGenFactory() android.Module { return g } +// syspropRustGenRule module generates rust source files containing generated rust APIs. +// It also depends on check api rule, so api check has to pass to use sysprop_library. +func (g *syspropRustGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + var checkApiFileTimeStamp android.WritablePath + + ctx.VisitDirectDeps(func(dep android.Module) { + if m, ok := dep.(*syspropLibrary); ok { + checkApiFileTimeStamp = m.checkApiFileTimeStamp + } + }) + + for _, syspropFile := range android.PathsForModuleSrc(ctx, g.properties.Srcs) { + syspropDir := strings.TrimSuffix(syspropFile.String(), syspropFile.Ext()) + outputDir := android.PathForModuleGen(ctx, syspropDir, "src") + libPath := android.PathForModuleGen(ctx, syspropDir, "src", "lib.rs") + parsersPath := android.PathForModuleGen(ctx, syspropDir, "src", "gen_parsers_and_formatters.rs") + + ctx.Build(pctx, android.BuildParams{ + Rule: syspropRust, + Description: "sysprop_rust " + syspropFile.Rel(), + Outputs: android.WritablePaths{libPath, parsersPath}, + Input: syspropFile, + Implicit: checkApiFileTimeStamp, + Args: map[string]string{ + "scope": g.properties.Scope, + "out_dir": outputDir.String(), + }, + }) + + g.genSrcs = append(g.genSrcs, libPath, parsersPath) + } +} + +func (g *syspropRustGenRule) DepsMutator(ctx android.BottomUpMutatorContext) { + // Add a dependency from the stubs to sysprop library so that the generator rule can depend on + // the check API rule of the sysprop library. + ctx.AddFarVariationDependencies(nil, nil, proptools.String(g.properties.Check_api)) +} + +func (g *syspropRustGenRule) OutputFiles(_ string) (android.Paths, error) { + return g.genSrcs, nil +} + +func syspropRustGenFactory() android.Module { + g := &syspropRustGenRule{} + g.AddProperties(&g.properties) + android.InitAndroidModule(g) + return g +} + type syspropLibrary struct { android.ModuleBase android.ApexModuleBase @@ -177,6 +247,12 @@ type syspropLibraryProperties struct { // Forwarded to java_library.min_sdk_version Min_sdk_version *string } + + Rust struct { + // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX). + // Forwarded to rust_library.min_sdk_version + Min_sdk_version *string + } } var ( @@ -230,6 +306,21 @@ func (m *syspropLibrary) javaGenPublicStubName() string { return m.BaseModuleName() + "_java_gen_public" } +func (m *syspropLibrary) rustGenModuleName() string { + return m.rustCrateName() + "_rust_gen" +} + +func (m *syspropLibrary) rustGenStubName() string { + return "lib" + m.rustCrateName() + "_rust" +} + +func (m *syspropLibrary) rustCrateName() string { + moduleName := strings.ToLower(m.BaseModuleName()) + moduleName = strings.ReplaceAll(moduleName, "-", "_") + moduleName = strings.ReplaceAll(moduleName, ".", "_") + return moduleName +} + func (m *syspropLibrary) BaseModuleName() string { return m.ModuleBase.Name() } @@ -434,6 +525,18 @@ type javaLibraryProperties struct { } } +type rustLibraryProperties struct { + Name *string + Srcs []string + Installable *bool + Crate_name string + Rustlibs []string + Vendor_available *bool + Product_available *bool + Apex_available []string + Min_sdk_version *string +} + func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { if len(m.properties.Srcs) == 0 { ctx.PropertyErrorf("srcs", "sysprop_library must specify srcs") @@ -579,6 +682,28 @@ func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { }) } + // Generate a Rust implementation library. + ctx.CreateModule(syspropRustGenFactory, &syspropGenProperties{ + Srcs: m.properties.Srcs, + Scope: scope, + Name: proptools.StringPtr(m.rustGenModuleName()), + Check_api: proptools.StringPtr(ctx.ModuleName()), + }) + rustProps := rustLibraryProperties{ + Name: proptools.StringPtr(m.rustGenStubName()), + Srcs: []string{":" + m.rustGenModuleName()}, + Installable: proptools.BoolPtr(false), + Crate_name: m.rustCrateName(), + Rustlibs: []string{ + "librustutils", + }, + Vendor_available: m.properties.Vendor_available, + Product_available: m.properties.Product_available, + Apex_available: m.ApexProperties.Apex_available, + Min_sdk_version: proptools.StringPtr("29"), + } + ctx.CreateModule(rust.RustLibraryFactory, &rustProps) + // syspropLibraries will be used by property_contexts to check types. // Record absolute paths of sysprop_library to prevent soong_namespace problem. if m.ExportedToMake() { diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go index 80b86e059..e6464a7bd 100644 --- a/sysprop/sysprop_test.go +++ b/sysprop/sysprop_test.go @@ -22,6 +22,7 @@ import ( "android/soong/android" "android/soong/cc" "android/soong/java" + "android/soong/rust" "github.com/google/blueprint/proptools" ) @@ -45,18 +46,6 @@ func test(t *testing.T, bp string) *android.TestResult { recovery_available: true, } - cc_library { - name: "liblog", - no_libcrt: true, - nocrt: true, - system_shared_libs: [], - recovery_available: true, - host_supported: true, - llndk: { - symbol_file: "liblog.map.txt", - } - } - java_library { name: "sysprop-library-stub-platform", sdk_version: "core_current", @@ -73,6 +62,15 @@ func test(t *testing.T, bp string) *android.TestResult { product_specific: true, sdk_version: "core_current", } + + rust_library { + name: "librustutils", + crate_name: "rustutils", + srcs: ["librustutils/lib.rs"], + product_available: true, + vendor_available: true, + min_sdk_version: "29", + } ` mockFS := android.MockFS{ @@ -114,11 +112,14 @@ func test(t *testing.T, bp string) *android.TestResult { "android/sysprop/PlatformProperties.sysprop": nil, "com/android/VendorProperties.sysprop": nil, "com/android2/OdmProperties.sysprop": nil, + + "librustutils/lib.rs": nil, } result := android.GroupFixturePreparers( cc.PrepareForTestWithCcDefaultModules, java.PrepareForTestWithJavaDefaultModules, + rust.PrepareForTestWithRustDefaultModules, PrepareForTestWithSyspropBuildComponents, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { variables.DeviceSystemSdkVersions = []string{"28"} @@ -342,6 +343,10 @@ func TestApexAvailabilityIsForwarded(t *testing.T) { javaModule := result.ModuleForTests("sysprop-platform", "android_common").Module().(*java.Library) propFromJava := javaModule.ApexProperties.Apex_available android.AssertDeepEquals(t, "apex_available forwarding to java module", expected, propFromJava) + + rustModule := result.ModuleForTests("libsysprop_platform_rust", "android_arm64_armv8-a_rlib_rlib-std").Module().(*rust.Module) + propFromRust := rustModule.ApexProperties.Apex_available + android.AssertDeepEquals(t, "apex_available forwarding to rust module", expected, propFromRust) } func TestMinSdkVersionIsForwarded(t *testing.T) { @@ -357,6 +362,9 @@ func TestMinSdkVersionIsForwarded(t *testing.T) { java: { min_sdk_version: "30", }, + rust: { + min_sdk_version: "29", + } } `) @@ -367,4 +375,8 @@ func TestMinSdkVersionIsForwarded(t *testing.T) { javaModule := result.ModuleForTests("sysprop-platform", "android_common").Module().(*java.Library) propFromJava := javaModule.MinSdkVersionString() android.AssertStringEquals(t, "min_sdk_version forwarding to java module", "30", propFromJava) + + rustModule := result.ModuleForTests("libsysprop_platform_rust", "android_arm64_armv8-a_rlib_rlib-std").Module().(*rust.Module) + propFromRust := proptools.String(rustModule.Properties.Min_sdk_version) + android.AssertStringEquals(t, "min_sdk_version forwarding to rust module", "29", propFromRust) }