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