diff options
author | 2025-02-03 12:17:42 -0800 | |
---|---|---|
committer | 2025-02-03 22:19:24 -0800 | |
commit | bd930bc6c4ff8539da60d6cda69f484a817a31ed (patch) | |
tree | cbdf1bd4fce5913ffd314187104869d8ac293ca2 | |
parent | c5f4de515f5d1686ed5164dddc2f28134c9aeee4 (diff) |
Add explicitlyImpl to shared library dependency tags
Instead of testing that explicit implementation libraries are not
incorrectly used in an apex after the fact add the explicitlyImpl
flag to dependency tags and use it in cc.DepIsInSameApex and
rust.DepIsInSameApex to require that explicit implementation
dependencies are in the same apex.
Bug: 372543712
Test: go test ./...
Change-Id: Ia968e06b578d5ab886a965c3981565d4895dddcd
-rw-r--r-- | apex/apex_test.go | 395 | ||||
-rw-r--r-- | cc/cc.go | 11 | ||||
-rw-r--r-- | rust/rust.go | 2 |
3 files changed, 11 insertions, 397 deletions
diff --git a/apex/apex_test.go b/apex/apex_test.go index d6cb79aa4..bc4669580 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -20,7 +20,6 @@ import ( "path/filepath" "reflect" "regexp" - "slices" "sort" "strconv" "strings" @@ -29,7 +28,6 @@ import ( "android/soong/aconfig/codegen" "github.com/google/blueprint" - "github.com/google/blueprint/bpmodify" "github.com/google/blueprint/proptools" "android/soong/android" @@ -12219,396 +12217,3 @@ func TestFilesystemWithApexDeps(t *testing.T) { fileList := android.ContentFromFileRuleForTests(t, result, partition.Output("fileList")) android.AssertDeepEquals(t, "filesystem with apex", "apex/myapex.apex\n", fileList) } - -func TestApexVerifyNativeImplementationLibs(t *testing.T) { - t.Parallel() - - extractDepenencyPathFromErrors := func(errs []error) []string { - i := slices.IndexFunc(errs, func(err error) bool { - return strings.Contains(err.Error(), "dependency path:") - }) - if i < 0 { - return nil - } - var dependencyPath []string - for _, err := range errs[i+1:] { - s := err.Error() - lastSpace := strings.LastIndexByte(s, ' ') - if lastSpace >= 0 { - dependencyPath = append(dependencyPath, s[lastSpace+1:]) - } - } - return dependencyPath - } - - checkErrors := func(wantDependencyPath []string) func(t *testing.T, result *android.TestResult) { - return func(t *testing.T, result *android.TestResult) { - t.Helper() - if len(result.Errs) == 0 { - t.Fatalf("expected errors") - } - t.Log("found errors:") - for _, err := range result.Errs { - t.Log(err) - } - if g, w := result.Errs[0].Error(), "library in apex transitively linked against implementation library"; !strings.Contains(g, w) { - t.Fatalf("expected error %q, got %q", w, g) - } - dependencyPath := extractDepenencyPathFromErrors(result.Errs) - if g, w := dependencyPath, wantDependencyPath; !slices.Equal(g, w) { - t.Errorf("expected dependency path %q, got %q", w, g) - } - } - } - - addToSharedLibs := func(module, lib string) func(bp *bpmodify.Blueprint) { - return func(bp *bpmodify.Blueprint) { - m := bp.ModulesByName(module) - props, err := m.GetOrCreateProperty(bpmodify.List, "shared_libs") - if err != nil { - panic(err) - } - props.AddStringToList(lib) - } - } - - bpTemplate := ` - apex { - name: "myapex", - key: "myapex.key", - native_shared_libs: ["mylib"], - rust_dyn_libs: ["libmyrust"], - binaries: ["mybin", "myrustbin"], - jni_libs: ["libjni"], - apps: ["myapp"], - updatable: false, - } - - apex { - name: "otherapex", - key: "myapex.key", - native_shared_libs: ["libotherapex"], - updatable: false, - } - - apex_key { - name: "myapex.key", - public_key: "testkey.avbpubkey", - private_key: "testkey.pem", - } - - cc_library { - name: "mylib", - srcs: ["foo.cpp"], - apex_available: ["myapex"], - } - - cc_binary { - name: "mybin", - srcs: ["foo.cpp"], - apex_available: ["myapex"], - } - - rust_library { - name: "libmyrust", - crate_name: "myrust", - srcs: ["src/lib.rs"], - rustlibs: ["libmyrust_transitive_dylib"], - rlibs: ["libmyrust_transitive_rlib"], - apex_available: ["myapex"], - } - - rust_library{ - name: "libmyrust_transitive_dylib", - crate_name: "myrust_transitive_dylib", - srcs: ["src/lib.rs"], - apex_available: ["myapex"], - } - - rust_library { - name: "libmyrust_transitive_rlib", - crate_name: "myrust_transitive_rlib", - srcs: ["src/lib.rs"], - apex_available: ["myapex"], - } - - rust_binary { - name: "myrustbin", - srcs: ["src/main.rs"], - apex_available: ["myapex"], - } - - cc_library { - name: "libbar", - sdk_version: "current", - srcs: ["bar.cpp"], - apex_available: ["myapex"], - stl: "none", - } - - android_app { - name: "myapp", - jni_libs: ["libembeddedjni"], - use_embedded_native_libs: true, - sdk_version: "current", - apex_available: ["myapex"], - } - - cc_library { - name: "libembeddedjni", - sdk_version: "current", - srcs: ["bar.cpp"], - apex_available: ["myapex"], - stl: "none", - } - - cc_library { - name: "libjni", - sdk_version: "current", - srcs: ["bar.cpp"], - apex_available: ["myapex"], - stl: "none", - } - - cc_library { - name: "libotherapex", - sdk_version: "current", - srcs: ["otherapex.cpp"], - apex_available: ["otherapex"], - stubs: { - symbol_file: "libotherapex.map.txt", - versions: ["1", "2", "3"], - }, - stl: "none", - } - - cc_library { - name: "libplatform", - sdk_version: "current", - srcs: ["libplatform.cpp"], - stubs: { - symbol_file: "libplatform.map.txt", - versions: ["1", "2", "3"], - }, - stl: "none", - system_shared_libs: [], - } - ` - - testCases := []struct { - name string - bpModifier func(bp *bpmodify.Blueprint) - dependencyPath []string - }{ - { - name: "library dependency in other apex", - bpModifier: addToSharedLibs("mylib", "libotherapex#impl"), - dependencyPath: []string{"myapex", "mylib", "libotherapex"}, - }, - { - name: "transitive library dependency in other apex", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("mylib", "libbar")(bp) - addToSharedLibs("libbar", "libotherapex#impl")(bp) - }, - dependencyPath: []string{"myapex", "mylib", "libbar", "libotherapex"}, - }, - { - name: "library dependency in platform", - bpModifier: addToSharedLibs("mylib", "libplatform#impl"), - dependencyPath: []string{"myapex", "mylib", "libplatform"}, - }, - { - name: "jni library dependency in other apex", - bpModifier: addToSharedLibs("libjni", "libotherapex#impl"), - dependencyPath: []string{"myapex", "libjni", "libotherapex"}, - }, - { - name: "transitive jni library dependency in other apex", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("libjni", "libbar")(bp) - addToSharedLibs("libbar", "libotherapex#impl")(bp) - }, - dependencyPath: []string{"myapex", "libjni", "libbar", "libotherapex"}, - }, - { - name: "jni library dependency in platform", - bpModifier: addToSharedLibs("libjni", "libplatform#impl"), - dependencyPath: []string{"myapex", "libjni", "libplatform"}, - }, - { - name: "transitive jni library dependency in platform", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("libjni", "libbar")(bp) - addToSharedLibs("libbar", "libplatform#impl")(bp) - }, - dependencyPath: []string{"myapex", "libjni", "libbar", "libplatform"}, - }, - { - name: "app jni library dependency in other apex", - bpModifier: addToSharedLibs("libembeddedjni", "libotherapex#impl"), - dependencyPath: []string{"myapex", "myapp", "libembeddedjni", "libotherapex"}, - }, - { - name: "transitive app jni library dependency in other apex", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("libembeddedjni", "libbar")(bp) - addToSharedLibs("libbar", "libotherapex#impl")(bp) - }, - dependencyPath: []string{"myapex", "myapp", "libembeddedjni", "libbar", "libotherapex"}, - }, - { - name: "app jni library dependency in platform", - bpModifier: addToSharedLibs("libembeddedjni", "libplatform#impl"), - dependencyPath: []string{"myapex", "myapp", "libembeddedjni", "libplatform"}, - }, - { - name: "transitive app jni library dependency in platform", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("libembeddedjni", "libbar")(bp) - addToSharedLibs("libbar", "libplatform#impl")(bp) - }, - dependencyPath: []string{"myapex", "myapp", "libembeddedjni", "libbar", "libplatform"}, - }, - { - name: "binary dependency in other apex", - bpModifier: addToSharedLibs("mybin", "libotherapex#impl"), - dependencyPath: []string{"myapex", "mybin", "libotherapex"}, - }, - { - name: "transitive binary dependency in other apex", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("mybin", "libbar")(bp) - addToSharedLibs("libbar", "libotherapex#impl")(bp) - }, - dependencyPath: []string{"myapex", "mybin", "libbar", "libotherapex"}, - }, - { - name: "binary dependency in platform", - bpModifier: addToSharedLibs("mybin", "libplatform#impl"), - dependencyPath: []string{"myapex", "mybin", "libplatform"}, - }, - { - name: "transitive binary dependency in platform", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("mybin", "libbar")(bp) - addToSharedLibs("libbar", "libplatform#impl")(bp) - }, - dependencyPath: []string{"myapex", "mybin", "libbar", "libplatform"}, - }, - - { - name: "rust library dependency in other apex", - bpModifier: addToSharedLibs("libmyrust", "libotherapex#impl"), - dependencyPath: []string{"myapex", "libmyrust", "libotherapex"}, - }, - { - name: "transitive rust library dependency in other apex", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("libmyrust", "libbar")(bp) - addToSharedLibs("libbar", "libotherapex#impl")(bp) - }, - dependencyPath: []string{"myapex", "libmyrust", "libbar", "libotherapex"}, - }, - { - name: "rust library dependency in platform", - bpModifier: addToSharedLibs("libmyrust", "libplatform#impl"), - dependencyPath: []string{"myapex", "libmyrust", "libplatform"}, - }, - { - name: "transitive rust library dependency in platform", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("libmyrust", "libbar")(bp) - addToSharedLibs("libbar", "libplatform#impl")(bp) - }, - dependencyPath: []string{"myapex", "libmyrust", "libbar", "libplatform"}, - }, - { - name: "transitive rust library dylib dependency in other apex", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("libmyrust_transitive_dylib", "libotherapex#impl")(bp) - }, - dependencyPath: []string{"myapex", "libmyrust", "libmyrust_transitive_dylib", "libotherapex"}, - }, - { - name: "transitive rust library dylib dependency in platform", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("libmyrust_transitive_dylib", "libplatform#impl")(bp) - }, - dependencyPath: []string{"myapex", "libmyrust", "libmyrust_transitive_dylib", "libplatform"}, - }, - { - name: "transitive rust library rlib dependency in other apex", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("libmyrust_transitive_rlib", "libotherapex#impl")(bp) - }, - dependencyPath: []string{"myapex", "libmyrust", "libmyrust_transitive_rlib", "libotherapex"}, - }, - { - name: "transitive rust library rlib dependency in platform", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("libmyrust_transitive_rlib", "libplatform#impl")(bp) - }, - dependencyPath: []string{"myapex", "libmyrust", "libmyrust_transitive_rlib", "libplatform"}, - }, - { - name: "rust binary dependency in other apex", - bpModifier: addToSharedLibs("myrustbin", "libotherapex#impl"), - dependencyPath: []string{"myapex", "myrustbin", "libotherapex"}, - }, - { - name: "transitive rust binary dependency in other apex", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("myrustbin", "libbar")(bp) - addToSharedLibs("libbar", "libotherapex#impl")(bp) - }, - dependencyPath: []string{"myapex", "myrustbin", "libbar", "libotherapex"}, - }, - { - name: "rust binary dependency in platform", - bpModifier: addToSharedLibs("myrustbin", "libplatform#impl"), - dependencyPath: []string{"myapex", "myrustbin", "libplatform"}, - }, - { - name: "transitive rust binary dependency in platform", - bpModifier: func(bp *bpmodify.Blueprint) { - addToSharedLibs("myrustbin", "libbar")(bp) - addToSharedLibs("libbar", "libplatform#impl")(bp) - }, - dependencyPath: []string{"myapex", "myrustbin", "libbar", "libplatform"}, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.name, func(t *testing.T) { - t.Parallel() - bp, err := bpmodify.NewBlueprint("", []byte(bpTemplate)) - if err != nil { - t.Fatal(err) - } - if testCase.bpModifier != nil { - func() { - defer func() { - if r := recover(); r != nil { - t.Fatalf("panic in bpModifier: %v", r) - } - }() - testCase.bpModifier(bp) - }() - } - android.GroupFixturePreparers( - android.PrepareForTestWithAndroidBuildComponents, - cc.PrepareForTestWithCcBuildComponents, - java.PrepareForTestWithDexpreopt, - rust.PrepareForTestWithRustDefaultModules, - PrepareForTestWithApexBuildComponents, - prepareForTestWithMyapex, - prepareForTestWithOtherapex, - android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { - variables.BuildId = proptools.StringPtr("TEST.BUILD_ID") - }), - ).ExtendWithErrorHandler(android.FixtureCustomErrorHandler(checkErrors(testCase.dependencyPath))). - RunTestWithBp(t, bp.String()) - }) - } -} @@ -839,6 +839,7 @@ type libraryDependencyTag struct { reexportFlags bool explicitlyVersioned bool + explicitlyImpl bool dataLib bool ndk bool @@ -934,6 +935,11 @@ var ( llndkHeaderLibTag = dependencyTag{name: "llndk_header_lib"} ) +func IsExplicitImplSharedDepTag(depTag blueprint.DependencyTag) bool { + ccLibDepTag, ok := depTag.(libraryDependencyTag) + return ok && ccLibDepTag.shared() && ccLibDepTag.explicitlyImpl +} + func IsSharedDepTag(depTag blueprint.DependencyTag) bool { ccLibDepTag, ok := depTag.(libraryDependencyTag) return ok && ccLibDepTag.shared() @@ -2699,6 +2705,9 @@ func AddSharedLibDependenciesWithVersions(ctx android.BottomUpMutatorContext, mo variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version}) if tag, ok := depTag.(libraryDependencyTag); ok { tag.explicitlyVersioned = true + if version == "" { + tag.explicitlyImpl = true + } // depTag is an interface that contains a concrete non-pointer struct. That makes the local // tag variable a copy of the contents of depTag, and updating it doesn't change depTag. Reassign // the modified copy to depTag. @@ -4074,7 +4083,7 @@ func (c *Module) OutgoingDepIsInSameApex(depTag blueprint.DependencyTag) bool { func (c *Module) IncomingDepIsInSameApex(depTag blueprint.DependencyTag) bool { if c.HasStubsVariants() { - if IsSharedDepTag(depTag) { + if IsSharedDepTag(depTag) && !IsExplicitImplSharedDepTag(depTag) { // dynamic dep to a stubs lib crosses APEX boundary return false } diff --git a/rust/rust.go b/rust/rust.go index c0df9f3da..88918cf82 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -2085,7 +2085,7 @@ func (mod *Module) IncomingDepIsInSameApex(depTag blueprint.DependencyTag) bool } if mod.HasStubsVariants() { - if cc.IsSharedDepTag(depTag) { + if cc.IsSharedDepTag(depTag) && !cc.IsExplicitImplSharedDepTag(depTag) { // dynamic dep to a stubs lib crosses APEX boundary return false } |