Merge "Add libraryDependencyTag to track dependencies on static and shared libraries"
This commit is contained in:
commit
2eddd06879
12 changed files with 465 additions and 343 deletions
|
@ -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, "")
|
||||||
|
|
|
@ -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",
|
||||||
|
|
664
cc/cc.go
664
cc/cc.go
|
@ -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,210 +2522,178 @@ 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():
|
||||||
ptr = &depPaths.SharedLibs
|
// nothing
|
||||||
depPtr = &depPaths.SharedLibsDeps
|
case libDepTag.shared():
|
||||||
depFile = ccDep.Toc()
|
ptr = &depPaths.SharedLibs
|
||||||
directSharedDeps = append(directSharedDeps, ccDep)
|
switch libDepTag.Order {
|
||||||
|
case earlyLibraryDependency:
|
||||||
case earlySharedDepTag:
|
ptr = &depPaths.EarlySharedLibs
|
||||||
ptr = &depPaths.EarlySharedLibs
|
depPtr = &depPaths.EarlySharedLibsDeps
|
||||||
depPtr = &depPaths.EarlySharedLibsDeps
|
case normalLibraryDependency:
|
||||||
depFile = ccDep.Toc()
|
ptr = &depPaths.SharedLibs
|
||||||
directSharedDeps = append(directSharedDeps, ccDep)
|
depPtr = &depPaths.SharedLibsDeps
|
||||||
case lateSharedDepTag, ndkLateStubDepTag:
|
directSharedDeps = append(directSharedDeps, ccDep)
|
||||||
ptr = &depPaths.LateSharedLibs
|
case lateLibraryDependency:
|
||||||
depPtr = &depPaths.LateSharedLibsDeps
|
ptr = &depPaths.LateSharedLibs
|
||||||
depFile = ccDep.Toc()
|
depPtr = &depPaths.LateSharedLibsDeps
|
||||||
case StaticDepTag, staticExportDepTag:
|
default:
|
||||||
ptr = nil
|
panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order))
|
||||||
directStaticDeps = append(directStaticDeps, ccDep)
|
|
||||||
case lateStaticDepTag:
|
|
||||||
ptr = &depPaths.LateStaticLibs
|
|
||||||
case wholeStaticDepTag:
|
|
||||||
ptr = &depPaths.WholeStaticLibs
|
|
||||||
if !ccDep.CcLibraryInterface() || !ccDep.Static() {
|
|
||||||
ctx.ModuleErrorf("module %q not a static library", depName)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Because the static library objects are included, this only makes sense
|
|
||||||
// in the context of proper cc.Modules.
|
|
||||||
if ccWholeStaticLib, ok := ccDep.(*Module); ok {
|
|
||||||
staticLib := ccWholeStaticLib.linker.(libraryInterface)
|
|
||||||
if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
|
|
||||||
postfix := " (required by " + ctx.OtherModuleName(dep) + ")"
|
|
||||||
for i := range missingDeps {
|
|
||||||
missingDeps[i] += postfix
|
|
||||||
}
|
|
||||||
ctx.AddMissingDependencies(missingDeps)
|
|
||||||
}
|
}
|
||||||
if _, ok := ccWholeStaticLib.linker.(prebuiltLinkerInterface); ok {
|
depFile = ccDep.Toc()
|
||||||
depPaths.WholeStaticLibsFromPrebuilts = append(depPaths.WholeStaticLibsFromPrebuilts, linkFile.Path())
|
case libDepTag.static():
|
||||||
} else {
|
if libDepTag.wholeStatic {
|
||||||
depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLib.objs())
|
ptr = &depPaths.WholeStaticLibs
|
||||||
}
|
if !ccDep.CcLibraryInterface() || !ccDep.Static() {
|
||||||
} else {
|
ctx.ModuleErrorf("module %q not a static library", depName)
|
||||||
ctx.ModuleErrorf(
|
return
|
||||||
"non-cc.Modules cannot be included as whole static libraries.", depName)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case headerDepTag:
|
|
||||||
// Nothing
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
switch depTag {
|
|
||||||
case StaticDepTag, staticExportDepTag, lateStaticDepTag:
|
|
||||||
if !ccDep.CcLibraryInterface() || !ccDep.Static() {
|
|
||||||
ctx.ModuleErrorf("module %q not a static library", depName)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// When combining coverage files for shared libraries and executables, coverage files
|
|
||||||
// in static libraries act as if they were whole static libraries. The same goes for
|
|
||||||
// source based Abi dump files.
|
|
||||||
if c, ok := ccDep.(*Module); ok {
|
|
||||||
staticLib := c.linker.(libraryInterface)
|
|
||||||
depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles,
|
|
||||||
staticLib.objs().coverageFiles...)
|
|
||||||
depPaths.StaticLibObjs.sAbiDumpFiles = append(depPaths.StaticLibObjs.sAbiDumpFiles,
|
|
||||||
staticLib.objs().sAbiDumpFiles...)
|
|
||||||
} else if c, ok := ccDep.(LinkableInterface); ok {
|
|
||||||
// Handle non-CC modules here
|
|
||||||
depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles,
|
|
||||||
c.CoverageFiles()...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ptr != nil {
|
|
||||||
if !linkFile.Valid() {
|
|
||||||
if !ctx.Config().AllowMissingDependencies() {
|
|
||||||
ctx.ModuleErrorf("module %q missing output file", depName)
|
|
||||||
} else {
|
|
||||||
ctx.AddMissingDependencies([]string{depName})
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
*ptr = append(*ptr, linkFile.Path())
|
|
||||||
}
|
|
||||||
|
|
||||||
if depPtr != nil {
|
|
||||||
dep := depFile
|
|
||||||
if !dep.Valid() {
|
|
||||||
dep = linkFile
|
|
||||||
}
|
|
||||||
*depPtr = append(*depPtr, dep.Path())
|
|
||||||
}
|
|
||||||
|
|
||||||
vendorSuffixModules := vendorSuffixModules(ctx.Config())
|
|
||||||
|
|
||||||
baseLibName := func(depName string) string {
|
|
||||||
libName := strings.TrimSuffix(depName, llndkLibrarySuffix)
|
|
||||||
libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix)
|
|
||||||
libName = strings.TrimPrefix(libName, "prebuilt_")
|
|
||||||
return libName
|
|
||||||
}
|
|
||||||
|
|
||||||
makeLibName := func(depName string) string {
|
|
||||||
libName := baseLibName(depName)
|
|
||||||
isLLndk := isLlndkLibrary(libName, ctx.Config())
|
|
||||||
isVendorPublicLib := inList(libName, *vendorPublicLibraries)
|
|
||||||
bothVendorAndCoreVariantsExist := ccDep.HasVendorVariant() || isLLndk
|
|
||||||
|
|
||||||
if c, ok := ccDep.(*Module); ok {
|
|
||||||
// Use base module name for snapshots when exporting to Makefile.
|
|
||||||
if c.isSnapshotPrebuilt() {
|
|
||||||
baseName := c.BaseModuleName()
|
|
||||||
|
|
||||||
if c.IsVndk() {
|
|
||||||
return baseName + ".vendor"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if vendorSuffixModules[baseName] {
|
// Because the static library objects are included, this only makes sense
|
||||||
return baseName + ".vendor"
|
// in the context of proper cc.Modules.
|
||||||
|
if ccWholeStaticLib, ok := ccDep.(*Module); ok {
|
||||||
|
staticLib := ccWholeStaticLib.linker.(libraryInterface)
|
||||||
|
if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
|
||||||
|
postfix := " (required by " + ctx.OtherModuleName(dep) + ")"
|
||||||
|
for i := range missingDeps {
|
||||||
|
missingDeps[i] += postfix
|
||||||
|
}
|
||||||
|
ctx.AddMissingDependencies(missingDeps)
|
||||||
|
}
|
||||||
|
if _, ok := ccWholeStaticLib.linker.(prebuiltLinkerInterface); ok {
|
||||||
|
depPaths.WholeStaticLibsFromPrebuilts = append(depPaths.WholeStaticLibsFromPrebuilts, linkFile.Path())
|
||||||
|
} else {
|
||||||
|
depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLib.objs())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return baseName
|
ctx.ModuleErrorf(
|
||||||
|
"non-cc.Modules cannot be included as whole static libraries.", depName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
switch libDepTag.Order {
|
||||||
|
case earlyLibraryDependency:
|
||||||
|
panic(fmt.Errorf("early static libs not suppported"))
|
||||||
|
case normalLibraryDependency:
|
||||||
|
// static dependencies will be handled separately so they can be ordered
|
||||||
|
// using transitive dependencies.
|
||||||
|
ptr = nil
|
||||||
|
directStaticDeps = append(directStaticDeps, ccDep)
|
||||||
|
case lateLibraryDependency:
|
||||||
|
ptr = &depPaths.LateStaticLibs
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("unexpected library dependency order %d", libDepTag.Order))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.IsVndk() && !ccDep.MustUseVendorVariant() && !c.InRamdisk() && !c.InRecovery() {
|
if libDepTag.static() && !libDepTag.wholeStatic {
|
||||||
// The vendor module is a no-vendor-variant VNDK library. Depend on the
|
if !ccDep.CcLibraryInterface() || !ccDep.Static() {
|
||||||
// core module instead.
|
ctx.ModuleErrorf("module %q not a static library", depName)
|
||||||
return libName
|
return
|
||||||
} else if c.UseVndk() && bothVendorAndCoreVariantsExist {
|
}
|
||||||
// The vendor module in Make will have been renamed to not conflict with the core
|
|
||||||
// module, so update the dependency name here accordingly.
|
|
||||||
return libName + c.getNameSuffixWithVndkVersion(ctx)
|
|
||||||
} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib {
|
|
||||||
return libName + vendorPublicLibrarySuffix
|
|
||||||
} else if ccDep.InRamdisk() && !ccDep.OnlyInRamdisk() {
|
|
||||||
return libName + ramdiskSuffix
|
|
||||||
} else if ccDep.InRecovery() && !ccDep.OnlyInRecovery() {
|
|
||||||
return libName + recoverySuffix
|
|
||||||
} else if ccDep.Module().Target().NativeBridge == android.NativeBridgeEnabled {
|
|
||||||
return libName + nativeBridgeSuffix
|
|
||||||
} else {
|
|
||||||
return libName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export the shared libs to Make.
|
// When combining coverage files for shared libraries and executables, coverage files
|
||||||
switch depTag {
|
// in static libraries act as if they were whole static libraries. The same goes for
|
||||||
case SharedDepTag, sharedExportDepTag, lateSharedDepTag, earlySharedDepTag:
|
// source based Abi dump files.
|
||||||
if ccDep.CcLibrary() {
|
if c, ok := ccDep.(*Module); ok {
|
||||||
if ccDep.BuildStubs() && android.InAnyApex(depName) {
|
staticLib := c.linker.(libraryInterface)
|
||||||
// Add the dependency to the APEX(es) providing the library so that
|
depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles,
|
||||||
// m <module> can trigger building the APEXes as well.
|
staticLib.objs().coverageFiles...)
|
||||||
for _, an := range android.GetApexesForModule(depName) {
|
depPaths.StaticLibObjs.sAbiDumpFiles = append(depPaths.StaticLibObjs.sAbiDumpFiles,
|
||||||
c.Properties.ApexesProvidingSharedLibs = append(
|
staticLib.objs().sAbiDumpFiles...)
|
||||||
c.Properties.ApexesProvidingSharedLibs, an)
|
} else if c, ok := ccDep.(LinkableInterface); ok {
|
||||||
}
|
// Handle non-CC modules here
|
||||||
|
depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles,
|
||||||
|
c.CoverageFiles()...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: the order of libs in this list is not important because
|
if ptr != nil {
|
||||||
// they merely serve as Make dependencies and do not affect this lib itself.
|
if !linkFile.Valid() {
|
||||||
c.Properties.AndroidMkSharedLibs = append(
|
if !ctx.Config().AllowMissingDependencies() {
|
||||||
c.Properties.AndroidMkSharedLibs, makeLibName(depName))
|
ctx.ModuleErrorf("module %q missing output file", depName)
|
||||||
// Record baseLibName for snapshots.
|
} else {
|
||||||
c.Properties.SnapshotSharedLibs = append(c.Properties.SnapshotSharedLibs, baseLibName(depName))
|
ctx.AddMissingDependencies([]string{depName})
|
||||||
case ndkStubDepTag, ndkLateStubDepTag:
|
}
|
||||||
c.Properties.AndroidMkSharedLibs = append(
|
return
|
||||||
c.Properties.AndroidMkSharedLibs,
|
}
|
||||||
depName+"."+ccDep.ApiLevel())
|
*ptr = append(*ptr, linkFile.Path())
|
||||||
case StaticDepTag, staticExportDepTag, lateStaticDepTag:
|
}
|
||||||
c.Properties.AndroidMkStaticLibs = append(
|
|
||||||
c.Properties.AndroidMkStaticLibs, makeLibName(depName))
|
if depPtr != nil {
|
||||||
case runtimeDepTag:
|
dep := depFile
|
||||||
c.Properties.AndroidMkRuntimeLibs = append(
|
if !dep.Valid() {
|
||||||
c.Properties.AndroidMkRuntimeLibs, makeLibName(depName))
|
dep = linkFile
|
||||||
// Record baseLibName for snapshots.
|
}
|
||||||
c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, baseLibName(depName))
|
*depPtr = append(*depPtr, dep.Path())
|
||||||
case wholeStaticDepTag:
|
}
|
||||||
c.Properties.AndroidMkWholeStaticLibs = append(
|
|
||||||
c.Properties.AndroidMkWholeStaticLibs, makeLibName(depName))
|
makeLibName := c.makeLibName(ctx, ccDep, depName) + libDepTag.makeSuffix
|
||||||
case headerDepTag:
|
switch {
|
||||||
c.Properties.AndroidMkHeaderLibs = append(
|
case libDepTag.header():
|
||||||
c.Properties.AndroidMkHeaderLibs, makeLibName(depName))
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -2665,6 +2718,61 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
||||||
return depPaths
|
return depPaths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// baseLibName trims known prefixes and suffixes
|
||||||
|
func baseLibName(depName string) string {
|
||||||
|
libName := strings.TrimSuffix(depName, llndkLibrarySuffix)
|
||||||
|
libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix)
|
||||||
|
libName = strings.TrimPrefix(libName, "prebuilt_")
|
||||||
|
return libName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Module) makeLibName(ctx android.ModuleContext, ccDep LinkableInterface, depName string) string {
|
||||||
|
vendorSuffixModules := vendorSuffixModules(ctx.Config())
|
||||||
|
vendorPublicLibraries := vendorPublicLibraries(ctx.Config())
|
||||||
|
|
||||||
|
libName := baseLibName(depName)
|
||||||
|
isLLndk := isLlndkLibrary(libName, ctx.Config())
|
||||||
|
isVendorPublicLib := inList(libName, *vendorPublicLibraries)
|
||||||
|
bothVendorAndCoreVariantsExist := ccDep.HasVendorVariant() || isLLndk
|
||||||
|
|
||||||
|
if c, ok := ccDep.(*Module); ok {
|
||||||
|
// Use base module name for snapshots when exporting to Makefile.
|
||||||
|
if c.isSnapshotPrebuilt() {
|
||||||
|
baseName := c.BaseModuleName()
|
||||||
|
|
||||||
|
if c.IsVndk() {
|
||||||
|
return baseName + ".vendor"
|
||||||
|
}
|
||||||
|
|
||||||
|
if vendorSuffixModules[baseName] {
|
||||||
|
return baseName + ".vendor"
|
||||||
|
} else {
|
||||||
|
return baseName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.IsVndk() && !ccDep.MustUseVendorVariant() && !c.InRamdisk() && !c.InRecovery() {
|
||||||
|
// The vendor module is a no-vendor-variant VNDK library. Depend on the
|
||||||
|
// core module instead.
|
||||||
|
return libName
|
||||||
|
} else if c.UseVndk() && bothVendorAndCoreVariantsExist {
|
||||||
|
// The vendor module in Make will have been renamed to not conflict with the core
|
||||||
|
// module, so update the dependency name here accordingly.
|
||||||
|
return libName + c.getNameSuffixWithVndkVersion(ctx)
|
||||||
|
} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib {
|
||||||
|
return libName + vendorPublicLibrarySuffix
|
||||||
|
} else if ccDep.InRamdisk() && !ccDep.OnlyInRamdisk() {
|
||||||
|
return libName + ramdiskSuffix
|
||||||
|
} else if ccDep.InRecovery() && !ccDep.OnlyInRecovery() {
|
||||||
|
return libName + recoverySuffix
|
||||||
|
} else if ccDep.Module().Target().NativeBridge == android.NativeBridgeEnabled {
|
||||||
|
return libName + nativeBridgeSuffix
|
||||||
|
} else {
|
||||||
|
return libName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Module) InstallInData() bool {
|
func (c *Module) InstallInData() bool {
|
||||||
if c.installer == nil {
|
if c.installer == nil {
|
||||||
return false
|
return false
|
||||||
|
@ -2876,26 +2984,30 @@ 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)
|
||||||
if cc, ok := dep.(*Module); ok {
|
libDepTag, isLibDepTag := depTag.(libraryDependencyTag)
|
||||||
if cc.HasStubsVariants() {
|
|
||||||
if depTag.Shared && depTag.Library {
|
if cc, ok := dep.(*Module); ok {
|
||||||
// dynamic dep to a stubs lib crosses APEX boundary
|
if cc.HasStubsVariants() {
|
||||||
return false
|
if isLibDepTag && libDepTag.shared() {
|
||||||
}
|
// dynamic dep to a stubs lib crosses APEX boundary
|
||||||
if IsRuntimeDepTag(depTag) {
|
return false
|
||||||
// runtime dep to a stubs lib also crosses APEX boundary
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if depTag.FromStatic {
|
if IsRuntimeDepTag(depTag) {
|
||||||
// shared_lib dependency from a static lib is considered as crossing
|
// runtime dep to a stubs lib also crosses APEX boundary
|
||||||
// the APEX boundary because the dependency doesn't actually is
|
|
||||||
// linked; the dependency is used only during the compilation phase.
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ctx.OtherModuleDependencyTag(dep) == llndkImplDep {
|
// 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
|
||||||
|
// the APEX boundary because the dependency doesn't actually is
|
||||||
|
// linked; the dependency is used only during the compilation phase.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if depTag == llndkImplDep {
|
||||||
// We don't track beyond LLNDK
|
// We don't track beyond LLNDK
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,10 +105,14 @@ 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 cc, ok := m.(*Module); ok && cc.coverage != nil {
|
if depTag, ok := ctx.OtherModuleDependencyTag(m).(libraryDependencyTag); ok {
|
||||||
if cc.coverage.linkCoverage {
|
if depTag.static() && depTag.wholeStatic {
|
||||||
cov.linkCoverage = true
|
if cc, ok := m.(*Module); ok && cc.coverage != nil {
|
||||||
|
if cc.coverage.linkCoverage {
|
||||||
|
cov.linkCoverage = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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"}
|
|
||||||
)
|
|
||||||
|
|
41
cc/lto.go
41
cc/lto.go
|
@ -148,24 +148,33 @@ 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:
|
|
||||||
if dep, ok := dep.(*Module); ok && dep.lto != nil &&
|
|
||||||
!dep.lto.Disabled() {
|
|
||||||
if full && !Bool(dep.lto.Properties.Lto.Full) {
|
|
||||||
dep.lto.Properties.FullDep = true
|
|
||||||
}
|
|
||||||
if thin && !Bool(dep.lto.Properties.Lto.Thin) {
|
|
||||||
dep.lto.Properties.ThinDep = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recursively walk static dependencies
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not recurse down non-static dependencies
|
// Do not recurse down non-static dependencies
|
||||||
return false
|
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 &&
|
||||||
|
!dep.lto.Disabled() {
|
||||||
|
if full && !Bool(dep.lto.Properties.Lto.Full) {
|
||||||
|
dep.lto.Properties.FullDep = true
|
||||||
|
}
|
||||||
|
if thin && !Bool(dep.lto.Properties.Lto.Thin) {
|
||||||
|
dep.lto.Properties.ThinDep = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively walk static dependencies
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
14
rust/rust.go
14
rust/rust.go
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue