| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 1 | // Copyright 2016 Google Inc. All rights reserved. | 
|  | 2 | // | 
|  | 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 4 | // you may not use this file except in compliance with the License. | 
|  | 5 | // You may obtain a copy of the License at | 
|  | 6 | // | 
|  | 7 | //     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 8 | // | 
|  | 9 | // Unless required by applicable law or agreed to in writing, software | 
|  | 10 | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 12 | // See the License for the specific language governing permissions and | 
|  | 13 | // limitations under the License. | 
|  | 14 |  | 
|  | 15 | package cc | 
|  | 16 |  | 
|  | 17 | import ( | 
|  | 18 | "strings" | 
|  | 19 |  | 
|  | 20 | "github.com/google/blueprint" | 
| Colin Cross | 26c34ed | 2016-09-30 17:10:16 -0700 | [diff] [blame] | 21 | "github.com/google/blueprint/pathtools" | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 22 |  | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 23 | "android/soong/android" | 
|  | 24 | ) | 
|  | 25 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 26 | type LibraryProperties struct { | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 27 | Static struct { | 
|  | 28 | Srcs         []string `android:"arch_variant"` | 
|  | 29 | Exclude_srcs []string `android:"arch_variant"` | 
|  | 30 | Cflags       []string `android:"arch_variant"` | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 31 |  | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 32 | Enabled           *bool    `android:"arch_variant"` | 
|  | 33 | Whole_static_libs []string `android:"arch_variant"` | 
|  | 34 | Static_libs       []string `android:"arch_variant"` | 
|  | 35 | Shared_libs       []string `android:"arch_variant"` | 
|  | 36 | } `android:"arch_variant"` | 
|  | 37 | Shared struct { | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 38 | Srcs         []string `android:"arch_variant"` | 
|  | 39 | Exclude_srcs []string `android:"arch_variant"` | 
|  | 40 | Cflags       []string `android:"arch_variant"` | 
|  | 41 |  | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 42 | Enabled           *bool    `android:"arch_variant"` | 
|  | 43 | Whole_static_libs []string `android:"arch_variant"` | 
|  | 44 | Static_libs       []string `android:"arch_variant"` | 
|  | 45 | Shared_libs       []string `android:"arch_variant"` | 
|  | 46 | } `android:"arch_variant"` | 
|  | 47 |  | 
|  | 48 | // local file name to pass to the linker as --version_script | 
|  | 49 | Version_script *string `android:"arch_variant"` | 
|  | 50 | // local file name to pass to the linker as -unexported_symbols_list | 
|  | 51 | Unexported_symbols_list *string `android:"arch_variant"` | 
|  | 52 | // local file name to pass to the linker as -force_symbols_not_weak_list | 
|  | 53 | Force_symbols_not_weak_list *string `android:"arch_variant"` | 
|  | 54 | // local file name to pass to the linker as -force_symbols_weak_list | 
|  | 55 | Force_symbols_weak_list *string `android:"arch_variant"` | 
|  | 56 |  | 
|  | 57 | // rename host libraries to prevent overlap with system installed libraries | 
|  | 58 | Unique_host_soname *bool | 
|  | 59 |  | 
|  | 60 | VariantName string `blueprint:"mutated"` | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 61 |  | 
|  | 62 | // Build a static variant | 
|  | 63 | BuildStatic bool `blueprint:"mutated"` | 
|  | 64 | // Build a shared variant | 
|  | 65 | BuildShared bool `blueprint:"mutated"` | 
|  | 66 | // This variant is shared | 
|  | 67 | VariantIsShared bool `blueprint:"mutated"` | 
|  | 68 | // This variant is static | 
|  | 69 | VariantIsStatic bool `blueprint:"mutated"` | 
|  | 70 | } | 
|  | 71 |  | 
|  | 72 | type FlagExporterProperties struct { | 
|  | 73 | // list of directories relative to the Blueprints file that will | 
|  | 74 | // be added to the include path using -I for any module that links against this module | 
|  | 75 | Export_include_dirs []string `android:"arch_variant"` | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 76 | } | 
|  | 77 |  | 
|  | 78 | func init() { | 
| Colin Cross | 798bfce | 2016-10-12 14:28:16 -0700 | [diff] [blame] | 79 | android.RegisterModuleType("cc_library_static", libraryStaticFactory) | 
|  | 80 | android.RegisterModuleType("cc_library_shared", librarySharedFactory) | 
|  | 81 | android.RegisterModuleType("cc_library", libraryFactory) | 
|  | 82 | android.RegisterModuleType("cc_library_host_static", libraryHostStaticFactory) | 
|  | 83 | android.RegisterModuleType("cc_library_host_shared", libraryHostSharedFactory) | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 84 | } | 
|  | 85 |  | 
|  | 86 | // Module factory for combined static + shared libraries, device by default but with possible host | 
|  | 87 | // support | 
|  | 88 | func libraryFactory() (blueprint.Module, []interface{}) { | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 89 | module, _ := NewLibrary(android.HostAndDeviceSupported, true, true) | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 90 | return module.Init() | 
|  | 91 | } | 
|  | 92 |  | 
|  | 93 | // Module factory for static libraries | 
|  | 94 | func libraryStaticFactory() (blueprint.Module, []interface{}) { | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 95 | module, _ := NewLibrary(android.HostAndDeviceSupported, false, true) | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 96 | return module.Init() | 
|  | 97 | } | 
|  | 98 |  | 
|  | 99 | // Module factory for shared libraries | 
|  | 100 | func librarySharedFactory() (blueprint.Module, []interface{}) { | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 101 | module, _ := NewLibrary(android.HostAndDeviceSupported, true, false) | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 102 | return module.Init() | 
|  | 103 | } | 
|  | 104 |  | 
|  | 105 | // Module factory for host static libraries | 
|  | 106 | func libraryHostStaticFactory() (blueprint.Module, []interface{}) { | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 107 | module, _ := NewLibrary(android.HostSupported, false, true) | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 108 | return module.Init() | 
|  | 109 | } | 
|  | 110 |  | 
|  | 111 | // Module factory for host shared libraries | 
|  | 112 | func libraryHostSharedFactory() (blueprint.Module, []interface{}) { | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 113 | module, _ := NewLibrary(android.HostSupported, true, false) | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 114 | return module.Init() | 
|  | 115 | } | 
|  | 116 |  | 
|  | 117 | type flagExporter struct { | 
|  | 118 | Properties FlagExporterProperties | 
|  | 119 |  | 
| Dan Willemsen | 847dcc7 | 2016-09-29 12:13:36 -0700 | [diff] [blame] | 120 | flags     []string | 
|  | 121 | flagsDeps android.Paths | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 122 | } | 
|  | 123 |  | 
|  | 124 | func (f *flagExporter) exportIncludes(ctx ModuleContext, inc string) { | 
|  | 125 | includeDirs := android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs) | 
|  | 126 | for _, dir := range includeDirs.Strings() { | 
|  | 127 | f.flags = append(f.flags, inc+dir) | 
|  | 128 | } | 
|  | 129 | } | 
|  | 130 |  | 
|  | 131 | func (f *flagExporter) reexportFlags(flags []string) { | 
|  | 132 | f.flags = append(f.flags, flags...) | 
|  | 133 | } | 
|  | 134 |  | 
| Dan Willemsen | 847dcc7 | 2016-09-29 12:13:36 -0700 | [diff] [blame] | 135 | func (f *flagExporter) reexportDeps(deps android.Paths) { | 
|  | 136 | f.flagsDeps = append(f.flagsDeps, deps...) | 
|  | 137 | } | 
|  | 138 |  | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 139 | func (f *flagExporter) exportedFlags() []string { | 
|  | 140 | return f.flags | 
|  | 141 | } | 
|  | 142 |  | 
| Dan Willemsen | 847dcc7 | 2016-09-29 12:13:36 -0700 | [diff] [blame] | 143 | func (f *flagExporter) exportedFlagsDeps() android.Paths { | 
|  | 144 | return f.flagsDeps | 
|  | 145 | } | 
|  | 146 |  | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 147 | type exportedFlagsProducer interface { | 
|  | 148 | exportedFlags() []string | 
| Dan Willemsen | 847dcc7 | 2016-09-29 12:13:36 -0700 | [diff] [blame] | 149 | exportedFlagsDeps() android.Paths | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 150 | } | 
|  | 151 |  | 
|  | 152 | var _ exportedFlagsProducer = (*flagExporter)(nil) | 
|  | 153 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 154 | // libraryDecorator wraps baseCompiler, baseLinker and baseInstaller to provide library-specific | 
|  | 155 | // functionality: static vs. shared linkage, reusing object files for shared libraries | 
|  | 156 | type libraryDecorator struct { | 
|  | 157 | Properties LibraryProperties | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 158 |  | 
|  | 159 | // For reusing static library objects for shared library | 
|  | 160 | reuseObjFiles android.Paths | 
| Colin Cross | 26c34ed | 2016-09-30 17:10:16 -0700 | [diff] [blame] | 161 | // table-of-contents file to optimize out relinking when possible | 
|  | 162 | tocFile android.OptionalPath | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 163 |  | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 164 | flagExporter | 
|  | 165 | stripper | 
| Dan Willemsen | 394e9dc | 2016-09-14 15:04:48 -0700 | [diff] [blame] | 166 | relocationPacker | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 167 |  | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 168 | // If we're used as a whole_static_lib, our missing dependencies need | 
|  | 169 | // to be given | 
|  | 170 | wholeStaticMissingDeps []string | 
|  | 171 |  | 
|  | 172 | // For whole_static_libs | 
|  | 173 | objFiles android.Paths | 
|  | 174 |  | 
|  | 175 | // Uses the module's name if empty, but can be overridden. Does not include | 
|  | 176 | // shlib suffix. | 
|  | 177 | libName string | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 178 |  | 
|  | 179 | sanitize *sanitize | 
|  | 180 |  | 
|  | 181 | // Decorated interafaces | 
|  | 182 | *baseCompiler | 
|  | 183 | *baseLinker | 
|  | 184 | *baseInstaller | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 185 | } | 
|  | 186 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 187 | func (library *libraryDecorator) linkerProps() []interface{} { | 
|  | 188 | var props []interface{} | 
|  | 189 | props = append(props, library.baseLinker.linkerProps()...) | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 190 | return append(props, | 
|  | 191 | &library.Properties, | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 192 | &library.flagExporter.Properties, | 
| Dan Willemsen | 394e9dc | 2016-09-14 15:04:48 -0700 | [diff] [blame] | 193 | &library.stripper.StripProperties, | 
|  | 194 | &library.relocationPacker.Properties) | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 195 | } | 
|  | 196 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 197 | func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { | 
| Colin Cross | 42742b8 | 2016-08-01 13:20:05 -0700 | [diff] [blame] | 198 | flags = library.baseLinker.linkerFlags(ctx, flags) | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 199 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 200 | // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because | 
|  | 201 | // all code is position independent, and then those warnings get promoted to | 
|  | 202 | // errors. | 
|  | 203 | if ctx.Os() != android.Windows { | 
|  | 204 | flags.CFlags = append(flags.CFlags, "-fPIC") | 
|  | 205 | } | 
|  | 206 |  | 
|  | 207 | if library.static() { | 
|  | 208 | flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...) | 
|  | 209 | } else { | 
|  | 210 | flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...) | 
|  | 211 | } | 
|  | 212 |  | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 213 | if !library.static() { | 
|  | 214 | libName := library.getLibName(ctx) | 
|  | 215 | // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead | 
|  | 216 | sharedFlag := "-Wl,-shared" | 
|  | 217 | if flags.Clang || ctx.Host() { | 
|  | 218 | sharedFlag = "-shared" | 
|  | 219 | } | 
|  | 220 | var f []string | 
|  | 221 | if ctx.Device() { | 
|  | 222 | f = append(f, | 
|  | 223 | "-nostdlib", | 
|  | 224 | "-Wl,--gc-sections", | 
|  | 225 | ) | 
|  | 226 | } | 
|  | 227 |  | 
|  | 228 | if ctx.Darwin() { | 
|  | 229 | f = append(f, | 
|  | 230 | "-dynamiclib", | 
|  | 231 | "-single_module", | 
| Colin Cross | 7d82ab7 | 2016-08-25 16:54:53 -0700 | [diff] [blame] | 232 | "-read_only_relocs suppress", | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 233 | "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(), | 
|  | 234 | ) | 
|  | 235 | } else { | 
|  | 236 | f = append(f, | 
|  | 237 | sharedFlag, | 
|  | 238 | "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix()) | 
|  | 239 | } | 
|  | 240 |  | 
|  | 241 | flags.LdFlags = append(f, flags.LdFlags...) | 
|  | 242 | } | 
|  | 243 |  | 
|  | 244 | return flags | 
|  | 245 | } | 
|  | 246 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 247 | func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Paths { | 
|  | 248 | var objFiles android.Paths | 
|  | 249 |  | 
|  | 250 | objFiles = library.baseCompiler.compile(ctx, flags, deps) | 
|  | 251 | library.reuseObjFiles = objFiles | 
|  | 252 |  | 
|  | 253 | pathDeps := deps.GeneratedHeaders | 
|  | 254 | pathDeps = append(pathDeps, ndkPathDeps(ctx)...) | 
|  | 255 |  | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 256 | if library.static() { | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 257 | objFiles = append(objFiles, compileObjs(ctx, flags, android.DeviceStaticLibrary, | 
|  | 258 | library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs, | 
|  | 259 | nil, pathDeps)...) | 
|  | 260 | } else { | 
|  | 261 | objFiles = append(objFiles, compileObjs(ctx, flags, android.DeviceSharedLibrary, | 
|  | 262 | library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs, | 
|  | 263 | nil, pathDeps)...) | 
|  | 264 | } | 
|  | 265 |  | 
|  | 266 | return objFiles | 
|  | 267 | } | 
|  | 268 |  | 
|  | 269 | type libraryInterface interface { | 
|  | 270 | getWholeStaticMissingDeps() []string | 
|  | 271 | static() bool | 
|  | 272 | objs() android.Paths | 
|  | 273 | reuseObjs() android.Paths | 
| Colin Cross | 26c34ed | 2016-09-30 17:10:16 -0700 | [diff] [blame] | 274 | toc() android.OptionalPath | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 275 |  | 
|  | 276 | // Returns true if the build options for the module have selected a static or shared build | 
|  | 277 | buildStatic() bool | 
|  | 278 | buildShared() bool | 
|  | 279 |  | 
|  | 280 | // Sets whether a specific variant is static or shared | 
|  | 281 | setStatic(bool) | 
|  | 282 | } | 
|  | 283 |  | 
|  | 284 | func (library *libraryDecorator) getLibName(ctx ModuleContext) string { | 
|  | 285 | name := library.libName | 
|  | 286 | if name == "" { | 
|  | 287 | name = ctx.ModuleName() | 
|  | 288 | } | 
|  | 289 |  | 
|  | 290 | if ctx.Host() && Bool(library.Properties.Unique_host_soname) { | 
|  | 291 | if !strings.HasSuffix(name, "-host") { | 
|  | 292 | name = name + "-host" | 
|  | 293 | } | 
|  | 294 | } | 
|  | 295 |  | 
|  | 296 | return name + library.Properties.VariantName | 
|  | 297 | } | 
|  | 298 |  | 
|  | 299 | func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) { | 
|  | 300 | location := InstallInSystem | 
|  | 301 | if library.sanitize.inData() { | 
|  | 302 | location = InstallInData | 
|  | 303 | } | 
|  | 304 | library.baseInstaller.location = location | 
|  | 305 |  | 
|  | 306 | library.baseLinker.linkerInit(ctx) | 
| Dan Willemsen | 394e9dc | 2016-09-14 15:04:48 -0700 | [diff] [blame] | 307 |  | 
|  | 308 | library.relocationPacker.packingInit(ctx) | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 309 | } | 
|  | 310 |  | 
|  | 311 | func (library *libraryDecorator) linkerDeps(ctx BaseModuleContext, deps Deps) Deps { | 
|  | 312 | deps = library.baseLinker.linkerDeps(ctx, deps) | 
|  | 313 |  | 
|  | 314 | if library.static() { | 
|  | 315 | deps.WholeStaticLibs = append(deps.WholeStaticLibs, | 
|  | 316 | library.Properties.Static.Whole_static_libs...) | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 317 | deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...) | 
|  | 318 | deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...) | 
|  | 319 | } else { | 
|  | 320 | if ctx.Device() && !Bool(library.baseLinker.Properties.Nocrt) { | 
|  | 321 | if !ctx.sdk() { | 
|  | 322 | deps.CrtBegin = "crtbegin_so" | 
|  | 323 | deps.CrtEnd = "crtend_so" | 
|  | 324 | } else { | 
|  | 325 | deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion() | 
|  | 326 | deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion() | 
|  | 327 | } | 
|  | 328 | } | 
|  | 329 | deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...) | 
|  | 330 | deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...) | 
|  | 331 | deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...) | 
|  | 332 | } | 
|  | 333 |  | 
|  | 334 | return deps | 
|  | 335 | } | 
|  | 336 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 337 | func (library *libraryDecorator) linkStatic(ctx ModuleContext, | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 338 | flags Flags, deps PathDeps, objFiles android.Paths) android.Path { | 
|  | 339 |  | 
|  | 340 | library.objFiles = append(android.Paths{}, deps.WholeStaticLibObjFiles...) | 
|  | 341 | library.objFiles = append(library.objFiles, objFiles...) | 
|  | 342 |  | 
|  | 343 | outputFile := android.PathForModuleOut(ctx, | 
|  | 344 | ctx.ModuleName()+library.Properties.VariantName+staticLibraryExtension) | 
|  | 345 |  | 
|  | 346 | if ctx.Darwin() { | 
|  | 347 | TransformDarwinObjToStaticLib(ctx, library.objFiles, flagsToBuilderFlags(flags), outputFile) | 
|  | 348 | } else { | 
|  | 349 | TransformObjToStaticLib(ctx, library.objFiles, flagsToBuilderFlags(flags), outputFile) | 
|  | 350 | } | 
|  | 351 |  | 
|  | 352 | library.wholeStaticMissingDeps = ctx.GetMissingDependencies() | 
|  | 353 |  | 
|  | 354 | ctx.CheckbuildFile(outputFile) | 
|  | 355 |  | 
|  | 356 | return outputFile | 
|  | 357 | } | 
|  | 358 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 359 | func (library *libraryDecorator) linkShared(ctx ModuleContext, | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 360 | flags Flags, deps PathDeps, objFiles android.Paths) android.Path { | 
|  | 361 |  | 
|  | 362 | var linkerDeps android.Paths | 
|  | 363 |  | 
|  | 364 | versionScript := android.OptionalPathForModuleSrc(ctx, library.Properties.Version_script) | 
|  | 365 | unexportedSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list) | 
|  | 366 | forceNotWeakSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list) | 
|  | 367 | forceWeakSymbols := android.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list) | 
|  | 368 | if !ctx.Darwin() { | 
|  | 369 | if versionScript.Valid() { | 
|  | 370 | flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String()) | 
|  | 371 | linkerDeps = append(linkerDeps, versionScript.Path()) | 
|  | 372 | } | 
|  | 373 | if unexportedSymbols.Valid() { | 
|  | 374 | ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin") | 
|  | 375 | } | 
|  | 376 | if forceNotWeakSymbols.Valid() { | 
|  | 377 | ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin") | 
|  | 378 | } | 
|  | 379 | if forceWeakSymbols.Valid() { | 
|  | 380 | ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin") | 
|  | 381 | } | 
|  | 382 | } else { | 
|  | 383 | if versionScript.Valid() { | 
|  | 384 | ctx.PropertyErrorf("version_script", "Not supported on Darwin") | 
|  | 385 | } | 
|  | 386 | if unexportedSymbols.Valid() { | 
|  | 387 | flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String()) | 
|  | 388 | linkerDeps = append(linkerDeps, unexportedSymbols.Path()) | 
|  | 389 | } | 
|  | 390 | if forceNotWeakSymbols.Valid() { | 
|  | 391 | flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String()) | 
|  | 392 | linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path()) | 
|  | 393 | } | 
|  | 394 | if forceWeakSymbols.Valid() { | 
|  | 395 | flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String()) | 
|  | 396 | linkerDeps = append(linkerDeps, forceWeakSymbols.Path()) | 
|  | 397 | } | 
|  | 398 | } | 
|  | 399 |  | 
|  | 400 | fileName := library.getLibName(ctx) + flags.Toolchain.ShlibSuffix() | 
|  | 401 | outputFile := android.PathForModuleOut(ctx, fileName) | 
|  | 402 | ret := outputFile | 
|  | 403 |  | 
|  | 404 | builderFlags := flagsToBuilderFlags(flags) | 
|  | 405 |  | 
| Colin Cross | 89562dc | 2016-10-03 17:47:19 -0700 | [diff] [blame] | 406 | if !ctx.Darwin() { | 
|  | 407 | // Optimize out relinking against shared libraries whose interface hasn't changed by | 
|  | 408 | // depending on a table of contents file instead of the library itself. | 
|  | 409 | tocPath := outputFile.RelPathString() | 
|  | 410 | tocPath = pathtools.ReplaceExtension(tocPath, flags.Toolchain.ShlibSuffix()[1:]+".toc") | 
|  | 411 | tocFile := android.PathForOutput(ctx, tocPath) | 
|  | 412 | library.tocFile = android.OptionalPathForPath(tocFile) | 
|  | 413 | TransformSharedObjectToToc(ctx, outputFile, tocFile, builderFlags) | 
|  | 414 | } | 
|  | 415 |  | 
| Dan Willemsen | 394e9dc | 2016-09-14 15:04:48 -0700 | [diff] [blame] | 416 | if library.relocationPacker.needsPacking(ctx) { | 
|  | 417 | packedOutputFile := outputFile | 
|  | 418 | outputFile = android.PathForModuleOut(ctx, "unpacked", fileName) | 
|  | 419 | library.relocationPacker.pack(ctx, outputFile, packedOutputFile, builderFlags) | 
|  | 420 | } | 
|  | 421 |  | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 422 | if library.stripper.needsStrip(ctx) { | 
|  | 423 | strippedOutputFile := outputFile | 
|  | 424 | outputFile = android.PathForModuleOut(ctx, "unstripped", fileName) | 
|  | 425 | library.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags) | 
|  | 426 | } | 
|  | 427 |  | 
|  | 428 | sharedLibs := deps.SharedLibs | 
|  | 429 | sharedLibs = append(sharedLibs, deps.LateSharedLibs...) | 
|  | 430 |  | 
| Dan Albert | d015c4a | 2016-08-10 14:34:08 -0700 | [diff] [blame] | 431 | // TODO(danalbert): Clean this up when soong supports prebuilts. | 
|  | 432 | if strings.HasPrefix(ctx.selectedStl(), "ndk_libc++") { | 
|  | 433 | libDir := getNdkStlLibDir(ctx, flags.Toolchain, "libc++") | 
|  | 434 |  | 
|  | 435 | if strings.HasSuffix(ctx.selectedStl(), "_shared") { | 
|  | 436 | deps.StaticLibs = append(deps.StaticLibs, | 
|  | 437 | libDir.Join(ctx, "libandroid_support.a")) | 
|  | 438 | } else { | 
|  | 439 | deps.StaticLibs = append(deps.StaticLibs, | 
|  | 440 | libDir.Join(ctx, "libc++abi.a"), | 
|  | 441 | libDir.Join(ctx, "libandroid_support.a")) | 
|  | 442 | } | 
|  | 443 |  | 
|  | 444 | if ctx.Arch().ArchType == android.Arm { | 
|  | 445 | deps.StaticLibs = append(deps.StaticLibs, | 
|  | 446 | libDir.Join(ctx, "libunwind.a")) | 
|  | 447 | } | 
|  | 448 | } | 
|  | 449 |  | 
| Colin Cross | 26c34ed | 2016-09-30 17:10:16 -0700 | [diff] [blame] | 450 | linkerDeps = append(linkerDeps, deps.SharedLibsDeps...) | 
|  | 451 | linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...) | 
|  | 452 |  | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 453 | TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, | 
|  | 454 | deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, | 
|  | 455 | linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile) | 
|  | 456 |  | 
|  | 457 | return ret | 
|  | 458 | } | 
|  | 459 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 460 | func (library *libraryDecorator) link(ctx ModuleContext, | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 461 | flags Flags, deps PathDeps, objFiles android.Paths) android.Path { | 
|  | 462 |  | 
|  | 463 | objFiles = append(objFiles, deps.ObjFiles...) | 
|  | 464 |  | 
|  | 465 | var out android.Path | 
|  | 466 | if library.static() { | 
|  | 467 | out = library.linkStatic(ctx, flags, deps, objFiles) | 
|  | 468 | } else { | 
|  | 469 | out = library.linkShared(ctx, flags, deps, objFiles) | 
|  | 470 | } | 
|  | 471 |  | 
|  | 472 | library.exportIncludes(ctx, "-I") | 
|  | 473 | library.reexportFlags(deps.ReexportedFlags) | 
| Dan Willemsen | 847dcc7 | 2016-09-29 12:13:36 -0700 | [diff] [blame] | 474 | library.reexportDeps(deps.ReexportedFlagsDeps) | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 475 |  | 
|  | 476 | return out | 
|  | 477 | } | 
|  | 478 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 479 | func (library *libraryDecorator) buildStatic() bool { | 
|  | 480 | return library.Properties.BuildStatic && | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 481 | (library.Properties.Static.Enabled == nil || *library.Properties.Static.Enabled) | 
|  | 482 | } | 
|  | 483 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 484 | func (library *libraryDecorator) buildShared() bool { | 
|  | 485 | return library.Properties.BuildShared && | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 486 | (library.Properties.Shared.Enabled == nil || *library.Properties.Shared.Enabled) | 
|  | 487 | } | 
|  | 488 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 489 | func (library *libraryDecorator) getWholeStaticMissingDeps() []string { | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 490 | return library.wholeStaticMissingDeps | 
|  | 491 | } | 
|  | 492 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 493 | func (library *libraryDecorator) objs() android.Paths { | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 494 | return library.objFiles | 
|  | 495 | } | 
|  | 496 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 497 | func (library *libraryDecorator) reuseObjs() android.Paths { | 
|  | 498 | return library.reuseObjFiles | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 499 | } | 
|  | 500 |  | 
| Colin Cross | 26c34ed | 2016-09-30 17:10:16 -0700 | [diff] [blame] | 501 | func (library *libraryDecorator) toc() android.OptionalPath { | 
|  | 502 | return library.tocFile | 
|  | 503 | } | 
|  | 504 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 505 | func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) { | 
|  | 506 | if !ctx.static() { | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 507 | library.baseInstaller.install(ctx, file) | 
|  | 508 | } | 
|  | 509 | } | 
|  | 510 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 511 | func (library *libraryDecorator) static() bool { | 
|  | 512 | return library.Properties.VariantIsStatic | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 513 | } | 
|  | 514 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 515 | func (library *libraryDecorator) setStatic(static bool) { | 
|  | 516 | library.Properties.VariantIsStatic = static | 
|  | 517 | } | 
|  | 518 |  | 
|  | 519 | func NewLibrary(hod android.HostOrDeviceSupported, shared, static bool) (*Module, *libraryDecorator) { | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 520 | module := newModule(hod, android.MultilibBoth) | 
|  | 521 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 522 | library := &libraryDecorator{ | 
|  | 523 | Properties: LibraryProperties{ | 
|  | 524 | BuildShared: shared, | 
|  | 525 | BuildStatic: static, | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 526 | }, | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 527 | baseCompiler:  NewBaseCompiler(), | 
|  | 528 | baseLinker:    NewBaseLinker(), | 
|  | 529 | baseInstaller: NewBaseInstaller("lib", "lib64", InstallInSystem), | 
|  | 530 | sanitize:      module.sanitize, | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 531 | } | 
|  | 532 |  | 
| Colin Cross | b916a38 | 2016-07-29 17:28:03 -0700 | [diff] [blame] | 533 | module.compiler = library | 
|  | 534 | module.linker = library | 
|  | 535 | module.installer = library | 
|  | 536 |  | 
|  | 537 | return module, library | 
|  | 538 | } | 
|  | 539 |  | 
|  | 540 | func linkageMutator(mctx android.BottomUpMutatorContext) { | 
|  | 541 | if m, ok := mctx.Module().(*Module); ok && m.linker != nil { | 
|  | 542 | if library, ok := m.linker.(libraryInterface); ok { | 
|  | 543 | var modules []blueprint.Module | 
|  | 544 | if library.buildStatic() && library.buildShared() { | 
|  | 545 | modules = mctx.CreateLocalVariations("static", "shared") | 
|  | 546 | static := modules[0].(*Module) | 
|  | 547 | shared := modules[1].(*Module) | 
|  | 548 |  | 
|  | 549 | static.linker.(libraryInterface).setStatic(true) | 
|  | 550 | shared.linker.(libraryInterface).setStatic(false) | 
|  | 551 |  | 
|  | 552 | if staticCompiler, ok := static.compiler.(*libraryDecorator); ok { | 
|  | 553 | sharedCompiler := shared.compiler.(*libraryDecorator) | 
|  | 554 | if len(staticCompiler.Properties.Static.Cflags) == 0 && | 
|  | 555 | len(sharedCompiler.Properties.Shared.Cflags) == 0 { | 
|  | 556 | // Optimize out compiling common .o files twice for static+shared libraries | 
|  | 557 | mctx.AddInterVariantDependency(reuseObjTag, shared, static) | 
|  | 558 | sharedCompiler.baseCompiler.Properties.Srcs = nil | 
|  | 559 | sharedCompiler.baseCompiler.Properties.Generated_sources = nil | 
|  | 560 | } | 
|  | 561 | } | 
|  | 562 | } else if library.buildStatic() { | 
|  | 563 | modules = mctx.CreateLocalVariations("static") | 
|  | 564 | modules[0].(*Module).linker.(libraryInterface).setStatic(true) | 
|  | 565 | } else if library.buildShared() { | 
|  | 566 | modules = mctx.CreateLocalVariations("shared") | 
|  | 567 | modules[0].(*Module).linker.(libraryInterface).setStatic(false) | 
|  | 568 | } | 
|  | 569 | } | 
|  | 570 | } | 
| Colin Cross | 4d9c2d1 | 2016-07-29 12:48:20 -0700 | [diff] [blame] | 571 | } |