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