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
This commit is contained in:
Jiyong Park
2019-12-13 13:28:36 +09:00
parent 0f41daf682
commit 1833ceff09
3 changed files with 46 additions and 37 deletions

View File

@@ -63,7 +63,11 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexName, moduleDir string)
} }
fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)") 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) fmt.Fprintln(w, "LOCAL_MODULE :=", fi.moduleName)
// /apex/<apex_name>/{lib|framework|...} // /apex/<apex_name>/{lib|framework|...}
pathWhenActivated := filepath.Join("$(PRODUCT_OUT)", "apex", apexName, fi.installDir) pathWhenActivated := filepath.Join("$(PRODUCT_OUT)", "apex", apexName, fi.installDir)

View File

@@ -459,16 +459,21 @@ type apexFile struct {
// list of symlinks that will be created in installDir that point to this apexFile // list of symlinks that will be created in installDir that point to this apexFile
symlinks []string symlinks []string
transitiveDep bool transitiveDep bool
moduleDir string
} }
func newApexFile(builtFile android.Path, moduleName string, installDir string, class apexFileClass, module android.Module) apexFile { func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, moduleName string, installDir string, class apexFileClass, module android.Module) apexFile {
return apexFile{ ret := apexFile{
builtFile: builtFile, builtFile: builtFile,
moduleName: moduleName, moduleName: moduleName,
installDir: installDir, installDir: installDir,
class: class, class: class,
module: module, module: module,
} }
if module != nil {
ret.moduleDir = ctx.OtherModuleDir(module)
}
return ret
} }
func (af *apexFile) Ok() bool { func (af *apexFile) Ok() bool {
@@ -789,7 +794,7 @@ func (a *apexBundle) HideFromMake() {
} }
// TODO(jiyong) move apexFileFor* close to the apexFile type definition // 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 // Decide the APEX-local directory by the multilib of the library
// In the future, we may query this to the module. // In the future, we may query this to the module.
var dirInApex string var dirInApex string
@@ -803,7 +808,7 @@ func apexFileForNativeLibrary(ccMod *cc.Module, config android.Config, handleSpe
if ccMod.Target().NativeBridge == android.NativeBridgeEnabled { if ccMod.Target().NativeBridge == android.NativeBridgeEnabled {
dirInApex = filepath.Join(dirInApex, ccMod.Target().NativeBridgeRelativePath) 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 // Special case for Bionic libs and other libs installed with them. This is
// to prevent those libs from being included in the search path // to prevent those libs from being included in the search path
// /apex/com.android.runtime/${LIB}. This exclusion is required because // /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() 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()) dirInApex := filepath.Join("bin", cc.RelativeInstallPath())
if cc.Target().NativeBridge == android.NativeBridgeEnabled { if cc.Target().NativeBridge == android.NativeBridgeEnabled {
dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath) dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
} }
fileToCopy := cc.OutputFile().Path() 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() af.symlinks = cc.Symlinks()
return af return af
} }
func apexFileForPyBinary(py *python.Module) apexFile { func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
dirInApex := "bin" dirInApex := "bin"
fileToCopy := py.HostToolPath().Path() 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" dirInApex := "bin"
s, err := filepath.Rel(android.PathForOutput(ctx).String(), gb.InstallPath()) s, err := filepath.Rel(android.PathForOutput(ctx).String(), gb.InstallPath())
if err != nil { 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 // 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 // good since the go tool is a blueprint.Module not an android.Module like we would
// normally use. // 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()) dirInApex := filepath.Join("bin", sh.SubDir())
fileToCopy := sh.OutputFile() fileToCopy := sh.OutputFile()
af := newApexFile(fileToCopy, sh.Name(), dirInApex, shBinary, sh) af := newApexFile(ctx, fileToCopy, sh.Name(), dirInApex, shBinary, sh)
af.symlinks = sh.Symlinks() af.symlinks = sh.Symlinks()
return af return af
} }
func apexFileForJavaLibrary(java *java.Library) apexFile { func apexFileForJavaLibrary(ctx android.BaseModuleContext, java *java.Library) apexFile {
dirInApex := "javalib" dirInApex := "javalib"
fileToCopy := java.DexJarFile() 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" dirInApex := "javalib"
// The output is only one, but for some reason, ImplementationJars returns Paths, not Path // The output is only one, but for some reason, ImplementationJars returns Paths, not Path
implJars := java.ImplementationJars() implJars := java.ImplementationJars()
@@ -874,16 +879,16 @@ func apexFileForPrebuiltJavaLibrary(java *java.Import) apexFile {
strings.Join(implJars.Strings(), ", "))) strings.Join(implJars.Strings(), ", ")))
} }
fileToCopy := implJars[0] 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()) dirInApex := filepath.Join("etc", prebuilt.SubDir())
fileToCopy := prebuilt.OutputFile() 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 android.Module
Privileged() bool Privileged() bool
OutputFile() android.Path OutputFile() android.Path
@@ -894,7 +899,7 @@ func apexFileForAndroidApp(aapp interface {
} }
dirInApex := filepath.Join(appDir, pkgName) dirInApex := filepath.Join(appDir, pkgName)
fileToCopy := aapp.OutputFile() 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`. // Context "decorator", overriding the InstallBypassMake method to always reply `true`.
@@ -982,19 +987,19 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if cc.HasStubsVariants() { if cc.HasStubsVariants() {
provideNativeLibs = append(provideNativeLibs, cc.OutputFile().Path().Base()) 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 return true // track transitive dependencies
} else { } else {
ctx.PropertyErrorf("native_shared_libs", "%q is not a cc_library or cc_library_shared module", depName) ctx.PropertyErrorf("native_shared_libs", "%q is not a cc_library or cc_library_shared module", depName)
} }
case executableTag: case executableTag:
if cc, ok := child.(*cc.Module); ok { if cc, ok := child.(*cc.Module); ok {
filesInfo = append(filesInfo, apexFileForExecutable(cc)) filesInfo = append(filesInfo, apexFileForExecutable(ctx, cc))
return true // track transitive dependencies return true // track transitive dependencies
} else if sh, ok := child.(*android.ShBinary); ok { } 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() { } 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() { } else if gb, ok := child.(bootstrap.GoBinaryTool); ok && a.Host() {
filesInfo = append(filesInfo, apexFileForGoBinary(ctx, depName, gb)) filesInfo = append(filesInfo, apexFileForGoBinary(ctx, depName, gb))
} else { } else {
@@ -1002,7 +1007,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
} }
case javaLibTag: case javaLibTag:
if javaLib, ok := child.(*java.Library); ok { if javaLib, ok := child.(*java.Library); ok {
af := apexFileForJavaLibrary(javaLib) af := apexFileForJavaLibrary(ctx, javaLib)
if !af.Ok() { if !af.Ok() {
ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName) ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
} else { } else {
@@ -1010,7 +1015,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
return true // track transitive dependencies return true // track transitive dependencies
} }
} else if javaLib, ok := child.(*java.Import); ok { } else if javaLib, ok := child.(*java.Import); ok {
af := apexFileForPrebuiltJavaLibrary(javaLib) af := apexFileForPrebuiltJavaLibrary(ctx, javaLib)
if !af.Ok() { if !af.Ok() {
ctx.PropertyErrorf("java_libs", "%q does not have a jar output", depName) ctx.PropertyErrorf("java_libs", "%q does not have a jar output", depName)
} else { } else {
@@ -1022,16 +1027,16 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
case androidAppTag: case androidAppTag:
pkgName := ctx.DeviceConfig().OverridePackageNameFor(depName) pkgName := ctx.DeviceConfig().OverridePackageNameFor(depName)
if ap, ok := child.(*java.AndroidApp); ok { 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 return true // track transitive dependencies
} else if ap, ok := child.(*java.AndroidAppImport); ok { } else if ap, ok := child.(*java.AndroidAppImport); ok {
filesInfo = append(filesInfo, apexFileForAndroidApp(ap, pkgName)) filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap, pkgName))
} else { } else {
ctx.PropertyErrorf("apps", "%q is not an android_app module", depName) ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
} }
case prebuiltTag: case prebuiltTag:
if prebuilt, ok := child.(android.PrebuiltEtcModule); ok { if prebuilt, ok := child.(android.PrebuiltEtcModule); ok {
filesInfo = append(filesInfo, apexFileForPrebuiltEtc(prebuilt, depName)) filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
} else { } else {
ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName) ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
} }
@@ -1047,7 +1052,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
return true return true
} else { } else {
// Single-output test module (where `test_per_src: false`). // Single-output test module (where `test_per_src: false`).
af := apexFileForExecutable(ccTest) af := apexFileForExecutable(ctx, ccTest)
af.class = nativeTest af.class = nativeTest
filesInfo = append(filesInfo, af) filesInfo = append(filesInfo, af)
} }
@@ -1103,14 +1108,14 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Don't track further // Don't track further
return false return false
} }
af := apexFileForNativeLibrary(cc, ctx.Config(), handleSpecialLibs) af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
af.transitiveDep = true af.transitiveDep = true
filesInfo = append(filesInfo, af) filesInfo = append(filesInfo, af)
return true // track transitive dependencies return true // track transitive dependencies
} }
} else if cc.IsTestPerSrcDepTag(depTag) { } else if cc.IsTestPerSrcDepTag(depTag) {
if cc, ok := child.(*cc.Module); ok { 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: // 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 // 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` // 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()) dirInApex := filepath.Join("javalib", arch.String())
for _, f := range files { for _, f := range files {
localModule := "javalib_" + arch.String() + "_" + filepath.Base(f.String()) 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) filesInfo = append(filesInfo, af)
} }
} }

View File

@@ -511,7 +511,7 @@ func (a *apexBundle) buildFilesInfo(ctx android.ModuleContext) {
if a.installable() { if a.installable() {
// For flattened APEX, do nothing but make sure that APEX manifest and apex_pubkey are also copied along // For flattened APEX, do nothing but make sure that APEX manifest and apex_pubkey are also copied along
// with other ordinary files. // 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 // rename to apex_pubkey
copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey") copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
@@ -520,7 +520,7 @@ func (a *apexBundle) buildFilesInfo(ctx android.ModuleContext) {
Input: a.public_key_file, Input: a.public_key_file,
Output: copiedPubkey, 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 { if a.properties.ApexType == flattenedApex {
apexName := proptools.StringDefault(a.properties.Apex_name, a.Name()) apexName := proptools.StringDefault(a.properties.Apex_name, a.Name())