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 inList("libc_scudo", deps.SharedLibs) { 302 // libc_scudo is an alternate implementation of all 303 // allocation functions (malloc, free), that uses 304 // the scudo allocator instead of the default native 305 // allocator. If this library is in the list, make 306 // sure it's first so it properly overrides the 307 // allocation functions of all other shared libraries. 308 _, deps.SharedLibs = removeFromList("libc_scudo", deps.SharedLibs) 309 deps.SharedLibs = append([]string{"libc_scudo"}, deps.SharedLibs...) 310 } 311 312 // If libc and libdl are both in system_shared_libs make sure libdl comes after libc 313 // to avoid loading libdl before libc. 314 if inList("libdl", systemSharedLibs) && inList("libc", systemSharedLibs) && 315 indexList("libdl", systemSharedLibs) < indexList("libc", systemSharedLibs) { 316 ctx.PropertyErrorf("system_shared_libs", "libdl must be after libc") 317 } 318 319 deps.LateSharedLibs = append(deps.LateSharedLibs, systemSharedLibs...) 320 } 321 322 if ctx.Fuchsia() { 323 if ctx.ModuleName() != "libbioniccompat" && 324 ctx.ModuleName() != "libcompiler_rt-extras" && 325 ctx.ModuleName() != "libcompiler_rt" { 326 deps.StaticLibs = append(deps.StaticLibs, "libbioniccompat") 327 } 328 if ctx.ModuleName() != "libcompiler_rt" && ctx.ModuleName() != "libcompiler_rt-extras" { 329 deps.LateStaticLibs = append(deps.LateStaticLibs, "libcompiler_rt") 330 } 331 332 } 333 334 if ctx.Windows() { 335 deps.LateStaticLibs = append(deps.LateStaticLibs, "libwinpthread") 336 } 337 338 return deps 339} 340 341func (linker *baseLinker) useClangLld(ctx ModuleContext) bool { 342 // Clang lld is not ready for for Darwin host executables yet. 343 // See https://lld.llvm.org/AtomLLD.html for status of lld for Mach-O. 344 if ctx.Darwin() { 345 return false 346 } 347 if linker.Properties.Use_clang_lld != nil { 348 return Bool(linker.Properties.Use_clang_lld) 349 } 350 return true 351} 352 353// Check whether the SDK version is not older than the specific one 354func CheckSdkVersionAtLeast(ctx ModuleContext, SdkVersion int) bool { 355 if ctx.sdkVersion() == "current" { 356 return true 357 } 358 parsedSdkVersion, err := strconv.Atoi(ctx.sdkVersion()) 359 if err != nil { 360 ctx.PropertyErrorf("sdk_version", 361 "Invalid sdk_version value (must be int or current): %q", 362 ctx.sdkVersion()) 363 } 364 if parsedSdkVersion < SdkVersion { 365 return false 366 } 367 return true 368} 369 370// ModuleContext extends BaseModuleContext 371// BaseModuleContext should know if LLD is used? 372func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { 373 toolchain := ctx.toolchain() 374 375 hod := "Host" 376 if ctx.Os().Class == android.Device { 377 hod = "Device" 378 } 379 380 if linker.useClangLld(ctx) { 381 flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod)) 382 if !BoolDefault(linker.Properties.Pack_relocations, true) { 383 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=none") 384 } else if ctx.Device() { 385 // The SHT_RELR relocations is only supported by API level >= 28. 386 // Do not turn this on if older version NDK is used. 387 if !ctx.useSdk() || CheckSdkVersionAtLeast(ctx, 28) { 388 flags.Global.LdFlags = append(flags.Global.LdFlags, 389 "-Wl,--pack-dyn-relocs=android+relr", 390 "-Wl,--use-android-relr-tags") 391 } else if CheckSdkVersionAtLeast(ctx, 23) { 392 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=android") 393 } 394 } 395 } else { 396 flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLdflags}", hod)) 397 } 398 if Bool(linker.Properties.Allow_undefined_symbols) { 399 if ctx.Darwin() { 400 // darwin defaults to treating undefined symbols as errors 401 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-undefined,dynamic_lookup") 402 } 403 } else if !ctx.Darwin() && !ctx.Windows() { 404 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--no-undefined") 405 } 406 407 if linker.useClangLld(ctx) { 408 flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ClangLldflags()) 409 } else { 410 flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ClangLdflags()) 411 } 412 413 if !ctx.toolchain().Bionic() && !ctx.Fuchsia() { 414 CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs) 415 416 flags.Local.LdFlags = append(flags.Local.LdFlags, linker.Properties.Host_ldlibs...) 417 418 if !ctx.Windows() { 419 // Add -ldl, -lpthread, -lm and -lrt to host builds to match the default behavior of device 420 // builds 421 flags.Global.LdFlags = append(flags.Global.LdFlags, 422 "-ldl", 423 "-lpthread", 424 "-lm", 425 ) 426 if !ctx.Darwin() { 427 flags.Global.LdFlags = append(flags.Global.LdFlags, "-lrt") 428 } 429 } 430 } 431 432 if ctx.Fuchsia() { 433 flags.Global.LdFlags = append(flags.Global.LdFlags, "-lfdio", "-lzircon") 434 } 435 436 if ctx.toolchain().LibclangRuntimeLibraryArch() != "" { 437 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--exclude-libs="+config.BuiltinsRuntimeLibrary(ctx.toolchain())+".a") 438 } 439 440 CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags) 441 442 flags.Local.LdFlags = append(flags.Local.LdFlags, proptools.NinjaAndShellEscapeList(linker.Properties.Ldflags)...) 443 444 if ctx.Host() && !ctx.Windows() { 445 rpath_prefix := `\$$ORIGIN/` 446 if ctx.Darwin() { 447 rpath_prefix = "@loader_path/" 448 } 449 450 if !ctx.static() { 451 for _, rpath := range linker.dynamicProperties.RunPaths { 452 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-rpath,"+rpath_prefix+rpath) 453 } 454 } 455 } 456 457 if ctx.useSdk() && (ctx.Arch().ArchType != android.Mips && ctx.Arch().ArchType != android.Mips64) { 458 // The bionic linker now has support gnu style hashes (which are much faster!), but shipping 459 // to older devices requires the old style hash. Fortunately, we can build with both and 460 // it'll work anywhere. 461 // This is not currently supported on MIPS architectures. 462 flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--hash-style=both") 463 } 464 465 flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainClangLdflags()) 466 467 if Bool(linker.Properties.Group_static_libs) { 468 flags.GroupStaticLibs = true 469 } 470 471 // Version_script is not needed when linking stubs lib where the version 472 // script is created from the symbol map file. 473 if !linker.dynamicProperties.BuildStubs { 474 versionScript := ctx.ExpandOptionalSource( 475 linker.Properties.Version_script, "version_script") 476 477 if ctx.useVndk() && linker.Properties.Target.Vendor.Version_script != nil { 478 versionScript = ctx.ExpandOptionalSource( 479 linker.Properties.Target.Vendor.Version_script, 480 "target.vendor.version_script") 481 } 482 483 if versionScript.Valid() { 484 if ctx.Darwin() { 485 ctx.PropertyErrorf("version_script", "Not supported on Darwin") 486 } else { 487 flags.Local.LdFlags = append(flags.Local.LdFlags, 488 "-Wl,--version-script,"+versionScript.String()) 489 flags.LdFlagsDeps = append(flags.LdFlagsDeps, versionScript.Path()) 490 491 if linker.sanitize.isSanitizerEnabled(cfi) { 492 cfiExportsMap := android.PathForSource(ctx, cfiExportsMapPath) 493 flags.Local.LdFlags = append(flags.Local.LdFlags, 494 "-Wl,--version-script,"+cfiExportsMap.String()) 495 flags.LdFlagsDeps = append(flags.LdFlagsDeps, cfiExportsMap) 496 } 497 } 498 } 499 } 500 501 return flags 502} 503 504func (linker *baseLinker) link(ctx ModuleContext, 505 flags Flags, deps PathDeps, objs Objects) android.Path { 506 panic(fmt.Errorf("baseLinker doesn't know how to link")) 507} 508 509func (linker *baseLinker) linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps { 510 specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, linker.Properties.Shared_libs...) 511 512 // Must distinguish nil and [] in system_shared_libs - ensure that [] in 513 // either input list doesn't come out as nil. 514 if specifiedDeps.systemSharedLibs == nil { 515 specifiedDeps.systemSharedLibs = linker.Properties.System_shared_libs 516 } else { 517 specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, linker.Properties.System_shared_libs...) 518 } 519 520 return specifiedDeps 521} 522 523// Injecting version symbols 524// Some host modules want a version number, but we don't want to rebuild it every time. Optionally add a step 525// after linking that injects a constant placeholder with the current version number. 526 527func init() { 528 pctx.HostBinToolVariable("symbolInjectCmd", "symbol_inject") 529} 530 531var injectVersionSymbol = pctx.AndroidStaticRule("injectVersionSymbol", 532 blueprint.RuleParams{ 533 Command: "$symbolInjectCmd -i $in -o $out -s soong_build_number " + 534 "-from 'SOONG BUILD NUMBER PLACEHOLDER' -v $$(cat $buildNumberFile)", 535 CommandDeps: []string{"$symbolInjectCmd"}, 536 }, 537 "buildNumberFile") 538 539func (linker *baseLinker) injectVersionSymbol(ctx ModuleContext, in android.Path, out android.WritablePath) { 540 buildNumberFile := ctx.Config().BuildNumberFile(ctx) 541 ctx.Build(pctx, android.BuildParams{ 542 Rule: injectVersionSymbol, 543 Description: "inject version symbol", 544 Input: in, 545 Output: out, 546 OrderOnly: android.Paths{buildNumberFile}, 547 Args: map[string]string{ 548 "buildNumberFile": buildNumberFile.String(), 549 }, 550 }) 551} 552 553// Rule to generate .bss symbol ordering file. 554 555var ( 556 _ = pctx.SourcePathVariable("genSortedBssSymbolsPath", "build/soong/scripts/gen_sorted_bss_symbols.sh") 557 gen_sorted_bss_symbols = pctx.AndroidStaticRule("gen_sorted_bss_symbols", 558 blueprint.RuleParams{ 559 Command: "CROSS_COMPILE=$crossCompile $genSortedBssSymbolsPath ${in} ${out}", 560 CommandDeps: []string{"$genSortedBssSymbolsPath", "${crossCompile}nm"}, 561 }, 562 "crossCompile") 563) 564 565func (linker *baseLinker) sortBssSymbolsBySize(ctx ModuleContext, in android.Path, symbolOrderingFile android.ModuleOutPath, flags builderFlags) string { 566 crossCompile := gccCmd(flags.toolchain, "") 567 ctx.Build(pctx, android.BuildParams{ 568 Rule: gen_sorted_bss_symbols, 569 Description: "generate bss symbol order " + symbolOrderingFile.Base(), 570 Output: symbolOrderingFile, 571 Input: in, 572 Args: map[string]string{ 573 "crossCompile": crossCompile, 574 }, 575 }) 576 return "-Wl,--symbol-ordering-file," + symbolOrderingFile.String() 577} 578