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