1// Copyright 2015 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 15package cc 16 17// This file contains the module types for compiling C/C++ for Android, and converts the properties 18// into the flags and filenames necessary to pass to the compiler. The final creation of the rules 19// is handled in builder.go 20 21import ( 22 "fmt" 23 "path/filepath" 24 "strings" 25 26 "github.com/google/blueprint" 27 "github.com/google/blueprint/proptools" 28 29 "android/soong" 30 "android/soong/common" 31 "android/soong/genrule" 32) 33 34func init() { 35 soong.RegisterModuleType("cc_library_static", libraryStaticFactory) 36 soong.RegisterModuleType("cc_library_shared", librarySharedFactory) 37 soong.RegisterModuleType("cc_library", libraryFactory) 38 soong.RegisterModuleType("cc_object", objectFactory) 39 soong.RegisterModuleType("cc_binary", binaryFactory) 40 soong.RegisterModuleType("cc_test", testFactory) 41 soong.RegisterModuleType("cc_benchmark", benchmarkFactory) 42 soong.RegisterModuleType("cc_defaults", defaultsFactory) 43 44 soong.RegisterModuleType("toolchain_library", toolchainLibraryFactory) 45 soong.RegisterModuleType("ndk_prebuilt_library", ndkPrebuiltLibraryFactory) 46 soong.RegisterModuleType("ndk_prebuilt_object", ndkPrebuiltObjectFactory) 47 soong.RegisterModuleType("ndk_prebuilt_static_stl", ndkPrebuiltStaticStlFactory) 48 soong.RegisterModuleType("ndk_prebuilt_shared_stl", ndkPrebuiltSharedStlFactory) 49 50 soong.RegisterModuleType("cc_library_host_static", libraryHostStaticFactory) 51 soong.RegisterModuleType("cc_library_host_shared", libraryHostSharedFactory) 52 soong.RegisterModuleType("cc_binary_host", binaryHostFactory) 53 soong.RegisterModuleType("cc_test_host", testHostFactory) 54 soong.RegisterModuleType("cc_benchmark_host", benchmarkHostFactory) 55 56 // LinkageMutator must be registered after common.ArchMutator, but that is guaranteed by 57 // the Go initialization order because this package depends on common, so common's init 58 // functions will run first. 59 common.RegisterBottomUpMutator("link", linkageMutator) 60 common.RegisterBottomUpMutator("test_per_src", testPerSrcMutator) 61 common.RegisterBottomUpMutator("deps", depsMutator) 62} 63 64var ( 65 HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", common.Config.PrebuiltOS) 66 67 LibcRoot = pctx.SourcePathVariable("LibcRoot", "bionic/libc") 68 LibmRoot = pctx.SourcePathVariable("LibmRoot", "bionic/libm") 69) 70 71// Flags used by lots of devices. Putting them in package static variables will save bytes in 72// build.ninja so they aren't repeated for every file 73var ( 74 commonGlobalCflags = []string{ 75 "-DANDROID", 76 "-fmessage-length=0", 77 "-W", 78 "-Wall", 79 "-Wno-unused", 80 "-Winit-self", 81 "-Wpointer-arith", 82 "-fdebug-prefix-map=/proc/self/cwd=", 83 84 // COMMON_RELEASE_CFLAGS 85 "-DNDEBUG", 86 "-UDEBUG", 87 } 88 89 deviceGlobalCflags = []string{ 90 "-fdiagnostics-color", 91 92 // TARGET_ERROR_FLAGS 93 "-Werror=return-type", 94 "-Werror=non-virtual-dtor", 95 "-Werror=address", 96 "-Werror=sequence-point", 97 "-Werror=date-time", 98 } 99 100 hostGlobalCflags = []string{} 101 102 commonGlobalCppflags = []string{ 103 "-Wsign-promo", 104 } 105 106 noOverrideGlobalCflags = []string{ 107 "-Werror=int-to-pointer-cast", 108 "-Werror=pointer-to-int-cast", 109 } 110 111 illegalFlags = []string{ 112 "-w", 113 } 114) 115 116func init() { 117 pctx.StaticVariable("commonGlobalCflags", strings.Join(commonGlobalCflags, " ")) 118 pctx.StaticVariable("deviceGlobalCflags", strings.Join(deviceGlobalCflags, " ")) 119 pctx.StaticVariable("hostGlobalCflags", strings.Join(hostGlobalCflags, " ")) 120 pctx.StaticVariable("noOverrideGlobalCflags", strings.Join(noOverrideGlobalCflags, " ")) 121 122 pctx.StaticVariable("commonGlobalCppflags", strings.Join(commonGlobalCppflags, " ")) 123 124 pctx.StaticVariable("commonClangGlobalCflags", 125 strings.Join(append(clangFilterUnknownCflags(commonGlobalCflags), "${clangExtraCflags}"), " ")) 126 pctx.StaticVariable("deviceClangGlobalCflags", 127 strings.Join(append(clangFilterUnknownCflags(deviceGlobalCflags), "${clangExtraTargetCflags}"), " ")) 128 pctx.StaticVariable("hostClangGlobalCflags", 129 strings.Join(clangFilterUnknownCflags(hostGlobalCflags), " ")) 130 pctx.StaticVariable("noOverrideClangGlobalCflags", 131 strings.Join(append(clangFilterUnknownCflags(noOverrideGlobalCflags), "${clangExtraNoOverrideCflags}"), " ")) 132 133 pctx.StaticVariable("commonClangGlobalCppflags", 134 strings.Join(append(clangFilterUnknownCflags(commonGlobalCppflags), "${clangExtraCppflags}"), " ")) 135 136 // Everything in this list is a crime against abstraction and dependency tracking. 137 // Do not add anything to this list. 138 pctx.PrefixedPathsForOptionalSourceVariable("commonGlobalIncludes", "-isystem ", 139 []string{ 140 "system/core/include", 141 "system/media/audio/include", 142 "hardware/libhardware/include", 143 "hardware/libhardware_legacy/include", 144 "hardware/ril/include", 145 "libnativehelper/include", 146 "frameworks/native/include", 147 "frameworks/native/opengl/include", 148 "frameworks/av/include", 149 "frameworks/base/include", 150 }) 151 // This is used by non-NDK modules to get jni.h. export_include_dirs doesn't help 152 // with this, since there is no associated library. 153 pctx.PrefixedPathsForOptionalSourceVariable("commonNativehelperInclude", "-I", 154 []string{"libnativehelper/include/nativehelper"}) 155 156 pctx.SourcePathVariable("clangDefaultBase", "prebuilts/clang/host") 157 pctx.VariableFunc("clangBase", func(config interface{}) (string, error) { 158 if override := config.(common.Config).Getenv("LLVM_PREBUILTS_BASE"); override != "" { 159 return override, nil 160 } 161 return "${clangDefaultBase}", nil 162 }) 163 pctx.VariableFunc("clangVersion", func(config interface{}) (string, error) { 164 if override := config.(common.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" { 165 return override, nil 166 } 167 return "clang-2690385", nil 168 }) 169 pctx.StaticVariable("clangPath", "${clangBase}/${HostPrebuiltTag}/${clangVersion}/bin") 170} 171 172type Deps struct { 173 SharedLibs, LateSharedLibs []string 174 StaticLibs, LateStaticLibs, WholeStaticLibs []string 175 176 ObjFiles common.Paths 177 178 Cflags, ReexportedCflags []string 179 180 CrtBegin, CrtEnd string 181} 182 183type PathDeps struct { 184 SharedLibs, LateSharedLibs common.Paths 185 StaticLibs, LateStaticLibs, WholeStaticLibs common.Paths 186 187 ObjFiles common.Paths 188 WholeStaticLibObjFiles common.Paths 189 190 Cflags, ReexportedCflags []string 191 192 CrtBegin, CrtEnd common.OptionalPath 193} 194 195type Flags struct { 196 GlobalFlags []string // Flags that apply to C, C++, and assembly source files 197 AsFlags []string // Flags that apply to assembly source files 198 CFlags []string // Flags that apply to C and C++ source files 199 ConlyFlags []string // Flags that apply to C source files 200 CppFlags []string // Flags that apply to C++ source files 201 YaccFlags []string // Flags that apply to Yacc source files 202 LdFlags []string // Flags that apply to linker command lines 203 204 Nocrt bool 205 Toolchain Toolchain 206 Clang bool 207 208 RequiredInstructionSet string 209} 210 211type BaseCompilerProperties struct { 212 // list of source files used to compile the C/C++ module. May be .c, .cpp, or .S files. 213 Srcs []string `android:"arch_variant"` 214 215 // list of source files that should not be used to build the C/C++ module. 216 // This is most useful in the arch/multilib variants to remove non-common files 217 Exclude_srcs []string `android:"arch_variant"` 218 219 // list of module-specific flags that will be used for C and C++ compiles. 220 Cflags []string `android:"arch_variant"` 221 222 // list of module-specific flags that will be used for C++ compiles 223 Cppflags []string `android:"arch_variant"` 224 225 // list of module-specific flags that will be used for C compiles 226 Conlyflags []string `android:"arch_variant"` 227 228 // list of module-specific flags that will be used for .S compiles 229 Asflags []string `android:"arch_variant"` 230 231 // list of module-specific flags that will be used for C and C++ compiles when 232 // compiling with clang 233 Clang_cflags []string `android:"arch_variant"` 234 235 // list of module-specific flags that will be used for .S compiles when 236 // compiling with clang 237 Clang_asflags []string `android:"arch_variant"` 238 239 // list of module-specific flags that will be used for .y and .yy compiles 240 Yaccflags []string 241 242 // the instruction set architecture to use to compile the C/C++ 243 // module. 244 Instruction_set string `android:"arch_variant"` 245 246 // list of directories relative to the root of the source tree that will 247 // be added to the include path using -I. 248 // If possible, don't use this. If adding paths from the current directory use 249 // local_include_dirs, if adding paths from other modules use export_include_dirs in 250 // that module. 251 Include_dirs []string `android:"arch_variant"` 252 253 // list of files relative to the root of the source tree that will be included 254 // using -include. 255 // If possible, don't use this. 256 Include_files []string `android:"arch_variant"` 257 258 // list of directories relative to the Blueprints file that will 259 // be added to the include path using -I 260 Local_include_dirs []string `android:"arch_variant"` 261 262 // list of files relative to the Blueprints file that will be included 263 // using -include. 264 // If possible, don't use this. 265 Local_include_files []string `android:"arch_variant"` 266 267 // pass -frtti instead of -fno-rtti 268 Rtti *bool 269 270 Debug, Release struct { 271 // list of module-specific flags that will be used for C and C++ compiles in debug or 272 // release builds 273 Cflags []string `android:"arch_variant"` 274 } `android:"arch_variant"` 275} 276 277type BaseLinkerProperties struct { 278 // list of modules whose object files should be linked into this module 279 // in their entirety. For static library modules, all of the .o files from the intermediate 280 // directory of the dependency will be linked into this modules .a file. For a shared library, 281 // the dependency's .a file will be linked into this module using -Wl,--whole-archive. 282 Whole_static_libs []string `android:"arch_variant"` 283 284 // list of modules that should be statically linked into this module. 285 Static_libs []string `android:"arch_variant"` 286 287 // list of modules that should be dynamically linked into this module. 288 Shared_libs []string `android:"arch_variant"` 289 290 // list of module-specific flags that will be used for all link steps 291 Ldflags []string `android:"arch_variant"` 292 293 // don't insert default compiler flags into asflags, cflags, 294 // cppflags, conlyflags, ldflags, or include_dirs 295 No_default_compiler_flags *bool 296 297 // list of system libraries that will be dynamically linked to 298 // shared library and executable modules. If unset, generally defaults to libc 299 // and libm. Set to [] to prevent linking against libc and libm. 300 System_shared_libs []string 301 302 // allow the module to contain undefined symbols. By default, 303 // modules cannot contain undefined symbols that are not satisified by their immediate 304 // dependencies. Set this flag to true to remove --no-undefined from the linker flags. 305 // This flag should only be necessary for compiling low-level libraries like libc. 306 Allow_undefined_symbols *bool 307 308 // don't link in libgcc.a 309 No_libgcc *bool 310 311 // -l arguments to pass to linker for host-provided shared libraries 312 Host_ldlibs []string `android:"arch_variant"` 313} 314 315type LibraryCompilerProperties struct { 316 Static struct { 317 Srcs []string `android:"arch_variant"` 318 Exclude_srcs []string `android:"arch_variant"` 319 Cflags []string `android:"arch_variant"` 320 } `android:"arch_variant"` 321 Shared struct { 322 Srcs []string `android:"arch_variant"` 323 Exclude_srcs []string `android:"arch_variant"` 324 Cflags []string `android:"arch_variant"` 325 } `android:"arch_variant"` 326} 327 328type LibraryLinkerProperties struct { 329 Static struct { 330 Whole_static_libs []string `android:"arch_variant"` 331 Static_libs []string `android:"arch_variant"` 332 Shared_libs []string `android:"arch_variant"` 333 } `android:"arch_variant"` 334 Shared struct { 335 Whole_static_libs []string `android:"arch_variant"` 336 Static_libs []string `android:"arch_variant"` 337 Shared_libs []string `android:"arch_variant"` 338 } `android:"arch_variant"` 339 340 // local file name to pass to the linker as --version_script 341 Version_script *string `android:"arch_variant"` 342 // local file name to pass to the linker as -unexported_symbols_list 343 Unexported_symbols_list *string `android:"arch_variant"` 344 // local file name to pass to the linker as -force_symbols_not_weak_list 345 Force_symbols_not_weak_list *string `android:"arch_variant"` 346 // local file name to pass to the linker as -force_symbols_weak_list 347 Force_symbols_weak_list *string `android:"arch_variant"` 348 349 // list of directories relative to the Blueprints file that will 350 // be added to the include path using -I for any module that links against this module 351 Export_include_dirs []string `android:"arch_variant"` 352 353 // don't link in crt_begin and crt_end. This flag should only be necessary for 354 // compiling crt or libc. 355 Nocrt *bool `android:"arch_variant"` 356} 357 358type BinaryLinkerProperties struct { 359 // compile executable with -static 360 Static_executable *bool 361 362 // set the name of the output 363 Stem string `android:"arch_variant"` 364 365 // append to the name of the output 366 Suffix string `android:"arch_variant"` 367 368 // if set, add an extra objcopy --prefix-symbols= step 369 Prefix_symbols string 370} 371 372type TestLinkerProperties struct { 373 // if set, build against the gtest library. Defaults to true. 374 Gtest bool 375 376 // Create a separate binary for each source file. Useful when there is 377 // global state that can not be torn down and reset between each test suite. 378 Test_per_src *bool 379} 380 381// Properties used to compile all C or C++ modules 382type BaseProperties struct { 383 // compile module with clang instead of gcc 384 Clang *bool `android:"arch_variant"` 385 386 // Minimum sdk version supported when compiling against the ndk 387 Sdk_version string 388 389 // don't insert default compiler flags into asflags, cflags, 390 // cppflags, conlyflags, ldflags, or include_dirs 391 No_default_compiler_flags *bool 392} 393 394type InstallerProperties struct { 395 // install to a subdirectory of the default install path for the module 396 Relative_install_path string 397} 398 399type UnusedProperties struct { 400 Native_coverage *bool 401 Required []string 402 Sanitize []string `android:"arch_variant"` 403 Sanitize_recover []string 404 Strip string 405 Tags []string 406} 407 408type ModuleContextIntf interface { 409 module() *Module 410 static() bool 411 staticBinary() bool 412 clang() bool 413 toolchain() Toolchain 414 noDefaultCompilerFlags() bool 415 sdk() bool 416 sdkVersion() string 417} 418 419type ModuleContext interface { 420 common.AndroidModuleContext 421 ModuleContextIntf 422} 423 424type BaseModuleContext interface { 425 common.AndroidBaseContext 426 ModuleContextIntf 427} 428 429type Customizer interface { 430 CustomizeProperties(BaseModuleContext) 431 Properties() []interface{} 432} 433 434type feature interface { 435 begin(ctx BaseModuleContext) 436 deps(ctx BaseModuleContext, deps Deps) Deps 437 flags(ctx ModuleContext, flags Flags) Flags 438 props() []interface{} 439} 440 441type compiler interface { 442 feature 443 compile(ctx ModuleContext, flags Flags) common.Paths 444} 445 446type linker interface { 447 feature 448 link(ctx ModuleContext, flags Flags, deps PathDeps, objFiles common.Paths) common.Path 449} 450 451type installer interface { 452 props() []interface{} 453 install(ctx ModuleContext, path common.Path) 454 inData() bool 455} 456 457// Module contains the properties and members used by all C/C++ module types, and implements 458// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces 459// to construct the output file. Behavior can be customized with a Customizer interface 460type Module struct { 461 common.AndroidModuleBase 462 common.DefaultableModule 463 464 Properties BaseProperties 465 unused UnusedProperties 466 467 // initialize before calling Init 468 hod common.HostOrDeviceSupported 469 multilib common.Multilib 470 471 // delegates, initialize before calling Init 472 customizer Customizer 473 features []feature 474 compiler compiler 475 linker linker 476 installer installer 477 478 deps Deps 479 outputFile common.OptionalPath 480 481 cachedToolchain Toolchain 482} 483 484func (c *Module) Init() (blueprint.Module, []interface{}) { 485 props := []interface{}{&c.Properties, &c.unused} 486 if c.customizer != nil { 487 props = append(props, c.customizer.Properties()...) 488 } 489 if c.compiler != nil { 490 props = append(props, c.compiler.props()...) 491 } 492 if c.linker != nil { 493 props = append(props, c.linker.props()...) 494 } 495 if c.installer != nil { 496 props = append(props, c.installer.props()...) 497 } 498 for _, feature := range c.features { 499 props = append(props, feature.props()...) 500 } 501 502 _, props = common.InitAndroidArchModule(c, c.hod, c.multilib, props...) 503 504 return common.InitDefaultableModule(c, c, props...) 505} 506 507type baseModuleContext struct { 508 common.AndroidBaseContext 509 moduleContextImpl 510} 511 512type moduleContext struct { 513 common.AndroidModuleContext 514 moduleContextImpl 515} 516 517type moduleContextImpl struct { 518 mod *Module 519 ctx BaseModuleContext 520} 521 522func (ctx *moduleContextImpl) module() *Module { 523 return ctx.mod 524} 525 526func (ctx *moduleContextImpl) clang() bool { 527 return ctx.mod.clang(ctx.ctx) 528} 529 530func (ctx *moduleContextImpl) toolchain() Toolchain { 531 return ctx.mod.toolchain(ctx.ctx) 532} 533 534func (ctx *moduleContextImpl) static() bool { 535 if ctx.mod.linker == nil { 536 panic(fmt.Errorf("static called on module %q with no linker", ctx.ctx.ModuleName())) 537 } 538 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok { 539 return linker.static() 540 } else { 541 panic(fmt.Errorf("static called on module %q that doesn't use base linker", ctx.ctx.ModuleName())) 542 } 543} 544 545func (ctx *moduleContextImpl) staticBinary() bool { 546 if ctx.mod.linker == nil { 547 panic(fmt.Errorf("staticBinary called on module %q with no linker", ctx.ctx.ModuleName())) 548 } 549 if linker, ok := ctx.mod.linker.(baseLinkerInterface); ok { 550 return linker.staticBinary() 551 } else { 552 panic(fmt.Errorf("staticBinary called on module %q that doesn't use base linker", ctx.ctx.ModuleName())) 553 } 554} 555 556func (ctx *moduleContextImpl) noDefaultCompilerFlags() bool { 557 return Bool(ctx.mod.Properties.No_default_compiler_flags) 558} 559 560func (ctx *moduleContextImpl) sdk() bool { 561 return ctx.mod.Properties.Sdk_version != "" 562} 563 564func (ctx *moduleContextImpl) sdkVersion() string { 565 return ctx.mod.Properties.Sdk_version 566} 567 568func newBaseModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module { 569 return &Module{ 570 hod: hod, 571 multilib: multilib, 572 } 573} 574 575func newModule(hod common.HostOrDeviceSupported, multilib common.Multilib) *Module { 576 module := newBaseModule(hod, multilib) 577 module.features = []feature{ 578 &stlFeature{}, 579 } 580 return module 581} 582 583func (c *Module) GenerateAndroidBuildActions(actx common.AndroidModuleContext) { 584 ctx := &moduleContext{ 585 AndroidModuleContext: actx, 586 moduleContextImpl: moduleContextImpl{ 587 mod: c, 588 }, 589 } 590 ctx.ctx = ctx 591 592 flags := Flags{ 593 Toolchain: c.toolchain(ctx), 594 Clang: c.clang(ctx), 595 } 596 597 if c.compiler != nil { 598 flags = c.compiler.flags(ctx, flags) 599 } 600 if c.linker != nil { 601 flags = c.linker.flags(ctx, flags) 602 } 603 for _, feature := range c.features { 604 flags = feature.flags(ctx, flags) 605 } 606 if ctx.Failed() { 607 return 608 } 609 610 flags.CFlags, _ = filterList(flags.CFlags, illegalFlags) 611 flags.CppFlags, _ = filterList(flags.CppFlags, illegalFlags) 612 flags.ConlyFlags, _ = filterList(flags.ConlyFlags, illegalFlags) 613 614 // Optimization to reduce size of build.ninja 615 // Replace the long list of flags for each file with a module-local variable 616 ctx.Variable(pctx, "cflags", strings.Join(flags.CFlags, " ")) 617 ctx.Variable(pctx, "cppflags", strings.Join(flags.CppFlags, " ")) 618 ctx.Variable(pctx, "asflags", strings.Join(flags.AsFlags, " ")) 619 flags.CFlags = []string{"$cflags"} 620 flags.CppFlags = []string{"$cppflags"} 621 flags.AsFlags = []string{"$asflags"} 622 623 deps := c.depsToPaths(actx, c.deps) 624 if ctx.Failed() { 625 return 626 } 627 628 flags.CFlags = append(flags.CFlags, deps.Cflags...) 629 630 var objFiles common.Paths 631 if c.compiler != nil { 632 objFiles = c.compiler.compile(ctx, flags) 633 if ctx.Failed() { 634 return 635 } 636 } 637 638 if c.linker != nil { 639 outputFile := c.linker.link(ctx, flags, deps, objFiles) 640 if ctx.Failed() { 641 return 642 } 643 c.outputFile = common.OptionalPathForPath(outputFile) 644 645 if c.installer != nil { 646 c.installer.install(ctx, outputFile) 647 if ctx.Failed() { 648 return 649 } 650 } 651 } 652} 653 654func (c *Module) toolchain(ctx BaseModuleContext) Toolchain { 655 if c.cachedToolchain == nil { 656 arch := ctx.Arch() 657 hod := ctx.HostOrDevice() 658 ht := ctx.HostType() 659 factory := toolchainFactories[hod][ht][arch.ArchType] 660 if factory == nil { 661 ctx.ModuleErrorf("Toolchain not found for %s %s arch %q", hod.String(), ht.String(), arch.String()) 662 return nil 663 } 664 c.cachedToolchain = factory(arch) 665 } 666 return c.cachedToolchain 667} 668 669func (c *Module) begin(ctx BaseModuleContext) { 670 if c.compiler != nil { 671 c.compiler.begin(ctx) 672 } 673 if c.linker != nil { 674 c.linker.begin(ctx) 675 } 676 for _, feature := range c.features { 677 feature.begin(ctx) 678 } 679} 680 681func (c *Module) depsMutator(actx common.AndroidBottomUpMutatorContext) { 682 ctx := &baseModuleContext{ 683 AndroidBaseContext: actx, 684 moduleContextImpl: moduleContextImpl{ 685 mod: c, 686 }, 687 } 688 ctx.ctx = ctx 689 690 if c.customizer != nil { 691 c.customizer.CustomizeProperties(ctx) 692 } 693 694 c.begin(ctx) 695 696 c.deps = Deps{} 697 698 if c.compiler != nil { 699 c.deps = c.compiler.deps(ctx, c.deps) 700 } 701 if c.linker != nil { 702 c.deps = c.linker.deps(ctx, c.deps) 703 } 704 for _, feature := range c.features { 705 c.deps = feature.deps(ctx, c.deps) 706 } 707 708 c.deps.WholeStaticLibs = lastUniqueElements(c.deps.WholeStaticLibs) 709 c.deps.StaticLibs = lastUniqueElements(c.deps.StaticLibs) 710 c.deps.LateStaticLibs = lastUniqueElements(c.deps.LateStaticLibs) 711 c.deps.SharedLibs = lastUniqueElements(c.deps.SharedLibs) 712 c.deps.LateSharedLibs = lastUniqueElements(c.deps.LateSharedLibs) 713 714 staticLibs := c.deps.WholeStaticLibs 715 staticLibs = append(staticLibs, c.deps.StaticLibs...) 716 staticLibs = append(staticLibs, c.deps.LateStaticLibs...) 717 actx.AddVariationDependencies([]blueprint.Variation{{"link", "static"}}, staticLibs...) 718 719 sharedLibs := c.deps.SharedLibs 720 sharedLibs = append(sharedLibs, c.deps.LateSharedLibs...) 721 actx.AddVariationDependencies([]blueprint.Variation{{"link", "shared"}}, sharedLibs...) 722 723 actx.AddDependency(ctx.module(), c.deps.ObjFiles.Strings()...) 724 if c.deps.CrtBegin != "" { 725 actx.AddDependency(ctx.module(), c.deps.CrtBegin) 726 } 727 if c.deps.CrtEnd != "" { 728 actx.AddDependency(ctx.module(), c.deps.CrtEnd) 729 } 730} 731 732func depsMutator(ctx common.AndroidBottomUpMutatorContext) { 733 if c, ok := ctx.Module().(*Module); ok { 734 c.depsMutator(ctx) 735 } 736} 737 738func (c *Module) clang(ctx BaseModuleContext) bool { 739 clang := Bool(c.Properties.Clang) 740 741 if c.Properties.Clang == nil { 742 if ctx.Host() { 743 clang = true 744 } 745 746 if ctx.Device() && ctx.AConfig().DeviceUsesClang() { 747 clang = true 748 } 749 } 750 751 if !c.toolchain(ctx).ClangSupported() { 752 clang = false 753 } 754 755 return clang 756} 757 758func (c *Module) depsToPathsFromList(ctx common.AndroidModuleContext, 759 names []string) (modules []common.AndroidModule, 760 outputFiles common.Paths, exportedFlags []string) { 761 762 for _, n := range names { 763 found := false 764 ctx.VisitDirectDeps(func(m blueprint.Module) { 765 otherName := ctx.OtherModuleName(m) 766 if otherName != n { 767 return 768 } 769 770 if a, ok := m.(*Module); ok { 771 if !a.Enabled() { 772 ctx.ModuleErrorf("depends on disabled module %q", otherName) 773 return 774 } 775 if a.HostOrDevice() != ctx.HostOrDevice() { 776 ctx.ModuleErrorf("host/device mismatch between %q and %q", ctx.ModuleName(), 777 otherName) 778 return 779 } 780 781 if outputFile := a.outputFile; outputFile.Valid() { 782 if found { 783 ctx.ModuleErrorf("multiple modules satisified dependency on %q", otherName) 784 return 785 } 786 outputFiles = append(outputFiles, outputFile.Path()) 787 modules = append(modules, a) 788 if i, ok := a.linker.(exportedFlagsProducer); ok { 789 exportedFlags = append(exportedFlags, i.exportedFlags()...) 790 } 791 found = true 792 } else { 793 ctx.ModuleErrorf("module %q missing output file", otherName) 794 return 795 } 796 } else { 797 ctx.ModuleErrorf("module %q not an android module", otherName) 798 return 799 } 800 }) 801 if !found && !inList(n, ctx.GetMissingDependencies()) { 802 ctx.ModuleErrorf("unsatisified dependency on %q", n) 803 } 804 } 805 806 return modules, outputFiles, exportedFlags 807} 808 809// Convert dependency names to paths. Takes a Deps containing names and returns a PathDeps 810// containing paths 811func (c *Module) depsToPaths(ctx common.AndroidModuleContext, deps Deps) PathDeps { 812 var depPaths PathDeps 813 var newCflags []string 814 815 var wholeStaticLibModules []common.AndroidModule 816 817 wholeStaticLibModules, depPaths.WholeStaticLibs, newCflags = 818 c.depsToPathsFromList(ctx, deps.WholeStaticLibs) 819 depPaths.Cflags = append(depPaths.Cflags, newCflags...) 820 depPaths.ReexportedCflags = append(depPaths.ReexportedCflags, newCflags...) 821 822 for _, am := range wholeStaticLibModules { 823 if m, ok := am.(*Module); ok { 824 if staticLib, ok := m.linker.(*libraryLinker); ok && staticLib.static() { 825 if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil { 826 postfix := " (required by " + ctx.OtherModuleName(m) + ")" 827 for i := range missingDeps { 828 missingDeps[i] += postfix 829 } 830 ctx.AddMissingDependencies(missingDeps) 831 } 832 depPaths.WholeStaticLibObjFiles = 833 append(depPaths.WholeStaticLibObjFiles, staticLib.objFiles...) 834 } else { 835 ctx.ModuleErrorf("module %q not a static library", ctx.OtherModuleName(m)) 836 } 837 } else { 838 ctx.ModuleErrorf("module %q not an android module", ctx.OtherModuleName(m)) 839 } 840 } 841 842 _, depPaths.StaticLibs, newCflags = c.depsToPathsFromList(ctx, deps.StaticLibs) 843 depPaths.Cflags = append(depPaths.Cflags, newCflags...) 844 845 _, depPaths.LateStaticLibs, newCflags = c.depsToPathsFromList(ctx, deps.LateStaticLibs) 846 depPaths.Cflags = append(depPaths.Cflags, newCflags...) 847 848 _, depPaths.SharedLibs, newCflags = c.depsToPathsFromList(ctx, deps.SharedLibs) 849 depPaths.Cflags = append(depPaths.Cflags, newCflags...) 850 851 _, depPaths.LateSharedLibs, newCflags = c.depsToPathsFromList(ctx, deps.LateSharedLibs) 852 depPaths.Cflags = append(depPaths.Cflags, newCflags...) 853 854 ctx.VisitDirectDeps(func(bm blueprint.Module) { 855 if m, ok := bm.(*Module); ok { 856 otherName := ctx.OtherModuleName(m) 857 if otherName == deps.CrtBegin { 858 depPaths.CrtBegin = m.outputFile 859 } else if otherName == deps.CrtEnd { 860 depPaths.CrtEnd = m.outputFile 861 } else { 862 output := m.outputFile 863 if output.Valid() { 864 depPaths.ObjFiles = append(depPaths.ObjFiles, output.Path()) 865 } else { 866 ctx.ModuleErrorf("module %s did not provide an output file", otherName) 867 } 868 } 869 } 870 }) 871 872 return depPaths 873} 874 875func (c *Module) InstallInData() bool { 876 if c.installer == nil { 877 return false 878 } 879 return c.installer.inData() 880} 881 882// Compiler 883 884type baseCompiler struct { 885 Properties BaseCompilerProperties 886} 887 888var _ compiler = (*baseCompiler)(nil) 889 890func (compiler *baseCompiler) props() []interface{} { 891 return []interface{}{&compiler.Properties} 892} 893 894func (compiler *baseCompiler) begin(ctx BaseModuleContext) {} 895func (compiler *baseCompiler) deps(ctx BaseModuleContext, deps Deps) Deps { return deps } 896 897// Create a Flags struct that collects the compile flags from global values, 898// per-target values, module type values, and per-module Blueprints properties 899func (compiler *baseCompiler) flags(ctx ModuleContext, flags Flags) Flags { 900 toolchain := ctx.toolchain() 901 902 flags.CFlags = append(flags.CFlags, compiler.Properties.Cflags...) 903 flags.CppFlags = append(flags.CppFlags, compiler.Properties.Cppflags...) 904 flags.ConlyFlags = append(flags.ConlyFlags, compiler.Properties.Conlyflags...) 905 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Asflags...) 906 flags.YaccFlags = append(flags.YaccFlags, compiler.Properties.Yaccflags...) 907 908 // Include dir cflags 909 rootIncludeDirs := common.PathsForSource(ctx, compiler.Properties.Include_dirs) 910 localIncludeDirs := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_dirs) 911 flags.GlobalFlags = append(flags.GlobalFlags, 912 includeDirsToFlags(localIncludeDirs), 913 includeDirsToFlags(rootIncludeDirs)) 914 915 rootIncludeFiles := common.PathsForSource(ctx, compiler.Properties.Include_files) 916 localIncludeFiles := common.PathsForModuleSrc(ctx, compiler.Properties.Local_include_files) 917 918 flags.GlobalFlags = append(flags.GlobalFlags, 919 includeFilesToFlags(rootIncludeFiles), 920 includeFilesToFlags(localIncludeFiles)) 921 922 if !ctx.noDefaultCompilerFlags() { 923 if !ctx.sdk() || ctx.Host() { 924 flags.GlobalFlags = append(flags.GlobalFlags, 925 "${commonGlobalIncludes}", 926 toolchain.IncludeFlags(), 927 "${commonNativehelperInclude}") 928 } 929 930 flags.GlobalFlags = append(flags.GlobalFlags, []string{ 931 "-I" + common.PathForModuleSrc(ctx).String(), 932 "-I" + common.PathForModuleOut(ctx).String(), 933 "-I" + common.PathForModuleGen(ctx).String(), 934 }...) 935 } 936 937 instructionSet := compiler.Properties.Instruction_set 938 if flags.RequiredInstructionSet != "" { 939 instructionSet = flags.RequiredInstructionSet 940 } 941 instructionSetFlags, err := toolchain.InstructionSetFlags(instructionSet) 942 if flags.Clang { 943 instructionSetFlags, err = toolchain.ClangInstructionSetFlags(instructionSet) 944 } 945 if err != nil { 946 ctx.ModuleErrorf("%s", err) 947 } 948 949 // TODO: debug 950 flags.CFlags = append(flags.CFlags, compiler.Properties.Release.Cflags...) 951 952 if flags.Clang { 953 flags.CFlags = clangFilterUnknownCflags(flags.CFlags) 954 flags.CFlags = append(flags.CFlags, compiler.Properties.Clang_cflags...) 955 flags.AsFlags = append(flags.AsFlags, compiler.Properties.Clang_asflags...) 956 flags.CppFlags = clangFilterUnknownCflags(flags.CppFlags) 957 flags.ConlyFlags = clangFilterUnknownCflags(flags.ConlyFlags) 958 flags.LdFlags = clangFilterUnknownCflags(flags.LdFlags) 959 960 target := "-target " + toolchain.ClangTriple() 961 gccPrefix := "-B" + filepath.Join(toolchain.GccRoot(), toolchain.GccTriple(), "bin") 962 963 flags.CFlags = append(flags.CFlags, target, gccPrefix) 964 flags.AsFlags = append(flags.AsFlags, target, gccPrefix) 965 flags.LdFlags = append(flags.LdFlags, target, gccPrefix) 966 } 967 968 if !ctx.noDefaultCompilerFlags() { 969 flags.GlobalFlags = append(flags.GlobalFlags, instructionSetFlags) 970 971 if flags.Clang { 972 flags.AsFlags = append(flags.AsFlags, toolchain.ClangAsflags()) 973 flags.CppFlags = append(flags.CppFlags, "${commonClangGlobalCppflags}") 974 flags.GlobalFlags = append(flags.GlobalFlags, 975 toolchain.ClangCflags(), 976 "${commonClangGlobalCflags}", 977 fmt.Sprintf("${%sClangGlobalCflags}", ctx.HostOrDevice())) 978 979 flags.ConlyFlags = append(flags.ConlyFlags, "${clangExtraConlyflags}") 980 } else { 981 flags.CppFlags = append(flags.CppFlags, "${commonGlobalCppflags}") 982 flags.GlobalFlags = append(flags.GlobalFlags, 983 toolchain.Cflags(), 984 "${commonGlobalCflags}", 985 fmt.Sprintf("${%sGlobalCflags}", ctx.HostOrDevice())) 986 } 987 988 if Bool(ctx.AConfig().ProductVariables.Brillo) { 989 flags.GlobalFlags = append(flags.GlobalFlags, "-D__BRILLO__") 990 } 991 992 if ctx.Device() { 993 if Bool(compiler.Properties.Rtti) { 994 flags.CppFlags = append(flags.CppFlags, "-frtti") 995 } else { 996 flags.CppFlags = append(flags.CppFlags, "-fno-rtti") 997 } 998 } 999 1000 flags.AsFlags = append(flags.AsFlags, "-D__ASSEMBLY__") 1001 1002 if flags.Clang { 1003 flags.CppFlags = append(flags.CppFlags, toolchain.ClangCppflags()) 1004 } else { 1005 flags.CppFlags = append(flags.CppFlags, toolchain.Cppflags()) 1006 } 1007 } 1008 1009 if flags.Clang { 1010 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainClangCflags()) 1011 } else { 1012 flags.GlobalFlags = append(flags.GlobalFlags, toolchain.ToolchainCflags()) 1013 } 1014 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags()) 1015 1016 if !ctx.sdk() { 1017 if ctx.Host() && !flags.Clang { 1018 // The host GCC doesn't support C++14 (and is deprecated, so likely 1019 // never will). Build these modules with C++11. 1020 flags.CppFlags = append(flags.CppFlags, "-std=gnu++11") 1021 } else { 1022 flags.CppFlags = append(flags.CppFlags, "-std=gnu++14") 1023 } 1024 } 1025 1026 // We can enforce some rules more strictly in the code we own. strict 1027 // indicates if this is code that we can be stricter with. If we have 1028 // rules that we want to apply to *our* code (but maybe can't for 1029 // vendor/device specific things), we could extend this to be a ternary 1030 // value. 1031 strict := true 1032 if strings.HasPrefix(common.PathForModuleSrc(ctx).String(), "external/") { 1033 strict = false 1034 } 1035 1036 // Can be used to make some annotations stricter for code we can fix 1037 // (such as when we mark functions as deprecated). 1038 if strict { 1039 flags.CFlags = append(flags.CFlags, "-DANDROID_STRICT") 1040 } 1041 1042 return flags 1043} 1044 1045func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags) common.Paths { 1046 // Compile files listed in c.Properties.Srcs into objects 1047 objFiles := compiler.compileObjs(ctx, flags, "", compiler.Properties.Srcs, compiler.Properties.Exclude_srcs) 1048 if ctx.Failed() { 1049 return nil 1050 } 1051 1052 var genSrcs common.Paths 1053 ctx.VisitDirectDeps(func(module blueprint.Module) { 1054 if gen, ok := module.(genrule.SourceFileGenerator); ok { 1055 genSrcs = append(genSrcs, gen.GeneratedSourceFiles()...) 1056 } 1057 }) 1058 1059 if len(genSrcs) != 0 { 1060 genObjs := TransformSourceToObj(ctx, "", genSrcs, flagsToBuilderFlags(flags), nil) 1061 objFiles = append(objFiles, genObjs...) 1062 } 1063 1064 return objFiles 1065} 1066 1067// Compile a list of source files into objects a specified subdirectory 1068func (compiler *baseCompiler) compileObjs(ctx common.AndroidModuleContext, flags Flags, 1069 subdir string, srcFiles, excludes []string) common.Paths { 1070 1071 buildFlags := flagsToBuilderFlags(flags) 1072 1073 inputFiles := ctx.ExpandSources(srcFiles, excludes) 1074 srcPaths, deps := genSources(ctx, inputFiles, buildFlags) 1075 1076 return TransformSourceToObj(ctx, subdir, srcPaths, buildFlags, deps) 1077} 1078 1079// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties 1080type baseLinker struct { 1081 Properties BaseLinkerProperties 1082 dynamicProperties struct { 1083 VariantIsShared bool `blueprint:"mutated"` 1084 VariantIsStatic bool `blueprint:"mutated"` 1085 VariantIsStaticBinary bool `blueprint:"mutated"` 1086 } 1087} 1088 1089func (linker *baseLinker) begin(ctx BaseModuleContext) {} 1090 1091func (linker *baseLinker) props() []interface{} { 1092 return []interface{}{&linker.Properties, &linker.dynamicProperties} 1093} 1094 1095func (linker *baseLinker) deps(ctx BaseModuleContext, deps Deps) Deps { 1096 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...) 1097 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...) 1098 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...) 1099 1100 if ctx.ModuleName() != "libcompiler_rt-extras" { 1101 deps.StaticLibs = append(deps.StaticLibs, "libcompiler_rt-extras") 1102 } 1103 1104 if ctx.Device() { 1105 // libgcc and libatomic have to be last on the command line 1106 deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic") 1107 if !Bool(linker.Properties.No_libgcc) { 1108 deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc") 1109 } 1110 1111 if !linker.static() { 1112 if linker.Properties.System_shared_libs != nil { 1113 deps.LateSharedLibs = append(deps.LateSharedLibs, 1114 linker.Properties.System_shared_libs...) 1115 } else if !ctx.sdk() { 1116 deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm") 1117 } 1118 } 1119 1120 if ctx.sdk() { 1121 version := ctx.sdkVersion() 1122 deps.SharedLibs = append(deps.SharedLibs, 1123 "ndk_libc."+version, 1124 "ndk_libm."+version, 1125 ) 1126 } 1127 } 1128 1129 return deps 1130} 1131 1132func (linker *baseLinker) flags(ctx ModuleContext, flags Flags) Flags { 1133 toolchain := ctx.toolchain() 1134 1135 flags.LdFlags = append(flags.LdFlags, linker.Properties.Ldflags...) 1136 1137 if !ctx.noDefaultCompilerFlags() { 1138 if ctx.Device() && !Bool(linker.Properties.Allow_undefined_symbols) { 1139 flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined") 1140 } 1141 1142 if flags.Clang { 1143 flags.LdFlags = append(flags.LdFlags, toolchain.ClangLdflags()) 1144 } else { 1145 flags.LdFlags = append(flags.LdFlags, toolchain.Ldflags()) 1146 } 1147 1148 if ctx.Host() { 1149 flags.LdFlags = append(flags.LdFlags, linker.Properties.Host_ldlibs...) 1150 } 1151 } 1152 1153 if !flags.Clang { 1154 flags.LdFlags = append(flags.LdFlags, toolchain.ToolchainLdflags()) 1155 } 1156 1157 return flags 1158} 1159 1160func (linker *baseLinker) static() bool { 1161 return linker.dynamicProperties.VariantIsStatic 1162} 1163 1164func (linker *baseLinker) staticBinary() bool { 1165 return linker.dynamicProperties.VariantIsStaticBinary 1166} 1167 1168func (linker *baseLinker) setStatic(static bool) { 1169 linker.dynamicProperties.VariantIsStatic = static 1170} 1171 1172type baseLinkerInterface interface { 1173 // Returns true if the build options for the module have selected a static or shared build 1174 buildStatic() bool 1175 buildShared() bool 1176 1177 // Sets whether a specific variant is static or shared 1178 setStatic(bool) 1179 1180 // Returns whether a specific variant is a static library or binary 1181 static() bool 1182 1183 // Returns whether a module is a static binary 1184 staticBinary() bool 1185} 1186 1187type exportedFlagsProducer interface { 1188 exportedFlags() []string 1189} 1190 1191type baseInstaller struct { 1192 Properties InstallerProperties 1193 1194 dir string 1195 dir64 string 1196 data bool 1197 1198 path common.OutputPath 1199} 1200 1201var _ installer = (*baseInstaller)(nil) 1202 1203func (installer *baseInstaller) props() []interface{} { 1204 return []interface{}{&installer.Properties} 1205} 1206 1207func (installer *baseInstaller) install(ctx ModuleContext, file common.Path) { 1208 subDir := installer.dir 1209 if ctx.toolchain().Is64Bit() && installer.dir64 != "" { 1210 subDir = installer.dir64 1211 } 1212 dir := common.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path) 1213 installer.path = ctx.InstallFile(dir, file) 1214} 1215 1216func (installer *baseInstaller) inData() bool { 1217 return installer.data 1218} 1219 1220// 1221// Combined static+shared libraries 1222// 1223 1224type libraryCompiler struct { 1225 baseCompiler 1226 1227 linker *libraryLinker 1228 Properties LibraryCompilerProperties 1229 1230 // For reusing static library objects for shared library 1231 reuseFrom *libraryCompiler 1232 reuseObjFiles common.Paths 1233} 1234 1235var _ compiler = (*libraryCompiler)(nil) 1236 1237func (library *libraryCompiler) props() []interface{} { 1238 props := library.baseCompiler.props() 1239 return append(props, &library.Properties) 1240} 1241 1242func (library *libraryCompiler) flags(ctx ModuleContext, flags Flags) Flags { 1243 flags = library.baseCompiler.flags(ctx, flags) 1244 1245 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because 1246 // all code is position independent, and then those warnings get promoted to 1247 // errors. 1248 if ctx.HostType() != common.Windows { 1249 flags.CFlags = append(flags.CFlags, "-fPIC") 1250 } 1251 1252 if library.linker.static() { 1253 flags.CFlags = append(flags.CFlags, library.Properties.Static.Cflags...) 1254 } else { 1255 flags.CFlags = append(flags.CFlags, library.Properties.Shared.Cflags...) 1256 } 1257 1258 return flags 1259} 1260 1261func (library *libraryCompiler) compile(ctx ModuleContext, flags Flags) common.Paths { 1262 var objFiles common.Paths 1263 1264 if library.reuseFrom != library && library.reuseFrom.Properties.Static.Cflags == nil && 1265 library.Properties.Shared.Cflags == nil { 1266 objFiles = append(common.Paths(nil), library.reuseFrom.reuseObjFiles...) 1267 } else { 1268 objFiles = library.baseCompiler.compile(ctx, flags) 1269 library.reuseObjFiles = objFiles 1270 } 1271 1272 if library.linker.static() { 1273 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceStaticLibrary, 1274 library.Properties.Static.Srcs, library.Properties.Static.Exclude_srcs)...) 1275 } else { 1276 objFiles = append(objFiles, library.compileObjs(ctx, flags, common.DeviceSharedLibrary, 1277 library.Properties.Shared.Srcs, library.Properties.Shared.Exclude_srcs)...) 1278 } 1279 1280 return objFiles 1281} 1282 1283type libraryLinker struct { 1284 baseLinker 1285 1286 Properties LibraryLinkerProperties 1287 1288 dynamicProperties struct { 1289 BuildStatic bool `blueprint:"mutated"` 1290 BuildShared bool `blueprint:"mutated"` 1291 } 1292 1293 exportFlags []string 1294 1295 // If we're used as a whole_static_lib, our missing dependencies need 1296 // to be given 1297 wholeStaticMissingDeps []string 1298 1299 // For whole_static_libs 1300 objFiles common.Paths 1301} 1302 1303var _ linker = (*libraryLinker)(nil) 1304var _ exportedFlagsProducer = (*libraryLinker)(nil) 1305 1306func (library *libraryLinker) props() []interface{} { 1307 props := library.baseLinker.props() 1308 return append(props, &library.Properties, &library.dynamicProperties) 1309} 1310 1311func (library *libraryLinker) flags(ctx ModuleContext, flags Flags) Flags { 1312 flags = library.baseLinker.flags(ctx, flags) 1313 1314 flags.Nocrt = Bool(library.Properties.Nocrt) 1315 1316 if !library.static() { 1317 libName := ctx.ModuleName() 1318 // GCC for Android assumes that -shared means -Bsymbolic, use -Wl,-shared instead 1319 sharedFlag := "-Wl,-shared" 1320 if flags.Clang || ctx.Host() { 1321 sharedFlag = "-shared" 1322 } 1323 if ctx.Device() { 1324 flags.LdFlags = append(flags.LdFlags, 1325 "-nostdlib", 1326 "-Wl,--gc-sections", 1327 ) 1328 } 1329 1330 if ctx.Darwin() { 1331 flags.LdFlags = append(flags.LdFlags, 1332 "-dynamiclib", 1333 "-single_module", 1334 //"-read_only_relocs suppress", 1335 "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(), 1336 ) 1337 } else { 1338 flags.LdFlags = append(flags.LdFlags, 1339 sharedFlag, 1340 "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix(), 1341 ) 1342 } 1343 } 1344 1345 return flags 1346} 1347 1348func (library *libraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps { 1349 deps = library.baseLinker.deps(ctx, deps) 1350 if library.static() { 1351 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Static.Whole_static_libs...) 1352 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...) 1353 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...) 1354 } else { 1355 if ctx.Device() && !Bool(library.Properties.Nocrt) { 1356 if !ctx.sdk() { 1357 deps.CrtBegin = "crtbegin_so" 1358 deps.CrtEnd = "crtend_so" 1359 } else { 1360 deps.CrtBegin = "ndk_crtbegin_so." + ctx.sdkVersion() 1361 deps.CrtEnd = "ndk_crtend_so." + ctx.sdkVersion() 1362 } 1363 } 1364 deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...) 1365 deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...) 1366 deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...) 1367 } 1368 1369 return deps 1370} 1371 1372func (library *libraryLinker) exportedFlags() []string { 1373 return library.exportFlags 1374} 1375 1376func (library *libraryLinker) linkStatic(ctx ModuleContext, 1377 flags Flags, deps PathDeps, objFiles common.Paths) common.Path { 1378 1379 objFiles = append(objFiles, deps.WholeStaticLibObjFiles...) 1380 library.objFiles = objFiles 1381 1382 outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+staticLibraryExtension) 1383 1384 if ctx.Darwin() { 1385 TransformDarwinObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile) 1386 } else { 1387 TransformObjToStaticLib(ctx, objFiles, flagsToBuilderFlags(flags), outputFile) 1388 } 1389 1390 library.wholeStaticMissingDeps = ctx.GetMissingDependencies() 1391 1392 ctx.CheckbuildFile(outputFile) 1393 1394 return outputFile 1395} 1396 1397func (library *libraryLinker) linkShared(ctx ModuleContext, 1398 flags Flags, deps PathDeps, objFiles common.Paths) common.Path { 1399 1400 outputFile := common.PathForModuleOut(ctx, ctx.ModuleName()+flags.Toolchain.ShlibSuffix()) 1401 1402 var linkerDeps common.Paths 1403 1404 versionScript := common.OptionalPathForModuleSrc(ctx, library.Properties.Version_script) 1405 unexportedSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Unexported_symbols_list) 1406 forceNotWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_not_weak_list) 1407 forceWeakSymbols := common.OptionalPathForModuleSrc(ctx, library.Properties.Force_symbols_weak_list) 1408 if !ctx.Darwin() { 1409 if versionScript.Valid() { 1410 flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String()) 1411 linkerDeps = append(linkerDeps, versionScript.Path()) 1412 } 1413 if unexportedSymbols.Valid() { 1414 ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin") 1415 } 1416 if forceNotWeakSymbols.Valid() { 1417 ctx.PropertyErrorf("force_symbols_not_weak_list", "Only supported on Darwin") 1418 } 1419 if forceWeakSymbols.Valid() { 1420 ctx.PropertyErrorf("force_symbols_weak_list", "Only supported on Darwin") 1421 } 1422 } else { 1423 if versionScript.Valid() { 1424 ctx.PropertyErrorf("version_script", "Not supported on Darwin") 1425 } 1426 if unexportedSymbols.Valid() { 1427 flags.LdFlags = append(flags.LdFlags, "-Wl,-unexported_symbols_list,"+unexportedSymbols.String()) 1428 linkerDeps = append(linkerDeps, unexportedSymbols.Path()) 1429 } 1430 if forceNotWeakSymbols.Valid() { 1431 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_not_weak_list,"+forceNotWeakSymbols.String()) 1432 linkerDeps = append(linkerDeps, forceNotWeakSymbols.Path()) 1433 } 1434 if forceWeakSymbols.Valid() { 1435 flags.LdFlags = append(flags.LdFlags, "-Wl,-force_symbols_weak_list,"+forceWeakSymbols.String()) 1436 linkerDeps = append(linkerDeps, forceWeakSymbols.Path()) 1437 } 1438 } 1439 1440 sharedLibs := deps.SharedLibs 1441 sharedLibs = append(sharedLibs, deps.LateSharedLibs...) 1442 1443 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, 1444 deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, 1445 linkerDeps, deps.CrtBegin, deps.CrtEnd, false, flagsToBuilderFlags(flags), outputFile) 1446 1447 return outputFile 1448} 1449 1450func (library *libraryLinker) link(ctx ModuleContext, 1451 flags Flags, deps PathDeps, objFiles common.Paths) common.Path { 1452 1453 var out common.Path 1454 if library.static() { 1455 out = library.linkStatic(ctx, flags, deps, objFiles) 1456 } else { 1457 out = library.linkShared(ctx, flags, deps, objFiles) 1458 } 1459 1460 includeDirs := common.PathsForModuleSrc(ctx, library.Properties.Export_include_dirs) 1461 library.exportFlags = []string{includeDirsToFlags(includeDirs)} 1462 library.exportFlags = append(library.exportFlags, deps.ReexportedCflags...) 1463 1464 return out 1465} 1466 1467func (library *libraryLinker) buildStatic() bool { 1468 return library.dynamicProperties.BuildStatic 1469} 1470 1471func (library *libraryLinker) buildShared() bool { 1472 return library.dynamicProperties.BuildShared 1473} 1474 1475func (library *libraryLinker) getWholeStaticMissingDeps() []string { 1476 return library.wholeStaticMissingDeps 1477} 1478 1479type libraryInstaller struct { 1480 baseInstaller 1481 1482 linker *libraryLinker 1483} 1484 1485func (library *libraryInstaller) install(ctx ModuleContext, file common.Path) { 1486 if !library.linker.static() { 1487 library.baseInstaller.install(ctx, file) 1488 } 1489} 1490 1491func NewLibrary(hod common.HostOrDeviceSupported, shared, static bool) *Module { 1492 module := newModule(hod, common.MultilibBoth) 1493 1494 linker := &libraryLinker{} 1495 linker.dynamicProperties.BuildShared = shared 1496 linker.dynamicProperties.BuildStatic = static 1497 module.linker = linker 1498 1499 module.compiler = &libraryCompiler{ 1500 linker: linker, 1501 } 1502 module.installer = &libraryInstaller{ 1503 baseInstaller: baseInstaller{ 1504 dir: "lib", 1505 dir64: "lib64", 1506 }, 1507 linker: linker, 1508 } 1509 1510 return module 1511} 1512 1513func libraryFactory() (blueprint.Module, []interface{}) { 1514 module := NewLibrary(common.HostAndDeviceSupported, true, true) 1515 return module.Init() 1516} 1517 1518// 1519// Objects (for crt*.o) 1520// 1521 1522type objectLinker struct { 1523} 1524 1525func objectFactory() (blueprint.Module, []interface{}) { 1526 module := newBaseModule(common.DeviceSupported, common.MultilibBoth) 1527 module.compiler = &baseCompiler{} 1528 module.linker = &objectLinker{} 1529 return module.Init() 1530} 1531 1532func (*objectLinker) props() []interface{} { 1533 return nil 1534} 1535 1536func (*objectLinker) begin(ctx BaseModuleContext) {} 1537 1538func (*objectLinker) deps(ctx BaseModuleContext, deps Deps) Deps { 1539 // object files can't have any dynamic dependencies 1540 return deps 1541} 1542 1543func (*objectLinker) flags(ctx ModuleContext, flags Flags) Flags { 1544 return flags 1545} 1546 1547func (object *objectLinker) link(ctx ModuleContext, 1548 flags Flags, deps PathDeps, objFiles common.Paths) common.Path { 1549 1550 objFiles = append(objFiles, deps.ObjFiles...) 1551 1552 var outputFile common.Path 1553 if len(objFiles) == 1 { 1554 outputFile = objFiles[0] 1555 } else { 1556 output := common.PathForModuleOut(ctx, ctx.ModuleName()+objectExtension) 1557 TransformObjsToObj(ctx, objFiles, flagsToBuilderFlags(flags), output) 1558 outputFile = output 1559 } 1560 1561 ctx.CheckbuildFile(outputFile) 1562 return outputFile 1563} 1564 1565// 1566// Executables 1567// 1568 1569type binaryLinker struct { 1570 baseLinker 1571 1572 Properties BinaryLinkerProperties 1573 1574 hostToolPath common.OptionalPath 1575} 1576 1577var _ linker = (*binaryLinker)(nil) 1578 1579func (binary *binaryLinker) props() []interface{} { 1580 return append(binary.baseLinker.props(), &binary.Properties) 1581} 1582 1583func (binary *binaryLinker) buildStatic() bool { 1584 return Bool(binary.Properties.Static_executable) 1585} 1586 1587func (binary *binaryLinker) buildShared() bool { 1588 return !Bool(binary.Properties.Static_executable) 1589} 1590 1591func (binary *binaryLinker) getStem(ctx BaseModuleContext) string { 1592 stem := ctx.ModuleName() 1593 if binary.Properties.Stem != "" { 1594 stem = binary.Properties.Stem 1595 } 1596 1597 return stem + binary.Properties.Suffix 1598} 1599 1600func (binary *binaryLinker) deps(ctx BaseModuleContext, deps Deps) Deps { 1601 deps = binary.baseLinker.deps(ctx, deps) 1602 if ctx.Device() { 1603 if !ctx.sdk() { 1604 if Bool(binary.Properties.Static_executable) { 1605 deps.CrtBegin = "crtbegin_static" 1606 } else { 1607 deps.CrtBegin = "crtbegin_dynamic" 1608 } 1609 deps.CrtEnd = "crtend_android" 1610 } else { 1611 if Bool(binary.Properties.Static_executable) { 1612 deps.CrtBegin = "ndk_crtbegin_static." + ctx.sdkVersion() 1613 } else { 1614 deps.CrtBegin = "ndk_crtbegin_dynamic." + ctx.sdkVersion() 1615 } 1616 deps.CrtEnd = "ndk_crtend_android." + ctx.sdkVersion() 1617 } 1618 1619 if Bool(binary.Properties.Static_executable) { 1620 if inList("libc++_static", deps.StaticLibs) { 1621 deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", "libdl") 1622 } 1623 // static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with 1624 // --start-group/--end-group along with libgcc. If they are in deps.StaticLibs, 1625 // move them to the beginning of deps.LateStaticLibs 1626 var groupLibs []string 1627 deps.StaticLibs, groupLibs = filterList(deps.StaticLibs, 1628 []string{"libc", "libc_nomalloc", "libcompiler_rt"}) 1629 deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...) 1630 } 1631 } 1632 1633 if !Bool(binary.Properties.Static_executable) && inList("libc", deps.StaticLibs) { 1634 ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" + 1635 "from static libs or set static_executable: true") 1636 } 1637 return deps 1638} 1639 1640func NewBinary(hod common.HostOrDeviceSupported) *Module { 1641 module := newModule(hod, common.MultilibFirst) 1642 module.compiler = &baseCompiler{} 1643 module.linker = &binaryLinker{} 1644 module.installer = &baseInstaller{ 1645 dir: "bin", 1646 } 1647 return module 1648} 1649 1650func binaryFactory() (blueprint.Module, []interface{}) { 1651 module := NewBinary(common.HostAndDeviceSupported) 1652 return module.Init() 1653} 1654 1655func (binary *binaryLinker) ModifyProperties(ctx ModuleContext) { 1656 if ctx.Darwin() { 1657 binary.Properties.Static_executable = proptools.BoolPtr(false) 1658 } 1659 if Bool(binary.Properties.Static_executable) { 1660 binary.dynamicProperties.VariantIsStaticBinary = true 1661 } 1662} 1663 1664func (binary *binaryLinker) flags(ctx ModuleContext, flags Flags) Flags { 1665 flags = binary.baseLinker.flags(ctx, flags) 1666 1667 if ctx.Host() { 1668 flags.LdFlags = append(flags.LdFlags, "-pie") 1669 if ctx.HostType() == common.Windows { 1670 flags.LdFlags = append(flags.LdFlags, "-Wl,-e_mainCRTStartup") 1671 } 1672 } 1673 1674 // MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because 1675 // all code is position independent, and then those warnings get promoted to 1676 // errors. 1677 if ctx.HostType() != common.Windows { 1678 flags.CFlags = append(flags.CFlags, "-fpie") 1679 } 1680 1681 if ctx.Device() { 1682 if Bool(binary.Properties.Static_executable) { 1683 // Clang driver needs -static to create static executable. 1684 // However, bionic/linker uses -shared to overwrite. 1685 // Linker for x86 targets does not allow coexistance of -static and -shared, 1686 // so we add -static only if -shared is not used. 1687 if !inList("-shared", flags.LdFlags) { 1688 flags.LdFlags = append(flags.LdFlags, "-static") 1689 } 1690 1691 flags.LdFlags = append(flags.LdFlags, 1692 "-nostdlib", 1693 "-Bstatic", 1694 "-Wl,--gc-sections", 1695 ) 1696 1697 } else { 1698 linker := "/system/bin/linker" 1699 if flags.Toolchain.Is64Bit() { 1700 linker += "64" 1701 } 1702 1703 flags.LdFlags = append(flags.LdFlags, 1704 "-pie", 1705 "-nostdlib", 1706 "-Bdynamic", 1707 fmt.Sprintf("-Wl,-dynamic-linker,%s", linker), 1708 "-Wl,--gc-sections", 1709 "-Wl,-z,nocopyreloc", 1710 ) 1711 } 1712 } else if ctx.Darwin() { 1713 flags.LdFlags = append(flags.LdFlags, "-Wl,-headerpad_max_install_names") 1714 } 1715 1716 return flags 1717} 1718 1719func (binary *binaryLinker) link(ctx ModuleContext, 1720 flags Flags, deps PathDeps, objFiles common.Paths) common.Path { 1721 1722 outputFile := common.PathForModuleOut(ctx, binary.getStem(ctx)+flags.Toolchain.ExecutableSuffix()) 1723 if ctx.HostOrDevice().Host() { 1724 binary.hostToolPath = common.OptionalPathForPath(outputFile) 1725 } 1726 ret := outputFile 1727 1728 if binary.Properties.Prefix_symbols != "" { 1729 afterPrefixSymbols := outputFile 1730 outputFile = common.PathForModuleOut(ctx, binary.getStem(ctx)+".intermediate") 1731 TransformBinaryPrefixSymbols(ctx, binary.Properties.Prefix_symbols, outputFile, 1732 flagsToBuilderFlags(flags), afterPrefixSymbols) 1733 } 1734 1735 var linkerDeps common.Paths 1736 1737 sharedLibs := deps.SharedLibs 1738 sharedLibs = append(sharedLibs, deps.LateSharedLibs...) 1739 1740 TransformObjToDynamicBinary(ctx, objFiles, sharedLibs, deps.StaticLibs, 1741 deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true, 1742 flagsToBuilderFlags(flags), outputFile) 1743 1744 return ret 1745} 1746 1747func (binary *binaryLinker) HostToolPath() common.OptionalPath { 1748 return binary.hostToolPath 1749} 1750 1751func testPerSrcMutator(mctx common.AndroidBottomUpMutatorContext) { 1752 if m, ok := mctx.Module().(*Module); ok { 1753 if test, ok := m.linker.(*testLinker); ok { 1754 if Bool(test.Properties.Test_per_src) { 1755 testNames := make([]string, len(m.compiler.(*baseCompiler).Properties.Srcs)) 1756 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs { 1757 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src)) 1758 } 1759 tests := mctx.CreateLocalVariations(testNames...) 1760 for i, src := range m.compiler.(*baseCompiler).Properties.Srcs { 1761 tests[i].(*Module).compiler.(*baseCompiler).Properties.Srcs = []string{src} 1762 tests[i].(*Module).linker.(*testLinker).binaryLinker.Properties.Stem = testNames[i] 1763 } 1764 } 1765 } 1766 } 1767} 1768 1769type testLinker struct { 1770 binaryLinker 1771 Properties TestLinkerProperties 1772} 1773 1774func (test *testLinker) props() []interface{} { 1775 return append(test.binaryLinker.props(), &test.Properties) 1776} 1777 1778func (test *testLinker) flags(ctx ModuleContext, flags Flags) Flags { 1779 flags = test.binaryLinker.flags(ctx, flags) 1780 1781 if !test.Properties.Gtest { 1782 return flags 1783 } 1784 1785 flags.CFlags = append(flags.CFlags, "-DGTEST_HAS_STD_STRING") 1786 if ctx.Host() { 1787 flags.CFlags = append(flags.CFlags, "-O0", "-g") 1788 1789 if ctx.HostType() == common.Windows { 1790 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_WINDOWS") 1791 } else { 1792 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX") 1793 flags.LdFlags = append(flags.LdFlags, "-lpthread") 1794 } 1795 } else { 1796 flags.CFlags = append(flags.CFlags, "-DGTEST_OS_LINUX_ANDROID") 1797 } 1798 1799 // TODO(danalbert): Make gtest export its dependencies. 1800 flags.CFlags = append(flags.CFlags, 1801 "-I"+common.PathForSource(ctx, "external/gtest/include").String()) 1802 1803 return flags 1804} 1805 1806func (test *testLinker) deps(ctx BaseModuleContext, deps Deps) Deps { 1807 if test.Properties.Gtest { 1808 deps.StaticLibs = append(deps.StaticLibs, "libgtest_main", "libgtest") 1809 } 1810 deps = test.binaryLinker.deps(ctx, deps) 1811 return deps 1812} 1813 1814type testInstaller struct { 1815 baseInstaller 1816} 1817 1818func (installer *testInstaller) install(ctx ModuleContext, file common.Path) { 1819 installer.dir = filepath.Join(installer.dir, ctx.ModuleName()) 1820 installer.dir64 = filepath.Join(installer.dir64, ctx.ModuleName()) 1821 installer.baseInstaller.install(ctx, file) 1822} 1823 1824func NewTest(hod common.HostOrDeviceSupported) *Module { 1825 module := newModule(hod, common.MultilibBoth) 1826 module.compiler = &baseCompiler{} 1827 linker := &testLinker{} 1828 linker.Properties.Gtest = true 1829 module.linker = linker 1830 module.installer = &testInstaller{ 1831 baseInstaller: baseInstaller{ 1832 dir: "nativetest", 1833 dir64: "nativetest64", 1834 data: true, 1835 }, 1836 } 1837 return module 1838} 1839 1840func testFactory() (blueprint.Module, []interface{}) { 1841 module := NewTest(common.HostAndDeviceSupported) 1842 return module.Init() 1843} 1844 1845type benchmarkLinker struct { 1846 binaryLinker 1847} 1848 1849func (benchmark *benchmarkLinker) deps(ctx BaseModuleContext, deps Deps) Deps { 1850 deps = benchmark.binaryLinker.deps(ctx, deps) 1851 deps.StaticLibs = append(deps.StaticLibs, "libbenchmark", "libbase") 1852 return deps 1853} 1854 1855func NewBenchmark(hod common.HostOrDeviceSupported) *Module { 1856 module := newModule(hod, common.MultilibFirst) 1857 module.compiler = &baseCompiler{} 1858 module.linker = &benchmarkLinker{} 1859 module.installer = &baseInstaller{ 1860 dir: "nativetest", 1861 dir64: "nativetest64", 1862 data: true, 1863 } 1864 return module 1865} 1866 1867func benchmarkFactory() (blueprint.Module, []interface{}) { 1868 module := NewBenchmark(common.HostAndDeviceSupported) 1869 return module.Init() 1870} 1871 1872// 1873// Static library 1874// 1875 1876func libraryStaticFactory() (blueprint.Module, []interface{}) { 1877 module := NewLibrary(common.HostAndDeviceSupported, false, true) 1878 return module.Init() 1879} 1880 1881// 1882// Shared libraries 1883// 1884 1885func librarySharedFactory() (blueprint.Module, []interface{}) { 1886 module := NewLibrary(common.HostAndDeviceSupported, true, false) 1887 return module.Init() 1888} 1889 1890// 1891// Host static library 1892// 1893 1894func libraryHostStaticFactory() (blueprint.Module, []interface{}) { 1895 module := NewLibrary(common.HostSupported, false, true) 1896 return module.Init() 1897} 1898 1899// 1900// Host Shared libraries 1901// 1902 1903func libraryHostSharedFactory() (blueprint.Module, []interface{}) { 1904 module := NewLibrary(common.HostSupported, true, false) 1905 return module.Init() 1906} 1907 1908// 1909// Host Binaries 1910// 1911 1912func binaryHostFactory() (blueprint.Module, []interface{}) { 1913 module := NewBinary(common.HostSupported) 1914 return module.Init() 1915} 1916 1917// 1918// Host Tests 1919// 1920 1921func testHostFactory() (blueprint.Module, []interface{}) { 1922 module := NewTest(common.HostSupported) 1923 return module.Init() 1924} 1925 1926// 1927// Host Benchmarks 1928// 1929 1930func benchmarkHostFactory() (blueprint.Module, []interface{}) { 1931 module := NewBenchmark(common.HostSupported) 1932 return module.Init() 1933} 1934 1935// 1936// Defaults 1937// 1938type Defaults struct { 1939 common.AndroidModuleBase 1940 common.DefaultsModule 1941} 1942 1943func (*Defaults) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) { 1944} 1945 1946func defaultsFactory() (blueprint.Module, []interface{}) { 1947 module := &Defaults{} 1948 1949 propertyStructs := []interface{}{ 1950 &BaseProperties{}, 1951 &BaseCompilerProperties{}, 1952 &BaseLinkerProperties{}, 1953 &LibraryCompilerProperties{}, 1954 &LibraryLinkerProperties{}, 1955 &BinaryLinkerProperties{}, 1956 &TestLinkerProperties{}, 1957 &UnusedProperties{}, 1958 &StlProperties{}, 1959 } 1960 1961 _, propertyStructs = common.InitAndroidArchModule(module, common.HostAndDeviceDefault, 1962 common.MultilibDefault, propertyStructs...) 1963 1964 return common.InitDefaultsModule(module, module, propertyStructs...) 1965} 1966 1967// 1968// Device libraries shipped with gcc 1969// 1970 1971type toolchainLibraryLinker struct { 1972 baseLinker 1973} 1974 1975var _ baseLinkerInterface = (*toolchainLibraryLinker)(nil) 1976 1977func (*toolchainLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps { 1978 // toolchain libraries can't have any dependencies 1979 return deps 1980} 1981 1982func (*toolchainLibraryLinker) buildStatic() bool { 1983 return true 1984} 1985 1986func (*toolchainLibraryLinker) buildShared() bool { 1987 return false 1988} 1989 1990func toolchainLibraryFactory() (blueprint.Module, []interface{}) { 1991 module := newBaseModule(common.DeviceSupported, common.MultilibBoth) 1992 module.compiler = &baseCompiler{} 1993 module.linker = &toolchainLibraryLinker{} 1994 module.Properties.Clang = proptools.BoolPtr(false) 1995 return module.Init() 1996} 1997 1998func (library *toolchainLibraryLinker) link(ctx ModuleContext, 1999 flags Flags, deps PathDeps, objFiles common.Paths) common.Path { 2000 2001 libName := ctx.ModuleName() + staticLibraryExtension 2002 outputFile := common.PathForModuleOut(ctx, libName) 2003 2004 if flags.Clang { 2005 ctx.ModuleErrorf("toolchain_library must use GCC, not Clang") 2006 } 2007 2008 CopyGccLib(ctx, libName, flagsToBuilderFlags(flags), outputFile) 2009 2010 ctx.CheckbuildFile(outputFile) 2011 2012 return outputFile 2013} 2014 2015// NDK prebuilt libraries. 2016// 2017// These differ from regular prebuilts in that they aren't stripped and usually aren't installed 2018// either (with the exception of the shared STLs, which are installed to the app's directory rather 2019// than to the system image). 2020 2021func getNdkLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, version string) common.SourcePath { 2022 return common.PathForSource(ctx, fmt.Sprintf("prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/lib", 2023 version, toolchain.Name())) 2024} 2025 2026func ndkPrebuiltModuleToPath(ctx common.AndroidModuleContext, toolchain Toolchain, 2027 ext string, version string) common.Path { 2028 2029 // NDK prebuilts are named like: ndk_NAME.EXT.SDK_VERSION. 2030 // We want to translate to just NAME.EXT 2031 name := strings.Split(strings.TrimPrefix(ctx.ModuleName(), "ndk_"), ".")[0] 2032 dir := getNdkLibDir(ctx, toolchain, version) 2033 return dir.Join(ctx, name+ext) 2034} 2035 2036type ndkPrebuiltObjectLinker struct { 2037 objectLinker 2038} 2039 2040func (*ndkPrebuiltObjectLinker) deps(ctx BaseModuleContext, deps Deps) Deps { 2041 // NDK objects can't have any dependencies 2042 return deps 2043} 2044 2045func ndkPrebuiltObjectFactory() (blueprint.Module, []interface{}) { 2046 module := newBaseModule(common.DeviceSupported, common.MultilibBoth) 2047 module.linker = &ndkPrebuiltObjectLinker{} 2048 return module.Init() 2049} 2050 2051func (c *ndkPrebuiltObjectLinker) link(ctx ModuleContext, flags Flags, 2052 deps PathDeps, objFiles common.Paths) common.Path { 2053 // A null build step, but it sets up the output path. 2054 if !strings.HasPrefix(ctx.ModuleName(), "ndk_crt") { 2055 ctx.ModuleErrorf("NDK prebuilts must have an ndk_crt prefixed name") 2056 } 2057 2058 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion()) 2059} 2060 2061type ndkPrebuiltLibraryLinker struct { 2062 libraryLinker 2063 Properties struct { 2064 Export_include_dirs []string `android:"arch_variant"` 2065 } 2066} 2067 2068var _ baseLinkerInterface = (*ndkPrebuiltLibraryLinker)(nil) 2069var _ exportedFlagsProducer = (*libraryLinker)(nil) 2070 2071func (ndk *ndkPrebuiltLibraryLinker) props() []interface{} { 2072 return []interface{}{&ndk.Properties} 2073} 2074 2075func (*ndkPrebuiltLibraryLinker) deps(ctx BaseModuleContext, deps Deps) Deps { 2076 // NDK libraries can't have any dependencies 2077 return deps 2078} 2079 2080func ndkPrebuiltLibraryFactory() (blueprint.Module, []interface{}) { 2081 module := newBaseModule(common.DeviceSupported, common.MultilibBoth) 2082 linker := &ndkPrebuiltLibraryLinker{} 2083 linker.dynamicProperties.BuildShared = true 2084 module.linker = linker 2085 return module.Init() 2086} 2087 2088func (ndk *ndkPrebuiltLibraryLinker) link(ctx ModuleContext, flags Flags, 2089 deps PathDeps, objFiles common.Paths) common.Path { 2090 // A null build step, but it sets up the output path. 2091 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") { 2092 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name") 2093 } 2094 2095 includeDirs := common.PathsForModuleSrc(ctx, ndk.Properties.Export_include_dirs) 2096 ndk.exportFlags = []string{common.JoinWithPrefix(includeDirs.Strings(), "-isystem ")} 2097 2098 return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, flags.Toolchain.ShlibSuffix(), 2099 ctx.sdkVersion()) 2100} 2101 2102// The NDK STLs are slightly different from the prebuilt system libraries: 2103// * Are not specific to each platform version. 2104// * The libraries are not in a predictable location for each STL. 2105 2106type ndkPrebuiltStlLinker struct { 2107 ndkPrebuiltLibraryLinker 2108} 2109 2110func ndkPrebuiltSharedStlFactory() (blueprint.Module, []interface{}) { 2111 module := newBaseModule(common.DeviceSupported, common.MultilibBoth) 2112 linker := &ndkPrebuiltStlLinker{} 2113 linker.dynamicProperties.BuildShared = true 2114 module.linker = linker 2115 return module.Init() 2116} 2117 2118func ndkPrebuiltStaticStlFactory() (blueprint.Module, []interface{}) { 2119 module := newBaseModule(common.DeviceSupported, common.MultilibBoth) 2120 linker := &ndkPrebuiltStlLinker{} 2121 linker.dynamicProperties.BuildStatic = true 2122 module.linker = linker 2123 return module.Init() 2124} 2125 2126func getNdkStlLibDir(ctx common.AndroidModuleContext, toolchain Toolchain, stl string) common.SourcePath { 2127 gccVersion := toolchain.GccVersion() 2128 var libDir string 2129 switch stl { 2130 case "libstlport": 2131 libDir = "cxx-stl/stlport/libs" 2132 case "libc++": 2133 libDir = "cxx-stl/llvm-libc++/libs" 2134 case "libgnustl": 2135 libDir = fmt.Sprintf("cxx-stl/gnu-libstdc++/%s/libs", gccVersion) 2136 } 2137 2138 if libDir != "" { 2139 ndkSrcRoot := "prebuilts/ndk/current/sources" 2140 return common.PathForSource(ctx, ndkSrcRoot).Join(ctx, libDir, ctx.Arch().Abi[0]) 2141 } 2142 2143 ctx.ModuleErrorf("Unknown NDK STL: %s", stl) 2144 return common.PathForSource(ctx, "") 2145} 2146 2147func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags, 2148 deps PathDeps, objFiles common.Paths) common.Path { 2149 // A null build step, but it sets up the output path. 2150 if !strings.HasPrefix(ctx.ModuleName(), "ndk_lib") { 2151 ctx.ModuleErrorf("NDK prebuilts must have an ndk_lib prefixed name") 2152 } 2153 2154 includeDirs := common.PathsForModuleSrc(ctx, ndk.Properties.Export_include_dirs) 2155 ndk.exportFlags = []string{includeDirsToFlags(includeDirs)} 2156 2157 libName := strings.TrimPrefix(ctx.ModuleName(), "ndk_") 2158 libExt := flags.Toolchain.ShlibSuffix() 2159 if ndk.dynamicProperties.BuildStatic { 2160 libExt = staticLibraryExtension 2161 } 2162 2163 stlName := strings.TrimSuffix(libName, "_shared") 2164 stlName = strings.TrimSuffix(stlName, "_static") 2165 libDir := getNdkStlLibDir(ctx, flags.Toolchain, stlName) 2166 return libDir.Join(ctx, libName+libExt) 2167} 2168 2169func linkageMutator(mctx common.AndroidBottomUpMutatorContext) { 2170 if m, ok := mctx.Module().(*Module); ok { 2171 if m.linker != nil { 2172 if linker, ok := m.linker.(baseLinkerInterface); ok { 2173 var modules []blueprint.Module 2174 if linker.buildStatic() && linker.buildShared() { 2175 modules = mctx.CreateLocalVariations("static", "shared") 2176 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true) 2177 modules[0].(*Module).installer = nil 2178 modules[1].(*Module).linker.(baseLinkerInterface).setStatic(false) 2179 } else if linker.buildStatic() { 2180 modules = mctx.CreateLocalVariations("static") 2181 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(true) 2182 modules[0].(*Module).installer = nil 2183 } else if linker.buildShared() { 2184 modules = mctx.CreateLocalVariations("shared") 2185 modules[0].(*Module).linker.(baseLinkerInterface).setStatic(false) 2186 } else { 2187 panic(fmt.Errorf("library %q not static or shared", mctx.ModuleName())) 2188 } 2189 2190 if _, ok := m.compiler.(*libraryCompiler); ok { 2191 reuseFrom := modules[0].(*Module).compiler.(*libraryCompiler) 2192 for _, m := range modules { 2193 m.(*Module).compiler.(*libraryCompiler).reuseFrom = reuseFrom 2194 } 2195 } 2196 } 2197 } 2198 } 2199} 2200 2201// lastUniqueElements returns all unique elements of a slice, keeping the last copy of each 2202// modifies the slice contents in place, and returns a subslice of the original slice 2203func lastUniqueElements(list []string) []string { 2204 totalSkip := 0 2205 for i := len(list) - 1; i >= totalSkip; i-- { 2206 skip := 0 2207 for j := i - 1; j >= totalSkip; j-- { 2208 if list[i] == list[j] { 2209 skip++ 2210 } else { 2211 list[j+skip] = list[j] 2212 } 2213 } 2214 totalSkip += skip 2215 } 2216 return list[totalSkip:] 2217} 2218 2219var Bool = proptools.Bool 2220