xref: /aosp_15_r20/build/soong/cc/object.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2016 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage cc
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"fmt"
19*333d2b36SAndroid Build Coastguard Worker	"strings"
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
22*333d2b36SAndroid Build Coastguard Worker
23*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
24*333d2b36SAndroid Build Coastguard Worker)
25*333d2b36SAndroid Build Coastguard Worker
26*333d2b36SAndroid Build Coastguard Worker//
27*333d2b36SAndroid Build Coastguard Worker// Objects (for crt*.o)
28*333d2b36SAndroid Build Coastguard Worker//
29*333d2b36SAndroid Build Coastguard Worker
30*333d2b36SAndroid Build Coastguard Workerfunc init() {
31*333d2b36SAndroid Build Coastguard Worker	android.RegisterModuleType("cc_object", ObjectFactory)
32*333d2b36SAndroid Build Coastguard Worker	android.RegisterSdkMemberType(ccObjectSdkMemberType)
33*333d2b36SAndroid Build Coastguard Worker
34*333d2b36SAndroid Build Coastguard Worker}
35*333d2b36SAndroid Build Coastguard Worker
36*333d2b36SAndroid Build Coastguard Workervar ccObjectSdkMemberType = &librarySdkMemberType{
37*333d2b36SAndroid Build Coastguard Worker	SdkMemberTypeBase: android.SdkMemberTypeBase{
38*333d2b36SAndroid Build Coastguard Worker		PropertyName: "native_objects",
39*333d2b36SAndroid Build Coastguard Worker		SupportsSdk:  true,
40*333d2b36SAndroid Build Coastguard Worker	},
41*333d2b36SAndroid Build Coastguard Worker	prebuiltModuleType: "cc_prebuilt_object",
42*333d2b36SAndroid Build Coastguard Worker}
43*333d2b36SAndroid Build Coastguard Worker
44*333d2b36SAndroid Build Coastguard Workertype objectLinker struct {
45*333d2b36SAndroid Build Coastguard Worker	*baseLinker
46*333d2b36SAndroid Build Coastguard Worker	Properties ObjectLinkerProperties
47*333d2b36SAndroid Build Coastguard Worker
48*333d2b36SAndroid Build Coastguard Worker	// Location of the object in the sysroot. Empty if the object is not
49*333d2b36SAndroid Build Coastguard Worker	// included in the NDK.
50*333d2b36SAndroid Build Coastguard Worker	ndkSysrootPath android.Path
51*333d2b36SAndroid Build Coastguard Worker}
52*333d2b36SAndroid Build Coastguard Worker
53*333d2b36SAndroid Build Coastguard Workertype ObjectLinkerProperties struct {
54*333d2b36SAndroid Build Coastguard Worker	// list of static library modules that should only provide headers for this module.
55*333d2b36SAndroid Build Coastguard Worker	Static_libs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
56*333d2b36SAndroid Build Coastguard Worker
57*333d2b36SAndroid Build Coastguard Worker	// list of shared library modules should only provide headers for this module.
58*333d2b36SAndroid Build Coastguard Worker	Shared_libs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard Worker	// list of modules that should only provide headers for this module.
61*333d2b36SAndroid Build Coastguard Worker	Header_libs proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
62*333d2b36SAndroid Build Coastguard Worker
63*333d2b36SAndroid Build Coastguard Worker	// list of default libraries that will provide headers for this module.  If unset, generally
64*333d2b36SAndroid Build Coastguard Worker	// defaults to libc, libm, and libdl.  Set to [] to prevent using headers from the defaults.
65*333d2b36SAndroid Build Coastguard Worker	System_shared_libs []string `android:"arch_variant"`
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Worker	// names of other cc_object modules to link into this module using partial linking
68*333d2b36SAndroid Build Coastguard Worker	Objs []string `android:"arch_variant"`
69*333d2b36SAndroid Build Coastguard Worker
70*333d2b36SAndroid Build Coastguard Worker	// if set, add an extra objcopy --prefix-symbols= step
71*333d2b36SAndroid Build Coastguard Worker	Prefix_symbols *string
72*333d2b36SAndroid Build Coastguard Worker
73*333d2b36SAndroid Build Coastguard Worker	// if set, the path to a linker script to pass to ld -r when combining multiple object files.
74*333d2b36SAndroid Build Coastguard Worker	Linker_script *string `android:"path,arch_variant"`
75*333d2b36SAndroid Build Coastguard Worker
76*333d2b36SAndroid Build Coastguard Worker	// Indicates that this module is a CRT object. CRT objects will be split
77*333d2b36SAndroid Build Coastguard Worker	// into a variant per-API level between min_sdk_version and current.
78*333d2b36SAndroid Build Coastguard Worker	Crt *bool
79*333d2b36SAndroid Build Coastguard Worker
80*333d2b36SAndroid Build Coastguard Worker	// Indicates that this module should not be included in the NDK sysroot.
81*333d2b36SAndroid Build Coastguard Worker	// Only applies to CRT objects. Defaults to false.
82*333d2b36SAndroid Build Coastguard Worker	Exclude_from_ndk_sysroot *bool
83*333d2b36SAndroid Build Coastguard Worker}
84*333d2b36SAndroid Build Coastguard Worker
85*333d2b36SAndroid Build Coastguard Workerfunc newObject(hod android.HostOrDeviceSupported) *Module {
86*333d2b36SAndroid Build Coastguard Worker	module := newBaseModule(hod, android.MultilibBoth)
87*333d2b36SAndroid Build Coastguard Worker	module.sanitize = &sanitize{}
88*333d2b36SAndroid Build Coastguard Worker	module.stl = &stl{}
89*333d2b36SAndroid Build Coastguard Worker	return module
90*333d2b36SAndroid Build Coastguard Worker}
91*333d2b36SAndroid Build Coastguard Worker
92*333d2b36SAndroid Build Coastguard Worker// cc_object runs the compiler without running the linker. It is rarely
93*333d2b36SAndroid Build Coastguard Worker// necessary, but sometimes used to generate .s files from .c files to use as
94*333d2b36SAndroid Build Coastguard Worker// input to a cc_genrule module.
95*333d2b36SAndroid Build Coastguard Workerfunc ObjectFactory() android.Module {
96*333d2b36SAndroid Build Coastguard Worker	module := newObject(android.HostAndDeviceSupported)
97*333d2b36SAndroid Build Coastguard Worker	module.linker = &objectLinker{
98*333d2b36SAndroid Build Coastguard Worker		baseLinker: NewBaseLinker(module.sanitize),
99*333d2b36SAndroid Build Coastguard Worker	}
100*333d2b36SAndroid Build Coastguard Worker	module.compiler = NewBaseCompiler()
101*333d2b36SAndroid Build Coastguard Worker
102*333d2b36SAndroid Build Coastguard Worker	// Clang's address-significance tables are incompatible with ld -r.
103*333d2b36SAndroid Build Coastguard Worker	module.compiler.appendCflags([]string{"-fno-addrsig"})
104*333d2b36SAndroid Build Coastguard Worker
105*333d2b36SAndroid Build Coastguard Worker	module.sdkMemberTypes = []android.SdkMemberType{ccObjectSdkMemberType}
106*333d2b36SAndroid Build Coastguard Worker
107*333d2b36SAndroid Build Coastguard Worker	return module.Init()
108*333d2b36SAndroid Build Coastguard Worker}
109*333d2b36SAndroid Build Coastguard Worker
110*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) appendLdflags(flags []string) {
111*333d2b36SAndroid Build Coastguard Worker	panic(fmt.Errorf("appendLdflags on objectLinker not supported"))
112*333d2b36SAndroid Build Coastguard Worker}
113*333d2b36SAndroid Build Coastguard Worker
114*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) linkerProps() []interface{} {
115*333d2b36SAndroid Build Coastguard Worker	return []interface{}{&object.Properties}
116*333d2b36SAndroid Build Coastguard Worker}
117*333d2b36SAndroid Build Coastguard Worker
118*333d2b36SAndroid Build Coastguard Workerfunc (*objectLinker) linkerInit(ctx BaseModuleContext) {}
119*333d2b36SAndroid Build Coastguard Worker
120*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
121*333d2b36SAndroid Build Coastguard Worker	deps.HeaderLibs = append(deps.HeaderLibs, object.Properties.Header_libs.GetOrDefault(ctx, nil)...)
122*333d2b36SAndroid Build Coastguard Worker	deps.SharedLibs = append(deps.SharedLibs, object.Properties.Shared_libs.GetOrDefault(ctx, nil)...)
123*333d2b36SAndroid Build Coastguard Worker	deps.StaticLibs = append(deps.StaticLibs, object.Properties.Static_libs.GetOrDefault(ctx, nil)...)
124*333d2b36SAndroid Build Coastguard Worker	deps.ObjFiles = append(deps.ObjFiles, object.Properties.Objs...)
125*333d2b36SAndroid Build Coastguard Worker
126*333d2b36SAndroid Build Coastguard Worker	deps.SystemSharedLibs = object.Properties.System_shared_libs
127*333d2b36SAndroid Build Coastguard Worker	if deps.SystemSharedLibs == nil {
128*333d2b36SAndroid Build Coastguard Worker		// Provide a default set of shared libraries if system_shared_libs is unspecified.
129*333d2b36SAndroid Build Coastguard Worker		// Note: If an empty list [] is specified, it implies that the module declines the
130*333d2b36SAndroid Build Coastguard Worker		// default shared libraries.
131*333d2b36SAndroid Build Coastguard Worker		deps.SystemSharedLibs = append(deps.SystemSharedLibs, ctx.toolchain().DefaultSharedLibraries()...)
132*333d2b36SAndroid Build Coastguard Worker	}
133*333d2b36SAndroid Build Coastguard Worker	deps.LateSharedLibs = append(deps.LateSharedLibs, deps.SystemSharedLibs...)
134*333d2b36SAndroid Build Coastguard Worker	return deps
135*333d2b36SAndroid Build Coastguard Worker}
136*333d2b36SAndroid Build Coastguard Worker
137*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
138*333d2b36SAndroid Build Coastguard Worker	flags.Global.LdFlags = append(flags.Global.LdFlags, ctx.toolchain().ToolchainLdflags())
139*333d2b36SAndroid Build Coastguard Worker
140*333d2b36SAndroid Build Coastguard Worker	if lds := android.OptionalPathForModuleSrc(ctx, object.Properties.Linker_script); lds.Valid() {
141*333d2b36SAndroid Build Coastguard Worker		flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-T,"+lds.String())
142*333d2b36SAndroid Build Coastguard Worker		flags.LdFlagsDeps = append(flags.LdFlagsDeps, lds.Path())
143*333d2b36SAndroid Build Coastguard Worker	}
144*333d2b36SAndroid Build Coastguard Worker	return flags
145*333d2b36SAndroid Build Coastguard Worker}
146*333d2b36SAndroid Build Coastguard Worker
147*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) link(ctx ModuleContext,
148*333d2b36SAndroid Build Coastguard Worker	flags Flags, deps PathDeps, objs Objects) android.Path {
149*333d2b36SAndroid Build Coastguard Worker
150*333d2b36SAndroid Build Coastguard Worker	objs = objs.Append(deps.Objs)
151*333d2b36SAndroid Build Coastguard Worker
152*333d2b36SAndroid Build Coastguard Worker	var output android.WritablePath
153*333d2b36SAndroid Build Coastguard Worker	builderFlags := flagsToBuilderFlags(flags)
154*333d2b36SAndroid Build Coastguard Worker	outputName := ctx.ModuleName()
155*333d2b36SAndroid Build Coastguard Worker	if !strings.HasSuffix(outputName, objectExtension) {
156*333d2b36SAndroid Build Coastguard Worker		outputName += objectExtension
157*333d2b36SAndroid Build Coastguard Worker	}
158*333d2b36SAndroid Build Coastguard Worker
159*333d2b36SAndroid Build Coastguard Worker	// isForPlatform is terribly named and actually means isNotApex.
160*333d2b36SAndroid Build Coastguard Worker	if Bool(object.Properties.Crt) &&
161*333d2b36SAndroid Build Coastguard Worker		!Bool(object.Properties.Exclude_from_ndk_sysroot) && ctx.useSdk() &&
162*333d2b36SAndroid Build Coastguard Worker		ctx.isSdkVariant() && ctx.isForPlatform() {
163*333d2b36SAndroid Build Coastguard Worker
164*333d2b36SAndroid Build Coastguard Worker		output = getVersionedLibraryInstallPath(ctx,
165*333d2b36SAndroid Build Coastguard Worker			nativeApiLevelOrPanic(ctx, ctx.sdkVersion())).Join(ctx, outputName)
166*333d2b36SAndroid Build Coastguard Worker		object.ndkSysrootPath = output
167*333d2b36SAndroid Build Coastguard Worker	} else {
168*333d2b36SAndroid Build Coastguard Worker		output = android.PathForModuleOut(ctx, outputName)
169*333d2b36SAndroid Build Coastguard Worker	}
170*333d2b36SAndroid Build Coastguard Worker
171*333d2b36SAndroid Build Coastguard Worker	outputFile := output
172*333d2b36SAndroid Build Coastguard Worker
173*333d2b36SAndroid Build Coastguard Worker	if len(objs.objFiles) == 1 && String(object.Properties.Linker_script) == "" {
174*333d2b36SAndroid Build Coastguard Worker		if String(object.Properties.Prefix_symbols) != "" {
175*333d2b36SAndroid Build Coastguard Worker			transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), objs.objFiles[0],
176*333d2b36SAndroid Build Coastguard Worker				builderFlags, output)
177*333d2b36SAndroid Build Coastguard Worker		} else {
178*333d2b36SAndroid Build Coastguard Worker			ctx.Build(pctx, android.BuildParams{
179*333d2b36SAndroid Build Coastguard Worker				Rule:   android.Cp,
180*333d2b36SAndroid Build Coastguard Worker				Input:  objs.objFiles[0],
181*333d2b36SAndroid Build Coastguard Worker				Output: output,
182*333d2b36SAndroid Build Coastguard Worker			})
183*333d2b36SAndroid Build Coastguard Worker		}
184*333d2b36SAndroid Build Coastguard Worker	} else {
185*333d2b36SAndroid Build Coastguard Worker		outputAddrSig := android.PathForModuleOut(ctx, "addrsig", outputName)
186*333d2b36SAndroid Build Coastguard Worker
187*333d2b36SAndroid Build Coastguard Worker		if String(object.Properties.Prefix_symbols) != "" {
188*333d2b36SAndroid Build Coastguard Worker			input := android.PathForModuleOut(ctx, "unprefixed", outputName)
189*333d2b36SAndroid Build Coastguard Worker			transformBinaryPrefixSymbols(ctx, String(object.Properties.Prefix_symbols), input,
190*333d2b36SAndroid Build Coastguard Worker				builderFlags, output)
191*333d2b36SAndroid Build Coastguard Worker			output = input
192*333d2b36SAndroid Build Coastguard Worker		}
193*333d2b36SAndroid Build Coastguard Worker
194*333d2b36SAndroid Build Coastguard Worker		transformObjsToObj(ctx, objs.objFiles, builderFlags, outputAddrSig, flags.LdFlagsDeps)
195*333d2b36SAndroid Build Coastguard Worker
196*333d2b36SAndroid Build Coastguard Worker		// ld -r reorders symbols and invalidates the .llvm_addrsig section, which then causes warnings
197*333d2b36SAndroid Build Coastguard Worker		// if the resulting object is used with ld --icf=safe.  Strip the .llvm_addrsig section to
198*333d2b36SAndroid Build Coastguard Worker		// prevent the warnings.
199*333d2b36SAndroid Build Coastguard Worker		transformObjectNoAddrSig(ctx, outputAddrSig, output)
200*333d2b36SAndroid Build Coastguard Worker	}
201*333d2b36SAndroid Build Coastguard Worker
202*333d2b36SAndroid Build Coastguard Worker	ctx.CheckbuildFile(outputFile)
203*333d2b36SAndroid Build Coastguard Worker	return outputFile
204*333d2b36SAndroid Build Coastguard Worker}
205*333d2b36SAndroid Build Coastguard Worker
206*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps {
207*333d2b36SAndroid Build Coastguard Worker	eval := module.ConfigurableEvaluator(ctx)
208*333d2b36SAndroid Build Coastguard Worker	specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, object.Properties.Shared_libs.GetOrDefault(eval, nil)...)
209*333d2b36SAndroid Build Coastguard Worker
210*333d2b36SAndroid Build Coastguard Worker	// Must distinguish nil and [] in system_shared_libs - ensure that [] in
211*333d2b36SAndroid Build Coastguard Worker	// either input list doesn't come out as nil.
212*333d2b36SAndroid Build Coastguard Worker	if specifiedDeps.systemSharedLibs == nil {
213*333d2b36SAndroid Build Coastguard Worker		specifiedDeps.systemSharedLibs = object.Properties.System_shared_libs
214*333d2b36SAndroid Build Coastguard Worker	} else {
215*333d2b36SAndroid Build Coastguard Worker		specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, object.Properties.System_shared_libs...)
216*333d2b36SAndroid Build Coastguard Worker	}
217*333d2b36SAndroid Build Coastguard Worker
218*333d2b36SAndroid Build Coastguard Worker	return specifiedDeps
219*333d2b36SAndroid Build Coastguard Worker}
220*333d2b36SAndroid Build Coastguard Worker
221*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) unstrippedOutputFilePath() android.Path {
222*333d2b36SAndroid Build Coastguard Worker	return nil
223*333d2b36SAndroid Build Coastguard Worker}
224*333d2b36SAndroid Build Coastguard Worker
225*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) strippedAllOutputFilePath() android.Path {
226*333d2b36SAndroid Build Coastguard Worker	return nil
227*333d2b36SAndroid Build Coastguard Worker}
228*333d2b36SAndroid Build Coastguard Worker
229*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) nativeCoverage() bool {
230*333d2b36SAndroid Build Coastguard Worker	return true
231*333d2b36SAndroid Build Coastguard Worker}
232*333d2b36SAndroid Build Coastguard Worker
233*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) coverageOutputFilePath() android.OptionalPath {
234*333d2b36SAndroid Build Coastguard Worker	return android.OptionalPath{}
235*333d2b36SAndroid Build Coastguard Worker}
236*333d2b36SAndroid Build Coastguard Worker
237*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) object() bool {
238*333d2b36SAndroid Build Coastguard Worker	return true
239*333d2b36SAndroid Build Coastguard Worker}
240*333d2b36SAndroid Build Coastguard Worker
241*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) isCrt() bool {
242*333d2b36SAndroid Build Coastguard Worker	return Bool(object.Properties.Crt)
243*333d2b36SAndroid Build Coastguard Worker}
244*333d2b36SAndroid Build Coastguard Worker
245*333d2b36SAndroid Build Coastguard Workerfunc (object *objectLinker) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
246*333d2b36SAndroid Build Coastguard Worker	object.baseLinker.moduleInfoJSON(ctx, moduleInfoJSON)
247*333d2b36SAndroid Build Coastguard Worker	moduleInfoJSON.Class = []string{"STATIC_LIBRARIES"}
248*333d2b36SAndroid Build Coastguard Worker}
249