blob: fa6c27950749b3cb25b86f7899f7d9edb7a50afc [file] [log] [blame]
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001// Copyright 2021 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/multitree"
Kiyoung Kim487689e2022-07-26 09:48:22 +090020 "strings"
Inseob Kim5eb7ee92022-04-27 10:30:34 +090021)
22
23func init() {
24 RegisterLibraryStubBuildComponents(android.InitRegistrationContext)
25}
26
27func RegisterLibraryStubBuildComponents(ctx android.RegistrationContext) {
28 // cc_api_stub_library shares a lot of ndk_library, and this will be refactored later
Kiyoung Kim487689e2022-07-26 09:48:22 +090029 ctx.RegisterModuleType("cc_api_library", CcApiLibraryFactory)
Inseob Kim5eb7ee92022-04-27 10:30:34 +090030 ctx.RegisterModuleType("cc_api_stub_library", CcApiStubLibraryFactory)
31 ctx.RegisterModuleType("cc_api_contribution", CcApiContributionFactory)
32}
33
Kiyoung Kim487689e2022-07-26 09:48:22 +090034// 'cc_api_library' is a module type which is from the exported API surface
35// with C shared library type. The module will replace original module, and
36// offer a link to the module that generates shared library object from the
37// map file.
38type apiLibraryProperties struct {
39 Src *string `android:"arch_variant"`
40}
41
42type apiLibraryDecorator struct {
43 *libraryDecorator
44 properties apiLibraryProperties
45}
46
47func CcApiLibraryFactory() android.Module {
48 module, decorator := NewLibrary(android.DeviceSupported)
49 apiLibraryDecorator := &apiLibraryDecorator{
50 libraryDecorator: decorator,
51 }
52 apiLibraryDecorator.BuildOnlyShared()
53
54 module.stl = nil
55 module.sanitize = nil
56 decorator.disableStripping()
57
58 module.compiler = nil
59 module.linker = apiLibraryDecorator
60 module.installer = nil
61 module.AddProperties(&module.Properties, &apiLibraryDecorator.properties)
62
63 // Mark module as stub, so APEX would not include this stub in the package.
64 module.library.setBuildStubs(true)
65
66 // Prevent default system libs (libc, libm, and libdl) from being linked
67 if apiLibraryDecorator.baseLinker.Properties.System_shared_libs == nil {
68 apiLibraryDecorator.baseLinker.Properties.System_shared_libs = []string{}
69 }
70
Kiyoung Kim835c5892022-08-17 16:40:16 +090071 apiLibraryDecorator.baseLinker.Properties.No_libcrt = BoolPtr(true)
72 apiLibraryDecorator.baseLinker.Properties.Nocrt = BoolPtr(true)
73
Kiyoung Kim487689e2022-07-26 09:48:22 +090074 module.Init()
75
76 return module
77}
78
79func (d *apiLibraryDecorator) Name(basename string) string {
80 return basename + multitree.GetApiImportSuffix()
81}
82
83func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path {
84 // Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
85 d.libraryDecorator.flagExporter.exportIncludes(ctx)
86 d.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
87 d.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
88 d.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
89 d.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
90 d.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
91 d.libraryDecorator.flagExporter.setProvider(ctx)
92
93 in := android.PathForModuleSrc(ctx, *d.properties.Src)
94
95 d.unstrippedOutputFile = in
96 libName := d.libraryDecorator.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
97
98 tocFile := android.PathForModuleOut(ctx, libName+".toc")
99 d.tocFile = android.OptionalPathForPath(tocFile)
100 TransformSharedObjectToToc(ctx, in, tocFile)
101
102 ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
103 SharedLibrary: in,
104 Target: ctx.Target(),
105
106 TableOfContents: d.tocFile,
107 })
108
109 return in
110}
111
112func (d *apiLibraryDecorator) availableFor(what string) bool {
113 // Stub from API surface should be available for any APEX.
114 return true
115}
116
117func (d *apiLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
118 d.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), multitree.GetApiImportSuffix())
119 return d.libraryDecorator.linkerFlags(ctx, flags)
120}
121
Inseob Kim5eb7ee92022-04-27 10:30:34 +0900122func CcApiStubLibraryFactory() android.Module {
123 module, decorator := NewLibrary(android.DeviceSupported)
124 apiStubDecorator := &apiStubDecorator{
125 libraryDecorator: decorator,
126 }
127 apiStubDecorator.BuildOnlyShared()
128
129 module.compiler = apiStubDecorator
130 module.linker = apiStubDecorator
131 module.installer = nil
132 module.library = apiStubDecorator
133 module.Properties.HideFromMake = true // TODO: remove
134
135 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
136 module.AddProperties(&module.Properties,
137 &apiStubDecorator.properties,
138 &apiStubDecorator.MutatedProperties,
139 &apiStubDecorator.apiStubLibraryProperties)
140 return module
141}
142
143type apiStubLiraryProperties struct {
144 Imported_includes []string `android:"path"`
145}
146
147type apiStubDecorator struct {
148 *libraryDecorator
149 properties libraryProperties
150 apiStubLibraryProperties apiStubLiraryProperties
151}
152
153func (compiler *apiStubDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
154 firstVersion := String(compiler.properties.First_version)
155 return ndkLibraryVersions(ctx, android.ApiLevelOrPanic(ctx, firstVersion))
156}
157
158func (decorator *apiStubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
159 if decorator.stubsVersion() == "" {
160 decorator.setStubsVersion("current")
161 } // TODO: fix
162 symbolFile := String(decorator.properties.Symbol_file)
163 nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
164 android.ApiLevelOrPanic(ctx, decorator.stubsVersion()),
165 "")
166 return compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
167}
168
169func (decorator *apiStubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path {
170 decorator.reexportDirs(android.PathsForModuleSrc(ctx, decorator.apiStubLibraryProperties.Imported_includes)...)
171 return decorator.libraryDecorator.link(ctx, flags, deps, objects)
172}
173
174func init() {
175 pctx.HostBinToolVariable("gen_api_surface_build_files", "gen_api_surface_build_files")
176}
177
178type CcApiContribution struct {
179 android.ModuleBase
180 properties ccApiContributionProperties
181}
182
183type ccApiContributionProperties struct {
184 Symbol_file *string `android:"path"`
185 First_version *string
186 Export_include_dir *string
187}
188
189func CcApiContributionFactory() android.Module {
190 module := &CcApiContribution{}
191 module.AddProperties(&module.properties)
192 android.InitAndroidModule(module)
193 return module
194}
195
196// Do some simple validations
197// Majority of the build rules will be created in the ctx of the api surface this module contributes to
198func (contrib *CcApiContribution) GenerateAndroidBuildActions(ctx android.ModuleContext) {
199 if contrib.properties.Symbol_file == nil {
200 ctx.PropertyErrorf("symbol_file", "%v does not have symbol file", ctx.ModuleName())
201 }
202 if contrib.properties.First_version == nil {
203 ctx.PropertyErrorf("first_version", "%v does not have first_version for stub variants", ctx.ModuleName())
204 }
205}
206
207// Path is out/soong/.export/ but will be different in final multi-tree layout
208func outPathApiSurface(ctx android.ModuleContext, myModuleName string, pathComponent string) android.OutputPath {
209 return android.PathForOutput(ctx, ".export", ctx.ModuleName(), myModuleName, pathComponent)
210}
211
212func (contrib *CcApiContribution) CopyFilesWithTag(apiSurfaceContext android.ModuleContext) map[string]android.Paths {
213 // copy map.txt for now
214 // hardlinks cannot be created since nsjail creates a different mountpoint for out/
215 myDir := apiSurfaceContext.OtherModuleDir(contrib)
216 genMapTxt := outPathApiSurface(apiSurfaceContext, contrib.Name(), String(contrib.properties.Symbol_file))
217 apiSurfaceContext.Build(pctx, android.BuildParams{
218 Rule: android.Cp,
219 Description: "import map.txt file",
220 Input: android.PathForSource(apiSurfaceContext, myDir, String(contrib.properties.Symbol_file)),
221 Output: genMapTxt,
222 })
223
224 outputs := make(map[string]android.Paths)
225 outputs["map"] = []android.Path{genMapTxt}
226
227 if contrib.properties.Export_include_dir != nil {
228 includeDir := android.PathForSource(apiSurfaceContext, myDir, String(contrib.properties.Export_include_dir))
229 outputs["export_include_dir"] = []android.Path{includeDir}
230 }
231 return outputs
232}
233
234var _ multitree.ApiContribution = (*CcApiContribution)(nil)
235
236/*
237func (contrib *CcApiContribution) GenerateBuildFiles(apiSurfaceContext android.ModuleContext) android.Paths {
238 genAndroidBp := outPathApiSurface(apiSurfaceContext, contrib.Name(), "Android.bp")
239
240 // generate Android.bp
241 apiSurfaceContext.Build(pctx, android.BuildParams{
242 Rule: genApiSurfaceBuildFiles,
243 Description: "generate API surface build files",
244 Outputs: []android.WritablePath{genAndroidBp},
245 Args: map[string]string{
246 "name": contrib.Name() + "." + apiSurfaceContext.ModuleName(), //e.g. liblog.ndk
247 "symbol_file": String(contrib.properties.Symbol_file),
248 "first_version": String(contrib.properties.First_version),
249 },
250 })
251 return []android.Path{genAndroidBp}
252}
253*/