From 10d2231d441ac2010f26ed88f0f32d85afe59340 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 3 May 2017 11:01:58 -0700 Subject: [PATCH] Check reused source files in hasSrcExt hasSrcExt is used to determine extra flags and dependencies when generated files are used. If the generated files are being handled in a static library whose objects are reused in a shared library, the flags and dependencies still need to apply. Instead of clearing the source files in the shared library, move them to an OriginalSrcs property, and check that in hasSrcExt along with the Srcs property. Also pass extra exported include directories from the static library to the shared library. Bug: 37555583 Test: use protos in a cc_library Change-Id: I709779ec03b66b220b7bd58a1f6f0b9b5067d955 --- cc/cc.go | 4 +++- cc/compiler.go | 8 ++++++++ cc/library.go | 51 ++++++++++++++++++++++++++++++++------------------ 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/cc/cc.go b/cc/cc.go index bbdcf6f96..f368a1335 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -950,7 +950,9 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { if tag == reuseObjTag { if l, ok := cc.compiler.(libraryInterface); ok { - depPaths.Objs = depPaths.Objs.Append(l.reuseObjs()) + objs, flags := l.reuseObjs() + depPaths.Objs = depPaths.Objs.Append(objs) + depPaths.ReexportedFlags = append(depPaths.ReexportedFlags, flags...) return } } diff --git a/cc/compiler.go b/cc/compiler.go index eb30767a0..8afd1bd21 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -125,6 +125,9 @@ type BaseCompilerProperties struct { Exclude_srcs []string } } + + // Stores the original list of source files before being cleared by library reuse + OriginalSrcs []string `blueprint:"mutated"` } func NewBaseCompiler() *baseCompiler { @@ -427,6 +430,11 @@ func (compiler *baseCompiler) hasSrcExt(ext string) bool { return true } } + for _, src := range compiler.Properties.OriginalSrcs { + if filepath.Ext(src) == ext { + return true + } + } return false } diff --git a/cc/library.go b/cc/library.go index 86e326986..1a5de619d 100644 --- a/cc/library.go +++ b/cc/library.go @@ -200,7 +200,9 @@ type libraryDecorator struct { MutatedProperties LibraryMutatedProperties // For reusing static library objects for shared library - reuseObjects Objects + reuseObjects Objects + reuseExportedFlags []string + // table-of-contents file to optimize out relinking when possible tocFile android.OptionalPath @@ -362,7 +364,7 @@ type libraryInterface interface { getWholeStaticMissingDeps() []string static() bool objs() Objects - reuseObjs() Objects + reuseObjs() (Objects, []string) toc() android.OptionalPath // Returns true if the build options for the module have selected a static or shared build @@ -615,19 +617,23 @@ func (library *libraryDecorator) link(ctx ModuleContext, if library.Properties.Aidl.Export_aidl_headers { if library.baseCompiler.hasSrcExt(".aidl") { - library.reexportFlags([]string{ + flags := []string{ "-I" + android.PathForModuleGen(ctx, "aidl").String(), - }) + } + library.reexportFlags(flags) + library.reuseExportedFlags = append(library.reuseExportedFlags, flags...) library.reexportDeps(library.baseCompiler.deps) // TODO: restrict to aidl deps } } if library.Properties.Proto.Export_proto_headers { if library.baseCompiler.hasSrcExt(".proto") { - library.reexportFlags([]string{ + flags := []string{ "-I" + protoSubDir(ctx).String(), "-I" + protoDir(ctx).String(), - }) + } + library.reexportFlags(flags) + library.reuseExportedFlags = append(library.reuseExportedFlags, flags...) library.reexportDeps(library.baseCompiler.deps) // TODO: restrict to proto deps } } @@ -653,8 +659,8 @@ func (library *libraryDecorator) objs() Objects { return library.objects } -func (library *libraryDecorator) reuseObjs() Objects { - return library.reuseObjects +func (library *libraryDecorator) reuseObjs() (Objects, []string) { + return library.reuseObjects, library.reuseExportedFlags } func (library *libraryDecorator) toc() android.OptionalPath { @@ -724,6 +730,23 @@ func NewLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) return module, library } +// connects a shared library to a static library in order to reuse its .o files to avoid +// compiling source files twice. +func reuseStaticLibrary(mctx android.BottomUpMutatorContext, static, shared *Module) { + if staticCompiler, ok := static.compiler.(*libraryDecorator); ok { + sharedCompiler := shared.compiler.(*libraryDecorator) + if len(staticCompiler.Properties.Static.Cflags) == 0 && + len(sharedCompiler.Properties.Shared.Cflags) == 0 { + + mctx.AddInterVariantDependency(reuseObjTag, shared, static) + sharedCompiler.baseCompiler.Properties.OriginalSrcs = + sharedCompiler.baseCompiler.Properties.Srcs + sharedCompiler.baseCompiler.Properties.Srcs = nil + sharedCompiler.baseCompiler.Properties.Generated_sources = nil + } + } +} + func linkageMutator(mctx android.BottomUpMutatorContext) { if m, ok := mctx.Module().(*Module); ok && m.linker != nil { if library, ok := m.linker.(libraryInterface); ok { @@ -736,16 +759,8 @@ func linkageMutator(mctx android.BottomUpMutatorContext) { static.linker.(libraryInterface).setStatic() shared.linker.(libraryInterface).setShared() - if staticCompiler, ok := static.compiler.(*libraryDecorator); ok { - sharedCompiler := shared.compiler.(*libraryDecorator) - if len(staticCompiler.Properties.Static.Cflags) == 0 && - len(sharedCompiler.Properties.Shared.Cflags) == 0 { - // Optimize out compiling common .o files twice for static+shared libraries - mctx.AddInterVariantDependency(reuseObjTag, shared, static) - sharedCompiler.baseCompiler.Properties.Srcs = nil - sharedCompiler.baseCompiler.Properties.Generated_sources = nil - } - } + reuseStaticLibrary(mctx, static, shared) + } else if library.buildStatic() { modules = mctx.CreateLocalVariations("static") modules[0].(*Module).linker.(libraryInterface).setStatic()