xref: /aosp_15_r20/build/soong/linkerconfig/linkerconfig.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright (C) 2020 The Android Open Source Project
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 linkerconfig
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"sort"
19*333d2b36SAndroid Build Coastguard Worker	"strings"
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
22*333d2b36SAndroid Build Coastguard Worker
23*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
24*333d2b36SAndroid Build Coastguard Worker	"android/soong/cc"
25*333d2b36SAndroid Build Coastguard Worker	"android/soong/etc"
26*333d2b36SAndroid Build Coastguard Worker)
27*333d2b36SAndroid Build Coastguard Worker
28*333d2b36SAndroid Build Coastguard Workervar (
29*333d2b36SAndroid Build Coastguard Worker	pctx = android.NewPackageContext("android/soong/linkerconfig")
30*333d2b36SAndroid Build Coastguard Worker)
31*333d2b36SAndroid Build Coastguard Worker
32*333d2b36SAndroid Build Coastguard Workerfunc init() {
33*333d2b36SAndroid Build Coastguard Worker	pctx.HostBinToolVariable("conv_linker_config", "conv_linker_config")
34*333d2b36SAndroid Build Coastguard Worker	registerLinkerConfigBuildComponent(android.InitRegistrationContext)
35*333d2b36SAndroid Build Coastguard Worker}
36*333d2b36SAndroid Build Coastguard Worker
37*333d2b36SAndroid Build Coastguard Workerfunc registerLinkerConfigBuildComponent(ctx android.RegistrationContext) {
38*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("linker_config", LinkerConfigFactory)
39*333d2b36SAndroid Build Coastguard Worker}
40*333d2b36SAndroid Build Coastguard Worker
41*333d2b36SAndroid Build Coastguard Workertype linkerConfigProperties struct {
42*333d2b36SAndroid Build Coastguard Worker	// source linker configuration property file
43*333d2b36SAndroid Build Coastguard Worker	Src *string `android:"path"`
44*333d2b36SAndroid Build Coastguard Worker
45*333d2b36SAndroid Build Coastguard Worker	// If set to true, allow module to be installed to one of the partitions.
46*333d2b36SAndroid Build Coastguard Worker	// Default value is true.
47*333d2b36SAndroid Build Coastguard Worker	// Installable should be marked as false for APEX configuration to avoid
48*333d2b36SAndroid Build Coastguard Worker	// conflicts of configuration on /system/etc directory.
49*333d2b36SAndroid Build Coastguard Worker	Installable *bool
50*333d2b36SAndroid Build Coastguard Worker}
51*333d2b36SAndroid Build Coastguard Worker
52*333d2b36SAndroid Build Coastguard Workertype linkerConfig struct {
53*333d2b36SAndroid Build Coastguard Worker	android.ModuleBase
54*333d2b36SAndroid Build Coastguard Worker	properties linkerConfigProperties
55*333d2b36SAndroid Build Coastguard Worker
56*333d2b36SAndroid Build Coastguard Worker	outputFilePath android.OutputPath
57*333d2b36SAndroid Build Coastguard Worker	installDirPath android.InstallPath
58*333d2b36SAndroid Build Coastguard Worker}
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard Worker// Implement PrebuiltEtcModule interface to fit in APEX prebuilt list.
61*333d2b36SAndroid Build Coastguard Workervar _ etc.PrebuiltEtcModule = (*linkerConfig)(nil)
62*333d2b36SAndroid Build Coastguard Worker
63*333d2b36SAndroid Build Coastguard Workerfunc (l *linkerConfig) BaseDir() string {
64*333d2b36SAndroid Build Coastguard Worker	return "etc"
65*333d2b36SAndroid Build Coastguard Worker}
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Workerfunc (l *linkerConfig) SubDir() string {
68*333d2b36SAndroid Build Coastguard Worker	return ""
69*333d2b36SAndroid Build Coastguard Worker}
70*333d2b36SAndroid Build Coastguard Worker
71*333d2b36SAndroid Build Coastguard Workerfunc (l *linkerConfig) OutputFile() android.OutputPath {
72*333d2b36SAndroid Build Coastguard Worker	return l.outputFilePath
73*333d2b36SAndroid Build Coastguard Worker}
74*333d2b36SAndroid Build Coastguard Worker
75*333d2b36SAndroid Build Coastguard Workerfunc (l *linkerConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
76*333d2b36SAndroid Build Coastguard Worker	input := android.PathForModuleSrc(ctx, android.String(l.properties.Src))
77*333d2b36SAndroid Build Coastguard Worker	output := android.PathForModuleOut(ctx, "linker.config.pb").OutputPath
78*333d2b36SAndroid Build Coastguard Worker
79*333d2b36SAndroid Build Coastguard Worker	builder := android.NewRuleBuilder(pctx, ctx)
80*333d2b36SAndroid Build Coastguard Worker	BuildLinkerConfig(ctx, builder, android.Paths{input}, nil, nil, output)
81*333d2b36SAndroid Build Coastguard Worker	builder.Build("conv_linker_config", "Generate linker config protobuf "+output.String())
82*333d2b36SAndroid Build Coastguard Worker
83*333d2b36SAndroid Build Coastguard Worker	l.outputFilePath = output
84*333d2b36SAndroid Build Coastguard Worker	l.installDirPath = android.PathForModuleInstall(ctx, "etc")
85*333d2b36SAndroid Build Coastguard Worker	if !proptools.BoolDefault(l.properties.Installable, true) {
86*333d2b36SAndroid Build Coastguard Worker		l.SkipInstall()
87*333d2b36SAndroid Build Coastguard Worker	}
88*333d2b36SAndroid Build Coastguard Worker	ctx.InstallFile(l.installDirPath, l.outputFilePath.Base(), l.outputFilePath)
89*333d2b36SAndroid Build Coastguard Worker
90*333d2b36SAndroid Build Coastguard Worker	ctx.SetOutputFiles(android.Paths{l.outputFilePath}, "")
91*333d2b36SAndroid Build Coastguard Worker}
92*333d2b36SAndroid Build Coastguard Worker
93*333d2b36SAndroid Build Coastguard Workerfunc BuildLinkerConfig(ctx android.ModuleContext, builder *android.RuleBuilder,
94*333d2b36SAndroid Build Coastguard Worker	inputs android.Paths, provideModules []android.Module, requireModules []android.Module, output android.OutputPath) {
95*333d2b36SAndroid Build Coastguard Worker
96*333d2b36SAndroid Build Coastguard Worker	// First, convert the input json to protobuf format
97*333d2b36SAndroid Build Coastguard Worker	interimOutput := android.PathForModuleOut(ctx, "temp.pb")
98*333d2b36SAndroid Build Coastguard Worker	cmd := builder.Command().
99*333d2b36SAndroid Build Coastguard Worker		BuiltTool("conv_linker_config").
100*333d2b36SAndroid Build Coastguard Worker		Flag("proto").
101*333d2b36SAndroid Build Coastguard Worker		Flag("--force")
102*333d2b36SAndroid Build Coastguard Worker	for _, input := range inputs {
103*333d2b36SAndroid Build Coastguard Worker		cmd.FlagWithInput("-s ", input)
104*333d2b36SAndroid Build Coastguard Worker	}
105*333d2b36SAndroid Build Coastguard Worker	cmd.FlagWithOutput("-o ", interimOutput)
106*333d2b36SAndroid Build Coastguard Worker
107*333d2b36SAndroid Build Coastguard Worker	// Secondly, if there's provideLibs gathered from provideModules, append them
108*333d2b36SAndroid Build Coastguard Worker	var provideLibs []string
109*333d2b36SAndroid Build Coastguard Worker	for _, m := range provideModules {
110*333d2b36SAndroid Build Coastguard Worker		if c, ok := m.(*cc.Module); ok && (cc.IsStubTarget(c) || c.HasLlndkStubs()) {
111*333d2b36SAndroid Build Coastguard Worker			for _, ps := range android.OtherModuleProviderOrDefault(
112*333d2b36SAndroid Build Coastguard Worker				ctx, c, android.InstallFilesProvider).PackagingSpecs {
113*333d2b36SAndroid Build Coastguard Worker				provideLibs = append(provideLibs, ps.FileName())
114*333d2b36SAndroid Build Coastguard Worker			}
115*333d2b36SAndroid Build Coastguard Worker		}
116*333d2b36SAndroid Build Coastguard Worker	}
117*333d2b36SAndroid Build Coastguard Worker	provideLibs = android.FirstUniqueStrings(provideLibs)
118*333d2b36SAndroid Build Coastguard Worker	sort.Strings(provideLibs)
119*333d2b36SAndroid Build Coastguard Worker
120*333d2b36SAndroid Build Coastguard Worker	var requireLibs []string
121*333d2b36SAndroid Build Coastguard Worker	for _, m := range requireModules {
122*333d2b36SAndroid Build Coastguard Worker		if c, ok := m.(*cc.Module); ok && c.HasStubsVariants() && !c.Host() {
123*333d2b36SAndroid Build Coastguard Worker			requireLibs = append(requireLibs, c.ImplementationModuleName(ctx)+".so")
124*333d2b36SAndroid Build Coastguard Worker		}
125*333d2b36SAndroid Build Coastguard Worker	}
126*333d2b36SAndroid Build Coastguard Worker
127*333d2b36SAndroid Build Coastguard Worker	requireLibs = android.FirstUniqueStrings(requireLibs)
128*333d2b36SAndroid Build Coastguard Worker	sort.Strings(requireLibs)
129*333d2b36SAndroid Build Coastguard Worker
130*333d2b36SAndroid Build Coastguard Worker	if len(provideLibs) > 0 {
131*333d2b36SAndroid Build Coastguard Worker		prevOutput := interimOutput
132*333d2b36SAndroid Build Coastguard Worker		interimOutput = android.PathForModuleOut(ctx, "temp_provideLibs.pb")
133*333d2b36SAndroid Build Coastguard Worker		builder.Command().
134*333d2b36SAndroid Build Coastguard Worker			BuiltTool("conv_linker_config").
135*333d2b36SAndroid Build Coastguard Worker			Flag("append").
136*333d2b36SAndroid Build Coastguard Worker			FlagWithInput("-s ", prevOutput).
137*333d2b36SAndroid Build Coastguard Worker			FlagWithOutput("-o ", interimOutput).
138*333d2b36SAndroid Build Coastguard Worker			FlagWithArg("--key ", "provideLibs").
139*333d2b36SAndroid Build Coastguard Worker			FlagWithArg("--value ", proptools.ShellEscapeIncludingSpaces(strings.Join(provideLibs, " ")))
140*333d2b36SAndroid Build Coastguard Worker		builder.Temporary(prevOutput)
141*333d2b36SAndroid Build Coastguard Worker	}
142*333d2b36SAndroid Build Coastguard Worker	if len(requireLibs) > 0 {
143*333d2b36SAndroid Build Coastguard Worker		prevOutput := interimOutput
144*333d2b36SAndroid Build Coastguard Worker		interimOutput = android.PathForModuleOut(ctx, "temp_requireLibs.pb")
145*333d2b36SAndroid Build Coastguard Worker		builder.Command().
146*333d2b36SAndroid Build Coastguard Worker			BuiltTool("conv_linker_config").
147*333d2b36SAndroid Build Coastguard Worker			Flag("append").
148*333d2b36SAndroid Build Coastguard Worker			FlagWithInput("-s ", prevOutput).
149*333d2b36SAndroid Build Coastguard Worker			FlagWithOutput("-o ", interimOutput).
150*333d2b36SAndroid Build Coastguard Worker			FlagWithArg("--key ", "requireLibs").
151*333d2b36SAndroid Build Coastguard Worker			FlagWithArg("--value ", proptools.ShellEscapeIncludingSpaces(strings.Join(requireLibs, " ")))
152*333d2b36SAndroid Build Coastguard Worker		builder.Temporary(prevOutput)
153*333d2b36SAndroid Build Coastguard Worker	}
154*333d2b36SAndroid Build Coastguard Worker
155*333d2b36SAndroid Build Coastguard Worker	// cp to the final output
156*333d2b36SAndroid Build Coastguard Worker	builder.Command().Text("cp").Input(interimOutput).Output(output)
157*333d2b36SAndroid Build Coastguard Worker
158*333d2b36SAndroid Build Coastguard Worker	builder.Temporary(interimOutput)
159*333d2b36SAndroid Build Coastguard Worker	builder.DeleteTemporaryFiles()
160*333d2b36SAndroid Build Coastguard Worker}
161*333d2b36SAndroid Build Coastguard Worker
162*333d2b36SAndroid Build Coastguard Worker// linker_config generates protobuf file from json file. This protobuf file will be used from
163*333d2b36SAndroid Build Coastguard Worker// linkerconfig while generating ld.config.txt. Format of this file can be found from
164*333d2b36SAndroid Build Coastguard Worker// https://android.googlesource.com/platform/system/linkerconfig/+/main/README.md
165*333d2b36SAndroid Build Coastguard Workerfunc LinkerConfigFactory() android.Module {
166*333d2b36SAndroid Build Coastguard Worker	m := &linkerConfig{}
167*333d2b36SAndroid Build Coastguard Worker	m.AddProperties(&m.properties)
168*333d2b36SAndroid Build Coastguard Worker	android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibFirst)
169*333d2b36SAndroid Build Coastguard Worker	return m
170*333d2b36SAndroid Build Coastguard Worker}
171*333d2b36SAndroid Build Coastguard Worker
172*333d2b36SAndroid Build Coastguard Workerfunc (l *linkerConfig) AndroidMkEntries() []android.AndroidMkEntries {
173*333d2b36SAndroid Build Coastguard Worker	installable := proptools.BoolDefault(l.properties.Installable, true)
174*333d2b36SAndroid Build Coastguard Worker	return []android.AndroidMkEntries{android.AndroidMkEntries{
175*333d2b36SAndroid Build Coastguard Worker		Class:      "ETC",
176*333d2b36SAndroid Build Coastguard Worker		OutputFile: android.OptionalPathForPath(l.outputFilePath),
177*333d2b36SAndroid Build Coastguard Worker		ExtraEntries: []android.AndroidMkExtraEntriesFunc{
178*333d2b36SAndroid Build Coastguard Worker			func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
179*333d2b36SAndroid Build Coastguard Worker				entries.SetString("LOCAL_MODULE_PATH", l.installDirPath.String())
180*333d2b36SAndroid Build Coastguard Worker				entries.SetString("LOCAL_INSTALLED_MODULE_STEM", l.outputFilePath.Base())
181*333d2b36SAndroid Build Coastguard Worker				entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !installable)
182*333d2b36SAndroid Build Coastguard Worker			},
183*333d2b36SAndroid Build Coastguard Worker		},
184*333d2b36SAndroid Build Coastguard Worker	}}
185*333d2b36SAndroid Build Coastguard Worker}
186