From ed4cf0b65565663fd611489dac44b5eca9e2f390 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Thu, 26 Mar 2015 14:43:45 -0700 Subject: [PATCH] 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 --- cc/builder.go | 13 +- cc/cc.go | 451 ++++++++++++++++++++++++++++++-------------------- cc/util.go | 12 ++ 3 files changed, 298 insertions(+), 178 deletions(-) diff --git a/cc/builder.go b/cc/builder.go index e7ea73d97..4c86110a4 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -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...) diff --git a/cc/cc.go b/cc/cc.go index 2583c8667..64a75260e 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -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) } } } diff --git a/cc/util.go b/cc/util.go index e0effebb8..db14c748b 100644 --- a/cc/util.go +++ b/cc/util.go @@ -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) {