From 1833ceff09bfbea7b72166ec0856621dc010c453 Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Fri, 13 Dec 2019 13:28:36 +0900 Subject: [PATCH] fix: LOCAL_PATH for modules included in APEX is wrong This change fixes a bug that LOCAL_PATH for modules included in an APEX is set to the path of the APEX bundle, not to the path of the embedded module. For example, LOCAL_PATH of libconscrypt included in com.android.adbd was set to /system/core/adb instead of /external/boringssl. This caused a problem that NOTICE file in /external/boringssl is not tagged to libconscrypt, but the NOTICE file for adbd is. Fixing the problem by recording the module directories of the included modules and emitting it in LOCAL_PATH. Bug: 145347092 Test: Settings -> About Phone -> Legal Information -> Third-party license. The license for /apex/com.android.adbd/lib64/libconscrypt.so is OpenSSL. Change-Id: I76f1830d5a10af63fa74dcc2a42730ffabb8c4ed --- apex/androidmk.go | 6 +++- apex/apex.go | 73 +++++++++++++++++++++++++---------------------- apex/builder.go | 4 +-- 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/apex/androidmk.go b/apex/androidmk.go index 35622f094..a231a907c 100644 --- a/apex/androidmk.go +++ b/apex/androidmk.go @@ -63,7 +63,11 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexName, moduleDir string) } fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)") - fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir) + if fi.moduleDir != "" { + fmt.Fprintln(w, "LOCAL_PATH :=", fi.moduleDir) + } else { + fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir) + } fmt.Fprintln(w, "LOCAL_MODULE :=", fi.moduleName) // /apex//{lib|framework|...} pathWhenActivated := filepath.Join("$(PRODUCT_OUT)", "apex", apexName, fi.installDir) diff --git a/apex/apex.go b/apex/apex.go index be86d8060..aedd12222 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -459,16 +459,21 @@ type apexFile struct { // list of symlinks that will be created in installDir that point to this apexFile symlinks []string transitiveDep bool + moduleDir string } -func newApexFile(builtFile android.Path, moduleName string, installDir string, class apexFileClass, module android.Module) apexFile { - return apexFile{ +func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, moduleName string, installDir string, class apexFileClass, module android.Module) apexFile { + ret := apexFile{ builtFile: builtFile, moduleName: moduleName, installDir: installDir, class: class, module: module, } + if module != nil { + ret.moduleDir = ctx.OtherModuleDir(module) + } + return ret } func (af *apexFile) Ok() bool { @@ -789,7 +794,7 @@ func (a *apexBundle) HideFromMake() { } // TODO(jiyong) move apexFileFor* close to the apexFile type definition -func apexFileForNativeLibrary(ccMod *cc.Module, config android.Config, handleSpecialLibs bool) apexFile { +func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile { // Decide the APEX-local directory by the multilib of the library // In the future, we may query this to the module. var dirInApex string @@ -803,7 +808,7 @@ func apexFileForNativeLibrary(ccMod *cc.Module, config android.Config, handleSpe if ccMod.Target().NativeBridge == android.NativeBridgeEnabled { dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath) } - if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), config) { + if handleSpecialLibs && cc.InstallToBootstrap(ccMod.BaseModuleName(), ctx.Config()) { // Special case for Bionic libs and other libs installed with them. This is // to prevent those libs from being included in the search path // /apex/com.android.runtime/${LIB}. This exclusion is required because @@ -818,26 +823,26 @@ func apexFileForNativeLibrary(ccMod *cc.Module, config android.Config, handleSpe } fileToCopy := ccMod.OutputFile().Path() - return newApexFile(fileToCopy, ccMod.Name(), dirInApex, nativeSharedLib, ccMod) + return newApexFile(ctx, fileToCopy, ccMod.Name(), dirInApex, nativeSharedLib, ccMod) } -func apexFileForExecutable(cc *cc.Module) apexFile { +func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFile { dirInApex := filepath.Join("bin", cc.RelativeInstallPath()) if cc.Target().NativeBridge == android.NativeBridgeEnabled { dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath) } fileToCopy := cc.OutputFile().Path() - af := newApexFile(fileToCopy, cc.Name(), dirInApex, nativeExecutable, cc) + af := newApexFile(ctx, fileToCopy, cc.Name(), dirInApex, nativeExecutable, cc) af.symlinks = cc.Symlinks() return af } -func apexFileForPyBinary(py *python.Module) apexFile { +func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile { dirInApex := "bin" fileToCopy := py.HostToolPath().Path() - return newApexFile(fileToCopy, py.Name(), dirInApex, pyBinary, py) + return newApexFile(ctx, fileToCopy, py.Name(), dirInApex, pyBinary, py) } -func apexFileForGoBinary(ctx android.ModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile { +func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb bootstrap.GoBinaryTool) apexFile { dirInApex := "bin" s, err := filepath.Rel(android.PathForOutput(ctx).String(), gb.InstallPath()) if err != nil { @@ -848,24 +853,24 @@ func apexFileForGoBinary(ctx android.ModuleContext, depName string, gb bootstrap // NB: Since go binaries are static we don't need the module for anything here, which is // good since the go tool is a blueprint.Module not an android.Module like we would // normally use. - return newApexFile(fileToCopy, depName, dirInApex, goBinary, nil) + return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil) } -func apexFileForShBinary(sh *android.ShBinary) apexFile { +func apexFileForShBinary(ctx android.BaseModuleContext, sh *android.ShBinary) apexFile { dirInApex := filepath.Join("bin", sh.SubDir()) fileToCopy := sh.OutputFile() - af := newApexFile(fileToCopy, sh.Name(), dirInApex, shBinary, sh) + af := newApexFile(ctx, fileToCopy, sh.Name(), dirInApex, shBinary, sh) af.symlinks = sh.Symlinks() return af } -func apexFileForJavaLibrary(java *java.Library) apexFile { +func apexFileForJavaLibrary(ctx android.BaseModuleContext, java *java.Library) apexFile { dirInApex := "javalib" fileToCopy := java.DexJarFile() - return newApexFile(fileToCopy, java.Name(), dirInApex, javaSharedLib, java) + return newApexFile(ctx, fileToCopy, java.Name(), dirInApex, javaSharedLib, java) } -func apexFileForPrebuiltJavaLibrary(java *java.Import) apexFile { +func apexFileForPrebuiltJavaLibrary(ctx android.BaseModuleContext, java *java.Import) apexFile { dirInApex := "javalib" // The output is only one, but for some reason, ImplementationJars returns Paths, not Path implJars := java.ImplementationJars() @@ -874,16 +879,16 @@ func apexFileForPrebuiltJavaLibrary(java *java.Import) apexFile { strings.Join(implJars.Strings(), ", "))) } fileToCopy := implJars[0] - return newApexFile(fileToCopy, java.Name(), dirInApex, javaSharedLib, java) + return newApexFile(ctx, fileToCopy, java.Name(), dirInApex, javaSharedLib, java) } -func apexFileForPrebuiltEtc(prebuilt android.PrebuiltEtcModule, depName string) apexFile { +func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt android.PrebuiltEtcModule, depName string) apexFile { dirInApex := filepath.Join("etc", prebuilt.SubDir()) fileToCopy := prebuilt.OutputFile() - return newApexFile(fileToCopy, depName, dirInApex, etc, prebuilt) + return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt) } -func apexFileForAndroidApp(aapp interface { +func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp interface { android.Module Privileged() bool OutputFile() android.Path @@ -894,7 +899,7 @@ func apexFileForAndroidApp(aapp interface { } dirInApex := filepath.Join(appDir, pkgName) fileToCopy := aapp.OutputFile() - return newApexFile(fileToCopy, aapp.Name(), dirInApex, app, aapp) + return newApexFile(ctx, fileToCopy, aapp.Name(), dirInApex, app, aapp) } // Context "decorator", overriding the InstallBypassMake method to always reply `true`. @@ -982,19 +987,19 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { if cc.HasStubsVariants() { provideNativeLibs = append(provideNativeLibs, cc.OutputFile().Path().Base()) } - filesInfo = append(filesInfo, apexFileForNativeLibrary(cc, ctx.Config(), handleSpecialLibs)) + filesInfo = append(filesInfo, apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)) return true // track transitive dependencies } else { ctx.PropertyErrorf("native_shared_libs", "%q is not a cc_library or cc_library_shared module", depName) } case executableTag: if cc, ok := child.(*cc.Module); ok { - filesInfo = append(filesInfo, apexFileForExecutable(cc)) + filesInfo = append(filesInfo, apexFileForExecutable(ctx, cc)) return true // track transitive dependencies } else if sh, ok := child.(*android.ShBinary); ok { - filesInfo = append(filesInfo, apexFileForShBinary(sh)) + filesInfo = append(filesInfo, apexFileForShBinary(ctx, sh)) } else if py, ok := child.(*python.Module); ok && py.HostToolPath().Valid() { - filesInfo = append(filesInfo, apexFileForPyBinary(py)) + filesInfo = append(filesInfo, apexFileForPyBinary(ctx, py)) } else if gb, ok := child.(bootstrap.GoBinaryTool); ok && a.Host() { filesInfo = append(filesInfo, apexFileForGoBinary(ctx, depName, gb)) } else { @@ -1002,7 +1007,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } case javaLibTag: if javaLib, ok := child.(*java.Library); ok { - af := apexFileForJavaLibrary(javaLib) + af := apexFileForJavaLibrary(ctx, javaLib) if !af.Ok() { ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName) } else { @@ -1010,7 +1015,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { return true // track transitive dependencies } } else if javaLib, ok := child.(*java.Import); ok { - af := apexFileForPrebuiltJavaLibrary(javaLib) + af := apexFileForPrebuiltJavaLibrary(ctx, javaLib) if !af.Ok() { ctx.PropertyErrorf("java_libs", "%q does not have a jar output", depName) } else { @@ -1022,16 +1027,16 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { case androidAppTag: pkgName := ctx.DeviceConfig().OverridePackageNameFor(depName) if ap, ok := child.(*java.AndroidApp); ok { - filesInfo = append(filesInfo, apexFileForAndroidApp(ap, pkgName)) + filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap, pkgName)) return true // track transitive dependencies } else if ap, ok := child.(*java.AndroidAppImport); ok { - filesInfo = append(filesInfo, apexFileForAndroidApp(ap, pkgName)) + filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap, pkgName)) } else { ctx.PropertyErrorf("apps", "%q is not an android_app module", depName) } case prebuiltTag: if prebuilt, ok := child.(android.PrebuiltEtcModule); ok { - filesInfo = append(filesInfo, apexFileForPrebuiltEtc(prebuilt, depName)) + filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName)) } else { ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName) } @@ -1047,7 +1052,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { return true } else { // Single-output test module (where `test_per_src: false`). - af := apexFileForExecutable(ccTest) + af := apexFileForExecutable(ctx, ccTest) af.class = nativeTest filesInfo = append(filesInfo, af) } @@ -1103,14 +1108,14 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Don't track further return false } - af := apexFileForNativeLibrary(cc, ctx.Config(), handleSpecialLibs) + af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs) af.transitiveDep = true filesInfo = append(filesInfo, af) return true // track transitive dependencies } } else if cc.IsTestPerSrcDepTag(depTag) { if cc, ok := child.(*cc.Module); ok { - af := apexFileForExecutable(cc) + af := apexFileForExecutable(ctx, cc) // Handle modules created as `test_per_src` variations of a single test module: // use the name of the generated test binary (`fileToCopy`) instead of the name // of the original test module (`depName`, shared by all `test_per_src` @@ -1139,7 +1144,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { dirInApex := filepath.Join("javalib", arch.String()) for _, f := range files { localModule := "javalib_" + arch.String() + "_" + filepath.Base(f.String()) - af := newApexFile(f, localModule, dirInApex, etc, nil) + af := newApexFile(ctx, f, localModule, dirInApex, etc, nil) filesInfo = append(filesInfo, af) } } diff --git a/apex/builder.go b/apex/builder.go index cbbf5f8aa..a90918d18 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -511,7 +511,7 @@ func (a *apexBundle) buildFilesInfo(ctx android.ModuleContext) { if a.installable() { // For flattened APEX, do nothing but make sure that APEX manifest and apex_pubkey are also copied along // with other ordinary files. - a.filesInfo = append(a.filesInfo, newApexFile(a.manifestPbOut, "apex_manifest.pb."+a.Name()+a.suffix, ".", etc, nil)) + a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb."+a.Name()+a.suffix, ".", etc, nil)) // rename to apex_pubkey copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey") @@ -520,7 +520,7 @@ func (a *apexBundle) buildFilesInfo(ctx android.ModuleContext) { Input: a.public_key_file, Output: copiedPubkey, }) - a.filesInfo = append(a.filesInfo, newApexFile(copiedPubkey, "apex_pubkey."+a.Name()+a.suffix, ".", etc, nil)) + a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey."+a.Name()+a.suffix, ".", etc, nil)) if a.properties.ApexType == flattenedApex { apexName := proptools.StringDefault(a.properties.Apex_name, a.Name())