Merge "Add libraryDependencyTag to track dependencies on static and shared libraries"

This commit is contained in:
Colin Cross 2020-08-06 00:06:28 +00:00 committed by Gerrit Code Review
commit 2eddd06879
12 changed files with 465 additions and 343 deletions

View File

@ -1839,7 +1839,7 @@ func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag {
// A regexp for removing boilerplate from BaseDependencyTag from the string representation of // A regexp for removing boilerplate from BaseDependencyTag from the string representation of
// a dependency tag. // a dependency tag.
var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:blueprint.BaseDependencyTag{}\E(, )?`) var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:{}\E(, )?`)
// PrettyPrintTag returns string representation of the tag, but prefers // PrettyPrintTag returns string representation of the tag, but prefers
// custom String() method if available. // custom String() method if available.
@ -1850,7 +1850,7 @@ func PrettyPrintTag(tag blueprint.DependencyTag) string {
} }
// Otherwise, get a default string representation of the tag's struct. // Otherwise, get a default string representation of the tag's struct.
tagString := fmt.Sprintf("%#v", tag) tagString := fmt.Sprintf("%T: %+v", tag, tag)
// Remove the boilerplate from BaseDependencyTag as it adds no value. // Remove the boilerplate from BaseDependencyTag as it adds no value.
tagString = tagCleaner.ReplaceAllString(tagString, "") tagString = tagCleaner.ReplaceAllString(tagString, "")

View File

@ -4450,11 +4450,11 @@ func TestApexAvailable_DirectDep(t *testing.T) {
func TestApexAvailable_IndirectDep(t *testing.T) { func TestApexAvailable_IndirectDep(t *testing.T) {
// libbbaz is an indirect dep // libbbaz is an indirect dep
testApexError(t, `requires "libbaz" that is not available for the APEX. Dependency path: testApexError(t, `requires "libbaz" that is not available for the APEX. Dependency path:
.*via tag apex\.dependencyTag.*"sharedLib".* .*via tag apex\.dependencyTag.*name:sharedLib.*
.*-> libfoo.*link:shared.* .*-> libfoo.*link:shared.*
.*via tag cc\.DependencyTag.*"shared".* .*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.*
.*-> libbar.*link:shared.* .*-> libbar.*link:shared.*
.*via tag cc\.DependencyTag.*"shared".* .*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.*
.*-> libbaz.*link:shared.*`, ` .*-> libbaz.*link:shared.*`, `
apex { apex {
name: "myapex", name: "myapex",

452
cc/cc.go
View File

@ -425,44 +425,130 @@ type xref interface {
XrefCcFiles() android.Paths XrefCcFiles() android.Paths
} }
type libraryDependencyKind int
const (
headerLibraryDependency = iota
sharedLibraryDependency
staticLibraryDependency
)
func (k libraryDependencyKind) String() string {
switch k {
case headerLibraryDependency:
return "headerLibraryDependency"
case sharedLibraryDependency:
return "sharedLibraryDependency"
case staticLibraryDependency:
return "staticLibraryDependency"
default:
panic(fmt.Errorf("unknown libraryDependencyKind %d", k))
}
}
type libraryDependencyOrder int
const (
earlyLibraryDependency = -1
normalLibraryDependency = 0
lateLibraryDependency = 1
)
func (o libraryDependencyOrder) String() string {
switch o {
case earlyLibraryDependency:
return "earlyLibraryDependency"
case normalLibraryDependency:
return "normalLibraryDependency"
case lateLibraryDependency:
return "lateLibraryDependency"
default:
panic(fmt.Errorf("unknown libraryDependencyOrder %d", o))
}
}
// libraryDependencyTag is used to tag dependencies on libraries. Unlike many dependency
// tags that have a set of predefined tag objects that are reused for each dependency, a
// libraryDependencyTag is designed to contain extra metadata and is constructed as needed.
// That means that comparing a libraryDependencyTag for equality will only be equal if all
// of the metadata is equal. Most usages will want to type assert to libraryDependencyTag and
// then check individual metadata fields instead.
type libraryDependencyTag struct {
blueprint.BaseDependencyTag
// These are exported so that fmt.Printf("%#v") can call their String methods.
Kind libraryDependencyKind
Order libraryDependencyOrder
wholeStatic bool
reexportFlags bool
explicitlyVersioned bool
dataLib bool
ndk bool
staticUnwinder bool
makeSuffix string
}
// header returns true if the libraryDependencyTag is tagging a header lib dependency.
func (d libraryDependencyTag) header() bool {
return d.Kind == headerLibraryDependency
}
// shared returns true if the libraryDependencyTag is tagging a shared lib dependency.
func (d libraryDependencyTag) shared() bool {
return d.Kind == sharedLibraryDependency
}
// shared returns true if the libraryDependencyTag is tagging a static lib dependency.
func (d libraryDependencyTag) static() bool {
return d.Kind == staticLibraryDependency
}
// dependencyTag is used for tagging miscellanous dependency types that don't fit into
// libraryDependencyTag. Each tag object is created globally and reused for multiple
// dependencies (although since the object contains no references, assigning a tag to a
// variable and modifying it will not modify the original). Users can compare the tag
// returned by ctx.OtherModuleDependencyTag against the global original
type dependencyTag struct {
blueprint.BaseDependencyTag
name string
}
var ( var (
dataLibDepTag = DependencyTag{Name: "data_lib", Library: true, Shared: true} genSourceDepTag = dependencyTag{name: "gen source"}
sharedExportDepTag = DependencyTag{Name: "shared", Library: true, Shared: true, ReexportFlags: true} genHeaderDepTag = dependencyTag{name: "gen header"}
earlySharedDepTag = DependencyTag{Name: "early_shared", Library: true, Shared: true} genHeaderExportDepTag = dependencyTag{name: "gen header export"}
lateSharedDepTag = DependencyTag{Name: "late shared", Library: true, Shared: true} objDepTag = dependencyTag{name: "obj"}
staticExportDepTag = DependencyTag{Name: "static", Library: true, ReexportFlags: true} linkerFlagsDepTag = dependencyTag{name: "linker flags file"}
lateStaticDepTag = DependencyTag{Name: "late static", Library: true} dynamicLinkerDepTag = dependencyTag{name: "dynamic linker"}
staticUnwinderDepTag = DependencyTag{Name: "static unwinder", Library: true} reuseObjTag = dependencyTag{name: "reuse objects"}
wholeStaticDepTag = DependencyTag{Name: "whole static", Library: true, ReexportFlags: true} staticVariantTag = dependencyTag{name: "static variant"}
headerDepTag = DependencyTag{Name: "header", Library: true} vndkExtDepTag = dependencyTag{name: "vndk extends"}
headerExportDepTag = DependencyTag{Name: "header", Library: true, ReexportFlags: true} dataLibDepTag = dependencyTag{name: "data lib"}
genSourceDepTag = DependencyTag{Name: "gen source"} runtimeDepTag = dependencyTag{name: "runtime lib"}
genHeaderDepTag = DependencyTag{Name: "gen header"} testPerSrcDepTag = dependencyTag{name: "test_per_src"}
genHeaderExportDepTag = DependencyTag{Name: "gen header", ReexportFlags: true}
objDepTag = DependencyTag{Name: "obj"}
linkerFlagsDepTag = DependencyTag{Name: "linker flags file"}
dynamicLinkerDepTag = DependencyTag{Name: "dynamic linker"}
reuseObjTag = DependencyTag{Name: "reuse objects"}
staticVariantTag = DependencyTag{Name: "static variant"}
ndkStubDepTag = DependencyTag{Name: "ndk stub", Library: true}
ndkLateStubDepTag = DependencyTag{Name: "ndk late stub", Library: true}
vndkExtDepTag = DependencyTag{Name: "vndk extends", Library: true}
runtimeDepTag = DependencyTag{Name: "runtime lib"}
testPerSrcDepTag = DependencyTag{Name: "test_per_src"}
) )
func IsSharedDepTag(depTag blueprint.DependencyTag) bool { func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
ccDepTag, ok := depTag.(DependencyTag) ccLibDepTag, ok := depTag.(libraryDependencyTag)
return ok && ccDepTag.Shared return ok && ccLibDepTag.shared()
}
func IsStaticDepTag(depTag blueprint.DependencyTag) bool {
ccLibDepTag, ok := depTag.(libraryDependencyTag)
return ok && ccLibDepTag.static()
} }
func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool { func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool {
ccDepTag, ok := depTag.(DependencyTag) ccDepTag, ok := depTag.(dependencyTag)
return ok && ccDepTag == runtimeDepTag return ok && ccDepTag == runtimeDepTag
} }
func IsTestPerSrcDepTag(depTag blueprint.DependencyTag) bool { func IsTestPerSrcDepTag(depTag blueprint.DependencyTag) bool {
ccDepTag, ok := depTag.(DependencyTag) ccDepTag, ok := depTag.(dependencyTag)
return ok && ccDepTag == testPerSrcDepTag return ok && ccDepTag == testPerSrcDepTag
} }
@ -1859,9 +1945,9 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
vendorSnapshotHeaderLibs := vendorSnapshotHeaderLibs(actx.Config()) vendorSnapshotHeaderLibs := vendorSnapshotHeaderLibs(actx.Config())
for _, lib := range deps.HeaderLibs { for _, lib := range deps.HeaderLibs {
depTag := headerDepTag depTag := libraryDependencyTag{Kind: headerLibraryDependency}
if inList(lib, deps.ReexportHeaderLibHeaders) { if inList(lib, deps.ReexportHeaderLibHeaders) {
depTag = headerExportDepTag depTag.reexportFlags = true
} }
lib = rewriteSnapshotLibs(lib, vendorSnapshotHeaderLibs) lib = rewriteSnapshotLibs(lib, vendorSnapshotHeaderLibs)
@ -1884,7 +1970,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
vendorSnapshotStaticLibs := vendorSnapshotStaticLibs(actx.Config()) vendorSnapshotStaticLibs := vendorSnapshotStaticLibs(actx.Config())
for _, lib := range deps.WholeStaticLibs { for _, lib := range deps.WholeStaticLibs {
depTag := wholeStaticDepTag depTag := libraryDependencyTag{Kind: staticLibraryDependency, wholeStatic: true, reexportFlags: true}
if impl, ok := syspropImplLibraries[lib]; ok { if impl, ok := syspropImplLibraries[lib]; ok {
lib = impl lib = impl
} }
@ -1897,9 +1983,9 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
} }
for _, lib := range deps.StaticLibs { for _, lib := range deps.StaticLibs {
depTag := StaticDepTag depTag := libraryDependencyTag{Kind: staticLibraryDependency}
if inList(lib, deps.ReexportStaticLibHeaders) { if inList(lib, deps.ReexportStaticLibHeaders) {
depTag = staticExportDepTag depTag.reexportFlags = true
} }
if impl, ok := syspropImplLibraries[lib]; ok { if impl, ok := syspropImplLibraries[lib]; ok {
@ -1917,24 +2003,26 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
// so that native libraries/binaries are linked with static unwinder // so that native libraries/binaries are linked with static unwinder
// because Q libc doesn't have unwinder APIs // because Q libc doesn't have unwinder APIs
if deps.StaticUnwinderIfLegacy { if deps.StaticUnwinderIfLegacy {
depTag := libraryDependencyTag{Kind: staticLibraryDependency, staticUnwinder: true}
actx.AddVariationDependencies([]blueprint.Variation{ actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"}, {Mutator: "link", Variation: "static"},
}, staticUnwinderDepTag, rewriteSnapshotLibs(staticUnwinder(actx), vendorSnapshotStaticLibs)) }, depTag, rewriteSnapshotLibs(staticUnwinder(actx), vendorSnapshotStaticLibs))
} }
for _, lib := range deps.LateStaticLibs { for _, lib := range deps.LateStaticLibs {
depTag := libraryDependencyTag{Kind: staticLibraryDependency, Order: lateLibraryDependency}
actx.AddVariationDependencies([]blueprint.Variation{ actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"}, {Mutator: "link", Variation: "static"},
}, lateStaticDepTag, rewriteSnapshotLibs(lib, vendorSnapshotStaticLibs)) }, depTag, rewriteSnapshotLibs(lib, vendorSnapshotStaticLibs))
} }
addSharedLibDependencies := func(depTag DependencyTag, name string, version string) { addSharedLibDependencies := func(depTag libraryDependencyTag, name string, version string) {
var variations []blueprint.Variation var variations []blueprint.Variation
variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"}) variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"})
if version != "" && VersionVariantAvailable(c) { if version != "" && VersionVariantAvailable(c) {
// Version is explicitly specified. i.e. libFoo#30 // Version is explicitly specified. i.e. libFoo#30
variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version}) variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
depTag.ExplicitlyVersioned = true depTag.explicitlyVersioned = true
} }
actx.AddVariationDependencies(variations, depTag, name) actx.AddVariationDependencies(variations, depTag, name)
@ -1956,12 +2044,9 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
var sharedLibNames []string var sharedLibNames []string
for _, lib := range deps.SharedLibs { for _, lib := range deps.SharedLibs {
depTag := SharedDepTag depTag := libraryDependencyTag{Kind: sharedLibraryDependency}
if c.static() {
depTag = SharedFromStaticDepTag
}
if inList(lib, deps.ReexportSharedLibHeaders) { if inList(lib, deps.ReexportSharedLibHeaders) {
depTag = sharedExportDepTag depTag.reexportFlags = true
} }
if impl, ok := syspropImplLibraries[lib]; ok { if impl, ok := syspropImplLibraries[lib]; ok {
@ -1981,7 +2066,8 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
// linking against both the stubs lib and the non-stubs lib at the same time. // linking against both the stubs lib and the non-stubs lib at the same time.
continue continue
} }
addSharedLibDependencies(lateSharedDepTag, lib, "") depTag := libraryDependencyTag{Kind: sharedLibraryDependency, Order: lateLibraryDependency}
addSharedLibDependencies(depTag, lib, "")
} }
actx.AddVariationDependencies([]blueprint.Variation{ actx.AddVariationDependencies([]blueprint.Variation{
@ -2020,10 +2106,14 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
} }
version := ctx.sdkVersion() version := ctx.sdkVersion()
ndkStubDepTag := libraryDependencyTag{Kind: sharedLibraryDependency, ndk: true, makeSuffix: "." + version}
actx.AddVariationDependencies([]blueprint.Variation{ actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "ndk_api", Variation: version}, {Mutator: "ndk_api", Variation: version},
{Mutator: "link", Variation: "shared"}, {Mutator: "link", Variation: "shared"},
}, ndkStubDepTag, variantNdkLibs...) }, ndkStubDepTag, variantNdkLibs...)
ndkLateStubDepTag := libraryDependencyTag{Kind: sharedLibraryDependency, Order: lateLibraryDependency, ndk: true, makeSuffix: "." + version}
actx.AddVariationDependencies([]blueprint.Variation{ actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "ndk_api", Variation: version}, {Mutator: "ndk_api", Variation: version},
{Mutator: "link", Variation: "shared"}, {Mutator: "link", Variation: "shared"},
@ -2047,7 +2137,19 @@ func BeginMutator(ctx android.BottomUpMutatorContext) {
// Whether a module can link to another module, taking into // Whether a module can link to another module, taking into
// account NDK linking. // account NDK linking.
func checkLinkType(ctx android.ModuleContext, from LinkableInterface, to LinkableInterface, tag DependencyTag) { func checkLinkType(ctx android.ModuleContext, from LinkableInterface, to LinkableInterface,
tag blueprint.DependencyTag) {
switch t := tag.(type) {
case dependencyTag:
if t != vndkExtDepTag {
return
}
case libraryDependencyTag:
default:
return
}
if from.Module().Target().Os != android.Android { if from.Module().Target().Os != android.Android {
// Host code is not restricted // Host code is not restricted
return return
@ -2205,8 +2307,6 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
directStaticDeps := []LinkableInterface{} directStaticDeps := []LinkableInterface{}
directSharedDeps := []LinkableInterface{} directSharedDeps := []LinkableInterface{}
vendorPublicLibraries := vendorPublicLibraries(ctx.Config())
reexportExporter := func(exporter exportedFlagsProducer) { reexportExporter := func(exporter exportedFlagsProducer) {
depPaths.ReexportedDirs = append(depPaths.ReexportedDirs, exporter.exportedDirs()...) depPaths.ReexportedDirs = append(depPaths.ReexportedDirs, exporter.exportedDirs()...)
depPaths.ReexportedSystemDirs = append(depPaths.ReexportedSystemDirs, exporter.exportedSystemDirs()...) depPaths.ReexportedSystemDirs = append(depPaths.ReexportedSystemDirs, exporter.exportedSystemDirs()...)
@ -2316,39 +2416,24 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
} }
} }
if depTag == staticUnwinderDepTag { checkLinkType(ctx, c, ccDep, depTag)
// Use static unwinder for legacy (min_sdk_version = 29) apexes (b/144430859)
if c.apexSdkVersion <= android.SdkVersion_Android10 { linkFile := ccDep.OutputFile()
depTag = StaticDepTag
} else { if libDepTag, ok := depTag.(libraryDependencyTag); ok {
// Only use static unwinder for legacy (min_sdk_version = 29) apexes (b/144430859)
if libDepTag.staticUnwinder && c.apexSdkVersion > android.SdkVersion_Android10 {
return return
} }
}
// Extract ExplicitlyVersioned field from the depTag and reset it inside the struct. if ccDep.CcLibrary() && !libDepTag.static() {
// Otherwise, SharedDepTag and lateSharedDepTag with ExplicitlyVersioned set to true
// won't be matched to SharedDepTag and lateSharedDepTag.
explicitlyVersioned := false
if t, ok := depTag.(DependencyTag); ok {
explicitlyVersioned = t.ExplicitlyVersioned
t.ExplicitlyVersioned = false
depTag = t
}
if t, ok := depTag.(DependencyTag); ok && t.Library {
depIsStatic := false
switch depTag {
case StaticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag:
depIsStatic = true
}
if ccDep.CcLibrary() && !depIsStatic {
depIsStubs := ccDep.BuildStubs() depIsStubs := ccDep.BuildStubs()
depHasStubs := VersionVariantAvailable(c) && ccDep.HasStubsVariants() depHasStubs := VersionVariantAvailable(c) && ccDep.HasStubsVariants()
depInSameApex := android.DirectlyInApex(c.ApexName(), depName) depInSameApex := android.DirectlyInApex(c.ApexName(), depName)
depInPlatform := !android.DirectlyInAnyApex(ctx, depName) depInPlatform := !android.DirectlyInAnyApex(ctx, depName)
var useThisDep bool var useThisDep bool
if depIsStubs && explicitlyVersioned { if depIsStubs && libDepTag.explicitlyVersioned {
// Always respect dependency to the versioned stubs (i.e. libX#10) // Always respect dependency to the versioned stubs (i.e. libX#10)
useThisDep = true useThisDep = true
} else if !depHasStubs { } else if !depHasStubs {
@ -2380,7 +2465,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
} }
// when to use (unspecified) stubs, check min_sdk_version and choose the right one // when to use (unspecified) stubs, check min_sdk_version and choose the right one
if useThisDep && depIsStubs && !explicitlyVersioned { if useThisDep && depIsStubs && !libDepTag.explicitlyVersioned {
versionToUse, err := c.ChooseSdkVersion(ccDep.StubsVersions(), c.apexSdkVersion) versionToUse, err := c.ChooseSdkVersion(ccDep.StubsVersions(), c.apexSdkVersion)
if err != nil { if err != nil {
ctx.OtherModuleErrorf(dep, err.Error()) ctx.OtherModuleErrorf(dep, err.Error())
@ -2425,7 +2510,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
depPaths.GeneratedDeps = append(depPaths.GeneratedDeps, i.exportedDeps()...) depPaths.GeneratedDeps = append(depPaths.GeneratedDeps, i.exportedDeps()...)
depPaths.Flags = append(depPaths.Flags, i.exportedFlags()...) depPaths.Flags = append(depPaths.Flags, i.exportedFlags()...)
if t.ReexportFlags { if libDepTag.reexportFlags {
reexportExporter(i) reexportExporter(i)
// Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library. // Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
// Re-exported shared library headers must be included as well since they can help us with type information // Re-exported shared library headers must be included as well since they can help us with type information
@ -2437,37 +2522,34 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
} }
} }
} }
checkLinkType(ctx, c, ccDep, t)
}
var ptr *android.Paths var ptr *android.Paths
var depPtr *android.Paths var depPtr *android.Paths
linkFile := ccDep.OutputFile()
depFile := android.OptionalPath{} depFile := android.OptionalPath{}
switch depTag { switch {
case ndkStubDepTag, SharedDepTag, SharedFromStaticDepTag, sharedExportDepTag: case libDepTag.header():
// nothing
case libDepTag.shared():
ptr = &depPaths.SharedLibs ptr = &depPaths.SharedLibs
depPtr = &depPaths.SharedLibsDeps switch libDepTag.Order {
depFile = ccDep.Toc() case earlyLibraryDependency:
directSharedDeps = append(directSharedDeps, ccDep)
case earlySharedDepTag:
ptr = &depPaths.EarlySharedLibs ptr = &depPaths.EarlySharedLibs
depPtr = &depPaths.EarlySharedLibsDeps depPtr = &depPaths.EarlySharedLibsDeps
depFile = ccDep.Toc() case normalLibraryDependency:
ptr = &depPaths.SharedLibs
depPtr = &depPaths.SharedLibsDeps
directSharedDeps = append(directSharedDeps, ccDep) directSharedDeps = append(directSharedDeps, ccDep)
case lateSharedDepTag, ndkLateStubDepTag: case lateLibraryDependency:
ptr = &depPaths.LateSharedLibs ptr = &depPaths.LateSharedLibs
depPtr = &depPaths.LateSharedLibsDeps depPtr = &depPaths.LateSharedLibsDeps
default:
panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order))
}
depFile = ccDep.Toc() depFile = ccDep.Toc()
case StaticDepTag, staticExportDepTag: case libDepTag.static():
ptr = nil if libDepTag.wholeStatic {
directStaticDeps = append(directStaticDeps, ccDep)
case lateStaticDepTag:
ptr = &depPaths.LateStaticLibs
case wholeStaticDepTag:
ptr = &depPaths.WholeStaticLibs ptr = &depPaths.WholeStaticLibs
if !ccDep.CcLibraryInterface() || !ccDep.Static() { if !ccDep.CcLibraryInterface() || !ccDep.Static() {
ctx.ModuleErrorf("module %q not a static library", depName) ctx.ModuleErrorf("module %q not a static library", depName)
@ -2495,20 +2577,25 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
"non-cc.Modules cannot be included as whole static libraries.", depName) "non-cc.Modules cannot be included as whole static libraries.", depName)
return return
} }
case headerDepTag:
// Nothing } else {
case objDepTag: switch libDepTag.Order {
depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path()) case earlyLibraryDependency:
case CrtBeginDepTag: panic(fmt.Errorf("early static libs not suppported"))
depPaths.CrtBegin = linkFile case normalLibraryDependency:
case CrtEndDepTag: // static dependencies will be handled separately so they can be ordered
depPaths.CrtEnd = linkFile // using transitive dependencies.
case dynamicLinkerDepTag: ptr = nil
depPaths.DynamicLinker = linkFile directStaticDeps = append(directStaticDeps, ccDep)
case lateLibraryDependency:
ptr = &depPaths.LateStaticLibs
default:
panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order))
}
}
} }
switch depTag { if libDepTag.static() && !libDepTag.wholeStatic {
case StaticDepTag, staticExportDepTag, lateStaticDepTag:
if !ccDep.CcLibraryInterface() || !ccDep.Static() { if !ccDep.CcLibraryInterface() || !ccDep.Static() {
ctx.ModuleErrorf("module %q not a static library", depName) ctx.ModuleErrorf("module %q not a static library", depName)
return return
@ -2550,16 +2637,99 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
*depPtr = append(*depPtr, dep.Path()) *depPtr = append(*depPtr, dep.Path())
} }
vendorSuffixModules := vendorSuffixModules(ctx.Config()) makeLibName := c.makeLibName(ctx, ccDep, depName) + libDepTag.makeSuffix
switch {
case libDepTag.header():
// TODO(ccross): The reexportFlags check is there to maintain previous
// behavior when adding libraryDependencyTag and should be removed.
if !libDepTag.reexportFlags {
c.Properties.AndroidMkHeaderLibs = append(
c.Properties.AndroidMkHeaderLibs, makeLibName)
}
case libDepTag.shared():
if ccDep.CcLibrary() {
if ccDep.BuildStubs() && android.InAnyApex(depName) {
// Add the dependency to the APEX(es) providing the library so that
// m <module> can trigger building the APEXes as well.
for _, an := range android.GetApexesForModule(depName) {
c.Properties.ApexesProvidingSharedLibs = append(
c.Properties.ApexesProvidingSharedLibs, an)
}
}
}
baseLibName := func(depName string) string { // Note: the order of libs in this list is not important because
// they merely serve as Make dependencies and do not affect this lib itself.
// TODO(ccross): The reexportFlags, order and ndk checks are there to
// maintain previous behavior when adding libraryDependencyTag and
// should be removed.
if !c.static() || libDepTag.reexportFlags || libDepTag.Order == lateLibraryDependency || libDepTag.ndk {
c.Properties.AndroidMkSharedLibs = append(
c.Properties.AndroidMkSharedLibs, makeLibName)
}
// Record baseLibName for snapshots.
c.Properties.SnapshotSharedLibs = append(c.Properties.SnapshotSharedLibs, baseLibName(depName))
case libDepTag.static():
if libDepTag.wholeStatic {
c.Properties.AndroidMkWholeStaticLibs = append(
c.Properties.AndroidMkWholeStaticLibs, makeLibName)
} else {
c.Properties.AndroidMkStaticLibs = append(
c.Properties.AndroidMkStaticLibs, makeLibName)
}
}
} else {
switch depTag {
case runtimeDepTag:
c.Properties.AndroidMkRuntimeLibs = append(
c.Properties.AndroidMkRuntimeLibs, c.makeLibName(ctx, ccDep, depName)+libDepTag.makeSuffix)
// Record baseLibName for snapshots.
c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, baseLibName(depName))
case objDepTag:
depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path())
case CrtBeginDepTag:
depPaths.CrtBegin = linkFile
case CrtEndDepTag:
depPaths.CrtEnd = linkFile
case dynamicLinkerDepTag:
depPaths.DynamicLinker = linkFile
}
}
})
// use the ordered dependencies as this module's dependencies
depPaths.StaticLibs = append(depPaths.StaticLibs, orderStaticModuleDeps(c, directStaticDeps, directSharedDeps)...)
// Dedup exported flags from dependencies
depPaths.Flags = android.FirstUniqueStrings(depPaths.Flags)
depPaths.IncludeDirs = android.FirstUniquePaths(depPaths.IncludeDirs)
depPaths.SystemIncludeDirs = android.FirstUniquePaths(depPaths.SystemIncludeDirs)
depPaths.GeneratedDeps = android.FirstUniquePaths(depPaths.GeneratedDeps)
depPaths.ReexportedDirs = android.FirstUniquePaths(depPaths.ReexportedDirs)
depPaths.ReexportedSystemDirs = android.FirstUniquePaths(depPaths.ReexportedSystemDirs)
depPaths.ReexportedFlags = android.FirstUniqueStrings(depPaths.ReexportedFlags)
depPaths.ReexportedDeps = android.FirstUniquePaths(depPaths.ReexportedDeps)
depPaths.ReexportedGeneratedHeaders = android.FirstUniquePaths(depPaths.ReexportedGeneratedHeaders)
if c.sabi != nil {
c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes)
}
return depPaths
}
// baseLibName trims known prefixes and suffixes
func baseLibName(depName string) string {
libName := strings.TrimSuffix(depName, llndkLibrarySuffix) libName := strings.TrimSuffix(depName, llndkLibrarySuffix)
libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix) libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix)
libName = strings.TrimPrefix(libName, "prebuilt_") libName = strings.TrimPrefix(libName, "prebuilt_")
return libName return libName
} }
makeLibName := func(depName string) string { func (c *Module) makeLibName(ctx android.ModuleContext, ccDep LinkableInterface, depName string) string {
vendorSuffixModules := vendorSuffixModules(ctx.Config())
vendorPublicLibraries := vendorPublicLibraries(ctx.Config())
libName := baseLibName(depName) libName := baseLibName(depName)
isLLndk := isLlndkLibrary(libName, ctx.Config()) isLLndk := isLlndkLibrary(libName, ctx.Config())
isVendorPublicLib := inList(libName, *vendorPublicLibraries) isVendorPublicLib := inList(libName, *vendorPublicLibraries)
@ -2603,68 +2773,6 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
} }
} }
// Export the shared libs to Make.
switch depTag {
case SharedDepTag, sharedExportDepTag, lateSharedDepTag, earlySharedDepTag:
if ccDep.CcLibrary() {
if ccDep.BuildStubs() && android.InAnyApex(depName) {
// Add the dependency to the APEX(es) providing the library so that
// m <module> can trigger building the APEXes as well.
for _, an := range android.GetApexesForModule(depName) {
c.Properties.ApexesProvidingSharedLibs = append(
c.Properties.ApexesProvidingSharedLibs, an)
}
}
}
// Note: the order of libs in this list is not important because
// they merely serve as Make dependencies and do not affect this lib itself.
c.Properties.AndroidMkSharedLibs = append(
c.Properties.AndroidMkSharedLibs, makeLibName(depName))
// Record baseLibName for snapshots.
c.Properties.SnapshotSharedLibs = append(c.Properties.SnapshotSharedLibs, baseLibName(depName))
case ndkStubDepTag, ndkLateStubDepTag:
c.Properties.AndroidMkSharedLibs = append(
c.Properties.AndroidMkSharedLibs,
depName+"."+ccDep.ApiLevel())
case StaticDepTag, staticExportDepTag, lateStaticDepTag:
c.Properties.AndroidMkStaticLibs = append(
c.Properties.AndroidMkStaticLibs, makeLibName(depName))
case runtimeDepTag:
c.Properties.AndroidMkRuntimeLibs = append(
c.Properties.AndroidMkRuntimeLibs, makeLibName(depName))
// Record baseLibName for snapshots.
c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, baseLibName(depName))
case wholeStaticDepTag:
c.Properties.AndroidMkWholeStaticLibs = append(
c.Properties.AndroidMkWholeStaticLibs, makeLibName(depName))
case headerDepTag:
c.Properties.AndroidMkHeaderLibs = append(
c.Properties.AndroidMkHeaderLibs, makeLibName(depName))
}
})
// use the ordered dependencies as this module's dependencies
depPaths.StaticLibs = append(depPaths.StaticLibs, orderStaticModuleDeps(c, directStaticDeps, directSharedDeps)...)
// Dedup exported flags from dependencies
depPaths.Flags = android.FirstUniqueStrings(depPaths.Flags)
depPaths.IncludeDirs = android.FirstUniquePaths(depPaths.IncludeDirs)
depPaths.SystemIncludeDirs = android.FirstUniquePaths(depPaths.SystemIncludeDirs)
depPaths.GeneratedDeps = android.FirstUniquePaths(depPaths.GeneratedDeps)
depPaths.ReexportedDirs = android.FirstUniquePaths(depPaths.ReexportedDirs)
depPaths.ReexportedSystemDirs = android.FirstUniquePaths(depPaths.ReexportedSystemDirs)
depPaths.ReexportedFlags = android.FirstUniqueStrings(depPaths.ReexportedFlags)
depPaths.ReexportedDeps = android.FirstUniquePaths(depPaths.ReexportedDeps)
depPaths.ReexportedGeneratedHeaders = android.FirstUniquePaths(depPaths.ReexportedGeneratedHeaders)
if c.sabi != nil {
c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes)
}
return depPaths
}
func (c *Module) InstallInData() bool { func (c *Module) InstallInData() bool {
if c.installer == nil { if c.installer == nil {
return false return false
@ -2876,10 +2984,12 @@ func (c *Module) AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Write
} }
func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
if depTag, ok := ctx.OtherModuleDependencyTag(dep).(DependencyTag); ok { depTag := ctx.OtherModuleDependencyTag(dep)
libDepTag, isLibDepTag := depTag.(libraryDependencyTag)
if cc, ok := dep.(*Module); ok { if cc, ok := dep.(*Module); ok {
if cc.HasStubsVariants() { if cc.HasStubsVariants() {
if depTag.Shared && depTag.Library { if isLibDepTag && libDepTag.shared() {
// dynamic dep to a stubs lib crosses APEX boundary // dynamic dep to a stubs lib crosses APEX boundary
return false return false
} }
@ -2888,14 +2998,16 @@ func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu
return false return false
} }
} }
if depTag.FromStatic { // TODO(ccross): The libDepTag.reexportFlags is there to maintain previous behavior
// when adding libraryDependencyTag and should be removed.
if isLibDepTag && c.static() && libDepTag.shared() && !libDepTag.reexportFlags {
// shared_lib dependency from a static lib is considered as crossing // shared_lib dependency from a static lib is considered as crossing
// the APEX boundary because the dependency doesn't actually is // the APEX boundary because the dependency doesn't actually is
// linked; the dependency is used only during the compilation phase. // linked; the dependency is used only during the compilation phase.
return false return false
} }
} }
} else if ctx.OtherModuleDependencyTag(dep) == llndkImplDep { if depTag == llndkImplDep {
// We don't track beyond LLNDK // We don't track beyond LLNDK
return false return false
} }

View File

@ -105,12 +105,16 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags
// For static libraries, the only thing that changes our object files // For static libraries, the only thing that changes our object files
// are included whole static libraries, so check to see if any of // are included whole static libraries, so check to see if any of
// those have coverage enabled. // those have coverage enabled.
ctx.VisitDirectDepsWithTag(wholeStaticDepTag, func(m android.Module) { ctx.VisitDirectDeps(func(m android.Module) {
if depTag, ok := ctx.OtherModuleDependencyTag(m).(libraryDependencyTag); ok {
if depTag.static() && depTag.wholeStatic {
if cc, ok := m.(*Module); ok && cc.coverage != nil { if cc, ok := m.(*Module); ok && cc.coverage != nil {
if cc.coverage.linkCoverage { if cc.coverage.linkCoverage {
cov.linkCoverage = true cov.linkCoverage = true
} }
} }
}
}
}) })
} else { } else {
// For executables and shared libraries, we need to check all of // For executables and shared libraries, we need to check all of

View File

@ -1633,8 +1633,7 @@ func maybeInjectBoringSSLHash(ctx android.ModuleContext, outputFile android.Modu
// TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries. // TODO(b/137267623): Remove this in favor of a cc_genrule when they support operating on shared libraries.
injectBoringSSLHash := Bool(inject) injectBoringSSLHash := Bool(inject)
ctx.VisitDirectDeps(func(dep android.Module) { ctx.VisitDirectDeps(func(dep android.Module) {
tag := ctx.OtherModuleDependencyTag(dep) if tag, ok := ctx.OtherModuleDependencyTag(dep).(libraryDependencyTag); ok && tag.static() {
if tag == StaticDepTag || tag == staticExportDepTag || tag == wholeStaticDepTag || tag == lateStaticDepTag {
if cc, ok := dep.(*Module); ok { if cc, ok := dep.(*Module); ok {
if library, ok := cc.linker.(*libraryDecorator); ok { if library, ok := cc.linker.(*libraryDecorator); ok {
if Bool(library.Properties.Inject_bssl_hash) { if Bool(library.Properties.Inject_bssl_hash) {

View File

@ -1,9 +1,9 @@
package cc package cc
import ( import (
"github.com/google/blueprint"
"android/soong/android" "android/soong/android"
"github.com/google/blueprint"
) )
type LinkableInterface interface { type LinkableInterface interface {
@ -63,27 +63,16 @@ type LinkableInterface interface {
StubDecorator() bool StubDecorator() bool
} }
type DependencyTag struct { var (
blueprint.BaseDependencyTag CrtBeginDepTag = dependencyTag{name: "crtbegin"}
Name string CrtEndDepTag = dependencyTag{name: "crtend"}
Library bool CoverageDepTag = dependencyTag{name: "coverage"}
Shared bool )
ReexportFlags bool func SharedDepTag() blueprint.DependencyTag {
return libraryDependencyTag{Kind: sharedLibraryDependency}
ExplicitlyVersioned bool
FromStatic bool
} }
var ( func StaticDepTag() blueprint.DependencyTag {
SharedDepTag = DependencyTag{Name: "shared", Library: true, Shared: true} return libraryDependencyTag{Kind: staticLibraryDependency}
StaticDepTag = DependencyTag{Name: "static", Library: true} }
// Same as SharedDepTag, but from a static lib
SharedFromStaticDepTag = DependencyTag{Name: "shared from static", Library: true, Shared: true, FromStatic: true}
CrtBeginDepTag = DependencyTag{Name: "crtbegin"}
CrtEndDepTag = DependencyTag{Name: "crtend"}
CoverageDepTag = DependencyTag{Name: "coverage"}
)

View File

@ -148,8 +148,21 @@ func ltoDepsMutator(mctx android.TopDownMutatorContext) {
mctx.WalkDeps(func(dep android.Module, parent android.Module) bool { mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
tag := mctx.OtherModuleDependencyTag(dep) tag := mctx.OtherModuleDependencyTag(dep)
switch tag { libTag, isLibTag := tag.(libraryDependencyTag)
case StaticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag, objDepTag, reuseObjTag:
// Do not recurse down non-static dependencies
if isLibTag {
// TODO(ccross): the staticUnwinder check is there to maintain existing behavior
// when adding libraryDependencyTag and should be removed.
if !libTag.static() || libTag.staticUnwinder {
return false
}
} else {
if tag != objDepTag && tag != reuseObjTag {
return false
}
}
if dep, ok := dep.(*Module); ok && dep.lto != nil && if dep, ok := dep.(*Module); ok && dep.lto != nil &&
!dep.lto.Disabled() { !dep.lto.Disabled() {
if full && !Bool(dep.lto.Properties.Lto.Full) { if full && !Bool(dep.lto.Properties.Lto.Full) {
@ -162,10 +175,6 @@ func ltoDepsMutator(mctx android.TopDownMutatorContext) {
// Recursively walk static dependencies // Recursively walk static dependencies
return true return true
}
// Do not recurse down non-static dependencies
return false
}) })
} }
} }

View File

@ -83,10 +83,7 @@ func sabiDepsMutator(mctx android.TopDownMutatorContext) {
((c.IsVndk() && c.UseVndk()) || c.isLlndk(mctx.Config()) || ((c.IsVndk() && c.UseVndk()) || c.isLlndk(mctx.Config()) ||
(c.sabi != nil && c.sabi.Properties.CreateSAbiDumps)) { (c.sabi != nil && c.sabi.Properties.CreateSAbiDumps)) {
mctx.VisitDirectDeps(func(m android.Module) { mctx.VisitDirectDeps(func(m android.Module) {
tag := mctx.OtherModuleDependencyTag(m) if tag, ok := mctx.OtherModuleDependencyTag(m).(libraryDependencyTag); ok && tag.static() {
switch tag {
case StaticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag:
cc, _ := m.(*Module) cc, _ := m.(*Module)
if cc == nil { if cc == nil {
return return

View File

@ -714,8 +714,14 @@ func (sanitize *sanitize) isSanitizerEnabled(t sanitizerType) bool {
} }
func isSanitizableDependencyTag(tag blueprint.DependencyTag) bool { func isSanitizableDependencyTag(tag blueprint.DependencyTag) bool {
t, ok := tag.(DependencyTag) switch t := tag.(type) {
return ok && t.Library || t == reuseObjTag || t == objDepTag case dependencyTag:
return t == reuseObjTag || t == objDepTag
case libraryDependencyTag:
return true
default:
return false
}
} }
// Propagate sanitizer requirements down from binaries // Propagate sanitizer requirements down from binaries
@ -957,10 +963,11 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
} }
// static executable gets static runtime libs // static executable gets static runtime libs
depTag := libraryDependencyTag{Kind: staticLibraryDependency}
mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{ mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
{Mutator: "link", Variation: "static"}, {Mutator: "link", Variation: "static"},
c.ImageVariation(), c.ImageVariation(),
}...), StaticDepTag, deps...) }...), depTag, deps...)
} else if !c.static() && !c.header() { } else if !c.static() && !c.header() {
// If we're using snapshots and in vendor, redirect to snapshot whenever possible // If we're using snapshots and in vendor, redirect to snapshot whenever possible
if c.VndkVersion() == mctx.DeviceConfig().VndkVersion() { if c.VndkVersion() == mctx.DeviceConfig().VndkVersion() {
@ -971,10 +978,11 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
} }
// dynamic executable and shared libs get shared runtime libs // dynamic executable and shared libs get shared runtime libs
depTag := libraryDependencyTag{Kind: sharedLibraryDependency, Order: earlyLibraryDependency}
mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{ mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
{Mutator: "link", Variation: "shared"}, {Mutator: "link", Variation: "shared"},
c.ImageVariation(), c.ImageVariation(),
}...), earlySharedDepTag, runtimeLibrary) }...), depTag, runtimeLibrary)
} }
// static lib does not have dependency to the runtime library. The // static lib does not have dependency to the runtime library. The
// dependency will be added to the executables or shared libs using // dependency will be added to the executables or shared libs using

View File

@ -26,6 +26,8 @@ import (
"android/soong/android" "android/soong/android"
"android/soong/cc/config" "android/soong/cc/config"
"android/soong/etc" "android/soong/etc"
"github.com/google/blueprint"
) )
const ( const (
@ -127,7 +129,7 @@ func (vndk *vndkdep) typeName() string {
return "native:vendor:vndkspext" return "native:vendor:vndkspext"
} }
func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, tag DependencyTag) { func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, tag blueprint.DependencyTag) {
if to.linker == nil { if to.linker == nil {
return return
} }

View File

@ -845,7 +845,9 @@ func collectAppDeps(ctx android.ModuleContext, app appDepsInterface,
otherName := ctx.OtherModuleName(module) otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module) tag := ctx.OtherModuleDependencyTag(module)
if IsJniDepTag(tag) || tag == cc.SharedDepTag { // TODO(ccross): The tag == cc.SharedDepTag() check should be cc.IsSharedDepTag(tag) but
// was left to maintain behavior when adding libraryDependencyTag.
if IsJniDepTag(tag) || tag == cc.SharedDepTag() {
if dep, ok := module.(*cc.Module); ok { if dep, ok := module.(*cc.Module); ok {
if dep.IsNdk() || dep.IsStubs() { if dep.IsNdk() || dep.IsStubs() {
return false return false

View File

@ -848,8 +848,8 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
} }
exportDep := false exportDep := false
switch depTag { switch {
case cc.StaticDepTag: case cc.IsStaticDepTag(depTag):
depFlag = "-lstatic=" + libName depFlag = "-lstatic=" + libName
depPaths.linkDirs = append(depPaths.linkDirs, linkPath) depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.depFlags = append(depPaths.depFlags, depFlag) depPaths.depFlags = append(depPaths.depFlags, depFlag)
@ -861,7 +861,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
depPaths.coverageFiles = append(depPaths.coverageFiles, ccDep.CoverageFiles()...) depPaths.coverageFiles = append(depPaths.coverageFiles, ccDep.CoverageFiles()...)
directStaticLibDeps = append(directStaticLibDeps, ccDep) directStaticLibDeps = append(directStaticLibDeps, ccDep)
mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName) mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName)
case cc.SharedDepTag: case cc.IsSharedDepTag(depTag):
depFlag = "-ldylib=" + libName depFlag = "-ldylib=" + libName
depPaths.linkDirs = append(depPaths.linkDirs, linkPath) depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.depFlags = append(depPaths.depFlags, depFlag) depPaths.depFlags = append(depPaths.depFlags, depFlag)
@ -873,9 +873,9 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
directSharedLibDeps = append(directSharedLibDeps, ccDep) directSharedLibDeps = append(directSharedLibDeps, ccDep)
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName) mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName)
exportDep = true exportDep = true
case cc.CrtBeginDepTag: case depTag == cc.CrtBeginDepTag:
depPaths.CrtBegin = linkFile depPaths.CrtBegin = linkFile
case cc.CrtEndDepTag: case depTag == cc.CrtEndDepTag:
depPaths.CrtEnd = linkFile depPaths.CrtEnd = linkFile
} }
@ -998,10 +998,10 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
actx.AddVariationDependencies(append(commonDepVariations, actx.AddVariationDependencies(append(commonDepVariations,
blueprint.Variation{Mutator: "link", Variation: "shared"}), blueprint.Variation{Mutator: "link", Variation: "shared"}),
cc.SharedDepTag, deps.SharedLibs...) cc.SharedDepTag(), deps.SharedLibs...)
actx.AddVariationDependencies(append(commonDepVariations, actx.AddVariationDependencies(append(commonDepVariations,
blueprint.Variation{Mutator: "link", Variation: "static"}), blueprint.Variation{Mutator: "link", Variation: "static"}),
cc.StaticDepTag, deps.StaticLibs...) cc.StaticDepTag(), deps.StaticLibs...)
if deps.CrtBegin != "" { if deps.CrtBegin != "" {
actx.AddVariationDependencies(commonDepVariations, cc.CrtBeginDepTag, deps.CrtBegin) actx.AddVariationDependencies(commonDepVariations, cc.CrtBeginDepTag, deps.CrtBegin)