blob: 3bd63369d476bac21076cf181ae2b810e29c9496 [file] [log] [blame]
Jiyong Park9b409bc2019-10-11 14:59:13 +09001// Copyright (C) 2019 The Android Open Source Project
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 sdk
16
17import (
18 "fmt"
Jiyong Park9b409bc2019-10-11 14:59:13 +090019 "path/filepath"
Paul Duffinb645ec82019-11-27 17:43:54 +000020 "reflect"
Jiyong Park9b409bc2019-10-11 14:59:13 +090021 "strings"
22
23 "github.com/google/blueprint/proptools"
24
25 "android/soong/android"
Jiyong Park73c54ee2019-10-22 20:31:18 +090026 "android/soong/cc"
Jiyong Park9b409bc2019-10-11 14:59:13 +090027 "android/soong/java"
28)
29
30var pctx = android.NewPackageContext("android/soong/sdk")
31
Paul Duffinb645ec82019-11-27 17:43:54 +000032type generatedContents struct {
Jiyong Park73c54ee2019-10-22 20:31:18 +090033 content strings.Builder
34 indentLevel int
Jiyong Park9b409bc2019-10-11 14:59:13 +090035}
36
Paul Duffinb645ec82019-11-27 17:43:54 +000037// generatedFile abstracts operations for writing contents into a file and emit a build rule
38// for the file.
39type generatedFile struct {
40 generatedContents
41 path android.OutputPath
42}
43
Jiyong Park232e7852019-11-04 12:23:40 +090044func newGeneratedFile(ctx android.ModuleContext, path ...string) *generatedFile {
Jiyong Park9b409bc2019-10-11 14:59:13 +090045 return &generatedFile{
Paul Duffinb645ec82019-11-27 17:43:54 +000046 path: android.PathForModuleOut(ctx, path...).OutputPath,
Jiyong Park9b409bc2019-10-11 14:59:13 +090047 }
48}
49
Paul Duffinb645ec82019-11-27 17:43:54 +000050func (gc *generatedContents) Indent() {
51 gc.indentLevel++
Jiyong Park73c54ee2019-10-22 20:31:18 +090052}
53
Paul Duffinb645ec82019-11-27 17:43:54 +000054func (gc *generatedContents) Dedent() {
55 gc.indentLevel--
Jiyong Park73c54ee2019-10-22 20:31:18 +090056}
57
Paul Duffinb645ec82019-11-27 17:43:54 +000058func (gc *generatedContents) Printfln(format string, args ...interface{}) {
Jiyong Park9b409bc2019-10-11 14:59:13 +090059 // ninja consumes newline characters in rspfile_content. Prevent it by
Paul Duffin0e0cf1d2019-11-12 19:39:25 +000060 // escaping the backslash in the newline character. The extra backslash
Jiyong Park9b409bc2019-10-11 14:59:13 +090061 // is removed when the rspfile is written to the actual script file
Paul Duffinb645ec82019-11-27 17:43:54 +000062 fmt.Fprintf(&(gc.content), strings.Repeat(" ", gc.indentLevel)+format+"\\n", args...)
Jiyong Park9b409bc2019-10-11 14:59:13 +090063}
64
65func (gf *generatedFile) build(pctx android.PackageContext, ctx android.BuilderContext, implicits android.Paths) {
66 rb := android.NewRuleBuilder()
67 // convert \\n to \n
68 rb.Command().
69 Implicits(implicits).
70 Text("echo").Text(proptools.ShellEscape(gf.content.String())).
71 Text("| sed 's/\\\\n/\\n/g' >").Output(gf.path)
72 rb.Command().
73 Text("chmod a+x").Output(gf.path)
74 rb.Build(pctx, ctx, gf.path.Base(), "Build "+gf.path.Base())
75}
76
Paul Duffin0e0cf1d2019-11-12 19:39:25 +000077func (s *sdk) javaLibs(ctx android.ModuleContext) []android.SdkAware {
78 result := []android.SdkAware{}
Jiyong Park9b409bc2019-10-11 14:59:13 +090079 ctx.VisitDirectDeps(func(m android.Module) {
Jiyong Park73c54ee2019-10-22 20:31:18 +090080 if j, ok := m.(*java.Library); ok {
81 result = append(result, j)
Jiyong Park9b409bc2019-10-11 14:59:13 +090082 }
83 })
84 return result
85}
86
Paul Duffin91547182019-11-12 19:39:36 +000087func (s *sdk) stubsSources(ctx android.ModuleContext) []android.SdkAware {
88 result := []android.SdkAware{}
89 ctx.VisitDirectDeps(func(m android.Module) {
90 if j, ok := m.(*java.Droidstubs); ok {
91 result = append(result, j)
92 }
93 })
94 return result
95}
96
Jiyong Park73c54ee2019-10-22 20:31:18 +090097// archSpecificNativeLibInfo represents an arch-specific variant of a native lib
98type archSpecificNativeLibInfo struct {
99 name string
100 archType string
101 exportedIncludeDirs android.Paths
102 exportedSystemIncludeDirs android.Paths
103 exportedFlags []string
Jiyong Park232e7852019-11-04 12:23:40 +0900104 exportedDeps android.Paths
Jiyong Park73c54ee2019-10-22 20:31:18 +0900105 outputFile android.Path
106}
Jiyong Park9b409bc2019-10-11 14:59:13 +0900107
Jiyong Park73c54ee2019-10-22 20:31:18 +0900108func (lib *archSpecificNativeLibInfo) signature() string {
109 return fmt.Sprintf("%v %v %v %v",
110 lib.name,
111 lib.exportedIncludeDirs.Strings(),
112 lib.exportedSystemIncludeDirs.Strings(),
113 lib.exportedFlags)
114}
115
116// nativeLibInfo represents a collection of arch-specific modules having the same name
117type nativeLibInfo struct {
118 name string
119 archVariants []archSpecificNativeLibInfo
120 // hasArchSpecificFlags is set to true if modules for each architecture all have the same
121 // include dirs, flags, etc, in which case only those of the first arch is selected.
122 hasArchSpecificFlags bool
123}
124
125// nativeMemberInfos collects all cc.Modules that are member of an SDK.
126func (s *sdk) nativeMemberInfos(ctx android.ModuleContext) []*nativeLibInfo {
127 infoMap := make(map[string]*nativeLibInfo)
128
129 // Collect cc.Modules
130 ctx.VisitDirectDeps(func(m android.Module) {
131 ccModule, ok := m.(*cc.Module)
132 if !ok {
133 return
134 }
135 depName := ctx.OtherModuleName(m)
136
137 if _, ok := infoMap[depName]; !ok {
138 infoMap[depName] = &nativeLibInfo{name: depName}
139 }
140
141 info := infoMap[depName]
142 info.archVariants = append(info.archVariants, archSpecificNativeLibInfo{
143 name: ccModule.BaseModuleName(),
144 archType: ccModule.Target().Arch.ArchType.String(),
145 exportedIncludeDirs: ccModule.ExportedIncludeDirs(),
146 exportedSystemIncludeDirs: ccModule.ExportedSystemIncludeDirs(),
147 exportedFlags: ccModule.ExportedFlags(),
Jiyong Park232e7852019-11-04 12:23:40 +0900148 exportedDeps: ccModule.ExportedDeps(),
Jiyong Park73c54ee2019-10-22 20:31:18 +0900149 outputFile: ccModule.OutputFile().Path(),
150 })
151 })
152
153 // Determine if include dirs and flags for each module are different across arch-specific
154 // modules or not. And set hasArchSpecificFlags accordingly
155 for _, info := range infoMap {
156 // by default, include paths and flags are assumed to be the same across arches
157 info.hasArchSpecificFlags = false
158 oldSignature := ""
159 for _, av := range info.archVariants {
160 newSignature := av.signature()
161 if oldSignature == "" {
162 oldSignature = newSignature
163 }
164 if oldSignature != newSignature {
165 info.hasArchSpecificFlags = true
166 break
167 }
168 }
Jiyong Park9b409bc2019-10-11 14:59:13 +0900169 }
170
Jiyong Park73c54ee2019-10-22 20:31:18 +0900171 var list []*nativeLibInfo
172 for _, v := range infoMap {
173 list = append(list, v)
174 }
175 return list
176}
Jiyong Park9b409bc2019-10-11 14:59:13 +0900177
Jiyong Park73c54ee2019-10-22 20:31:18 +0900178// SDK directory structure
179// <sdk_root>/
180// Android.bp : definition of a 'sdk' module is here. This is a hand-made one.
181// <api_ver>/ : below this directory are all auto-generated
182// Android.bp : definition of 'sdk_snapshot' module is here
183// aidl/
184// frameworks/base/core/..../IFoo.aidl : an exported AIDL file
185// java/
Jiyong Park232e7852019-11-04 12:23:40 +0900186// <module_name>.jar : the stub jar for a java library 'module_name'
Jiyong Park73c54ee2019-10-22 20:31:18 +0900187// include/
188// bionic/libc/include/stdlib.h : an exported header file
189// include_gen/
Jiyong Park232e7852019-11-04 12:23:40 +0900190// <module_name>/com/android/.../IFoo.h : a generated header file
Jiyong Park73c54ee2019-10-22 20:31:18 +0900191// <arch>/include/ : arch-specific exported headers
192// <arch>/include_gen/ : arch-specific generated headers
193// <arch>/lib/
194// libFoo.so : a stub library
195
196const (
Jiyong Park73c54ee2019-10-22 20:31:18 +0900197 nativeIncludeDir = "include"
198 nativeGeneratedIncludeDir = "include_gen"
199 nativeStubDir = "lib"
200 nativeStubFileSuffix = ".so"
201)
202
Jiyong Park73c54ee2019-10-22 20:31:18 +0900203// path to the stub file of a native shared library. Relative to <sdk_root>/<api_dir>
204func nativeStubFilePathFor(lib archSpecificNativeLibInfo) string {
205 return filepath.Join(lib.archType,
206 nativeStubDir, lib.name+nativeStubFileSuffix)
207}
208
209// paths to the include dirs of a native shared library. Relative to <sdk_root>/<api_dir>
210func nativeIncludeDirPathsFor(ctx android.ModuleContext, lib archSpecificNativeLibInfo,
211 systemInclude bool, archSpecific bool) []string {
212 var result []string
Jiyong Park73c54ee2019-10-22 20:31:18 +0900213 var includeDirs []android.Path
214 if !systemInclude {
215 includeDirs = lib.exportedIncludeDirs
216 } else {
217 includeDirs = lib.exportedSystemIncludeDirs
218 }
219 for _, dir := range includeDirs {
220 var path string
Jiyong Park232e7852019-11-04 12:23:40 +0900221 if _, gen := dir.(android.WritablePath); gen {
222 path = filepath.Join(nativeGeneratedIncludeDir, lib.name)
Jiyong Park73c54ee2019-10-22 20:31:18 +0900223 } else {
224 path = filepath.Join(nativeIncludeDir, dir.String())
225 }
226 if archSpecific {
227 path = filepath.Join(lib.archType, path)
228 }
229 result = append(result, path)
230 }
231 return result
232}
233
Jiyong Park232e7852019-11-04 12:23:40 +0900234// A name that uniquely identifies a prebuilt SDK member for a version of SDK snapshot
Jiyong Park73c54ee2019-10-22 20:31:18 +0900235// This isn't visible to users, so could be changed in future.
236func versionedSdkMemberName(ctx android.ModuleContext, memberName string, version string) string {
237 return ctx.ModuleName() + "_" + memberName + string(android.SdkVersionSeparator) + version
238}
239
Jiyong Park232e7852019-11-04 12:23:40 +0900240// buildSnapshot is the main function in this source file. It creates rules to copy
241// the contents (header files, stub libraries, etc) into the zip file.
242func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000243 snapshotDir := android.PathForModuleOut(ctx, "snapshot")
Jiyong Park9b409bc2019-10-11 14:59:13 +0900244
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000245 bp := newGeneratedFile(ctx, "snapshot", "Android.bp")
Paul Duffinb645ec82019-11-27 17:43:54 +0000246
247 bpFile := &bpFile{
248 modules: make(map[string]*bpModule),
249 }
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000250
251 builder := &snapshotBuilder{
Paul Duffinb645ec82019-11-27 17:43:54 +0000252 ctx: ctx,
253 version: "current",
254 snapshotDir: snapshotDir.OutputPath,
255 filesToZip: []android.Path{bp.path},
256 bpFile: bpFile,
257 prebuiltModules: make(map[string]*bpModule),
Jiyong Park73c54ee2019-10-22 20:31:18 +0900258 }
Paul Duffinac37c502019-11-26 18:02:20 +0000259 s.builderForTests = builder
Jiyong Park9b409bc2019-10-11 14:59:13 +0900260
Jiyong Park232e7852019-11-04 12:23:40 +0900261 // copy exported AIDL files and stub jar files
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000262 javaLibs := s.javaLibs(ctx)
263 for _, m := range javaLibs {
264 m.BuildSnapshot(ctx, builder)
Jiyong Park73c54ee2019-10-22 20:31:18 +0900265 }
266
Paul Duffin91547182019-11-12 19:39:36 +0000267 // copy stubs sources
268 stubsSources := s.stubsSources(ctx)
269 for _, m := range stubsSources {
270 m.BuildSnapshot(ctx, builder)
271 }
272
Jiyong Park232e7852019-11-04 12:23:40 +0900273 // copy exported header files and stub *.so files
Jiyong Park73c54ee2019-10-22 20:31:18 +0900274 nativeLibInfos := s.nativeMemberInfos(ctx)
275 for _, info := range nativeLibInfos {
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000276 buildSharedNativeLibSnapshot(ctx, info, builder)
Jiyong Park73c54ee2019-10-22 20:31:18 +0900277 }
Jiyong Park9b409bc2019-10-11 14:59:13 +0900278
Paul Duffinb645ec82019-11-27 17:43:54 +0000279 for _, unversioned := range builder.prebuiltOrder {
280 // Copy the unversioned module so it can be modified to make it versioned.
281 versioned := unversioned.copy()
282 name := versioned.properties["name"].(string)
283 versioned.setProperty("name", builder.versionedSdkMemberName(name))
284 versioned.insertAfter("name", "sdk_member_name", name)
285 bpFile.AddModule(versioned)
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000286
Paul Duffinb645ec82019-11-27 17:43:54 +0000287 // Set prefer: false - this is not strictly required as that is the default.
288 unversioned.insertAfter("name", "prefer", false)
289 bpFile.AddModule(unversioned)
290 }
291
292 // Create the snapshot module.
293 snapshotName := ctx.ModuleName() + string(android.SdkVersionSeparator) + builder.version
294 snapshotModule := bpFile.newModule("sdk_snapshot")
295 snapshotModule.AddProperty("name", snapshotName)
Paul Duffin66905ed2019-11-28 13:44:47 +0000296 if len(s.properties.Java_libs) > 0 {
Paul Duffinb645ec82019-11-27 17:43:54 +0000297 snapshotModule.AddProperty("java_libs", builder.versionedSdkMemberNames(s.properties.Java_libs))
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000298 }
Paul Duffin66905ed2019-11-28 13:44:47 +0000299 if len(s.properties.Stubs_sources) > 0 {
Paul Duffinb645ec82019-11-27 17:43:54 +0000300 snapshotModule.AddProperty("stubs_sources", builder.versionedSdkMemberNames(s.properties.Stubs_sources))
Paul Duffin91547182019-11-12 19:39:36 +0000301 }
Paul Duffin66905ed2019-11-28 13:44:47 +0000302 if len(s.properties.Native_shared_libs) > 0 {
Paul Duffinb645ec82019-11-27 17:43:54 +0000303 snapshotModule.AddProperty("native_shared_libs", builder.versionedSdkMemberNames(s.properties.Native_shared_libs))
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000304 }
Paul Duffinb645ec82019-11-27 17:43:54 +0000305 bpFile.AddModule(snapshotModule)
306
307 // generate Android.bp
308 bp = newGeneratedFile(ctx, "snapshot", "Android.bp")
309 generateBpContents(&bp.generatedContents, bpFile)
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000310
311 bp.build(pctx, ctx, nil)
312
313 filesToZip := builder.filesToZip
Jiyong Park9b409bc2019-10-11 14:59:13 +0900314
Jiyong Park232e7852019-11-04 12:23:40 +0900315 // zip them all
Paul Duffin91547182019-11-12 19:39:36 +0000316 outputZipFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.zip").OutputPath
317 outputRuleName := "snapshot"
318 outputDesc := "Building snapshot for " + ctx.ModuleName()
319
320 // If there are no zips to merge then generate the output zip directly.
321 // Otherwise, generate an intermediate zip file into which other zips can be
322 // merged.
323 var zipFile android.OutputPath
324 var ruleName string
325 var desc string
326 if len(builder.zipsToMerge) == 0 {
327 zipFile = outputZipFile
328 ruleName = outputRuleName
329 desc = outputDesc
330 } else {
331 zipFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.unmerged.zip").OutputPath
332 ruleName = "intermediate snapshot"
333 desc = "Building intermediate snapshot for " + ctx.ModuleName()
334 }
335
Jiyong Park232e7852019-11-04 12:23:40 +0900336 rb := android.NewRuleBuilder()
337 rb.Command().
338 BuiltTool(ctx, "soong_zip").
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000339 FlagWithArg("-C ", builder.snapshotDir.String()).
Jiyong Park232e7852019-11-04 12:23:40 +0900340 FlagWithRspFileInputList("-l ", filesToZip).
341 FlagWithOutput("-o ", zipFile)
Paul Duffin91547182019-11-12 19:39:36 +0000342 rb.Build(pctx, ctx, ruleName, desc)
Jiyong Park9b409bc2019-10-11 14:59:13 +0900343
Paul Duffin91547182019-11-12 19:39:36 +0000344 if len(builder.zipsToMerge) != 0 {
345 rb := android.NewRuleBuilder()
346 rb.Command().
347 BuiltTool(ctx, "merge_zips").
348 Output(outputZipFile).
349 Input(zipFile).
350 Inputs(builder.zipsToMerge)
351 rb.Build(pctx, ctx, outputRuleName, outputDesc)
352 }
353
354 return outputZipFile
Jiyong Park9b409bc2019-10-11 14:59:13 +0900355}
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000356
Paul Duffinb645ec82019-11-27 17:43:54 +0000357func generateBpContents(contents *generatedContents, bpFile *bpFile) {
358 contents.Printfln("// This is auto-generated. DO NOT EDIT.")
359 for _, bpModule := range bpFile.order {
360 contents.Printfln("")
361 contents.Printfln("%s {", bpModule.moduleType)
362 outputPropertySet(contents, &bpModule.bpPropertySet)
363 contents.Printfln("}")
364 }
365 contents.Printfln("")
366}
367
368func outputPropertySet(contents *generatedContents, set *bpPropertySet) {
369 contents.Indent()
370 for _, name := range set.order {
371 value := set.properties[name]
372
373 reflectedValue := reflect.ValueOf(value)
374 t := reflectedValue.Type()
375
376 kind := t.Kind()
377 switch kind {
378 case reflect.Slice:
379 length := reflectedValue.Len()
380 if length > 1 {
381 contents.Printfln("%s: [", name)
382 contents.Indent()
383 for i := 0; i < length; i = i + 1 {
384 contents.Printfln("%q,", reflectedValue.Index(i).Interface())
385 }
386 contents.Dedent()
387 contents.Printfln("],")
388 } else if length == 0 {
389 contents.Printfln("%s: [],", name)
390 } else {
391 contents.Printfln("%s: [%q],", name, reflectedValue.Index(0).Interface())
392 }
393 case reflect.Bool:
394 contents.Printfln("%s: %t,", name, reflectedValue.Bool())
395
396 case reflect.Ptr:
397 contents.Printfln("%s: {", name)
398 outputPropertySet(contents, reflectedValue.Interface().(*bpPropertySet))
399 contents.Printfln("},")
400
401 default:
402 contents.Printfln("%s: %q,", name, value)
403 }
404 }
405 contents.Dedent()
406}
407
Paul Duffinac37c502019-11-26 18:02:20 +0000408func (s *sdk) GetAndroidBpContentsForTests() string {
Paul Duffinb645ec82019-11-27 17:43:54 +0000409 contents := &generatedContents{}
410 generateBpContents(contents, s.builderForTests.bpFile)
411 return contents.content.String()
Paul Duffinac37c502019-11-26 18:02:20 +0000412}
413
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000414func buildSharedNativeLibSnapshot(ctx android.ModuleContext, info *nativeLibInfo, builder android.SnapshotBuilder) {
415 // a function for emitting include dirs
416 printExportedDirCopyCommandsForNativeLibs := func(lib archSpecificNativeLibInfo) {
417 includeDirs := lib.exportedIncludeDirs
418 includeDirs = append(includeDirs, lib.exportedSystemIncludeDirs...)
419 if len(includeDirs) == 0 {
420 return
421 }
422 for _, dir := range includeDirs {
423 if _, gen := dir.(android.WritablePath); gen {
424 // generated headers are copied via exportedDeps. See below.
425 continue
426 }
427 targetDir := nativeIncludeDir
428 if info.hasArchSpecificFlags {
429 targetDir = filepath.Join(lib.archType, targetDir)
430 }
431
432 // TODO(jiyong) copy headers having other suffixes
433 headers, _ := ctx.GlobWithDeps(dir.String()+"/**/*.h", nil)
434 for _, file := range headers {
435 src := android.PathForSource(ctx, file)
436 dest := filepath.Join(targetDir, file)
437 builder.CopyToSnapshot(src, dest)
438 }
439 }
440
441 genHeaders := lib.exportedDeps
442 for _, file := range genHeaders {
443 targetDir := nativeGeneratedIncludeDir
444 if info.hasArchSpecificFlags {
445 targetDir = filepath.Join(lib.archType, targetDir)
446 }
447 dest := filepath.Join(targetDir, lib.name, file.Rel())
448 builder.CopyToSnapshot(file, dest)
449 }
450 }
451
452 if !info.hasArchSpecificFlags {
453 printExportedDirCopyCommandsForNativeLibs(info.archVariants[0])
454 }
455
456 // for each architecture
457 for _, av := range info.archVariants {
458 builder.CopyToSnapshot(av.outputFile, nativeStubFilePathFor(av))
459
460 if info.hasArchSpecificFlags {
461 printExportedDirCopyCommandsForNativeLibs(av)
462 }
463 }
464
Paul Duffinb645ec82019-11-27 17:43:54 +0000465 info.generatePrebuiltLibrary(ctx, builder)
Paul Duffin90102502019-11-25 19:49:33 +0000466}
467
Paul Duffinb645ec82019-11-27 17:43:54 +0000468func (info *nativeLibInfo) generatePrebuiltLibrary(ctx android.ModuleContext, builder android.SnapshotBuilder) {
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000469
470 // a function for emitting include dirs
Paul Duffinb645ec82019-11-27 17:43:54 +0000471 addExportedDirsForNativeLibs := func(lib archSpecificNativeLibInfo, properties android.BpPropertySet, systemInclude bool) {
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000472 includeDirs := nativeIncludeDirPathsFor(ctx, lib, systemInclude, info.hasArchSpecificFlags)
473 if len(includeDirs) == 0 {
474 return
475 }
Paul Duffinb645ec82019-11-27 17:43:54 +0000476 var propertyName string
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000477 if !systemInclude {
Paul Duffinb645ec82019-11-27 17:43:54 +0000478 propertyName = "export_include_dirs"
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000479 } else {
Paul Duffinb645ec82019-11-27 17:43:54 +0000480 propertyName = "export_system_include_dirs"
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000481 }
Paul Duffinb645ec82019-11-27 17:43:54 +0000482 properties.AddProperty(propertyName, includeDirs)
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000483 }
484
Paul Duffinb645ec82019-11-27 17:43:54 +0000485 pbm := builder.AddPrebuiltModule(info.name, "cc_prebuilt_library_shared")
486
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000487 if !info.hasArchSpecificFlags {
Paul Duffinb645ec82019-11-27 17:43:54 +0000488 addExportedDirsForNativeLibs(info.archVariants[0], pbm, false /*systemInclude*/)
489 addExportedDirsForNativeLibs(info.archVariants[0], pbm, true /*systemInclude*/)
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000490 }
491
Paul Duffinb645ec82019-11-27 17:43:54 +0000492 archProperties := pbm.AddPropertySet("arch")
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000493 for _, av := range info.archVariants {
Paul Duffinb645ec82019-11-27 17:43:54 +0000494 archTypeProperties := archProperties.AddPropertySet(av.archType)
495 archTypeProperties.AddProperty("srcs", []string{nativeStubFilePathFor(av)})
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000496 if info.hasArchSpecificFlags {
497 // export_* properties are added inside the arch: {<arch>: {...}} block
Paul Duffinb645ec82019-11-27 17:43:54 +0000498 addExportedDirsForNativeLibs(av, archTypeProperties, false /*systemInclude*/)
499 addExportedDirsForNativeLibs(av, archTypeProperties, true /*systemInclude*/)
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000500 }
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000501 }
Paul Duffinb645ec82019-11-27 17:43:54 +0000502 pbm.AddProperty("stl", "none")
503 pbm.AddProperty("system_shared_libs", []string{})
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000504}
505
506type snapshotBuilder struct {
Paul Duffinb645ec82019-11-27 17:43:54 +0000507 ctx android.ModuleContext
508 version string
509 snapshotDir android.OutputPath
510 bpFile *bpFile
511 filesToZip android.Paths
512 zipsToMerge android.Paths
513
514 prebuiltModules map[string]*bpModule
515 prebuiltOrder []*bpModule
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000516}
517
518func (s *snapshotBuilder) CopyToSnapshot(src android.Path, dest string) {
519 path := s.snapshotDir.Join(s.ctx, dest)
520 s.ctx.Build(pctx, android.BuildParams{
521 Rule: android.Cp,
522 Input: src,
523 Output: path,
524 })
525 s.filesToZip = append(s.filesToZip, path)
526}
527
Paul Duffin91547182019-11-12 19:39:36 +0000528func (s *snapshotBuilder) UnzipToSnapshot(zipPath android.Path, destDir string) {
529 ctx := s.ctx
530
531 // Repackage the zip file so that the entries are in the destDir directory.
532 // This will allow the zip file to be merged into the snapshot.
533 tmpZipPath := android.PathForModuleOut(ctx, "tmp", destDir+".zip").OutputPath
534 rb := android.NewRuleBuilder()
535 rb.Command().
536 BuiltTool(ctx, "zip2zip").
537 FlagWithInput("-i ", zipPath).
538 FlagWithOutput("-o ", tmpZipPath).
539 Flag("**/*:" + destDir)
540 rb.Build(pctx, ctx, "repackaging "+destDir,
541 "Repackaging zip file "+destDir+" for snapshot "+ctx.ModuleName())
542
543 // Add the repackaged zip file to the files to merge.
544 s.zipsToMerge = append(s.zipsToMerge, tmpZipPath)
545}
546
Paul Duffinb645ec82019-11-27 17:43:54 +0000547func (s *snapshotBuilder) AddPrebuiltModule(name string, moduleType string) android.BpModule {
548 if s.prebuiltModules[name] != nil {
549 panic(fmt.Sprintf("Duplicate module detected, module %s has already been added", name))
550 }
551
552 m := s.bpFile.newModule(moduleType)
553 m.AddProperty("name", name)
554
555 s.prebuiltModules[name] = m
556 s.prebuiltOrder = append(s.prebuiltOrder, m)
557 return m
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000558}
559
Paul Duffinb645ec82019-11-27 17:43:54 +0000560// Get a versioned name appropriate for the SDK snapshot version being taken.
561func (s *snapshotBuilder) versionedSdkMemberName(unversionedName string) string {
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000562 return versionedSdkMemberName(s.ctx, unversionedName, s.version)
563}
Paul Duffinb645ec82019-11-27 17:43:54 +0000564
565func (s *snapshotBuilder) versionedSdkMemberNames(members []string) []string {
566 var references []string = nil
567 for _, m := range members {
568 references = append(references, s.versionedSdkMemberName(m))
569 }
570 return references
571}