blob: 8159d3b4de516c2ad4b8ac3525ef075c23d19b37 [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,
Paul Duffine44358f2019-11-26 18:04:12 +0000253 sdk: s,
Paul Duffinb645ec82019-11-27 17:43:54 +0000254 version: "current",
255 snapshotDir: snapshotDir.OutputPath,
256 filesToZip: []android.Path{bp.path},
257 bpFile: bpFile,
258 prebuiltModules: make(map[string]*bpModule),
Jiyong Park73c54ee2019-10-22 20:31:18 +0900259 }
Paul Duffinac37c502019-11-26 18:02:20 +0000260 s.builderForTests = builder
Jiyong Park9b409bc2019-10-11 14:59:13 +0900261
Jiyong Park232e7852019-11-04 12:23:40 +0900262 // copy exported AIDL files and stub jar files
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000263 javaLibs := s.javaLibs(ctx)
264 for _, m := range javaLibs {
265 m.BuildSnapshot(ctx, builder)
Jiyong Park73c54ee2019-10-22 20:31:18 +0900266 }
267
Paul Duffin91547182019-11-12 19:39:36 +0000268 // copy stubs sources
269 stubsSources := s.stubsSources(ctx)
270 for _, m := range stubsSources {
271 m.BuildSnapshot(ctx, builder)
272 }
273
Jiyong Park232e7852019-11-04 12:23:40 +0900274 // copy exported header files and stub *.so files
Jiyong Park73c54ee2019-10-22 20:31:18 +0900275 nativeLibInfos := s.nativeMemberInfos(ctx)
276 for _, info := range nativeLibInfos {
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000277 buildSharedNativeLibSnapshot(ctx, info, builder)
Jiyong Park73c54ee2019-10-22 20:31:18 +0900278 }
Jiyong Park9b409bc2019-10-11 14:59:13 +0900279
Paul Duffinb645ec82019-11-27 17:43:54 +0000280 for _, unversioned := range builder.prebuiltOrder {
281 // Copy the unversioned module so it can be modified to make it versioned.
282 versioned := unversioned.copy()
283 name := versioned.properties["name"].(string)
284 versioned.setProperty("name", builder.versionedSdkMemberName(name))
285 versioned.insertAfter("name", "sdk_member_name", name)
286 bpFile.AddModule(versioned)
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000287
Paul Duffinb645ec82019-11-27 17:43:54 +0000288 // Set prefer: false - this is not strictly required as that is the default.
289 unversioned.insertAfter("name", "prefer", false)
290 bpFile.AddModule(unversioned)
291 }
292
293 // Create the snapshot module.
294 snapshotName := ctx.ModuleName() + string(android.SdkVersionSeparator) + builder.version
295 snapshotModule := bpFile.newModule("sdk_snapshot")
296 snapshotModule.AddProperty("name", snapshotName)
Paul Duffine44358f2019-11-26 18:04:12 +0000297 addHostDeviceSupportedProperties(&s.ModuleBase, snapshotModule)
Paul Duffin66905ed2019-11-28 13:44:47 +0000298 if len(s.properties.Java_libs) > 0 {
Paul Duffinb645ec82019-11-27 17:43:54 +0000299 snapshotModule.AddProperty("java_libs", builder.versionedSdkMemberNames(s.properties.Java_libs))
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000300 }
Paul Duffin66905ed2019-11-28 13:44:47 +0000301 if len(s.properties.Stubs_sources) > 0 {
Paul Duffinb645ec82019-11-27 17:43:54 +0000302 snapshotModule.AddProperty("stubs_sources", builder.versionedSdkMemberNames(s.properties.Stubs_sources))
Paul Duffin91547182019-11-12 19:39:36 +0000303 }
Paul Duffin66905ed2019-11-28 13:44:47 +0000304 if len(s.properties.Native_shared_libs) > 0 {
Paul Duffinb645ec82019-11-27 17:43:54 +0000305 snapshotModule.AddProperty("native_shared_libs", builder.versionedSdkMemberNames(s.properties.Native_shared_libs))
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000306 }
Paul Duffinb645ec82019-11-27 17:43:54 +0000307 bpFile.AddModule(snapshotModule)
308
309 // generate Android.bp
310 bp = newGeneratedFile(ctx, "snapshot", "Android.bp")
311 generateBpContents(&bp.generatedContents, bpFile)
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000312
313 bp.build(pctx, ctx, nil)
314
315 filesToZip := builder.filesToZip
Jiyong Park9b409bc2019-10-11 14:59:13 +0900316
Jiyong Park232e7852019-11-04 12:23:40 +0900317 // zip them all
Paul Duffin91547182019-11-12 19:39:36 +0000318 outputZipFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.zip").OutputPath
319 outputRuleName := "snapshot"
320 outputDesc := "Building snapshot for " + ctx.ModuleName()
321
322 // If there are no zips to merge then generate the output zip directly.
323 // Otherwise, generate an intermediate zip file into which other zips can be
324 // merged.
325 var zipFile android.OutputPath
326 var ruleName string
327 var desc string
328 if len(builder.zipsToMerge) == 0 {
329 zipFile = outputZipFile
330 ruleName = outputRuleName
331 desc = outputDesc
332 } else {
333 zipFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.unmerged.zip").OutputPath
334 ruleName = "intermediate snapshot"
335 desc = "Building intermediate snapshot for " + ctx.ModuleName()
336 }
337
Jiyong Park232e7852019-11-04 12:23:40 +0900338 rb := android.NewRuleBuilder()
339 rb.Command().
340 BuiltTool(ctx, "soong_zip").
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000341 FlagWithArg("-C ", builder.snapshotDir.String()).
Jiyong Park232e7852019-11-04 12:23:40 +0900342 FlagWithRspFileInputList("-l ", filesToZip).
343 FlagWithOutput("-o ", zipFile)
Paul Duffin91547182019-11-12 19:39:36 +0000344 rb.Build(pctx, ctx, ruleName, desc)
Jiyong Park9b409bc2019-10-11 14:59:13 +0900345
Paul Duffin91547182019-11-12 19:39:36 +0000346 if len(builder.zipsToMerge) != 0 {
347 rb := android.NewRuleBuilder()
348 rb.Command().
349 BuiltTool(ctx, "merge_zips").
350 Output(outputZipFile).
351 Input(zipFile).
352 Inputs(builder.zipsToMerge)
353 rb.Build(pctx, ctx, outputRuleName, outputDesc)
354 }
355
356 return outputZipFile
Jiyong Park9b409bc2019-10-11 14:59:13 +0900357}
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000358
Paul Duffinb645ec82019-11-27 17:43:54 +0000359func generateBpContents(contents *generatedContents, bpFile *bpFile) {
360 contents.Printfln("// This is auto-generated. DO NOT EDIT.")
361 for _, bpModule := range bpFile.order {
362 contents.Printfln("")
363 contents.Printfln("%s {", bpModule.moduleType)
364 outputPropertySet(contents, &bpModule.bpPropertySet)
365 contents.Printfln("}")
366 }
367 contents.Printfln("")
368}
369
370func outputPropertySet(contents *generatedContents, set *bpPropertySet) {
371 contents.Indent()
372 for _, name := range set.order {
373 value := set.properties[name]
374
375 reflectedValue := reflect.ValueOf(value)
376 t := reflectedValue.Type()
377
378 kind := t.Kind()
379 switch kind {
380 case reflect.Slice:
381 length := reflectedValue.Len()
382 if length > 1 {
383 contents.Printfln("%s: [", name)
384 contents.Indent()
385 for i := 0; i < length; i = i + 1 {
386 contents.Printfln("%q,", reflectedValue.Index(i).Interface())
387 }
388 contents.Dedent()
389 contents.Printfln("],")
390 } else if length == 0 {
391 contents.Printfln("%s: [],", name)
392 } else {
393 contents.Printfln("%s: [%q],", name, reflectedValue.Index(0).Interface())
394 }
395 case reflect.Bool:
396 contents.Printfln("%s: %t,", name, reflectedValue.Bool())
397
398 case reflect.Ptr:
399 contents.Printfln("%s: {", name)
400 outputPropertySet(contents, reflectedValue.Interface().(*bpPropertySet))
401 contents.Printfln("},")
402
403 default:
404 contents.Printfln("%s: %q,", name, value)
405 }
406 }
407 contents.Dedent()
408}
409
Paul Duffinac37c502019-11-26 18:02:20 +0000410func (s *sdk) GetAndroidBpContentsForTests() string {
Paul Duffinb645ec82019-11-27 17:43:54 +0000411 contents := &generatedContents{}
412 generateBpContents(contents, s.builderForTests.bpFile)
413 return contents.content.String()
Paul Duffinac37c502019-11-26 18:02:20 +0000414}
415
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000416func buildSharedNativeLibSnapshot(ctx android.ModuleContext, info *nativeLibInfo, builder android.SnapshotBuilder) {
417 // a function for emitting include dirs
418 printExportedDirCopyCommandsForNativeLibs := func(lib archSpecificNativeLibInfo) {
419 includeDirs := lib.exportedIncludeDirs
420 includeDirs = append(includeDirs, lib.exportedSystemIncludeDirs...)
421 if len(includeDirs) == 0 {
422 return
423 }
424 for _, dir := range includeDirs {
425 if _, gen := dir.(android.WritablePath); gen {
426 // generated headers are copied via exportedDeps. See below.
427 continue
428 }
429 targetDir := nativeIncludeDir
430 if info.hasArchSpecificFlags {
431 targetDir = filepath.Join(lib.archType, targetDir)
432 }
433
434 // TODO(jiyong) copy headers having other suffixes
435 headers, _ := ctx.GlobWithDeps(dir.String()+"/**/*.h", nil)
436 for _, file := range headers {
437 src := android.PathForSource(ctx, file)
438 dest := filepath.Join(targetDir, file)
439 builder.CopyToSnapshot(src, dest)
440 }
441 }
442
443 genHeaders := lib.exportedDeps
444 for _, file := range genHeaders {
445 targetDir := nativeGeneratedIncludeDir
446 if info.hasArchSpecificFlags {
447 targetDir = filepath.Join(lib.archType, targetDir)
448 }
449 dest := filepath.Join(targetDir, lib.name, file.Rel())
450 builder.CopyToSnapshot(file, dest)
451 }
452 }
453
454 if !info.hasArchSpecificFlags {
455 printExportedDirCopyCommandsForNativeLibs(info.archVariants[0])
456 }
457
458 // for each architecture
459 for _, av := range info.archVariants {
460 builder.CopyToSnapshot(av.outputFile, nativeStubFilePathFor(av))
461
462 if info.hasArchSpecificFlags {
463 printExportedDirCopyCommandsForNativeLibs(av)
464 }
465 }
466
Paul Duffinb645ec82019-11-27 17:43:54 +0000467 info.generatePrebuiltLibrary(ctx, builder)
Paul Duffin90102502019-11-25 19:49:33 +0000468}
469
Paul Duffinb645ec82019-11-27 17:43:54 +0000470func (info *nativeLibInfo) generatePrebuiltLibrary(ctx android.ModuleContext, builder android.SnapshotBuilder) {
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000471
472 // a function for emitting include dirs
Paul Duffinb645ec82019-11-27 17:43:54 +0000473 addExportedDirsForNativeLibs := func(lib archSpecificNativeLibInfo, properties android.BpPropertySet, systemInclude bool) {
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000474 includeDirs := nativeIncludeDirPathsFor(ctx, lib, systemInclude, info.hasArchSpecificFlags)
475 if len(includeDirs) == 0 {
476 return
477 }
Paul Duffinb645ec82019-11-27 17:43:54 +0000478 var propertyName string
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000479 if !systemInclude {
Paul Duffinb645ec82019-11-27 17:43:54 +0000480 propertyName = "export_include_dirs"
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000481 } else {
Paul Duffinb645ec82019-11-27 17:43:54 +0000482 propertyName = "export_system_include_dirs"
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000483 }
Paul Duffinb645ec82019-11-27 17:43:54 +0000484 properties.AddProperty(propertyName, includeDirs)
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000485 }
486
Paul Duffinb645ec82019-11-27 17:43:54 +0000487 pbm := builder.AddPrebuiltModule(info.name, "cc_prebuilt_library_shared")
488
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000489 if !info.hasArchSpecificFlags {
Paul Duffinb645ec82019-11-27 17:43:54 +0000490 addExportedDirsForNativeLibs(info.archVariants[0], pbm, false /*systemInclude*/)
491 addExportedDirsForNativeLibs(info.archVariants[0], pbm, true /*systemInclude*/)
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000492 }
493
Paul Duffinb645ec82019-11-27 17:43:54 +0000494 archProperties := pbm.AddPropertySet("arch")
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000495 for _, av := range info.archVariants {
Paul Duffinb645ec82019-11-27 17:43:54 +0000496 archTypeProperties := archProperties.AddPropertySet(av.archType)
497 archTypeProperties.AddProperty("srcs", []string{nativeStubFilePathFor(av)})
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000498 if info.hasArchSpecificFlags {
499 // export_* properties are added inside the arch: {<arch>: {...}} block
Paul Duffinb645ec82019-11-27 17:43:54 +0000500 addExportedDirsForNativeLibs(av, archTypeProperties, false /*systemInclude*/)
501 addExportedDirsForNativeLibs(av, archTypeProperties, true /*systemInclude*/)
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000502 }
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000503 }
Paul Duffinb645ec82019-11-27 17:43:54 +0000504 pbm.AddProperty("stl", "none")
505 pbm.AddProperty("system_shared_libs", []string{})
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000506}
507
508type snapshotBuilder struct {
Paul Duffinb645ec82019-11-27 17:43:54 +0000509 ctx android.ModuleContext
Paul Duffine44358f2019-11-26 18:04:12 +0000510 sdk *sdk
Paul Duffinb645ec82019-11-27 17:43:54 +0000511 version string
512 snapshotDir android.OutputPath
513 bpFile *bpFile
514 filesToZip android.Paths
515 zipsToMerge android.Paths
516
517 prebuiltModules map[string]*bpModule
518 prebuiltOrder []*bpModule
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000519}
520
521func (s *snapshotBuilder) CopyToSnapshot(src android.Path, dest string) {
522 path := s.snapshotDir.Join(s.ctx, dest)
523 s.ctx.Build(pctx, android.BuildParams{
524 Rule: android.Cp,
525 Input: src,
526 Output: path,
527 })
528 s.filesToZip = append(s.filesToZip, path)
529}
530
Paul Duffin91547182019-11-12 19:39:36 +0000531func (s *snapshotBuilder) UnzipToSnapshot(zipPath android.Path, destDir string) {
532 ctx := s.ctx
533
534 // Repackage the zip file so that the entries are in the destDir directory.
535 // This will allow the zip file to be merged into the snapshot.
536 tmpZipPath := android.PathForModuleOut(ctx, "tmp", destDir+".zip").OutputPath
537 rb := android.NewRuleBuilder()
538 rb.Command().
539 BuiltTool(ctx, "zip2zip").
540 FlagWithInput("-i ", zipPath).
541 FlagWithOutput("-o ", tmpZipPath).
542 Flag("**/*:" + destDir)
543 rb.Build(pctx, ctx, "repackaging "+destDir,
544 "Repackaging zip file "+destDir+" for snapshot "+ctx.ModuleName())
545
546 // Add the repackaged zip file to the files to merge.
547 s.zipsToMerge = append(s.zipsToMerge, tmpZipPath)
548}
549
Paul Duffinb645ec82019-11-27 17:43:54 +0000550func (s *snapshotBuilder) AddPrebuiltModule(name string, moduleType string) android.BpModule {
551 if s.prebuiltModules[name] != nil {
552 panic(fmt.Sprintf("Duplicate module detected, module %s has already been added", name))
553 }
554
555 m := s.bpFile.newModule(moduleType)
556 m.AddProperty("name", name)
Paul Duffine44358f2019-11-26 18:04:12 +0000557 addHostDeviceSupportedProperties(&s.sdk.ModuleBase, m)
Paul Duffinb645ec82019-11-27 17:43:54 +0000558
559 s.prebuiltModules[name] = m
560 s.prebuiltOrder = append(s.prebuiltOrder, m)
561 return m
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000562}
563
Paul Duffine44358f2019-11-26 18:04:12 +0000564func addHostDeviceSupportedProperties(module *android.ModuleBase, bpModule *bpModule) {
565 if !module.DeviceSupported() {
566 bpModule.AddProperty("device_supported", false)
567 }
568 if module.HostSupported() {
569 bpModule.AddProperty("host_supported", true)
570 }
571}
572
Paul Duffinb645ec82019-11-27 17:43:54 +0000573// Get a versioned name appropriate for the SDK snapshot version being taken.
574func (s *snapshotBuilder) versionedSdkMemberName(unversionedName string) string {
Paul Duffin0e0cf1d2019-11-12 19:39:25 +0000575 return versionedSdkMemberName(s.ctx, unversionedName, s.version)
576}
Paul Duffinb645ec82019-11-27 17:43:54 +0000577
578func (s *snapshotBuilder) versionedSdkMemberNames(members []string) []string {
579 var references []string = nil
580 for _, m := range members {
581 references = append(references, s.versionedSdkMemberName(m))
582 }
583 return references
584}