Introduce runtime_libs to cc_binary and cc_library
This commit adds `runtime_libs` to cc_binary and cc_library. Similar to the `required` property, if a module specifies the `runtime_libs` properties and it is installed, then the modules specified in `runtime_libs` will be installed as well. Differnt from the `required` property, if a module is using VNDK and the module names specified in `runtime_libs` are resolved to the modules with both core and vendor variants, then '.vendor' will be appended to those module names. For example, if `libb` is vendor_available and `libd` is a vendor lib, then LOCAL_REQUIRED_MODULES will contain `libb.vendor` (instead of `libb`). Bug: 72343507 Test: lunch aosp_arm64_ab-userdebug && make # this runs the unit tests Test: Create a vendor module with runtime_libs property to a vendor_available shared library and check the generated Android.mk. Change-Id: I9e245d80004dab597a5d3db5acd8a09117118db7
This commit is contained in:
@@ -169,7 +169,7 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.M
|
|||||||
data.Include = "$(BUILD_PREBUILT)"
|
data.Include = "$(BUILD_PREBUILT)"
|
||||||
}
|
}
|
||||||
|
|
||||||
data.Required = amod.commonProperties.Required
|
data.Required = append(data.Required, amod.commonProperties.Required...)
|
||||||
|
|
||||||
// Make does not understand LinuxBionic
|
// Make does not understand LinuxBionic
|
||||||
if amod.Os() == LinuxBionic {
|
if amod.Os() == LinuxBionic {
|
||||||
|
@@ -58,6 +58,8 @@ func (c *Module) AndroidMk() android.AndroidMkData {
|
|||||||
|
|
||||||
ret := android.AndroidMkData{
|
ret := android.AndroidMkData{
|
||||||
OutputFile: c.outputFile,
|
OutputFile: c.outputFile,
|
||||||
|
Required: c.Properties.AndroidMkRuntimeLibs,
|
||||||
|
|
||||||
Extra: []android.AndroidMkExtraFunc{
|
Extra: []android.AndroidMkExtraFunc{
|
||||||
func(w io.Writer, outputFile android.Path) {
|
func(w io.Writer, outputFile android.Path) {
|
||||||
if len(c.Properties.Logtags) > 0 {
|
if len(c.Properties.Logtags) > 0 {
|
||||||
|
30
cc/cc.go
30
cc/cc.go
@@ -68,6 +68,7 @@ type Deps struct {
|
|||||||
SharedLibs, LateSharedLibs []string
|
SharedLibs, LateSharedLibs []string
|
||||||
StaticLibs, LateStaticLibs, WholeStaticLibs []string
|
StaticLibs, LateStaticLibs, WholeStaticLibs []string
|
||||||
HeaderLibs []string
|
HeaderLibs []string
|
||||||
|
RuntimeLibs []string
|
||||||
|
|
||||||
ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string
|
ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string
|
||||||
|
|
||||||
@@ -165,6 +166,7 @@ type BaseProperties struct {
|
|||||||
Sdk_version *string
|
Sdk_version *string
|
||||||
|
|
||||||
AndroidMkSharedLibs []string `blueprint:"mutated"`
|
AndroidMkSharedLibs []string `blueprint:"mutated"`
|
||||||
|
AndroidMkRuntimeLibs []string `blueprint:"mutated"`
|
||||||
HideFromMake bool `blueprint:"mutated"`
|
HideFromMake bool `blueprint:"mutated"`
|
||||||
PreventInstall bool `blueprint:"mutated"`
|
PreventInstall bool `blueprint:"mutated"`
|
||||||
|
|
||||||
@@ -306,6 +308,7 @@ var (
|
|||||||
ndkStubDepTag = dependencyTag{name: "ndk stub", library: true}
|
ndkStubDepTag = dependencyTag{name: "ndk stub", library: true}
|
||||||
ndkLateStubDepTag = dependencyTag{name: "ndk late stub", library: true}
|
ndkLateStubDepTag = dependencyTag{name: "ndk late stub", library: true}
|
||||||
vndkExtDepTag = dependencyTag{name: "vndk extends", library: true}
|
vndkExtDepTag = dependencyTag{name: "vndk extends", library: true}
|
||||||
|
runtimeDepTag = dependencyTag{name: "runtime lib"}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Module contains the properties and members used by all C/C++ module types, and implements
|
// Module contains the properties and members used by all C/C++ module types, and implements
|
||||||
@@ -667,7 +670,6 @@ func orderStaticModuleDeps(module *Module, staticDeps []*Module, sharedDeps []*M
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
||||||
|
|
||||||
ctx := &moduleContext{
|
ctx := &moduleContext{
|
||||||
ModuleContext: actx,
|
ModuleContext: actx,
|
||||||
moduleContextImpl: moduleContextImpl{
|
moduleContextImpl: moduleContextImpl{
|
||||||
@@ -846,6 +848,7 @@ func (c *Module) deps(ctx DepsContext) Deps {
|
|||||||
deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs)
|
deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs)
|
||||||
deps.LateSharedLibs = android.LastUniqueStrings(deps.LateSharedLibs)
|
deps.LateSharedLibs = android.LastUniqueStrings(deps.LateSharedLibs)
|
||||||
deps.HeaderLibs = android.LastUniqueStrings(deps.HeaderLibs)
|
deps.HeaderLibs = android.LastUniqueStrings(deps.HeaderLibs)
|
||||||
|
deps.RuntimeLibs = android.LastUniqueStrings(deps.RuntimeLibs)
|
||||||
|
|
||||||
for _, lib := range deps.ReexportSharedLibHeaders {
|
for _, lib := range deps.ReexportSharedLibHeaders {
|
||||||
if !inList(lib, deps.SharedLibs) {
|
if !inList(lib, deps.SharedLibs) {
|
||||||
@@ -987,6 +990,9 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||||||
actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
|
actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, lateSharedDepTag,
|
||||||
deps.LateSharedLibs...)
|
deps.LateSharedLibs...)
|
||||||
|
|
||||||
|
actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, runtimeDepTag,
|
||||||
|
deps.RuntimeLibs...)
|
||||||
|
|
||||||
actx.AddDependency(c, genSourceDepTag, deps.GeneratedSources...)
|
actx.AddDependency(c, genSourceDepTag, deps.GeneratedSources...)
|
||||||
|
|
||||||
for _, gen := range deps.GeneratedHeaders {
|
for _, gen := range deps.GeneratedHeaders {
|
||||||
@@ -1346,28 +1352,34 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
*depPtr = append(*depPtr, dep.Path())
|
*depPtr = append(*depPtr, dep.Path())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export the shared libs to Make.
|
makeLibName := func(depName string) string {
|
||||||
switch depTag {
|
|
||||||
case sharedDepTag, sharedExportDepTag, lateSharedDepTag:
|
|
||||||
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_")
|
||||||
isLLndk := inList(libName, llndkLibraries)
|
isLLndk := inList(libName, llndkLibraries)
|
||||||
isVendorPublicLib := inList(libName, vendorPublicLibraries)
|
isVendorPublicLib := inList(libName, vendorPublicLibraries)
|
||||||
var makeLibName string
|
|
||||||
bothVendorAndCoreVariantsExist := ccDep.hasVendorVariant() || isLLndk
|
bothVendorAndCoreVariantsExist := ccDep.hasVendorVariant() || isLLndk
|
||||||
if c.useVndk() && bothVendorAndCoreVariantsExist {
|
if c.useVndk() && bothVendorAndCoreVariantsExist {
|
||||||
// The vendor module in Make will have been renamed to not conflict with the core
|
// The vendor module in Make will have been renamed to not conflict with the core
|
||||||
// module, so update the dependency name here accordingly.
|
// module, so update the dependency name here accordingly.
|
||||||
makeLibName = libName + vendorSuffix
|
return libName + vendorSuffix
|
||||||
} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib {
|
} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib {
|
||||||
makeLibName = libName + vendorPublicLibrarySuffix
|
return libName + vendorPublicLibrarySuffix
|
||||||
} else {
|
} else {
|
||||||
makeLibName = libName
|
return libName
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export the shared libs to Make.
|
||||||
|
switch depTag {
|
||||||
|
case sharedDepTag, sharedExportDepTag, lateSharedDepTag:
|
||||||
// Note: the order of libs in this list is not important because
|
// 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.
|
// they merely serve as Make dependencies and do not affect this lib itself.
|
||||||
c.Properties.AndroidMkSharedLibs = append(c.Properties.AndroidMkSharedLibs, makeLibName)
|
c.Properties.AndroidMkSharedLibs = append(
|
||||||
|
c.Properties.AndroidMkSharedLibs, makeLibName(depName))
|
||||||
|
case runtimeDepTag:
|
||||||
|
c.Properties.AndroidMkRuntimeLibs = append(
|
||||||
|
c.Properties.AndroidMkRuntimeLibs, makeLibName(depName))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
114
cc/cc_test.go
114
cc/cc_test.go
@@ -1388,6 +1388,120 @@ func TestLlndkHeaders(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
|
||||||
|
actual := module.Properties.AndroidMkRuntimeLibs
|
||||||
|
if !reflect.DeepEqual(actual, expected) {
|
||||||
|
t.Errorf("incorrect runtime_libs for shared libs"+
|
||||||
|
"\nactual: %v"+
|
||||||
|
"\nexpected: %v",
|
||||||
|
actual,
|
||||||
|
expected,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const runtimeLibAndroidBp = `
|
||||||
|
cc_library {
|
||||||
|
name: "libvendor_available1",
|
||||||
|
vendor_available: true,
|
||||||
|
no_libgcc : true,
|
||||||
|
nocrt : true,
|
||||||
|
system_shared_libs : [],
|
||||||
|
}
|
||||||
|
cc_library {
|
||||||
|
name: "libvendor_available2",
|
||||||
|
vendor_available: true,
|
||||||
|
runtime_libs: ["libvendor_available1"],
|
||||||
|
no_libgcc : true,
|
||||||
|
nocrt : true,
|
||||||
|
system_shared_libs : [],
|
||||||
|
}
|
||||||
|
cc_library {
|
||||||
|
name: "libvendor_available3",
|
||||||
|
vendor_available: true,
|
||||||
|
runtime_libs: ["libvendor_available1"],
|
||||||
|
target: {
|
||||||
|
vendor: {
|
||||||
|
exclude_runtime_libs: ["libvendor_available1"],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
no_libgcc : true,
|
||||||
|
nocrt : true,
|
||||||
|
system_shared_libs : [],
|
||||||
|
}
|
||||||
|
cc_library {
|
||||||
|
name: "libcore",
|
||||||
|
runtime_libs: ["libvendor_available1"],
|
||||||
|
no_libgcc : true,
|
||||||
|
nocrt : true,
|
||||||
|
system_shared_libs : [],
|
||||||
|
}
|
||||||
|
cc_library {
|
||||||
|
name: "libvendor1",
|
||||||
|
vendor: true,
|
||||||
|
no_libgcc : true,
|
||||||
|
nocrt : true,
|
||||||
|
system_shared_libs : [],
|
||||||
|
}
|
||||||
|
cc_library {
|
||||||
|
name: "libvendor2",
|
||||||
|
vendor: true,
|
||||||
|
runtime_libs: ["libvendor_available1", "libvendor1"],
|
||||||
|
no_libgcc : true,
|
||||||
|
nocrt : true,
|
||||||
|
system_shared_libs : [],
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
func TestRuntimeLibs(t *testing.T) {
|
||||||
|
ctx := testCc(t, runtimeLibAndroidBp)
|
||||||
|
|
||||||
|
// runtime_libs for core variants use the module names without suffixes.
|
||||||
|
variant := "android_arm64_armv8-a_core_shared"
|
||||||
|
|
||||||
|
module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
|
||||||
|
checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
|
||||||
|
|
||||||
|
module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
|
||||||
|
checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
|
||||||
|
|
||||||
|
// runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
|
||||||
|
// and vendor variants.
|
||||||
|
variant = "android_arm64_armv8-a_vendor_shared"
|
||||||
|
|
||||||
|
module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
|
||||||
|
checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
|
||||||
|
|
||||||
|
module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
|
||||||
|
checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExcludeRuntimeLibs(t *testing.T) {
|
||||||
|
ctx := testCc(t, runtimeLibAndroidBp)
|
||||||
|
|
||||||
|
variant := "android_arm64_armv8-a_core_shared"
|
||||||
|
module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
|
||||||
|
checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
|
||||||
|
|
||||||
|
variant = "android_arm64_armv8-a_vendor_shared"
|
||||||
|
module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
|
||||||
|
checkRuntimeLibs(t, nil, module)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRuntimeLibsNoVndk(t *testing.T) {
|
||||||
|
ctx := testCcNoVndk(t, runtimeLibAndroidBp)
|
||||||
|
|
||||||
|
// If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
|
||||||
|
|
||||||
|
variant := "android_arm64_armv8-a_core_shared"
|
||||||
|
|
||||||
|
module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
|
||||||
|
checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
|
||||||
|
|
||||||
|
module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
|
||||||
|
checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
|
||||||
|
}
|
||||||
|
|
||||||
var compilerFlagsTestCases = []struct {
|
var compilerFlagsTestCases = []struct {
|
||||||
in string
|
in string
|
||||||
out bool
|
out bool
|
||||||
|
19
cc/linker.go
19
cc/linker.go
@@ -88,15 +88,24 @@ type BaseLinkerProperties struct {
|
|||||||
// between static libraries, but it is generally better to order them correctly instead.
|
// between static libraries, but it is generally better to order them correctly instead.
|
||||||
Group_static_libs *bool `android:"arch_variant"`
|
Group_static_libs *bool `android:"arch_variant"`
|
||||||
|
|
||||||
|
// list of modules that should be installed with this module. This is similar to 'required'
|
||||||
|
// but '.vendor' suffix will be appended to the module names if the shared libraries have
|
||||||
|
// vendor variants and this module uses VNDK.
|
||||||
|
Runtime_libs []string `android:"arch_variant"`
|
||||||
|
|
||||||
Target struct {
|
Target struct {
|
||||||
Vendor struct {
|
Vendor struct {
|
||||||
// list of shared libs that should not be used to build
|
// list of shared libs that should not be used to build the vendor variant
|
||||||
// the vendor variant of the C/C++ module.
|
// of the C/C++ module.
|
||||||
Exclude_shared_libs []string
|
Exclude_shared_libs []string
|
||||||
|
|
||||||
// list of static libs that should not be used to build
|
// list of static libs that should not be used to build the vendor variant
|
||||||
// the vendor variant of the C/C++ module.
|
// of the C/C++ module.
|
||||||
Exclude_static_libs []string
|
Exclude_static_libs []string
|
||||||
|
|
||||||
|
// list of runtime libs that should not be installed along with the vendor
|
||||||
|
// variant of the C/C++ module.
|
||||||
|
Exclude_runtime_libs []string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +146,7 @@ func (linker *baseLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
|||||||
deps.HeaderLibs = append(deps.HeaderLibs, linker.Properties.Header_libs...)
|
deps.HeaderLibs = append(deps.HeaderLibs, linker.Properties.Header_libs...)
|
||||||
deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
|
deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...)
|
||||||
deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
|
deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...)
|
||||||
|
deps.RuntimeLibs = append(deps.RuntimeLibs, linker.Properties.Runtime_libs...)
|
||||||
|
|
||||||
deps.ReexportHeaderLibHeaders = append(deps.ReexportHeaderLibHeaders, linker.Properties.Export_header_lib_headers...)
|
deps.ReexportHeaderLibHeaders = append(deps.ReexportHeaderLibHeaders, linker.Properties.Export_header_lib_headers...)
|
||||||
deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, linker.Properties.Export_static_lib_headers...)
|
deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, linker.Properties.Export_static_lib_headers...)
|
||||||
@@ -153,6 +163,7 @@ func (linker *baseLinker) linkerDeps(ctx BaseModuleContext, deps Deps) Deps {
|
|||||||
deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs)
|
deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs)
|
||||||
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor.Exclude_static_libs)
|
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor.Exclude_static_libs)
|
||||||
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs)
|
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs)
|
||||||
|
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Vendor.Exclude_runtime_libs)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.ModuleName() != "libcompiler_rt-extras" {
|
if ctx.ModuleName() != "libcompiler_rt-extras" {
|
||||||
|
Reference in New Issue
Block a user