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