1// Copyright 2016 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package cc 16 17import ( 18 "android/soong/android" 19 "android/soong/cc/config" 20 "fmt" 21 "strconv" 22 23 "github.com/google/blueprint" 24 "github.com/google/blueprint/proptools" 25) 26 27// This file contains the basic functionality for linking against static libraries and shared 28// libraries. Final linking into libraries or executables is handled in library.go, binary.go, etc. 29 30type BaseLinkerProperties struct { 31 // list of modules whose object files should be linked into this module 32 // in their entirety. For static library modules, all of the .o files from the intermediate 33 // directory of the dependency will be linked into this modules .a file. For a shared library, 34 // the dependency's .a file will be linked into this module using -Wl,--whole-archive. 35 Whole_static_libs []string `android:"arch_variant,variant_prepend"` 36 37 // list of modules that should be statically linked into this module. 38 Static_libs []string `android:"arch_variant,variant_prepend"` 39 40 // list of modules that should be dynamically linked into this module. 41 Shared_libs []string `android:"arch_variant"` 42 43 // list of modules that should only provide headers for this module. 44 Header_libs []string `android:"arch_variant,variant_prepend"` 45 46 // list of module-specific flags that will be used for all link steps 47 Ldflags []string `android:"arch_variant"` 48 49 // list of system libraries that will be dynamically linked to 50 // shared library and executable modules. If unset, generally defaults to libc, 51 // libm, and libdl. Set to [] to prevent linking against the defaults. 52 System_shared_libs []string `android:"arch_variant"` 53 54 // allow the module to contain undefined symbols. By default, 55 // modules cannot contain undefined symbols that are not satisified by their immediate 56 // dependencies. Set this flag to true to remove --no-undefined from the linker flags. 57 // This flag should only be necessary for compiling low-level libraries like libc. 58 Allow_undefined_symbols *bool `android:"arch_variant"` 59 60 // don't link in libclang_rt.builtins-*.a 61 No_libcrt *bool `android:"arch_variant"` 62 63 // Use clang lld instead of gnu ld. 64 Use_clang_lld *bool `android:"arch_variant"` 65 66 // -l arguments to pass to linker for host-provided shared libraries 67 Host_ldlibs []string `android:"arch_variant"` 68 69 // list of shared libraries to re-export include directories from. Entries must be 70 // present in shared_libs. 71 Export_shared_lib_headers []string `android:"arch_variant"` 72 73 // list of static libraries to re-export include directories from. Entries must be 74 // present in static_libs. 75 Export_static_lib_headers []string `android:"arch_variant"` 76 77 // list of header libraries to re-export include directories from. Entries must be 78 // present in header_libs. 79 Export_header_lib_headers []string `android:"arch_variant"` 80 81 // list of generated headers to re-export include directories from. Entries must be 82 // present in generated_headers. 83 Export_generated_headers []string `android:"arch_variant"` 84 85 // don't link in crt_begin and crt_end. This flag should only be necessary for 86 // compiling crt or libc. 87 Nocrt *bool `android:"arch_variant"` 88 89 // group static libraries. This can resolve missing symbols issues with interdependencies 90 // between static libraries, but it is generally better to order them correctly instead. 91 Group_static_libs *bool `android:"arch_variant"` 92 93 // list of modules that should be installed with this module. This is similar to 'required' 94 // but '.vendor' suffix will be appended to the module names if the shared libraries have 95 // vendor variants and this module uses VNDK. 96 Runtime_libs []string `android:"arch_variant"` 97 98 Target struct { 99 Vendor struct { 100 // list of shared libs that only should be used to build the vendor 101 // variant of the C/C++ module. 102 Shared_libs []string 103 104 // list of static libs that only should be used to build the vendor 105 // variant of the C/C++ module. 106 Static_libs []string 107 108 // list of shared libs that should not be used to build the vendor variant 109 // of the C/C++ module. 110 Exclude_shared_libs []string 111 112 // list of static libs that should not be used to build the vendor variant 113 // of the C/C++ module. 114 Exclude_static_libs []string 115 116 // list of header libs that should not be used to build the vendor variant 117 // of the C/C++ module. 118 Exclude_header_libs []string 119 120 // list of runtime libs that should not be installed along with the vendor 121 // variant of the C/C++ module. 122 Exclude_runtime_libs []string 123 124 // version script for this vendor variant 125 Version_script *string `android:"arch_variant"` 126 } 127 Recovery struct { 128 // list of shared libs that only should be used to build the recovery 129 // variant of the C/C++ module. 130 Shared_libs []string 131 132 // list of static libs that only should be used to build the recovery 133 // variant of the C/C++ module. 134 Static_libs []string 135 136 // list of shared libs that should not be used to build 137 // the recovery variant of the C/C++ module. 138 Exclude_shared_libs []string 139 140 // list of static libs that should not be used to build 141 // the recovery variant of the C/C++ module. 142 Exclude_static_libs []string 143 144 // list of header libs that should not be used to build the recovery variant 145 // of the C/C++ module. 146 Exclude_header_libs []string 147 } 148 Ramdisk struct { 149 // list of static libs that only should be used to build the recovery 150 // variant of the C/C++ module. 151 Static_libs []string 152 153 // list of shared libs that should not be used to build 154 // the ramdisk variant of the C/C++ module. 155 Exclude_shared_libs []string 156 157 // list of static libs that should not be used to build 158 // the ramdisk variant of the C/C++ module. 159 Exclude_static_libs []string 160 } 161 Platform struct { 162 // list of shared libs that should be use to build the platform variant 163 // of a module that sets sdk_version. This should rarely be necessary, 164 // in most cases the same libraries are available for the SDK and platform 165 // variants. 166 Shared_libs []string 167 } 168 } 169 170 // make android::build:GetBuildNumber() available containing the build ID. 171 Use_version_lib *bool `android:"arch_variant"` 172 173 // Generate compact dynamic relocation table, default true. 174 Pack_relocations *bool `android:"arch_variant"` 175 176 // local file name to pass to the linker as --version_script 177 Version_script *string `android:"path,arch_variant"` 178 179 // list of static libs that should not be used to build this module 180 Exclude_static_libs []string `android:"arch_variant"` 181 182 // list of shared libs that should not be used to build this module 183 Exclude_shared_libs []string `android:"arch_variant"` 184} 185 186func NewBaseLinker(sanitize *sanitize) *baseLinker { 187 return &baseLinker{sanitize: sanitize} 188} 189 190// baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties 191type baseLinker struct { 192 Properties BaseLinkerProperties 193 dynamicProperties struct { 194 RunPaths []string `blueprint:"mutated"` 195 BuildStubs bool `blueprint:"mutated"` 196 } 197 198 sanitize *sanitize 199} 200 201func (linker *baseLinker) appendLdflags(flags []string) { 202 linker.Properties.Ldflags = append(linker.Properties.Ldflags, flags...) 203} 204 205func (linker *baseLinker) linkerInit(ctx BaseModuleContext) { 206 if ctx.toolchain().Is64Bit() { 207 linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, "../lib64", "lib64") 208 } else { 209 linker.dynamicProperties.RunPaths = append(linker.dynamicProperties.RunPaths, "../lib", "lib") 210 } 211} 212 213func (linker *baseLinker) linkerProps() []interface{} { 214 return []interface{}{&linker.Properties, &linker.dynamicProperties} 215} 216 217func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { 218 deps.WholeStaticLibs = append(deps.WholeStaticLibs, linker.Properties.Whole_static_libs...) 219 deps.HeaderLibs = append(deps.HeaderLibs, linker.Properties.Header_libs...) 220 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Static_libs...) 221 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Shared_libs...) 222 deps.RuntimeLibs = append(deps.RuntimeLibs, linker.Properties.Runtime_libs...) 223 224 deps.ReexportHeaderLibHeaders = append(deps.ReexportHeaderLibHeaders, linker.Properties.Export_header_lib_headers...) 225 deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, linker.Properties.Export_static_lib_headers...) 226 deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, linker.Properties.Export_shared_lib_headers...) 227 deps.ReexportGeneratedHeaders = append(deps.ReexportGeneratedHeaders, linker.Properties.Export_generated_headers...) 228 229 deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Exclude_shared_libs) 230 deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Exclude_static_libs) 231 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Exclude_static_libs) 232 233 if Bool(linker.Properties.Use_version_lib) { 234 deps.WholeStaticLibs = append(deps.WholeStaticLibs, "libbuildversion") 235 } 236 237 if ctx.useVndk() { 238 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Vendor.Shared_libs...) 239 deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Vendor.Exclude_shared_libs) 240 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Vendor.Exclude_shared_libs) 241 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Target.Vendor.Static_libs...) 242 deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs) 243 deps.HeaderLibs = removeListFromList(deps.HeaderLibs, linker.Properties.Target.Vendor.Exclude_header_libs) 244 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor.Exclude_static_libs) 245 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs) 246 deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Vendor.Exclude_runtime_libs) 247 } 248 249 if ctx.inRecovery() { 250 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Recovery.Shared_libs...) 251 deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Recovery.Exclude_shared_libs) 252 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Recovery.Exclude_shared_libs) 253 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Target.Recovery.Static_libs...) 254 deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs) 255 deps.HeaderLibs = removeListFromList(deps.HeaderLibs, linker.Properties.Target.Recovery.Exclude_header_libs) 256 deps.ReexportHeaderLibHeaders = removeListFromList(deps.ReexportHeaderLibHeaders, linker.Properties.Target.Recovery.Exclude_header_libs) 257 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Recovery.Exclude_static_libs) 258 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs) 259 } 260 261 if ctx.inRamdisk() { 262 deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Recovery.Exclude_shared_libs) 263 deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Recovery.Exclude_shared_libs) 264 deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Target.Recovery.Static_libs...) 265 deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs) 266 deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Recovery.Exclude_static_libs) 267 deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs) 268 } 269 270 if !ctx.useSdk() { 271 deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Platform.Shared_libs...) 272 } 273 274 if ctx.toolchain().Bionic() { 275 // libclang_rt.builtins and libatomic have to be last on the command line 276 if !Bool(linker.Properties.No_libcrt) { 277 deps.LateStaticLibs = append(deps.LateStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain())) 278 deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic") 279 } 280 281 systemSharedLibs := linker.Properties.System_shared_libs 282 if systemSharedLibs == nil { 283 // Provide a default system_shared_libs if it is unspecified. Note: If an 284 // empty list [] is specified, it implies that the module declines the 285 // default system_shared_libs. 286 systemSharedLibs = []string{"libc", "libm", "libdl"} 287 } 288 289 if inList("libdl", deps.SharedLibs) { 290 // If system_shared_libs has libc but not libdl, make sure shared_libs does not 291 // have libdl to avoid loading libdl before libc. 292 if inList("libc", systemSharedLibs) { 293 if !inList("libdl", systemSharedLibs) { 294 ctx.PropertyErrorf("shared_libs", 295 "libdl must be in system_shared_libs, not shared_libs") 296 } 297 _, deps.SharedLibs = removeFromList("libdl", deps.SharedLibs) 298 } 299 } 300 301 // If libc and libdl are both in system_shared_libs make sure libdl comes after libc 302 // to avoid loading libdl before libc. 303 if inList("libdl", systemSharedLibs) && inList("libc", systemSharedLibs) && 304 indexList("libdl", systemSharedLibs) < indexList("libc", systemSharedLibs) { 305 ctx.PropertyErrorf("system_shared_libs", "libdl must be after libc") 306 } 307 308 deps.LateSharedLibs = append(deps.LateSharedLibs, systemSharedLibs...) 309 } 310 311 if ctx.Fuchsia() { 312 if ctx.ModuleName() != "libbioniccompat" && 313 ctx.ModuleName() != "libcompiler_rt-extras" && 314 ctx.ModuleName() != "libcompiler_rt" { 315 deps.StaticLibs = append(deps.StaticLibs, "libbioniccompat") 316 } 317 if ctx.ModuleName() != "libcompiler_rt" && ctx.ModuleName() != "libcompiler_rt-extras" { 318 deps.LateStaticLibs = append(deps.LateStaticLibs, "libcompiler_rt") 319 } 320 321 } 322 323 if ctx.Windows() { 324 deps.LateStaticLibs = append(deps.LateStaticLibs, "libwinpthread") 325 } 326 327 return deps 328} 329 330func (linker *baseLinker) useClangLld(ctx ModuleContext) bool { 331 // Clang lld is not ready for for Darwin host executables yet. 332 // See https://lld.llvm.org/AtomLLD.html for status of lld for Mach-O. 333 if ctx.Darwin() { 334 return false 335 } 336 if linker.Properties.Use_clang_lld != nil { 337 return Bool(linker.Properties.Use_clang_lld) 338 } 339 return true 340} 341 342// Check whether the SDK version is not older than the specific one 343func CheckSdkVersionAtLeast(ctx ModuleContext, SdkVersion int) bool { 344 if ctx.sdkVersion() == "current" { 345 return true 346 } 347 parsedSdkVersion, err := strconv.Atoi(ctx.sdkVersion()) 348 if err != nil { 349 ctx.PropertyErrorf("sdk_version", 350 "Invalid sdk_version value (must be int or current): %q", 351 ctx.sdkVersion()) 352 } 353 if parsedSdkVersion < SdkVersion { 354 return false 355 } 356 return true 357} 358 359// ModuleContext extends BaseModuleContext 360// BaseModuleContext should know if LLD is used? 361func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { 362 toolchain := ctx.toolchain() 363 364 hod := "Host" 365 if ctx.Os().Class == android.Device { 366 hod = "Device" 367 } 368 369 if linker.useClangLld(ctx) { 370 flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod)) 371 if !BoolDefault(linker.Properties.Pack_relocations, true) { 372 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=none") 373 } else if ctx.Device() { 374 // The SHT_RELR relocations is only supported by API level >= 28. 375 // Do not turn this on if older version NDK is used. 376 if !ctx.useSdk() || CheckSdkVersionAtLeast(ctx, 28) { 377 flags.Global.LdFlags = append(flags.Global.LdFlags, 378 "-Wl,--pack-dyn-relocs=android+relr", 379 "-Wl,--use-android-relr-tags") 380 } else if CheckSdkVersionAtLeast(ctx, 23) { 381 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=android") 382 } 383 } 384 } else { 385 flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLdflags}", hod)) 386 } 387 if Bool(linker.Properties.Allow_undefined_symbols) { 388 if ctx.Darwin() { 389 // darwin defaults to treating undefined symbols as errors 390 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-undefined,dynamic_lookup") 391 } 392 } else if !ctx.Darwin() && !ctx.Windows() { 393 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--no-undefined") 394 } 395 396 if linker.useClangLld(ctx) { 397 flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ClangLldflags()) 398 } else { 399 flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ClangLdflags()) 400 } 401 402 if !ctx.toolchain().Bionic() && !ctx.Fuchsia() { 403 CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs) 404 405 flags.Local.LdFlags = append(flags.Local.LdFlags, linker.Properties.Host_ldlibs...) 406 407 if !ctx.Windows() { 408 // Add -ldl, -lpthread, -lm and -lrt to host builds to match the default behavior of device 409 // builds 410 flags.Global.LdFlags = append(flags.Global.LdFlags, 411 "-ldl", 412 "-lpthread", 413 "-lm", 414 ) 415 if !ctx.Darwin() { 416 flags.Global.LdFlags = append(flags.Global.LdFlags, "-lrt") 417 } 418 } 419 } 420 421 if ctx.Fuchsia() { 422 flags.Global.LdFlags = append(flags.Global.LdFlags, "-lfdio", "-lzircon") 423 } 424 425 if ctx.toolchain().LibclangRuntimeLibraryArch() != "" { 426 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--exclude-libs="+config.BuiltinsRuntimeLibrary(ctx.toolchain())+".a") 427 } 428 429 CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags) 430 431 flags.Local.LdFlags = append(flags.Local.LdFlags, proptools.NinjaAndShellEscapeList(linker.Properties.Ldflags)...) 432 433 if ctx.Host() && !ctx.Windows() { 434 rpath_prefix := `\$$ORIGIN/` 435 if ctx.Darwin() { 436 rpath_prefix = "@loader_path/" 437 } 438 439 if !ctx.static() { 440 for _, rpath := range linker.dynamicProperties.RunPaths { 441 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath) 442 } 443 } 444 } 445 446 if ctx.useSdk() { 447 // The bionic linker now has support gnu style hashes (which are much faster!), but shipping 448 // to older devices requires the old style hash. Fortunately, we can build with both and 449 // it'll work anywhere. 450 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--hash-style=both") 451 } 452 453 flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainClangLdflags()) 454 455 if Bool(linker.Properties.Group_static_libs) { 456 flags.GroupStaticLibs = true 457 } 458 459 // Version_script is not needed when linking stubs lib where the version 460 // script is created from the symbol map file. 461 if !linker.dynamicProperties.BuildStubs { 462 versionScript := ctx.ExpandOptionalSource( 463 linker.Properties.Version_script, "version_script") 464 465 if ctx.useVndk() && linker.Properties.Target.Vendor.Version_script != nil { 466 versionScript = ctx.ExpandOptionalSource( 467 linker.Properties.Target.Vendor.Version_script, 468 "target.vendor.version_script") 469 } 470 471 if versionScript.Valid() { 472 if ctx.Darwin() { 473 ctx.PropertyErrorf("version_script", "Not supported on Darwin") 474 } else { 475 flags.Local.LdFlags = append(flags.Local.LdFlags, 476 "-Wl,--version-script,"+versionScript.String()) 477 flags.LdFlagsDeps = append(flags.LdFlagsDeps, versionScript.Path()) 478 479 if linker.sanitize.isSanitizerEnabled(cfi) { 480 cfiExportsMap := android.PathForSource(ctx, cfiExportsMapPath) 481 flags.Local.LdFlags = append(flags.Local.LdFlags, 482 "-Wl,--version-script,"+cfiExportsMap.String()) 483 flags.LdFlagsDeps = append(flags.LdFlagsDeps, cfiExportsMap) 484 } 485 } 486 } 487 } 488 489 return flags 490} 491 492func (linker *baseLinker) link(ctx ModuleContext, 493 flags Flags, deps PathDeps, objs Objects) android.Path { 494 panic(fmt.Errorf("baseLinker doesn't know how to link")) 495} 496 497func (linker *baseLinker) linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps { 498 specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, linker.Properties.Shared_libs...) 499 500 // Must distinguish nil and [] in system_shared_libs - ensure that [] in 501 // either input list doesn't come out as nil. 502 if specifiedDeps.systemSharedLibs == nil { 503 specifiedDeps.systemSharedLibs = linker.Properties.System_shared_libs 504 } else { 505 specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, linker.Properties.System_shared_libs...) 506 } 507 508 return specifiedDeps 509} 510 511// Injecting version symbols 512// Some host modules want a version number, but we don't want to rebuild it every time. Optionally add a step 513// after linking that injects a constant placeholder with the current version number. 514 515func init() { 516 pctx.HostBinToolVariable("symbolInjectCmd", "symbol_inject") 517} 518 519var injectVersionSymbol = pctx.AndroidStaticRule("injectVersionSymbol", 520 blueprint.RuleParams{ 521 Command: "$symbolInjectCmd -i $in -o $out -s soong_build_number " + 522 "-from 'SOONG BUILD NUMBER PLACEHOLDER' -v $$(cat $buildNumberFile)", 523 CommandDeps: []string{"$symbolInjectCmd"}, 524 }, 525 "buildNumberFile") 526 527func (linker *baseLinker) injectVersionSymbol(ctx ModuleContext, in android.Path, out android.WritablePath) { 528 buildNumberFile := ctx.Config().BuildNumberFile(ctx) 529 ctx.Build(pctx, android.BuildParams{ 530 Rule: injectVersionSymbol, 531 Description: "inject version symbol", 532 Input: in, 533 Output: out, 534 OrderOnly: android.Paths{buildNumberFile}, 535 Args: map[string]string{ 536 "buildNumberFile": buildNumberFile.String(), 537 }, 538 }) 539} 540 541// Rule to generate .bss symbol ordering file. 542 543var ( 544 _ = pctx.SourcePathVariable("genSortedBssSymbolsPath", "build/soong/scripts/gen_sorted_bss_symbols.sh") 545 gen_sorted_bss_symbols = pctx.AndroidStaticRule("gen_sorted_bss_symbols", 546 blueprint.RuleParams{ 547 Command: "CROSS_COMPILE=$crossCompile $genSortedBssSymbolsPath ${in} ${out}", 548 CommandDeps: []string{"$genSortedBssSymbolsPath", "${crossCompile}nm"}, 549 }, 550 "crossCompile") 551) 552 553func (linker *baseLinker) sortBssSymbolsBySize(ctx ModuleContext, in android.Path, symbolOrderingFile android.ModuleOutPath, flags builderFlags) string { 554 crossCompile := gccCmd(flags.toolchain, "") 555 ctx.Build(pctx, android.BuildParams{ 556 Rule: gen_sorted_bss_symbols, 557 Description: "generate bss symbol order " + symbolOrderingFile.Base(), 558 Output: symbolOrderingFile, 559 Input: in, 560 Args: map[string]string{ 561 "crossCompile": crossCompile, 562 }, 563 }) 564 return "-Wl,--symbol-ordering-file," + symbolOrderingFile.String() 565} 566