diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go index 4dbda49b3..814b75dc7 100644 --- a/dexpreopt/dexpreopt.go +++ b/dexpreopt/dexpreopt.go @@ -218,13 +218,21 @@ func (m classLoaderContextMap) getValue(sdkVer int) *classLoaderContext { return m[sdkVer] } -func (m classLoaderContextMap) addLibs(sdkVer int, module *ModuleConfig, libs ...string) bool { +func (m classLoaderContextMap) addLibs(ctx android.PathContext, sdkVer int, module *ModuleConfig, libs ...string) bool { clc := m.getValue(sdkVer) for _, lib := range libs { - if p := pathForLibrary(module, lib); p != nil { + if p, ok := module.LibraryPaths[lib]; ok && p.Host != nil && p.Device != UnknownInstallLibraryPath { clc.Host = append(clc.Host, p.Host) clc.Target = append(clc.Target, p.Device) } else { + if sdkVer == anySdkVersion { + // Fail the build if dexpreopt doesn't know paths to one of the + // dependencies. In the future we may need to relax this and just disable dexpreopt. + android.ReportPathErrorf(ctx, "dexpreopt cannot find path for '%s'", lib) + } else { + // No error for compatibility libraries, as Soong doesn't know if they are needed + // (this depends on the targetSdkVersion in the manifest). + } return false } } @@ -270,14 +278,14 @@ func genClassLoaderContext(ctx android.PathContext, global *GlobalConfig, module } else if module.EnforceUsesLibraries { // Unconditional class loader context. usesLibs := append(copyOf(module.UsesLibraries), module.OptionalUsesLibraries...) - if !classLoaderContexts.addLibs(anySdkVersion, module, usesLibs...) { + if !classLoaderContexts.addLibs(ctx, anySdkVersion, module, usesLibs...) { return nil } // Conditional class loader context for API version < 28. const httpLegacy = "org.apache.http.legacy" if !contains(usesLibs, httpLegacy) { - if !classLoaderContexts.addLibs(28, module, httpLegacy) { + if !classLoaderContexts.addLibs(ctx, 28, module, httpLegacy) { return nil } } @@ -287,14 +295,14 @@ func genClassLoaderContext(ctx android.PathContext, global *GlobalConfig, module "android.hidl.base-V1.0-java", "android.hidl.manager-V1.0-java", } - if !classLoaderContexts.addLibs(29, module, usesLibs29...) { + if !classLoaderContexts.addLibs(ctx, 29, module, usesLibs29...) { return nil } // Conditional class loader context for API version < 30. const testBase = "android.test.base" if !contains(usesLibs, testBase) { - if !classLoaderContexts.addLibs(30, module, testBase) { + if !classLoaderContexts.addLibs(ctx, 30, module, testBase) { return nil } } @@ -589,14 +597,6 @@ func PathToLocation(path android.Path, arch android.ArchType) string { return filepath.Join(filepath.Dir(filepath.Dir(path.String())), filepath.Base(path.String())) } -func pathForLibrary(module *ModuleConfig, lib string) *LibraryPath { - if path, ok := module.LibraryPaths[lib]; ok && path.Host != nil && path.Device != "error" { - return path - } else { - return nil - } -} - func makefileMatch(pattern, s string) bool { percent := strings.IndexByte(pattern, '%') switch percent { diff --git a/java/app_test.go b/java/app_test.go index 4347db8b1..31b422c64 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -2754,19 +2754,6 @@ func TestUsesLibraries(t *testing.T) { android_app { name: "app", srcs: ["a.java"], - libs: ["qux", "quuz"], - static_libs: ["static-runtime-helper"], - uses_libs: ["foo"], - sdk_version: "current", - optional_uses_libs: [ - "bar", - "baz", - ], - } - - android_app { - name: "app_with_stub_deps", - srcs: ["a.java"], libs: ["qux", "quuz.stubs"], static_libs: ["static-runtime-helper"], uses_libs: ["foo"], @@ -2797,7 +2784,6 @@ func TestUsesLibraries(t *testing.T) { run(t, ctx, config) app := ctx.ModuleForTests("app", "android_common") - appWithStubDeps := ctx.ModuleForTests("app_with_stub_deps", "android_common") prebuilt := ctx.ModuleForTests("prebuilt", "android_common") // Test that implicit dependencies on java_sdk_library instances are passed to the manifest. @@ -2828,7 +2814,7 @@ func TestUsesLibraries(t *testing.T) { t.Errorf("wanted %q in %q", w, cmd) } - // Test that all present libraries are preopted, including implicit SDK dependencies + // Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs cmd = app.Rule("dexpreopt").RuleParams.Command w := `--target-classpath-for-sdk any` + ` /system/framework/foo.jar` + @@ -2840,11 +2826,6 @@ func TestUsesLibraries(t *testing.T) { t.Errorf("wanted %q in %q", w, cmd) } - // TODO(skvadrik) fix dexpreopt for stub libraries for which the implementation is present - if appWithStubDeps.MaybeRule("dexpreopt").RuleParams.Command != "" { - t.Errorf("dexpreopt should be disabled for apps with dependencies on stub libraries") - } - cmd = prebuilt.Rule("dexpreopt").RuleParams.Command if w := `--target-classpath-for-sdk any /system/framework/foo.jar:/system/framework/bar.jar`; !strings.Contains(cmd, w) { t.Errorf("wanted %q in %q", w, cmd) diff --git a/java/java.go b/java/java.go index 1d7eaa771..1200e2731 100644 --- a/java/java.go +++ b/java/java.go @@ -735,9 +735,21 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { return ret } - ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...) + libDeps := ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...) ctx.AddVariationDependencies(nil, staticLibTag, rewriteSyspropLibs(j.properties.Static_libs, "static_libs")...) + // For library dependencies that are component libraries (like stubs), add the implementation + // as a dependency (dexpreopt needs to be against the implementation library, not stubs). + for _, dep := range libDeps { + if dep != nil { + if component, ok := dep.(SdkLibraryComponentDependency); ok { + if lib := component.OptionalSdkLibraryImplementation(); lib != nil { + ctx.AddVariationDependencies(nil, usesLibTag, *lib) + } + } + } + } + ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...) ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...) diff --git a/java/sdk_library.go b/java/sdk_library.go index 60924a662..9caa97a0a 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -870,6 +870,12 @@ func (e *EmbeddableSdkLibraryComponent) OptionalImplicitSdkLibrary() *string { return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack } +// to satisfy SdkLibraryComponentDependency +func (e *EmbeddableSdkLibraryComponent) OptionalSdkLibraryImplementation() *string { + // Currently implementation library name is the same as the SDK library name. + return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack +} + // Implemented by modules that are (or possibly could be) a component of a java_sdk_library // (including the java_sdk_library) itself. type SdkLibraryComponentDependency interface { @@ -880,6 +886,9 @@ type SdkLibraryComponentDependency interface { // // Returns the name of the optional implicit SDK library or nil, if there isn't one. OptionalImplicitSdkLibrary() *string + + // The name of the implementation library for the optional SDK library or nil, if there isn't one. + OptionalSdkLibraryImplementation() *string } // Make sure that all the module types that are components of java_sdk_library/_import