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