Refactor ccDynamic for static binaries

ccLibrary uses ccDynamic for linking shared libraries, but bypasses
it by calling directly into ccBase for static libraries.  Instead of
duplicating the same mess for ccBinary, rename ccDynamic to ccLinked
and add the logic for dealing with static or shared linkage.  This
also allows moving the stl logic out of ccBase and into ccLinked.

Change-Id: Idfa6d86de16911c8851f694d6ed92681c8939281
This commit is contained in:
Colin Cross 2015-03-26 14:43:45 -07:00
parent be96168ee3
commit ed4cf0b655
3 changed files with 298 additions and 178 deletions

View file

@ -21,10 +21,11 @@ package cc
import (
"android/soong/common"
"github.com/google/blueprint"
"github.com/google/blueprint/pathtools"
"path/filepath"
"strings"
"github.com/google/blueprint"
"github.com/google/blueprint/pathtools"
)
const (
@ -185,7 +186,7 @@ func TransformObjToStaticLib(ctx common.AndroidModuleContext, objFiles []string,
// and shared libraires, to a shared library (.so) or dynamic executable
func TransformObjToDynamicBinary(ctx common.AndroidModuleContext,
objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs []string,
crtBegin, crtEnd string, flags builderFlags, outputFile string) {
crtBegin, crtEnd string, groupLate bool, flags builderFlags, outputFile string) {
var ldCmd string
if flags.clang {
@ -218,7 +219,13 @@ func TransformObjToDynamicBinary(ctx common.AndroidModuleContext,
ldDirs = append(ldDirs, dir)
}
if groupLate {
libFlagsList = append(libFlagsList, "-Wl,--start-group")
}
libFlagsList = append(libFlagsList, lateStaticLibs...)
if groupLate {
libFlagsList = append(libFlagsList, "-Wl,--end-group")
}
deps := []string{ldCmd}
deps = append(deps, sharedLibs...)

451
cc/cc.go
View file

@ -350,52 +350,11 @@ func (c *ccBase) findToolchain(ctx common.AndroidModuleContext) Toolchain {
return factory(arch.ArchVariant, arch.CpuVariant)
}
func addNdkStlDepNames(ctx common.AndroidBaseContext, stl string, depNames CCDeps) CCDeps {
if stl == "ndk_system" {
// TODO: Make a system STL prebuilt for the NDK.
// The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
// its own includes. The includes are handled in ccBase.Flags().
return depNames
}
if strings.HasSuffix(stl, "_static") {
depNames.StaticLibs = append(depNames.StaticLibs, stl)
} else {
depNames.SharedLibs = append(depNames.SharedLibs, stl)
}
return depNames
}
func (c *ccBase) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
depNames.WholeStaticLibs = append(depNames.WholeStaticLibs, c.properties.Whole_static_libs...)
depNames.StaticLibs = append(depNames.StaticLibs, c.properties.Static_libs...)
depNames.SharedLibs = append(depNames.SharedLibs, c.properties.Shared_libs...)
stl := c.stl(ctx)
if ctx.Failed() {
return depNames
}
switch stl {
case "libc++", "libstdc++":
depNames.SharedLibs = append(depNames.SharedLibs, stl)
case "libc++_static":
depNames.StaticLibs = append(depNames.StaticLibs, stl)
case "stlport":
depNames.SharedLibs = append(depNames.SharedLibs, "libstdc++", "libstlport")
case "stlport_static":
depNames.StaticLibs = append(depNames.StaticLibs, "libstdc++", "libstlport_static")
case "":
// None or error.
default:
if !strings.HasPrefix(stl, "ndk_") {
panic("unexpected case")
}
depNames = addNdkStlDepNames(ctx, stl, depNames)
}
return depNames
}
@ -557,74 +516,7 @@ func (c *ccBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
return flags
}
func (c *ccBase) stl(ctx common.AndroidBaseContext) string {
if c.properties.Sdk_version != "" {
stl := c.properties.Stl
if stl == "" {
return "ndk_system"
}
return "ndk_lib" + stl
}
switch c.properties.Stl {
case "libc++", "libc++_static",
"stlport", "stlport_static",
"libstdc++":
return c.properties.Stl
case "none":
return ""
case "":
return "libc++" // TODO: mingw needs libstdc++
default:
ctx.ModuleErrorf("stl: %q is not a supported STL", c.properties.Stl)
return ""
}
}
func (c *ccBase) Flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
stl := c.stl(ctx)
if ctx.Failed() {
return flags
}
switch stl {
case "libc++", "libc++_static":
flags.CFlags = append(flags.CFlags, "-D_USING_LIBCXX")
flags.IncludeDirs = append(flags.IncludeDirs, "${SrcDir}/external/libcxx/include")
if ctx.Host() {
flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
flags.LdLibs = append(flags.LdLibs, "-lc", "-lm", "-lpthread")
}
case "stlport", "stlport_static":
if ctx.Device() {
flags.IncludeDirs = append(flags.IncludeDirs,
"${SrcDir}/external/stlport/stlport",
"${SrcDir}/bionic/libstdc++/include",
"${SrcDir}/bionic")
}
case "libstdc++":
// Using bionic's basic libstdc++. Not actually an STL. Only around until the
// tree is in good enough shape to not need it.
// Host builds will use GNU libstdc++.
if ctx.Device() {
flags.IncludeDirs = append(flags.IncludeDirs, "${SrcDir}/bionic/libstdc++/include")
}
case "ndk_system":
ndkSrcRoot := ctx.Config().(Config).SrcDir() + "/prebuilts/ndk/current/sources/"
flags.IncludeDirs = append(flags.IncludeDirs, ndkSrcRoot + "cxx-stl/system/include")
case "ndk_c++_shared", "ndk_c++_static":
// TODO(danalbert): This really shouldn't be here...
flags.CppFlags = append(flags.CppFlags, "-std=c++11")
case "":
// None or error.
if ctx.Host() {
flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
flags.LdLibs = append(flags.LdLibs, "-lc", "-lm")
}
}
return flags
}
@ -779,22 +671,29 @@ func (c *ccBase) depsToPaths(ctx common.AndroidModuleContext, depNames CCDeps) C
return depPaths
}
// ccDynamic contains the properties and members used by shared libraries and dynamic executables
type ccDynamic struct {
// ccLinked contains the properties and members used by libraries and executables
type ccLinked struct {
ccBase
dynamicProperties struct {
VariantIsShared bool `blueprint:"mutated"`
VariantIsStatic bool `blueprint:"mutated"`
}
}
func newCCDynamic(dynamic *ccDynamic, module CCModuleType, hod common.HostOrDeviceSupported,
func newCCDynamic(dynamic *ccLinked, module CCModuleType, hod common.HostOrDeviceSupported,
multilib common.Multilib, props ...interface{}) (blueprint.Module, []interface{}) {
dynamic.properties.System_shared_libs = []string{defaultSystemSharedLibraries}
props = append(props, &dynamic.dynamicProperties)
return newCCBase(&dynamic.ccBase, module, hod, multilib, props...)
}
const defaultSystemSharedLibraries = "__default__"
func (c *ccDynamic) systemSharedLibs(ctx common.AndroidBaseContext) []string {
func (c *ccLinked) systemSharedLibs(ctx common.AndroidBaseContext) []string {
if len(c.properties.System_shared_libs) == 1 &&
c.properties.System_shared_libs[0] == defaultSystemSharedLibraries {
@ -818,19 +717,175 @@ func (c *ccDynamic) systemSharedLibs(ctx common.AndroidBaseContext) []string {
return c.properties.System_shared_libs
}
func (c *ccDynamic) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
func (c *ccLinked) stl(ctx common.AndroidBaseContext) string {
if c.properties.Sdk_version != "" {
switch c.properties.Stl {
case "":
return "ndk_system"
case "c++_shared", "c++_static",
"stlport_shared", "stlport_static",
"gnustl_static":
return "ndk_lib" + c.properties.Stl
default:
ctx.ModuleErrorf("stl: %q is not a supported STL with sdk_version set", c.properties.Stl)
return ""
}
}
switch c.properties.Stl {
case "libc++", "libc++_static",
"stlport", "stlport_static",
"libstdc++":
return c.properties.Stl
case "none":
return ""
case "":
if c.shared() {
return "libc++" // TODO: mingw needs libstdc++
} else {
return "libc++_static"
}
default:
ctx.ModuleErrorf("stl: %q is not a supported STL", c.properties.Stl)
return ""
}
}
func (c *ccLinked) Flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
stl := c.stl(ctx)
if ctx.Failed() {
return flags
}
switch stl {
case "libc++", "libc++_static":
flags.CFlags = append(flags.CFlags, "-D_USING_LIBCXX")
flags.IncludeDirs = append(flags.IncludeDirs, "${SrcDir}/external/libcxx/include")
if ctx.Host() {
flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
flags.LdLibs = append(flags.LdLibs, "-lc", "-lm", "-lpthread")
}
case "stlport", "stlport_static":
if ctx.Device() {
flags.IncludeDirs = append(flags.IncludeDirs,
"${SrcDir}/external/stlport/stlport",
"${SrcDir}/bionic/libstdc++/include",
"${SrcDir}/bionic")
}
case "libstdc++":
// Using bionic's basic libstdc++. Not actually an STL. Only around until the
// tree is in good enough shape to not need it.
// Host builds will use GNU libstdc++.
if ctx.Device() {
flags.IncludeDirs = append(flags.IncludeDirs, "${SrcDir}/bionic/libstdc++/include")
}
case "ndk_system":
ndkSrcRoot := ctx.Config().(Config).SrcDir() + "/prebuilts/ndk/current/sources/"
flags.IncludeDirs = append(flags.IncludeDirs, ndkSrcRoot+"cxx-stl/system/include")
case "ndk_libc++_shared", "ndk_libc++_static":
// TODO(danalbert): This really shouldn't be here...
flags.CppFlags = append(flags.CppFlags, "-std=c++11")
case "ndk_libstlport_shared", "ndk_libstlport_static", "ndk_libgnustl_static":
// Nothing
case "":
// None or error.
if ctx.Host() {
flags.CppFlags = append(flags.CppFlags, "-nostdinc++")
flags.LdFlags = append(flags.LdFlags, "-nodefaultlibs")
flags.LdLibs = append(flags.LdLibs, "-lc", "-lm")
}
default:
panic(fmt.Errorf("Unknown stl in ccLinked.Flags: %q", stl))
}
return flags
}
func (c *ccLinked) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
depNames = c.ccBase.DepNames(ctx, depNames)
stl := c.stl(ctx)
if ctx.Failed() {
return depNames
}
switch stl {
case "libc++":
depNames.SharedLibs = append(depNames.SharedLibs, stl)
case "libstdc++":
if ctx.Device() {
depNames.SharedLibs = append(depNames.SharedLibs, stl)
}
case "libc++_static":
depNames.StaticLibs = append(depNames.StaticLibs, stl)
case "stlport":
depNames.SharedLibs = append(depNames.SharedLibs, "libstdc++", "libstlport")
case "stlport_static":
depNames.StaticLibs = append(depNames.StaticLibs, "libstdc++", "libstlport_static")
case "":
// None or error.
case "ndk_system":
// TODO: Make a system STL prebuilt for the NDK.
// The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
// its own includes. The includes are handled in ccBase.Flags().
case "ndk_libc++_shared", "ndk_libstlport_shared":
depNames.SharedLibs = append(depNames.SharedLibs, stl)
case "ndk_libc++_static", "ndk_libstlport_static", "ndk_libgnustl_static":
depNames.StaticLibs = append(depNames.StaticLibs, stl)
default:
panic(fmt.Errorf("Unknown stl in ccLinked.DepNames: %q", stl))
}
if ctx.Device() {
depNames.StaticLibs = append(depNames.StaticLibs, "libcompiler_rt-extras")
if ctx.ModuleName() != "libcompiler_rt-extras" {
depNames.StaticLibs = append(depNames.StaticLibs, "libcompiler_rt-extras")
}
// libgcc and libatomic have to be last on the command line
depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcov", "libatomic", "libgcc")
depNames.SharedLibs = append(depNames.SharedLibs, c.systemSharedLibs(ctx)...)
if c.shared() {
depNames.SharedLibs = append(depNames.SharedLibs, c.systemSharedLibs(ctx)...)
}
}
return depNames
}
// ccLinkedInterface interface is used on ccLinked to deal with static or shared variants
type ccLinkedInterface interface {
// Returns true if the build options for the module have selected a static or shared build
buildStatic() bool
buildShared() bool
// Sets whether a specific variant is static or shared
setStatic()
setShared()
// Returns whether a specific variant is static or shared
static() bool
shared() bool
}
var _ ccLinkedInterface = (*CCLibrary)(nil)
var _ ccLinkedInterface = (*CCBinary)(nil)
func (c *ccLinked) static() bool {
return c.dynamicProperties.VariantIsStatic
}
func (c *ccLinked) shared() bool {
return c.dynamicProperties.VariantIsShared
}
func (c *ccLinked) setStatic() {
c.dynamicProperties.VariantIsStatic = true
}
func (c *ccLinked) setShared() {
c.dynamicProperties.VariantIsShared = true
}
type ccExportedIncludeDirsProducer interface {
exportedIncludeDirs() []string
}
@ -840,10 +895,10 @@ type ccExportedIncludeDirsProducer interface {
//
type CCLibrary struct {
ccDynamic
ccLinked
primary *CCLibrary
primaryObjFiles []string
reuseFrom ccLibraryInterface
reuseObjFiles []string
objFiles []string
exportIncludeDirs []string
out string
@ -851,10 +906,7 @@ type CCLibrary struct {
LibraryProperties struct {
BuildStatic bool `blueprint:"mutated"`
BuildShared bool `blueprint:"mutated"`
IsShared bool `blueprint:"mutated"`
IsStatic bool `blueprint:"mutated"`
Static struct {
Static struct {
Srcs []string `android:"arch_variant"`
Cflags []string `android:"arch_variant"`
} `android:"arch_variant"`
@ -865,29 +917,33 @@ type CCLibrary struct {
}
}
func (c *CCLibrary) buildStatic() bool {
return c.LibraryProperties.BuildStatic
}
func (c *CCLibrary) buildShared() bool {
return c.LibraryProperties.BuildShared
}
type ccLibraryInterface interface {
ccLinkedInterface
ccLibrary() *CCLibrary
static() bool
shared() bool
setReuseFrom(ccLibraryInterface)
getReuseFrom() ccLibraryInterface
getReuseObjFiles() []string
allObjFiles() []string
}
var _ ccLibraryInterface = (*CCLibrary)(nil)
func (c *CCLibrary) ccLibrary() *CCLibrary {
return c
}
func (c *CCLibrary) static() bool {
return c.LibraryProperties.IsStatic
}
func (c *CCLibrary) shared() bool {
return c.LibraryProperties.IsShared
}
func NewCCLibrary(library *CCLibrary, module CCModuleType,
hod common.HostOrDeviceSupported) (blueprint.Module, []interface{}) {
return newCCDynamic(&library.ccDynamic, module, hod, common.MultilibBoth,
return newCCDynamic(&library.ccLinked, module, hod, common.MultilibBoth,
&library.LibraryProperties)
}
@ -901,14 +957,12 @@ func CCLibraryFactory() (blueprint.Module, []interface{}) {
}
func (c *CCLibrary) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
depNames = c.ccLinked.DepNames(ctx, depNames)
if c.shared() {
depNames = c.ccDynamic.DepNames(ctx, depNames)
if ctx.Device() {
depNames.CrtBegin = "crtbegin_so"
depNames.CrtEnd = "crtend_so"
}
} else {
depNames = c.ccBase.DepNames(ctx, depNames)
}
return depNames
@ -918,6 +972,18 @@ func (c *CCLibrary) outputFile() string {
return c.out
}
func (c *CCLibrary) getReuseObjFiles() []string {
return c.reuseObjFiles
}
func (c *CCLibrary) setReuseFrom(reuseFrom ccLibraryInterface) {
c.reuseFrom = reuseFrom
}
func (c *CCLibrary) getReuseFrom() ccLibraryInterface {
return c.reuseFrom
}
func (c *CCLibrary) allObjFiles() []string {
return c.objFiles
}
@ -927,11 +993,11 @@ func (c *CCLibrary) exportedIncludeDirs() []string {
}
func (c *CCLibrary) Flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
flags = c.ccDynamic.Flags(ctx, flags)
flags = c.ccLinked.Flags(ctx, flags)
flags.CFlags = append(flags.CFlags, "-fPIC")
if c.LibraryProperties.IsShared {
if c.shared() {
libName := ctx.ModuleName()
// GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead
sharedFlag := "-Wl,-shared"
@ -988,7 +1054,7 @@ func (c *CCLibrary) compileSharedLibrary(ctx common.AndroidModuleContext,
outputFile := filepath.Join(common.ModuleOutDir(ctx), ctx.ModuleName()+sharedLibraryExtension)
TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
deps.LateStaticLibs, deps.WholeStaticLibs, deps.CrtBegin, deps.CrtEnd,
deps.LateStaticLibs, deps.WholeStaticLibs, deps.CrtBegin, deps.CrtEnd, false,
ccFlagsToBuilderFlags(flags), outputFile)
c.out = outputFile
@ -1000,13 +1066,13 @@ func (c *CCLibrary) compileModule(ctx common.AndroidModuleContext,
flags CCFlags, deps CCDeps, objFiles []string) {
// Reuse the object files from the matching static library if it exists
if c.primary == c {
c.primaryObjFiles = objFiles
if c.getReuseFrom().ccLibrary() == c {
c.reuseObjFiles = objFiles
} else {
objFiles = append([]string(nil), c.primary.primaryObjFiles...)
objFiles = append([]string(nil), c.getReuseFrom().getReuseObjFiles()...)
}
if c.LibraryProperties.IsStatic {
if c.static() {
c.compileStaticLibrary(ctx, flags, deps, objFiles)
} else {
c.compileSharedLibrary(ctx, flags, deps, objFiles)
@ -1027,7 +1093,7 @@ func (c *CCLibrary) installSharedLibrary(ctx common.AndroidModuleContext, flags
}
func (c *CCLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
if c.LibraryProperties.IsStatic {
if c.static() {
c.installStaticLibrary(ctx, flags)
} else {
c.installSharedLibrary(ctx, flags)
@ -1090,7 +1156,7 @@ func (c *ccObject) outputFile() string {
//
type CCBinary struct {
ccDynamic
ccLinked
out string
BinaryProperties struct {
// static_executable: compile executable with -static
@ -1104,6 +1170,14 @@ type CCBinary struct {
}
}
func (c *CCBinary) buildStatic() bool {
return c.BinaryProperties.Static_executable
}
func (c *CCBinary) buildShared() bool {
return !c.BinaryProperties.Static_executable
}
func (c *CCBinary) getStem(ctx common.AndroidModuleContext) string {
if c.BinaryProperties.Stem != "" {
return c.BinaryProperties.Stem
@ -1112,7 +1186,7 @@ func (c *CCBinary) getStem(ctx common.AndroidModuleContext) string {
}
func (c *CCBinary) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDeps {
depNames = c.ccDynamic.DepNames(ctx, depNames)
depNames = c.ccLinked.DepNames(ctx, depNames)
if ctx.Device() {
if c.BinaryProperties.Static_executable {
depNames.CrtBegin = "crtbegin_static"
@ -1120,6 +1194,16 @@ func (c *CCBinary) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDe
depNames.CrtBegin = "crtbegin_dynamic"
}
depNames.CrtEnd = "crtend_android"
if c.BinaryProperties.Static_executable {
// static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
// --start-group/--end-group along with libgcc. If they are in deps.StaticLibs,
// move them to the beginning of deps.LateStaticLibs
var groupLibs []string
depNames.StaticLibs, groupLibs = filterList(depNames.StaticLibs,
[]string{"libc", "libc_nomalloc", "libcompiler_rt"})
depNames.LateStaticLibs = append(groupLibs, depNames.LateStaticLibs...)
}
}
return depNames
}
@ -1127,7 +1211,7 @@ func (c *CCBinary) DepNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDe
func NewCCBinary(binary *CCBinary, module CCModuleType,
hod common.HostOrDeviceSupported) (blueprint.Module, []interface{}) {
return newCCDynamic(&binary.ccDynamic, module, hod, common.MultilibFirst,
return newCCDynamic(&binary.ccLinked, module, hod, common.MultilibFirst,
&binary.BinaryProperties)
}
@ -1138,23 +1222,40 @@ func CCBinaryFactory() (blueprint.Module, []interface{}) {
}
func (c *CCBinary) Flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags {
flags = c.ccDynamic.Flags(ctx, flags)
flags = c.ccLinked.Flags(ctx, flags)
flags.CFlags = append(flags.CFlags, "-fpie")
if ctx.Device() {
linker := "/system/bin/linker"
if flags.Toolchain.Is64Bit() {
linker = "/system/bin/linker64"
}
if c.BinaryProperties.Static_executable {
// Clang driver needs -static to create static executable.
// However, bionic/linker uses -shared to overwrite.
// Linker for x86 targets does not allow coexistance of -static and -shared,
// so we add -static only if -shared is not used.
if !inList("-shared", flags.LdFlags) {
flags.LdFlags = append(flags.LdFlags, "-static")
}
flags.LdFlags = append(flags.LdFlags,
"-nostdlib",
"-Bdynamic",
fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
"-Wl,--gc-sections",
"-Wl,-z,nocopyreloc",
)
flags.LdFlags = append(flags.LdFlags,
"-nostdlib",
"-Bstatic",
"-Wl,--gc-sections",
)
} else {
linker := "/system/bin/linker"
if flags.Toolchain.Is64Bit() {
linker = "/system/bin/linker64"
}
flags.LdFlags = append(flags.LdFlags,
"-nostdlib",
"-Bdynamic",
fmt.Sprintf("-Wl,-dynamic-linker,%s", linker),
"-Wl,--gc-sections",
"-Wl,-z,nocopyreloc",
)
}
}
return flags
@ -1172,7 +1273,7 @@ func (c *CCBinary) compileModule(ctx common.AndroidModuleContext,
c.out = outputFile
TransformObjToDynamicBinary(ctx, objFiles, deps.SharedLibs, deps.StaticLibs,
deps.LateStaticLibs, deps.WholeStaticLibs, deps.CrtBegin, deps.CrtEnd,
deps.LateStaticLibs, deps.WholeStaticLibs, deps.CrtBegin, deps.CrtEnd, true,
ccFlagsToBuilderFlags(flags), outputFile)
}
@ -1222,7 +1323,7 @@ func (c *ccTest) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
func CCTestFactory() (blueprint.Module, []interface{}) {
module := &ccTest{}
return newCCDynamic(&module.ccDynamic, module, common.HostAndDeviceSupported,
return newCCDynamic(&module.ccLinked, module, common.HostAndDeviceSupported,
common.MultilibFirst, &module.BinaryProperties, &module.testProperties)
}
@ -1387,7 +1488,7 @@ func (c *ndkPrebuiltLibrary) compileModule(ctx common.AndroidModuleContext, flag
// We want to translate to just LIBNAME.
libName := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0]
libDir := getNdkLibDir(ctx, flags.Toolchain, c.properties.Sdk_version)
c.out = filepath.Join(libDir, libName + sharedLibraryExtension)
c.out = filepath.Join(libDir, libName+sharedLibraryExtension)
}
func (c *ndkPrebuiltLibrary) installModule(ctx common.AndroidModuleContext, flags CCFlags) {
@ -1466,26 +1567,26 @@ func (c *ndkPrebuiltStl) compileModule(ctx common.AndroidModuleContext, flags CC
}
func LinkageMutator(mctx blueprint.EarlyMutatorContext) {
if c, ok := mctx.Module().(ccLibraryInterface); ok {
if c, ok := mctx.Module().(ccLinkedInterface); ok {
var modules []blueprint.Module
if c.ccLibrary().LibraryProperties.BuildStatic && c.ccLibrary().LibraryProperties.BuildShared {
if c.buildStatic() && c.buildShared() {
modules = mctx.CreateLocalVariations("static", "shared")
modules[0].(ccLibraryInterface).ccLibrary().LibraryProperties.IsStatic = true
modules[1].(ccLibraryInterface).ccLibrary().LibraryProperties.IsShared = true
} else if c.ccLibrary().LibraryProperties.BuildStatic {
modules[0].(ccLinkedInterface).setStatic()
modules[1].(ccLinkedInterface).setShared()
} else if c.buildStatic() {
modules = mctx.CreateLocalVariations("static")
modules[0].(ccLibraryInterface).ccLibrary().LibraryProperties.IsStatic = true
} else if c.ccLibrary().LibraryProperties.BuildShared {
modules[0].(ccLinkedInterface).setStatic()
} else if c.buildShared() {
modules = mctx.CreateLocalVariations("shared")
modules[0].(ccLibraryInterface).ccLibrary().LibraryProperties.IsShared = true
modules[0].(ccLinkedInterface).setShared()
} else {
panic(fmt.Errorf("ccLibrary %q not static or shared", mctx.ModuleName()))
}
primary := modules[0].(ccLibraryInterface).ccLibrary()
for _, m := range modules {
m.(ccLibraryInterface).ccLibrary().primary = primary
if m.(ccLibraryInterface).ccLibrary() != primary {
m.(ccLibraryInterface).ccLibrary().properties.SkipCompileObjs = true
if _, ok := c.(ccLibraryInterface); ok {
reuseFrom := modules[0].(ccLibraryInterface)
for _, m := range modules {
m.(ccLibraryInterface).setReuseFrom(reuseFrom)
}
}
}

View file

@ -69,6 +69,18 @@ func inList(s string, list []string) bool {
return false
}
func filterList(list []string, filter []string) (remainder []string, filtered []string) {
for _, l := range list {
if inList(l, filter) {
filtered = append(filtered, l)
} else {
remainder = append(remainder, l)
}
}
return
}
var libNameRegexp = regexp.MustCompile(`^lib(.*)$`)
func moduleToLibName(module string) (string, error) {