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