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 15package cc 16 17import ( 18 "android/soong/android" 19 "android/soong/cc/config" 20 "fmt" 21 22 "github.com/google/blueprint" 23 "github.com/google/blueprint/proptools" 24) 25 26// This file contains the basic functionality for linking against static libraries and shared 27// libraries. Final linking into libraries or executables is handled in library.go, binary.go, etc. 28 29type BaseLinkerProperties struct { 30 // list of modules whose object files should be linked into this module 31 // in their entirety. For static library modules, all of the .o files from the intermediate 32 // directory of the dependency will be linked into this modules .a file. For a shared library, 33 // the dependency's .a file will be linked into this module using -Wl,--whole-archive. 34 Whole_static_libs []string `android:"arch_variant,variant_prepend"` 35 36 // list of modules that should be statically linked into this module. 37 Static_libs []string `android:"arch_variant,variant_prepend"` 38 39 // list of modules that should be dynamically linked into this module. 40 Shared_libs []string `android:"arch_variant"` 41 42 // list of modules that should only provide headers for this module. 43 Header_libs []string `android:"arch_variant,variant_prepend"` 44 45 // list of module-specific flags that will be used for all link steps 46 Ldflags []string `android:"arch_variant"` 47 48 // list of system libraries that will be dynamically linked to 49 // shared library and executable modules. If unset, generally defaults to libc, 50 // libm, and libdl. Set to [] to prevent linking against the defaults. 51 System_shared_libs []string `android:"arch_variant"` 52 53 // allow the module to contain undefined symbols. By default, 54 // modules cannot contain undefined symbols that are not satisified by their immediate 55 // dependencies. Set this flag to true to remove --no-undefined from the linker flags. 56 // This flag should only be necessary for compiling low-level libraries like libc. 57 Allow_undefined_symbols *bool `android:"arch_variant"` 58 59 // don't link in libclang_rt.builtins-*.a 60 No_libcrt *bool `android:"arch_variant"` 61 62 // Use clang lld instead of gnu ld. 63 Use_clang_lld *bool `android:"arch_variant"` 64 65 // -l arguments to pass to linker for host-provided shared libraries 66 Host_ldlibs []string `android:"arch_variant"` 67 68 // list of shared libraries to re-export include directories from. Entries must be 69 // present in shared_libs. 70 Export_shared_lib_headers []string `android:"arch_variant"` 71 72 // list of static libraries to re-export include directories from. Entries must be 73 // present in static_libs. 74 Export_static_lib_headers []string `android:"arch_variant"` 75 76 // list of header libraries to re-export include directories from. Entries must be 77 // present in header_libs. 78 Export_header_lib_headers []string `android:"arch_variant"` 79 80 // list of generated headers to re-export include directories from. Entries must be 81 // present in generated_headers. 82 Export_generated_headers []string `android:"arch_variant"` 83 84 // don't link in crt_begin and crt_end. This flag should only be necessary for 85 // compiling crt or libc. 86 Nocrt *bool `android:"arch_variant"` 87 88 // group static libraries. This can resolve missing symbols issues with interdependencies 89 // between static libraries, but it is generally better to order them correctly instead. 90 Group_static_libs *bool `android:"arch_variant"` 91 92 // list of modules that should be installed with this module. This is similar to 'required' 93 // but '.vendor' suffix will be appended to the module names if the shared libraries have 94 // vendor variants and this module uses VNDK. 95 Runtime_libs []string `android:"arch_variant"` 96 97 Target struct { 98 Vendor, Product struct { 99 // list of shared libs that only should be used to build vendor or 100 // product variant of the C/C++ module. 101 Shared_libs []string 102 103 // list of static libs that only should be used to build vendor or 104 // product variant of the C/C++ module. 105 Static_libs []string 106 107 // list of shared libs that should not be used to build vendor or 108 // product variant of the C/C++ module. 109 Exclude_shared_libs []string 110 111 // list of static libs that should not be used to build vendor or 112 // product variant of the C/C++ module. 113 Exclude_static_libs []string 114 115 // list of header libs that should not be used to build vendor or 116 // product variant of the C/C++ module. 117 Exclude_header_libs []string 118 119 // list of runtime libs that should not be installed along with 120 // vendor or variant of the C/C++ module. 121 Exclude_runtime_libs []string 122 123 // version script for vendor or product variant 124 Version_script *string `android:"arch_variant"` 125 } `android:"arch_variant"` 126 Recovery struct { 127 // list of shared libs that only should be used to build the recovery 128 // variant of the C/C++ module. 129 Shared_libs []string 130 131 // list of static libs that only should be used to build the recovery 132 // variant of the C/C++ module. 133 Static_libs []string 134 135 // list of shared libs that should not be used to build 136 // the recovery variant of the C/C++ module. 137 Exclude_shared_libs []string 138 139 // list of static libs that should not be used to build 140 // the recovery variant of the C/C++ module. 141 Exclude_static_libs []string 142 143 // list of header libs that should not be used to build the recovery variant 144 // of the C/C++ module. 145 Exclude_header_libs []string 146 } 147 Ramdisk struct { 148 // list of static libs that only should be used to build the recovery 149 // variant of the C/C++ module. 150 Static_libs []string 151 152 // list of shared libs that should not be used to build 153 // the ramdisk variant of the C/C++ module. 154 Exclude_shared_libs []string 155 156 // list of static libs that should not be used to build 157 // the ramdisk variant of the C/C++ module. 158 Exclude_static_libs []string 159 } 160 Vendor_ramdisk struct { 161 // list of shared libs that should not be used to build 162 // the recovery variant of the C/C++ module. 163 Exclude_shared_libs []string 164 165 // list of static libs that should not be used to build 166 // the vendor ramdisk variant of the C/C++ module. 167 Exclude_static_libs []string 168 } 169 Platform struct { 170 // list of shared libs that should be use to build the platform variant 171 // of a module that sets sdk_version. This should rarely be necessary, 172 // in most cases the same libraries are available for the SDK and platform 173 // variants. 174 Shared_libs []string 175 } 176 Apex struct { 177 // list of shared libs that should not be used to build the apex variant of 178 // the C/C++ module. 179 Exclude_shared_libs []string 180 181 // list of static libs that should not be used to build the apex ramdisk 182 // variant of the C/C++ module. 183 Exclude_static_libs []string 184 } 185 } `android:"arch_variant"` 186 187 // make android::build:GetBuildNumber() available containing the build ID. 188 Use_version_lib *bool `android:"arch_variant"` 189 190 // Generate compact dynamic relocation table, default true. 191 Pack_relocations *bool `android:"arch_variant"` 192 193 // local file name to pass to the linker as --version_script 194 Version_script *string `android:"path,arch_variant"` 195 196 // list of static libs that should not be used to build this module 197 Exclude_static_libs []string `android:"arch_variant"` 198 199 // list of shared libs that should not be used to build this module 200 Exclude_shared_libs []string `android:"arch_variant"` 201} 202 203func NewBaseLinker(sanitize *sanitize) *baseLinker { 204 return &baseLinker{sanitize: sanitize} 205} 206 207// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties 208type baseLinker struct { 209 Properties BaseLinkerProperties 210 dynamicProperties struct { 211 RunPaths []string `blueprint:"mutated"` 212 BuildStubs bool `blueprint:"mutated"` 213 } 214 215 sanitize *sanitize 216} 217 218func (linker *baseLinker) appendLdflags(flags []string) { 219 linker.Properties.Ldflags = append(linker.Properties.Ldflags, flags...) 220} 221 222// linkerInit initializes dynamic properties of the linker (such as runpath). 223func (linker *baseLinker) linkerInit(ctx BaseModuleContext) { 224 if ctx.toolchain().Is64Bit() { 225 linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, "../lib64", "lib64") 226 } else { 227 linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, "../lib", "lib") 228 } 229} 230 231func (linker *baseLinker) linkerProps() []interface{} { 232 return []interface{}{&linker.Properties, &linker.dynamicProperties} 233} 234 235func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { 236 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...) 237 deps.HeaderLibs = append(deps.HeaderLibs, linker.Properties.Header_libs...) 238 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...) 239 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...) 240 deps.RuntimeLibs = append(deps.RuntimeLibs, linker.Properties.Runtime_libs...) 241 242 deps.ReexportHeaderLibHeaders = append(deps.ReexportHeaderLibHeaders, linker.Properties.Export_header_lib_headers...) 243 deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, linker.Properties.Export_static_lib_headers...) 244 deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, linker.Properties.Export_shared_lib_headers...) 245 deps.ReexportGeneratedHeaders = append(deps.ReexportGeneratedHeaders, linker.Properties.Export_generated_headers...) 246 247 deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Exclude_shared_libs) 248 deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Exclude_static_libs) 249 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Exclude_static_libs) 250 251 // Record the libraries that need to be excluded when building for APEX. Unlike other 252 // target.*.exclude_* properties, SharedLibs and StaticLibs are not modified here because 253 // this module hasn't yet passed the apexMutator. Therefore, we can't tell whether this is 254 // an apex variant of not. Record the exclude list in the deps struct for now. The info is 255 // used to mark the dependency tag when adding dependencies to the deps. Then inside 256 // GenerateAndroidBuildActions, the marked dependencies are ignored (i.e. not used) for APEX 257 // variants. 258 deps.ExcludeLibsForApex = append(deps.ExcludeLibsForApex, linker.Properties.Target.Apex.Exclude_shared_libs...) 259 deps.ExcludeLibsForApex = append(deps.ExcludeLibsForApex, linker.Properties.Target.Apex.Exclude_static_libs...) 260 261 if Bool(linker.Properties.Use_version_lib) { 262 deps.WholeStaticLibs = append(deps.WholeStaticLibs, "libbuildversion") 263 } 264 265 if ctx.inVendor() { 266 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Vendor.Shared_libs...) 267 deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Vendor.Exclude_shared_libs) 268 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Vendor.Exclude_shared_libs) 269 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Target.Vendor.Static_libs...) 270 deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs) 271 deps.HeaderLibs = removeListFromList(deps.HeaderLibs, linker.Properties.Target.Vendor.Exclude_header_libs) 272 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor.Exclude_static_libs) 273 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs) 274 deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Vendor.Exclude_runtime_libs) 275 } 276 277 if ctx.inProduct() { 278 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Product.Shared_libs...) 279 deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Product.Exclude_shared_libs) 280 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Product.Exclude_shared_libs) 281 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Target.Product.Static_libs...) 282 deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Product.Exclude_static_libs) 283 deps.HeaderLibs = removeListFromList(deps.HeaderLibs, linker.Properties.Target.Product.Exclude_header_libs) 284 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Product.Exclude_static_libs) 285 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Product.Exclude_static_libs) 286 deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Product.Exclude_runtime_libs) 287 } 288 289 if ctx.inRecovery() { 290 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Recovery.Shared_libs...) 291 deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Recovery.Exclude_shared_libs) 292 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Recovery.Exclude_shared_libs) 293 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Target.Recovery.Static_libs...) 294 deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs) 295 deps.HeaderLibs = removeListFromList(deps.HeaderLibs, linker.Properties.Target.Recovery.Exclude_header_libs) 296 deps.ReexportHeaderLibHeaders = removeListFromList(deps.ReexportHeaderLibHeaders, linker.Properties.Target.Recovery.Exclude_header_libs) 297 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Recovery.Exclude_static_libs) 298 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs) 299 } 300 301 if ctx.inRamdisk() { 302 deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Ramdisk.Exclude_shared_libs) 303 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Ramdisk.Exclude_shared_libs) 304 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Target.Ramdisk.Static_libs...) 305 deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Ramdisk.Exclude_static_libs) 306 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Ramdisk.Exclude_static_libs) 307 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Ramdisk.Exclude_static_libs) 308 } 309 310 if ctx.inVendorRamdisk() { 311 deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs) 312 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs) 313 deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Vendor_ramdisk.Exclude_static_libs) 314 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor_ramdisk.Exclude_static_libs) 315 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor_ramdisk.Exclude_static_libs) 316 } 317 318 if !ctx.useSdk() { 319 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Platform.Shared_libs...) 320 } 321 322 if ctx.toolchain().Bionic() { 323 // libclang_rt.builtins has to be last on the command line 324 if !Bool(linker.Properties.No_libcrt) && !ctx.header() { 325 deps.LateStaticLibs = append(deps.LateStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain())) 326 } 327 328 deps.SystemSharedLibs = linker.Properties.System_shared_libs 329 // In Bazel conversion mode, variations have not been specified, so SystemSharedLibs may 330 // inaccuarately appear unset, which can cause issues with circular dependencies. 331 if deps.SystemSharedLibs == nil && !ctx.BazelConversionMode() { 332 // Provide a default system_shared_libs if it is unspecified. Note: If an 333 // empty list [] is specified, it implies that the module declines the 334 // default system_shared_libs. 335 deps.SystemSharedLibs = []string{"libc", "libm", "libdl"} 336 } 337 338 if inList("libdl", deps.SharedLibs) { 339 // If system_shared_libs has libc but not libdl, make sure shared_libs does not 340 // have libdl to avoid loading libdl before libc. 341 if inList("libc", deps.SystemSharedLibs) { 342 if !inList("libdl", deps.SystemSharedLibs) { 343 ctx.PropertyErrorf("shared_libs", 344 "libdl must be in system_shared_libs, not shared_libs") 345 } 346 _, deps.SharedLibs = removeFromList("libdl", deps.SharedLibs) 347 } 348 } 349 350 // If libc and libdl are both in system_shared_libs make sure libdl comes after libc 351 // to avoid loading libdl before libc. 352 if inList("libdl", deps.SystemSharedLibs) && inList("libc", deps.SystemSharedLibs) && 353 indexList("libdl", deps.SystemSharedLibs) < indexList("libc", deps.SystemSharedLibs) { 354 ctx.PropertyErrorf("system_shared_libs", "libdl must be after libc") 355 } 356 357 deps.LateSharedLibs = append(deps.LateSharedLibs, deps.SystemSharedLibs...) 358 } 359 360 if ctx.Fuchsia() { 361 if ctx.ModuleName() != "libbioniccompat" && 362 ctx.ModuleName() != "libcompiler_rt-extras" && 363 ctx.ModuleName() != "libcompiler_rt" { 364 deps.StaticLibs = append(deps.StaticLibs, "libbioniccompat") 365 } 366 if ctx.ModuleName() != "libcompiler_rt" && ctx.ModuleName() != "libcompiler_rt-extras" { 367 deps.LateStaticLibs = append(deps.LateStaticLibs, "libcompiler_rt") 368 } 369 370 } 371 372 if ctx.Windows() { 373 deps.LateStaticLibs = append(deps.LateStaticLibs, "libwinpthread") 374 } 375 376 return deps 377} 378 379func (linker *baseLinker) useClangLld(ctx ModuleContext) bool { 380 // Clang lld is not ready for for Darwin host executables yet. 381 // See https://lld.llvm.org/AtomLLD.html for status of lld for Mach-O. 382 if ctx.Darwin() { 383 return false 384 } 385 if linker.Properties.Use_clang_lld != nil { 386 return Bool(linker.Properties.Use_clang_lld) 387 } 388 return true 389} 390 391// Check whether the SDK version is not older than the specific one 392func CheckSdkVersionAtLeast(ctx ModuleContext, SdkVersion android.ApiLevel) bool { 393 if ctx.minSdkVersion() == "current" { 394 return true 395 } 396 parsedSdkVersion, err := nativeApiLevelFromUser(ctx, ctx.minSdkVersion()) 397 if err != nil { 398 ctx.PropertyErrorf("min_sdk_version", 399 "Invalid min_sdk_version value (must be int or current): %q", 400 ctx.minSdkVersion()) 401 } 402 if parsedSdkVersion.LessThan(SdkVersion) { 403 return false 404 } 405 return true 406} 407 408// ModuleContext extends BaseModuleContext 409// BaseModuleContext should know if LLD is used? 410func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { 411 toolchain := ctx.toolchain() 412 413 hod := "Host" 414 if ctx.Os().Class == android.Device { 415 hod = "Device" 416 } 417 418 if linker.useClangLld(ctx) { 419 flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod)) 420 if !BoolDefault(linker.Properties.Pack_relocations, true) { 421 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=none") 422 } else if ctx.Device() { 423 // SHT_RELR relocations are only supported at API level >= 30. 424 // ANDROID_RELR relocations were supported at API level >= 28. 425 // Relocation packer was supported at API level >= 23. 426 // Do the best we can... 427 if (!ctx.useSdk() && ctx.minSdkVersion() == "") || CheckSdkVersionAtLeast(ctx, android.FirstShtRelrVersion) { 428 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=android+relr") 429 } else if CheckSdkVersionAtLeast(ctx, android.FirstAndroidRelrVersion) { 430 flags.Global.LdFlags = append(flags.Global.LdFlags, 431 "-Wl,--pack-dyn-relocs=android+relr", 432 "-Wl,--use-android-relr-tags") 433 } else if CheckSdkVersionAtLeast(ctx, android.FirstPackedRelocationsVersion) { 434 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=android") 435 } 436 } 437 } else { 438 flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLdflags}", hod)) 439 } 440 if Bool(linker.Properties.Allow_undefined_symbols) { 441 if ctx.Darwin() { 442 // darwin defaults to treating undefined symbols as errors 443 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-undefined,dynamic_lookup") 444 } 445 } else if !ctx.Darwin() && !ctx.Windows() { 446 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--no-undefined") 447 } 448 449 if linker.useClangLld(ctx) { 450 flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ClangLldflags()) 451 } else { 452 flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ClangLdflags()) 453 } 454 455 if !ctx.toolchain().Bionic() && !ctx.Fuchsia() { 456 CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs) 457 458 flags.Local.LdFlags = append(flags.Local.LdFlags, linker.Properties.Host_ldlibs...) 459 460 if !ctx.Windows() { 461 // Add -ldl, -lpthread, -lm and -lrt to host builds to match the default behavior of device 462 // builds 463 flags.Global.LdFlags = append(flags.Global.LdFlags, 464 "-ldl", 465 "-lpthread", 466 "-lm", 467 ) 468 if !ctx.Darwin() { 469 flags.Global.LdFlags = append(flags.Global.LdFlags, "-lrt") 470 } 471 } 472 } 473 474 if ctx.Fuchsia() { 475 flags.Global.LdFlags = append(flags.Global.LdFlags, "-lfdio", "-lzircon") 476 } 477 478 if ctx.toolchain().LibclangRuntimeLibraryArch() != "" { 479 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--exclude-libs="+config.BuiltinsRuntimeLibrary(ctx.toolchain())+".a") 480 } 481 482 CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags) 483 484 flags.Local.LdFlags = append(flags.Local.LdFlags, proptools.NinjaAndShellEscapeList(linker.Properties.Ldflags)...) 485 486 if ctx.Host() && !ctx.Windows() { 487 rpathPrefix := `\$$ORIGIN/` 488 if ctx.Darwin() { 489 rpathPrefix = "@loader_path/" 490 } 491 492 if !ctx.static() { 493 for _, rpath := range linker.dynamicProperties.RunPaths { 494 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-rpath,"+rpathPrefix+rpath) 495 } 496 } 497 } 498 499 if ctx.useSdk() { 500 // The bionic linker now has support gnu style hashes (which are much faster!), but shipping 501 // to older devices requires the old style hash. Fortunately, we can build with both and 502 // it'll work anywhere. 503 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--hash-style=both") 504 } 505 506 flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainClangLdflags()) 507 508 if Bool(linker.Properties.Group_static_libs) { 509 flags.GroupStaticLibs = true 510 } 511 512 // Version_script is not needed when linking stubs lib where the version 513 // script is created from the symbol map file. 514 if !linker.dynamicProperties.BuildStubs { 515 versionScript := ctx.ExpandOptionalSource( 516 linker.Properties.Version_script, "version_script") 517 518 if ctx.inVendor() && linker.Properties.Target.Vendor.Version_script != nil { 519 versionScript = ctx.ExpandOptionalSource( 520 linker.Properties.Target.Vendor.Version_script, 521 "target.vendor.version_script") 522 } else if ctx.inProduct() && linker.Properties.Target.Product.Version_script != nil { 523 versionScript = ctx.ExpandOptionalSource( 524 linker.Properties.Target.Product.Version_script, 525 "target.product.version_script") 526 } 527 528 if versionScript.Valid() { 529 if ctx.Darwin() { 530 ctx.PropertyErrorf("version_script", "Not supported on Darwin") 531 } else { 532 flags.Local.LdFlags = append(flags.Local.LdFlags, 533 "-Wl,--version-script,"+versionScript.String()) 534 flags.LdFlagsDeps = append(flags.LdFlagsDeps, versionScript.Path()) 535 536 if linker.sanitize.isSanitizerEnabled(cfi) { 537 cfiExportsMap := android.PathForSource(ctx, cfiExportsMapPath) 538 flags.Local.LdFlags = append(flags.Local.LdFlags, 539 "-Wl,--version-script,"+cfiExportsMap.String()) 540 flags.LdFlagsDeps = append(flags.LdFlagsDeps, cfiExportsMap) 541 } 542 } 543 } 544 } 545 546 return flags 547} 548 549func (linker *baseLinker) link(ctx ModuleContext, 550 flags Flags, deps PathDeps, objs Objects) android.Path { 551 panic(fmt.Errorf("baseLinker doesn't know how to link")) 552} 553 554func (linker *baseLinker) linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps { 555 specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, linker.Properties.Shared_libs...) 556 557 // Must distinguish nil and [] in system_shared_libs - ensure that [] in 558 // either input list doesn't come out as nil. 559 if specifiedDeps.systemSharedLibs == nil { 560 specifiedDeps.systemSharedLibs = linker.Properties.System_shared_libs 561 } else { 562 specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, linker.Properties.System_shared_libs...) 563 } 564 565 return specifiedDeps 566} 567 568// Injecting version symbols 569// Some host modules want a version number, but we don't want to rebuild it every time. Optionally add a step 570// after linking that injects a constant placeholder with the current version number. 571 572func init() { 573 pctx.HostBinToolVariable("symbolInjectCmd", "symbol_inject") 574} 575 576var injectVersionSymbol = pctx.AndroidStaticRule("injectVersionSymbol", 577 blueprint.RuleParams{ 578 Command: "$symbolInjectCmd -i $in -o $out -s soong_build_number " + 579 "-from 'SOONG BUILD NUMBER PLACEHOLDER' -v $$(cat $buildNumberFile)", 580 CommandDeps: []string{"$symbolInjectCmd"}, 581 }, 582 "buildNumberFile") 583 584func (linker *baseLinker) injectVersionSymbol(ctx ModuleContext, in android.Path, out android.WritablePath) { 585 buildNumberFile := ctx.Config().BuildNumberFile(ctx) 586 ctx.Build(pctx, android.BuildParams{ 587 Rule: injectVersionSymbol, 588 Description: "inject version symbol", 589 Input: in, 590 Output: out, 591 OrderOnly: android.Paths{buildNumberFile}, 592 Args: map[string]string{ 593 "buildNumberFile": buildNumberFile.String(), 594 }, 595 }) 596} 597 598// Rule to generate .bss symbol ordering file. 599 600var ( 601 _ = pctx.SourcePathVariable("genSortedBssSymbolsPath", "build/soong/scripts/gen_sorted_bss_symbols.sh") 602 genSortedBssSymbols = pctx.AndroidStaticRule("gen_sorted_bss_symbols", 603 blueprint.RuleParams{ 604 Command: "CLANG_BIN=${clangBin} $genSortedBssSymbolsPath ${in} ${out}", 605 CommandDeps: []string{"$genSortedBssSymbolsPath", "${clangBin}/llvm-nm"}, 606 }, 607 "clangBin") 608) 609 610func (linker *baseLinker) sortBssSymbolsBySize(ctx ModuleContext, in android.Path, symbolOrderingFile android.ModuleOutPath, flags builderFlags) string { 611 ctx.Build(pctx, android.BuildParams{ 612 Rule: genSortedBssSymbols, 613 Description: "generate bss symbol order " + symbolOrderingFile.Base(), 614 Output: symbolOrderingFile, 615 Input: in, 616 Args: map[string]string{ 617 "clangBin": "${config.ClangBin}", 618 }, 619 }) 620 return "-Wl,--symbol-ordering-file," + symbolOrderingFile.String() 621} 622