blob: bb4aafce3fa0b20f7854d0ed92465e4f412d6416 [file] [log] [blame]
Justin Yun8effde42017-06-23 19:24:43 +09001// Copyright 2017 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 (
Inseob Kimae553032019-05-14 18:52:49 +090018 "encoding/json"
Martin Stjernholm257eb0c2018-10-15 13:05:27 +010019 "errors"
Jooyung Han0302a842019-10-30 18:43:49 +090020 "fmt"
Inseob Kim1f086e22019-05-09 13:29:15 +090021 "path/filepath"
Inseob Kim242ef0c2019-10-22 20:15:20 +090022 "sort"
Jiyong Parkd5b18a52017-08-03 21:22:50 +090023 "strings"
24 "sync"
25
Justin Yun8effde42017-06-23 19:24:43 +090026 "android/soong/android"
Vic Yangefd249e2018-11-12 20:19:56 -080027 "android/soong/cc/config"
Justin Yun8effde42017-06-23 19:24:43 +090028)
29
30type VndkProperties struct {
31 Vndk struct {
32 // declared as a VNDK or VNDK-SP module. The vendor variant
33 // will be installed in /system instead of /vendor partition.
34 //
Roland Levillaindfe75b32019-07-23 16:53:32 +010035 // `vendor_available` must be explicitly set to either true or
Jiyong Park82e2bf32017-08-16 14:05:54 +090036 // false together with `vndk: {enabled: true}`.
Justin Yun8effde42017-06-23 19:24:43 +090037 Enabled *bool
38
39 // declared as a VNDK-SP module, which is a subset of VNDK.
40 //
41 // `vndk: { enabled: true }` must set together.
42 //
43 // All these modules are allowed to link to VNDK-SP or LL-NDK
44 // modules only. Other dependency will cause link-type errors.
45 //
46 // If `support_system_process` is not set or set to false,
47 // the module is VNDK-core and can link to other VNDK-core,
48 // VNDK-SP or LL-NDK modules only.
49 Support_system_process *bool
Logan Chienf3511742017-10-31 18:04:35 +080050
51 // Extending another module
52 Extends *string
Justin Yun8effde42017-06-23 19:24:43 +090053 }
54}
55
56type vndkdep struct {
57 Properties VndkProperties
58}
59
60func (vndk *vndkdep) props() []interface{} {
61 return []interface{}{&vndk.Properties}
62}
63
64func (vndk *vndkdep) begin(ctx BaseModuleContext) {}
65
66func (vndk *vndkdep) deps(ctx BaseModuleContext, deps Deps) Deps {
67 return deps
68}
69
70func (vndk *vndkdep) isVndk() bool {
71 return Bool(vndk.Properties.Vndk.Enabled)
72}
73
74func (vndk *vndkdep) isVndkSp() bool {
75 return Bool(vndk.Properties.Vndk.Support_system_process)
76}
77
Logan Chienf3511742017-10-31 18:04:35 +080078func (vndk *vndkdep) isVndkExt() bool {
79 return vndk.Properties.Vndk.Extends != nil
80}
81
82func (vndk *vndkdep) getVndkExtendsModuleName() string {
83 return String(vndk.Properties.Vndk.Extends)
84}
85
Justin Yun8effde42017-06-23 19:24:43 +090086func (vndk *vndkdep) typeName() string {
87 if !vndk.isVndk() {
88 return "native:vendor"
89 }
Logan Chienf3511742017-10-31 18:04:35 +080090 if !vndk.isVndkExt() {
91 if !vndk.isVndkSp() {
92 return "native:vendor:vndk"
93 }
94 return "native:vendor:vndksp"
Justin Yun8effde42017-06-23 19:24:43 +090095 }
Logan Chienf3511742017-10-31 18:04:35 +080096 if !vndk.isVndkSp() {
97 return "native:vendor:vndkext"
98 }
99 return "native:vendor:vndkspext"
Justin Yun8effde42017-06-23 19:24:43 +0900100}
101
Ivan Lozano183a3212019-10-18 14:18:45 -0700102func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, tag DependencyTag) {
Justin Yun8effde42017-06-23 19:24:43 +0900103 if to.linker == nil {
104 return
105 }
Jiyong Park82e2bf32017-08-16 14:05:54 +0900106 if !vndk.isVndk() {
107 // Non-VNDK modules (those installed to /vendor) can't depend on modules marked with
108 // vendor_available: false.
109 violation := false
Nan Zhang0007d812017-11-07 10:57:05 -0800110 if lib, ok := to.linker.(*llndkStubDecorator); ok && !Bool(lib.Properties.Vendor_available) {
Jiyong Park82e2bf32017-08-16 14:05:54 +0900111 violation = true
112 } else {
113 if _, ok := to.linker.(libraryInterface); ok && to.VendorProperties.Vendor_available != nil && !Bool(to.VendorProperties.Vendor_available) {
114 // Vendor_available == nil && !Bool(Vendor_available) should be okay since
115 // it means a vendor-only library which is a valid dependency for non-VNDK
116 // modules.
117 violation = true
118 }
119 }
120 if violation {
121 ctx.ModuleErrorf("Vendor module that is not VNDK should not link to %q which is marked as `vendor_available: false`", to.Name())
122 }
123 }
Justin Yun8effde42017-06-23 19:24:43 +0900124 if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() {
125 // Check only shared libraries.
126 // Other (static and LL-NDK) libraries are allowed to link.
127 return
128 }
Ivan Lozano52767be2019-10-18 14:49:46 -0700129 if !to.UseVndk() {
Justin Yun8effde42017-06-23 19:24:43 +0900130 ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library",
131 vndk.typeName(), to.Name())
132 return
133 }
Logan Chienf3511742017-10-31 18:04:35 +0800134 if tag == vndkExtDepTag {
135 // Ensure `extends: "name"` property refers a vndk module that has vendor_available
136 // and has identical vndk properties.
137 if to.vndkdep == nil || !to.vndkdep.isVndk() {
138 ctx.ModuleErrorf("`extends` refers a non-vndk module %q", to.Name())
139 return
140 }
141 if vndk.isVndkSp() != to.vndkdep.isVndkSp() {
142 ctx.ModuleErrorf(
143 "`extends` refers a module %q with mismatched support_system_process",
144 to.Name())
145 return
146 }
147 if !Bool(to.VendorProperties.Vendor_available) {
148 ctx.ModuleErrorf(
149 "`extends` refers module %q which does not have `vendor_available: true`",
150 to.Name())
151 return
152 }
153 }
Justin Yun8effde42017-06-23 19:24:43 +0900154 if to.vndkdep == nil {
155 return
156 }
Logan Chienf3511742017-10-31 18:04:35 +0800157
Logan Chiend3c59a22018-03-29 14:08:15 +0800158 // Check the dependencies of VNDK shared libraries.
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100159 if err := vndkIsVndkDepAllowed(vndk, to.vndkdep); err != nil {
160 ctx.ModuleErrorf("(%s) should not link to %q (%s): %v",
161 vndk.typeName(), to.Name(), to.vndkdep.typeName(), err)
Logan Chienf3511742017-10-31 18:04:35 +0800162 return
163 }
Logan Chiend3c59a22018-03-29 14:08:15 +0800164}
Logan Chienf3511742017-10-31 18:04:35 +0800165
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100166func vndkIsVndkDepAllowed(from *vndkdep, to *vndkdep) error {
Logan Chiend3c59a22018-03-29 14:08:15 +0800167 // Check the dependencies of VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext and vendor modules.
168 if from.isVndkExt() {
169 if from.isVndkSp() {
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100170 if to.isVndk() && !to.isVndkSp() {
171 return errors.New("VNDK-SP extensions must not depend on VNDK or VNDK extensions")
172 }
173 return nil
Logan Chiend3c59a22018-03-29 14:08:15 +0800174 }
175 // VNDK-Ext may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100176 return nil
Justin Yun8effde42017-06-23 19:24:43 +0900177 }
Logan Chiend3c59a22018-03-29 14:08:15 +0800178 if from.isVndk() {
179 if to.isVndkExt() {
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100180 return errors.New("VNDK-core and VNDK-SP must not depend on VNDK extensions")
Logan Chiend3c59a22018-03-29 14:08:15 +0800181 }
182 if from.isVndkSp() {
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100183 if !to.isVndkSp() {
184 return errors.New("VNDK-SP must only depend on VNDK-SP")
185 }
186 return nil
Logan Chiend3c59a22018-03-29 14:08:15 +0800187 }
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100188 if !to.isVndk() {
189 return errors.New("VNDK-core must only depend on VNDK-core or VNDK-SP")
190 }
191 return nil
Logan Chiend3c59a22018-03-29 14:08:15 +0800192 }
193 // Vendor modules may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100194 return nil
Justin Yun8effde42017-06-23 19:24:43 +0900195}
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900196
197var (
Jooyung Hana463f722019-11-01 08:45:59 +0900198 vndkCoreLibrariesKey = android.NewOnceKey("vndkCoreLibrarires")
199 vndkSpLibrariesKey = android.NewOnceKey("vndkSpLibrarires")
200 llndkLibrariesKey = android.NewOnceKey("llndkLibrarires")
201 vndkPrivateLibrariesKey = android.NewOnceKey("vndkPrivateLibrarires")
202 vndkUsingCoreVariantLibrariesKey = android.NewOnceKey("vndkUsingCoreVariantLibrarires")
Jooyung Hana463f722019-11-01 08:45:59 +0900203 vndkMustUseVendorVariantListKey = android.NewOnceKey("vndkMustUseVendorVariantListKey")
204 vndkLibrariesLock sync.Mutex
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900205
Inseob Kimae553032019-05-14 18:52:49 +0900206 headerExts = []string{".h", ".hh", ".hpp", ".hxx", ".h++", ".inl", ".inc", ".ipp", ".h.generic"}
207)
Inseob Kim1f086e22019-05-09 13:29:15 +0900208
Jooyung Han0302a842019-10-30 18:43:49 +0900209func vndkCoreLibraries(config android.Config) map[string]string {
Inseob Kim9516ee92019-05-09 10:56:13 +0900210 return config.Once(vndkCoreLibrariesKey, func() interface{} {
Jooyung Han0302a842019-10-30 18:43:49 +0900211 return make(map[string]string)
212 }).(map[string]string)
Inseob Kim9516ee92019-05-09 10:56:13 +0900213}
214
Jooyung Han0302a842019-10-30 18:43:49 +0900215func vndkSpLibraries(config android.Config) map[string]string {
Inseob Kim9516ee92019-05-09 10:56:13 +0900216 return config.Once(vndkSpLibrariesKey, func() interface{} {
Jooyung Han0302a842019-10-30 18:43:49 +0900217 return make(map[string]string)
218 }).(map[string]string)
Inseob Kim9516ee92019-05-09 10:56:13 +0900219}
220
Jooyung Han0302a842019-10-30 18:43:49 +0900221func isLlndkLibrary(baseModuleName string, config android.Config) bool {
222 _, ok := llndkLibraries(config)[baseModuleName]
223 return ok
224}
225
226func llndkLibraries(config android.Config) map[string]string {
Inseob Kim9516ee92019-05-09 10:56:13 +0900227 return config.Once(llndkLibrariesKey, func() interface{} {
Jooyung Han0302a842019-10-30 18:43:49 +0900228 return make(map[string]string)
229 }).(map[string]string)
Inseob Kim9516ee92019-05-09 10:56:13 +0900230}
231
Jooyung Han0302a842019-10-30 18:43:49 +0900232func isVndkPrivateLibrary(baseModuleName string, config android.Config) bool {
233 _, ok := vndkPrivateLibraries(config)[baseModuleName]
234 return ok
235}
236
237func vndkPrivateLibraries(config android.Config) map[string]string {
Inseob Kim9516ee92019-05-09 10:56:13 +0900238 return config.Once(vndkPrivateLibrariesKey, func() interface{} {
Jooyung Han0302a842019-10-30 18:43:49 +0900239 return make(map[string]string)
240 }).(map[string]string)
Inseob Kim9516ee92019-05-09 10:56:13 +0900241}
242
Jooyung Han0302a842019-10-30 18:43:49 +0900243func vndkUsingCoreVariantLibraries(config android.Config) map[string]string {
Inseob Kim9516ee92019-05-09 10:56:13 +0900244 return config.Once(vndkUsingCoreVariantLibrariesKey, func() interface{} {
Jooyung Han0302a842019-10-30 18:43:49 +0900245 return make(map[string]string)
246 }).(map[string]string)
Inseob Kim9516ee92019-05-09 10:56:13 +0900247}
248
Jooyung Han097087b2019-10-22 19:32:18 +0900249func vndkMustUseVendorVariantList(cfg android.Config) []string {
250 return cfg.Once(vndkMustUseVendorVariantListKey, func() interface{} {
Jooyung Han097087b2019-10-22 19:32:18 +0900251 return config.VndkMustUseVendorVariantList
252 }).([]string)
253}
254
255// test may call this to override global configuration(config.VndkMustUseVendorVariantList)
256// when it is called, it must be before the first call to vndkMustUseVendorVariantList()
257func setVndkMustUseVendorVariantListForTest(config android.Config, mustUseVendorVariantList []string) {
Jooyung Hana463f722019-11-01 08:45:59 +0900258 config.Once(vndkMustUseVendorVariantListKey, func() interface{} {
Jooyung Han097087b2019-10-22 19:32:18 +0900259 return mustUseVendorVariantList
260 })
261}
262
Inseob Kim1f086e22019-05-09 13:29:15 +0900263func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
264 lib := m.linker.(*llndkStubDecorator)
Jooyung Han0302a842019-10-30 18:43:49 +0900265 name := m.BaseModuleName()
266 filename := m.BaseModuleName() + ".so"
Inseob Kim9516ee92019-05-09 10:56:13 +0900267
Inseob Kim1f086e22019-05-09 13:29:15 +0900268 vndkLibrariesLock.Lock()
269 defer vndkLibrariesLock.Unlock()
Inseob Kim9516ee92019-05-09 10:56:13 +0900270
Jooyung Han0302a842019-10-30 18:43:49 +0900271 llndkLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900272 if !Bool(lib.Properties.Vendor_available) {
Jooyung Han0302a842019-10-30 18:43:49 +0900273 vndkPrivateLibraries(mctx.Config())[name] = filename
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900274 }
275}
Inseob Kim1f086e22019-05-09 13:29:15 +0900276
277func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
Jooyung Han0302a842019-10-30 18:43:49 +0900278 name := m.BaseModuleName()
279 filename, err := getVndkFileName(m)
280 if err != nil {
281 panic(err)
282 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900283
284 vndkLibrariesLock.Lock()
285 defer vndkLibrariesLock.Unlock()
286
Jooyung Han097087b2019-10-22 19:32:18 +0900287 if inList(name, vndkMustUseVendorVariantList(mctx.Config())) {
288 m.Properties.MustUseVendorVariant = true
289 }
Jooyung Han0302a842019-10-30 18:43:49 +0900290 if mctx.DeviceConfig().VndkUseCoreVariant() && !m.Properties.MustUseVendorVariant {
291 vndkUsingCoreVariantLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900292 }
Jooyung Han0302a842019-10-30 18:43:49 +0900293
Inseob Kim1f086e22019-05-09 13:29:15 +0900294 if m.vndkdep.isVndkSp() {
Jooyung Han0302a842019-10-30 18:43:49 +0900295 vndkSpLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900296 } else {
Jooyung Han0302a842019-10-30 18:43:49 +0900297 vndkCoreLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900298 }
299 if !Bool(m.VendorProperties.Vendor_available) {
Jooyung Han0302a842019-10-30 18:43:49 +0900300 vndkPrivateLibraries(mctx.Config())[name] = filename
Inseob Kim1f086e22019-05-09 13:29:15 +0900301 }
302}
303
Jooyung Han31c470b2019-10-18 16:26:59 +0900304func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
305 if !m.Enabled() {
306 return false
307 }
308
Jooyung Han87a7f302019-10-29 05:18:21 +0900309 if !mctx.Device() {
310 return false
311 }
312
Jooyung Han31c470b2019-10-18 16:26:59 +0900313 if m.Target().NativeBridge == android.NativeBridgeEnabled {
314 return false
315 }
316
317 // prebuilt vndk modules should match with device
318 // TODO(b/142675459): Use enabled: to select target device in vndk_prebuilt_shared
319 // When b/142675459 is landed, remove following check
320 if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok && !p.matchesWithDevice(mctx.DeviceConfig()) {
321 return false
322 }
323
324 if lib, ok := m.linker.(libraryInterface); ok {
325 useCoreVariant := m.vndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
Jooyung Han87a7f302019-10-29 05:18:21 +0900326 mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant()
Ivan Lozano52767be2019-10-18 14:49:46 -0700327 return lib.shared() && m.UseVndk() && m.IsVndk() && !m.isVndkExt() && !useCoreVariant
Jooyung Han31c470b2019-10-18 16:26:59 +0900328 }
329 return false
330}
331
Inseob Kim1f086e22019-05-09 13:29:15 +0900332// gather list of vndk-core, vndk-sp, and ll-ndk libs
333func VndkMutator(mctx android.BottomUpMutatorContext) {
334 m, ok := mctx.Module().(*Module)
335 if !ok {
336 return
337 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900338 if !m.Enabled() {
339 return
340 }
Justin Yun7390ea32019-09-08 11:34:06 +0900341 if m.Target().NativeBridge == android.NativeBridgeEnabled {
342 // Skip native_bridge modules
343 return
344 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900345
346 if _, ok := m.linker.(*llndkStubDecorator); ok {
347 processLlndkLibrary(mctx, m)
348 return
349 }
350
351 lib, is_lib := m.linker.(*libraryDecorator)
352 prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker)
353
Inseob Kim64c43952019-08-26 16:52:35 +0900354 if (is_lib && lib.buildShared()) || (is_prebuilt_lib && prebuilt_lib.buildShared()) {
355 if m.vndkdep != nil && m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
Inseob Kim1f086e22019-05-09 13:29:15 +0900356 processVndkLibrary(mctx, m)
357 return
358 }
359 }
360}
361
362func init() {
363 android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
Inseob Kim1f086e22019-05-09 13:29:15 +0900364}
365
366func VndkSnapshotSingleton() android.Singleton {
367 return &vndkSnapshotSingleton{}
368}
369
Jooyung Han0302a842019-10-30 18:43:49 +0900370type vndkSnapshotSingleton struct {
371 installedLlndkLibraries []string
Inseob Kim242ef0c2019-10-22 20:15:20 +0900372 llndkLibrariesFile android.Path
Jooyung Han0302a842019-10-30 18:43:49 +0900373 vndkSpLibrariesFile android.Path
374 vndkCoreLibrariesFile android.Path
375 vndkPrivateLibrariesFile android.Path
376 vndkCoreVariantLibrariesFile android.Path
377 vndkLibrariesFile android.Path
Inseob Kim242ef0c2019-10-22 20:15:20 +0900378 vndkSnapshotZipFile android.OptionalPath
Jooyung Han0302a842019-10-30 18:43:49 +0900379}
Inseob Kim1f086e22019-05-09 13:29:15 +0900380
Inseob Kim1f086e22019-05-09 13:29:15 +0900381func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
Jooyung Han0302a842019-10-30 18:43:49 +0900382 // build these files even if PlatformVndkVersion or BoardVndkVersion is not set
383 c.buildVndkLibrariesTxtFiles(ctx)
384
Inseob Kim1f086e22019-05-09 13:29:15 +0900385 // BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot.
386 if ctx.DeviceConfig().VndkVersion() != "current" {
387 return
388 }
389
390 if ctx.DeviceConfig().PlatformVndkVersion() == "" {
391 return
392 }
393
394 if ctx.DeviceConfig().BoardVndkRuntimeDisable() {
395 return
396 }
397
Inseob Kim242ef0c2019-10-22 20:15:20 +0900398 var snapshotOutputs android.Paths
399
400 /*
401 VNDK snapshot zipped artifacts directory structure:
402 {SNAPSHOT_ARCH}/
403 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/
404 shared/
405 vndk-core/
406 (VNDK-core libraries, e.g. libbinder.so)
407 vndk-sp/
408 (VNDK-SP libraries, e.g. libc++.so)
409 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/
410 shared/
411 vndk-core/
412 (VNDK-core libraries, e.g. libbinder.so)
413 vndk-sp/
414 (VNDK-SP libraries, e.g. libc++.so)
415 binder32/
416 (This directory is newly introduced in v28 (Android P) to hold
417 prebuilts built for 32-bit binder interface.)
418 arch-{TARGET_ARCH}-{TARGE_ARCH_VARIANT}/
419 ...
420 configs/
421 (various *.txt configuration files)
422 include/
423 (header files of same directory structure with source tree)
424 NOTICE_FILES/
425 (notice files of libraries, e.g. libcutils.so.txt)
426 */
Inseob Kim1f086e22019-05-09 13:29:15 +0900427
428 snapshotDir := "vndk-snapshot"
Inseob Kim242ef0c2019-10-22 20:15:20 +0900429 snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
Inseob Kim1f086e22019-05-09 13:29:15 +0900430
Inseob Kim242ef0c2019-10-22 20:15:20 +0900431 targetArchDirMap := make(map[android.ArchType]string)
Inseob Kimae553032019-05-14 18:52:49 +0900432 for _, target := range ctx.Config().Targets[android.Android] {
Inseob Kim242ef0c2019-10-22 20:15:20 +0900433 dir := snapshotArchDir
Inseob Kimae553032019-05-14 18:52:49 +0900434 if ctx.DeviceConfig().BinderBitness() == "32" {
435 dir = filepath.Join(dir, "binder32")
436 }
437 arch := "arch-" + target.Arch.ArchType.String()
438 if target.Arch.ArchVariant != "" {
439 arch += "-" + target.Arch.ArchVariant
440 }
441 dir = filepath.Join(dir, arch)
Inseob Kim242ef0c2019-10-22 20:15:20 +0900442 targetArchDirMap[target.Arch.ArchType] = dir
Inseob Kim1f086e22019-05-09 13:29:15 +0900443 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900444 configsDir := filepath.Join(snapshotArchDir, "configs")
445 noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES")
446 includeDir := filepath.Join(snapshotArchDir, "include")
447
448 // set of include paths exported by VNDK libraries
449 exportedIncludes := make(map[string]bool)
450
451 // generated header files among exported headers.
452 var generatedHeaders android.Paths
453
454 // set of notice files copied.
Inseob Kim1f086e22019-05-09 13:29:15 +0900455 noticeBuilt := make(map[string]bool)
456
Inseob Kim242ef0c2019-10-22 20:15:20 +0900457 // paths of VNDK modules for GPL license checking
458 modulePaths := make(map[string]string)
459
460 // actual module names of .so files
461 // e.g. moduleNames["libprotobuf-cpp-full-3.9.1.so"] = "libprotobuf-cpp-full"
462 moduleNames := make(map[string]string)
463
464 installSnapshotFileFromPath := func(path android.Path, out string) android.OutputPath {
465 outPath := android.PathForOutput(ctx, out)
Inseob Kimae553032019-05-14 18:52:49 +0900466 ctx.Build(pctx, android.BuildParams{
467 Rule: android.Cp,
468 Input: path,
Inseob Kim242ef0c2019-10-22 20:15:20 +0900469 Output: outPath,
Inseob Kimae553032019-05-14 18:52:49 +0900470 Description: "vndk snapshot " + out,
471 Args: map[string]string{
472 "cpFlags": "-f -L",
473 },
474 })
Inseob Kim242ef0c2019-10-22 20:15:20 +0900475 return outPath
Inseob Kimae553032019-05-14 18:52:49 +0900476 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900477
478 installSnapshotFileFromContent := func(content, out string) android.OutputPath {
479 outPath := android.PathForOutput(ctx, out)
Inseob Kimae553032019-05-14 18:52:49 +0900480 ctx.Build(pctx, android.BuildParams{
481 Rule: android.WriteFile,
Inseob Kim242ef0c2019-10-22 20:15:20 +0900482 Output: outPath,
Inseob Kimae553032019-05-14 18:52:49 +0900483 Description: "vndk snapshot " + out,
484 Args: map[string]string{
485 "content": content,
486 },
487 })
Inseob Kim242ef0c2019-10-22 20:15:20 +0900488 return outPath
Inseob Kimae553032019-05-14 18:52:49 +0900489 }
490
Inseob Kimae553032019-05-14 18:52:49 +0900491 type vndkSnapshotLibraryInterface interface {
492 exportedFlagsProducer
493 libraryInterface
494 }
495
496 var _ vndkSnapshotLibraryInterface = (*prebuiltLibraryLinker)(nil)
497 var _ vndkSnapshotLibraryInterface = (*libraryDecorator)(nil)
498
Inseob Kim242ef0c2019-10-22 20:15:20 +0900499 installVndkSnapshotLib := func(m *Module, l vndkSnapshotLibraryInterface, vndkType string) (android.Paths, bool) {
500 targetArchDir, ok := targetArchDirMap[m.Target().Arch.ArchType]
501 if !ok {
502 return nil, false
503 }
Inseob Kimae553032019-05-14 18:52:49 +0900504
Inseob Kim242ef0c2019-10-22 20:15:20 +0900505 var ret android.Paths
506
507 libPath := m.outputFile.Path()
508 stem := libPath.Base()
509 snapshotLibOut := filepath.Join(targetArchDir, "shared", vndkType, stem)
510 ret = append(ret, installSnapshotFileFromPath(libPath, snapshotLibOut))
511
512 moduleNames[stem] = ctx.ModuleName(m)
513 modulePaths[stem] = ctx.ModuleDir(m)
514
515 if m.NoticeFile().Valid() {
516 noticeName := stem + ".txt"
517 // skip already copied notice file
518 if _, ok := noticeBuilt[noticeName]; !ok {
519 noticeBuilt[noticeName] = true
520 ret = append(ret, installSnapshotFileFromPath(
521 m.NoticeFile().Path(), filepath.Join(noticeDir, noticeName)))
522 }
523 }
Inseob Kimae553032019-05-14 18:52:49 +0900524
525 if ctx.Config().VndkSnapshotBuildArtifacts() {
526 prop := struct {
527 ExportedDirs []string `json:",omitempty"`
528 ExportedSystemDirs []string `json:",omitempty"`
529 ExportedFlags []string `json:",omitempty"`
530 RelativeInstallPath string `json:",omitempty"`
531 }{}
532 prop.ExportedFlags = l.exportedFlags()
Jiyong Park74955042019-10-22 20:19:51 +0900533 prop.ExportedDirs = l.exportedDirs().Strings()
534 prop.ExportedSystemDirs = l.exportedSystemDirs().Strings()
Inseob Kimae553032019-05-14 18:52:49 +0900535 prop.RelativeInstallPath = m.RelativeInstallPath()
536
Inseob Kim242ef0c2019-10-22 20:15:20 +0900537 propOut := snapshotLibOut + ".json"
Inseob Kimae553032019-05-14 18:52:49 +0900538
539 j, err := json.Marshal(prop)
540 if err != nil {
541 ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
Inseob Kim242ef0c2019-10-22 20:15:20 +0900542 return nil, false
Inseob Kimae553032019-05-14 18:52:49 +0900543 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900544 ret = append(ret, installSnapshotFileFromContent(string(j), propOut))
Inseob Kimae553032019-05-14 18:52:49 +0900545 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900546 return ret, true
Inseob Kimae553032019-05-14 18:52:49 +0900547 }
548
Inseob Kim242ef0c2019-10-22 20:15:20 +0900549 isVndkSnapshotLibrary := func(m *Module) (i vndkSnapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) {
Inseob Kimae553032019-05-14 18:52:49 +0900550 if m.Target().NativeBridge == android.NativeBridgeEnabled {
551 return nil, "", false
552 }
Ivan Lozano52767be2019-10-18 14:49:46 -0700553 if !m.UseVndk() || !m.IsForPlatform() || !m.installable() {
Inseob Kimae553032019-05-14 18:52:49 +0900554 return nil, "", false
555 }
556 l, ok := m.linker.(vndkSnapshotLibraryInterface)
557 if !ok || !l.shared() {
558 return nil, "", false
559 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900560 if m.vndkVersion() == ctx.DeviceConfig().PlatformVndkVersion() && m.IsVndk() && !m.isVndkExt() {
561 if m.isVndkSp() {
562 return l, "vndk-sp", true
563 } else {
564 return l, "vndk-core", true
565 }
Inseob Kimae553032019-05-14 18:52:49 +0900566 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900567
568 return nil, "", false
Inseob Kimae553032019-05-14 18:52:49 +0900569 }
570
Inseob Kim1f086e22019-05-09 13:29:15 +0900571 ctx.VisitAllModules(func(module android.Module) {
572 m, ok := module.(*Module)
Inseob Kimae553032019-05-14 18:52:49 +0900573 if !ok || !m.Enabled() {
Inseob Kim1f086e22019-05-09 13:29:15 +0900574 return
575 }
576
Inseob Kim242ef0c2019-10-22 20:15:20 +0900577 l, vndkType, ok := isVndkSnapshotLibrary(m)
Inseob Kimae553032019-05-14 18:52:49 +0900578 if !ok {
dimitry51ea18a2019-05-20 10:39:52 +0200579 return
580 }
581
Inseob Kim242ef0c2019-10-22 20:15:20 +0900582 libs, ok := installVndkSnapshotLib(m, l, vndkType)
Inseob Kimae553032019-05-14 18:52:49 +0900583 if !ok {
Inseob Kim1f086e22019-05-09 13:29:15 +0900584 return
585 }
586
Inseob Kim242ef0c2019-10-22 20:15:20 +0900587 snapshotOutputs = append(snapshotOutputs, libs...)
Inseob Kim1f086e22019-05-09 13:29:15 +0900588
Inseob Kim242ef0c2019-10-22 20:15:20 +0900589 // We glob headers from include directories inside source tree. So we first gather
590 // all include directories inside our source tree. On the contrast, we manually
591 // collect generated headers from dependencies as they can't globbed.
Inseob Kimae553032019-05-14 18:52:49 +0900592 generatedHeaders = append(generatedHeaders, l.exportedDeps()...)
593 for _, dir := range append(l.exportedDirs(), l.exportedSystemDirs()...) {
Inseob Kim242ef0c2019-10-22 20:15:20 +0900594 exportedIncludes[dir.String()] = true
Inseob Kimae553032019-05-14 18:52:49 +0900595 }
596 })
Inseob Kim1f086e22019-05-09 13:29:15 +0900597
Inseob Kimae553032019-05-14 18:52:49 +0900598 if ctx.Config().VndkSnapshotBuildArtifacts() {
Inseob Kim242ef0c2019-10-22 20:15:20 +0900599 globbedHeaders := make(map[string]bool)
Inseob Kimae553032019-05-14 18:52:49 +0900600
Inseob Kim242ef0c2019-10-22 20:15:20 +0900601 for _, dir := range android.SortedStringKeys(exportedIncludes) {
602 // Skip if dir is for generated headers
Inseob Kimae553032019-05-14 18:52:49 +0900603 if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) {
604 continue
Inseob Kim1f086e22019-05-09 13:29:15 +0900605 }
Inseob Kimae553032019-05-14 18:52:49 +0900606 exts := headerExts
607 // Glob all files under this special directory, because of C++ headers.
608 if strings.HasPrefix(dir, "external/libcxx/include") {
609 exts = []string{""}
Inseob Kim1f086e22019-05-09 13:29:15 +0900610 }
Inseob Kimae553032019-05-14 18:52:49 +0900611 for _, ext := range exts {
612 glob, err := ctx.GlobWithDeps(dir+"/**/*"+ext, nil)
613 if err != nil {
614 ctx.Errorf("%#v\n", err)
615 return
616 }
617 for _, header := range glob {
618 if strings.HasSuffix(header, "/") {
619 continue
620 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900621 globbedHeaders[header] = true
Inseob Kimae553032019-05-14 18:52:49 +0900622 }
623 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900624 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900625
Inseob Kim242ef0c2019-10-22 20:15:20 +0900626 for _, header := range android.SortedStringKeys(globbedHeaders) {
627 snapshotOutputs = append(snapshotOutputs, installSnapshotFileFromPath(
628 android.PathForSource(ctx, header), filepath.Join(includeDir, header)))
Inseob Kimae553032019-05-14 18:52:49 +0900629 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900630
Inseob Kimae553032019-05-14 18:52:49 +0900631 isHeader := func(path string) bool {
632 for _, ext := range headerExts {
633 if strings.HasSuffix(path, ext) {
634 return true
635 }
636 }
637 return false
638 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900639
Inseob Kim242ef0c2019-10-22 20:15:20 +0900640 // For generated headers, manually install one by one, rather than glob
Inseob Kimae553032019-05-14 18:52:49 +0900641 for _, path := range android.PathsToDirectorySortedPaths(android.FirstUniquePaths(generatedHeaders)) {
642 header := path.String()
643
644 if !isHeader(header) {
645 continue
646 }
647
Inseob Kim242ef0c2019-10-22 20:15:20 +0900648 snapshotOutputs = append(snapshotOutputs, installSnapshotFileFromPath(
649 path, filepath.Join(includeDir, header)))
Inseob Kimae553032019-05-14 18:52:49 +0900650 }
651 }
652
Inseob Kim242ef0c2019-10-22 20:15:20 +0900653 snapshotOutputs = append(snapshotOutputs,
654 installSnapshotFileFromPath(c.vndkCoreLibrariesFile, filepath.Join(configsDir, "vndkcore.libraries.txt")),
655 installSnapshotFileFromPath(c.vndkPrivateLibrariesFile, filepath.Join(configsDir, "vndkprivate.libraries.txt")),
656 installSnapshotFileFromPath(c.vndkSpLibrariesFile, filepath.Join(configsDir, "vndksp.libraries.txt")),
657 installSnapshotFileFromPath(c.llndkLibrariesFile, filepath.Join(configsDir, "llndk.libraries.txt")),
658 )
Inseob Kim1f086e22019-05-09 13:29:15 +0900659
Inseob Kim242ef0c2019-10-22 20:15:20 +0900660 /*
661 Dump a map to a list file as:
Inseob Kim1f086e22019-05-09 13:29:15 +0900662
Inseob Kim242ef0c2019-10-22 20:15:20 +0900663 {key1} {value1}
664 {key2} {value2}
665 ...
666 */
667 installMapListFile := func(m map[string]string, path string) android.OutputPath {
668 var txtBuilder strings.Builder
669 for idx, k := range android.SortedStringKeys(m) {
670 if idx > 0 {
671 txtBuilder.WriteString("\\n")
672 }
673 txtBuilder.WriteString(k)
674 txtBuilder.WriteString(" ")
675 txtBuilder.WriteString(m[k])
Inseob Kim1f086e22019-05-09 13:29:15 +0900676 }
Inseob Kim242ef0c2019-10-22 20:15:20 +0900677 return installSnapshotFileFromContent(txtBuilder.String(), path)
Inseob Kim1f086e22019-05-09 13:29:15 +0900678 }
679
Inseob Kim242ef0c2019-10-22 20:15:20 +0900680 /*
681 module_paths.txt contains paths on which VNDK modules are defined.
682 e.g.,
683 libbase.so system/core/base
684 libc.so bionic/libc
685 ...
686 */
687 snapshotOutputs = append(snapshotOutputs, installMapListFile(modulePaths, filepath.Join(configsDir, "module_paths.txt")))
688
689 /*
690 module_names.txt contains names as which VNDK modules are defined,
691 because output filename and module name can be different with stem and suffix properties.
692
693 e.g.,
694 libcutils.so libcutils
695 libprotobuf-cpp-full-3.9.2.so libprotobuf-cpp-full
696 ...
697 */
698 snapshotOutputs = append(snapshotOutputs, installMapListFile(moduleNames, filepath.Join(configsDir, "module_names.txt")))
699
700 // All artifacts are ready. Sort them to normalize ninja and then zip.
701 sort.Slice(snapshotOutputs, func(i, j int) bool {
702 return snapshotOutputs[i].String() < snapshotOutputs[j].String()
703 })
704
705 zipPath := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+".zip")
706 zipRule := android.NewRuleBuilder()
707
708 // If output files are too many, soong_zip command can exceed ARG_MAX.
709 // So first dump file lists into a single list file, and then feed it to Soong
710 snapshotOutputList := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+"_list")
711 zipRule.Command().
712 Text("( xargs").
713 FlagWithRspFileInputList("-n1 echo < ", snapshotOutputs).
714 FlagWithOutput("| tr -d \\' > ", snapshotOutputList).
715 Text(")")
716
717 zipRule.Temporary(snapshotOutputList)
718
719 zipRule.Command().
720 BuiltTool(ctx, "soong_zip").
721 FlagWithOutput("-o ", zipPath).
722 FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
723 FlagWithInput("-l ", snapshotOutputList)
724
725 zipRule.Build(pctx, ctx, zipPath.String(), "vndk snapshot "+zipPath.String())
726 c.vndkSnapshotZipFile = android.OptionalPathForPath(zipPath)
Inseob Kim1f086e22019-05-09 13:29:15 +0900727}
Jooyung Han097087b2019-10-22 19:32:18 +0900728
Jooyung Han0302a842019-10-30 18:43:49 +0900729func getVndkFileName(m *Module) (string, error) {
730 if library, ok := m.linker.(*libraryDecorator); ok {
731 return library.getLibNameHelper(m.BaseModuleName(), true) + ".so", nil
732 }
733 if prebuilt, ok := m.linker.(*prebuiltLibraryLinker); ok {
734 return prebuilt.libraryDecorator.getLibNameHelper(m.BaseModuleName(), true) + ".so", nil
735 }
736 return "", fmt.Errorf("VNDK library should have libraryDecorator or prebuiltLibraryLinker as linker: %T", m.linker)
Jooyung Han097087b2019-10-22 19:32:18 +0900737}
738
739func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.SingletonContext) {
Jooyung Han0302a842019-10-30 18:43:49 +0900740 // Make uses LLNDK_LIBRARIES to determine which libraries to install.
741 // HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN.
742 // Therefore, by removing the library here, we cause it to only be installed if libc
743 // depends on it.
744 installedLlndkLibraries := make(map[string]string)
745 for lib, filename := range llndkLibraries(ctx.Config()) {
746 if strings.HasPrefix(lib, "libclang_rt.hwasan-") {
747 continue
Jooyung Han097087b2019-10-22 19:32:18 +0900748 }
Jooyung Han0302a842019-10-30 18:43:49 +0900749 installedLlndkLibraries[lib] = filename
750 }
Jooyung Han097087b2019-10-22 19:32:18 +0900751
Jooyung Han0302a842019-10-30 18:43:49 +0900752 installListFile := func(list []string, fileName string) android.Path {
753 out := android.PathForOutput(ctx, "vndk", fileName)
754 ctx.Build(pctx, android.BuildParams{
755 Rule: android.WriteFile,
756 Output: out,
757 Description: "Writing " + out.String(),
758 Args: map[string]string{
759 "content": strings.Join(list, "\\n"),
760 },
761 })
762 return out
763 }
Jooyung Han097087b2019-10-22 19:32:18 +0900764
Jooyung Han0302a842019-10-30 18:43:49 +0900765 c.installedLlndkLibraries = android.SortedStringKeys(installedLlndkLibraries)
Jooyung Han097087b2019-10-22 19:32:18 +0900766
Jooyung Han0302a842019-10-30 18:43:49 +0900767 llndk := android.SortedStringMapValues(installedLlndkLibraries)
768 vndkcore := android.SortedStringMapValues(vndkCoreLibraries(ctx.Config()))
769 vndksp := android.SortedStringMapValues(vndkSpLibraries(ctx.Config()))
770 vndkprivate := android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config()))
771 vndkcorevariant := android.SortedStringMapValues(vndkUsingCoreVariantLibraries(ctx.Config()))
772
Inseob Kim242ef0c2019-10-22 20:15:20 +0900773 c.llndkLibrariesFile = installListFile(llndk, "llndk.libraries.txt")
Jooyung Han0302a842019-10-30 18:43:49 +0900774 c.vndkCoreLibrariesFile = installListFile(vndkcore, "vndkcore.libraries.txt")
775 c.vndkSpLibrariesFile = installListFile(vndksp, "vndksp.libraries.txt")
776 c.vndkPrivateLibrariesFile = installListFile(vndkprivate, "vndkprivate.libraries.txt")
777 c.vndkCoreVariantLibrariesFile = installListFile(vndkcorevariant, "vndkcorevariant.libraries.txt")
Jooyung Han097087b2019-10-22 19:32:18 +0900778
779 // merged & tagged & filtered-out(libclang_rt)
Jooyung Han0302a842019-10-30 18:43:49 +0900780 // Since each target have different set of libclang_rt.* files,
781 // keep the common set of files in vndk.libraries.txt
782 var merged []string
Jooyung Han097087b2019-10-22 19:32:18 +0900783 filterOutLibClangRt := func(libList []string) (filtered []string) {
784 for _, lib := range libList {
785 if !strings.HasPrefix(lib, "libclang_rt.") {
786 filtered = append(filtered, lib)
787 }
788 }
789 return
790 }
791 merged = append(merged, addPrefix(filterOutLibClangRt(llndk), "LLNDK: ")...)
792 merged = append(merged, addPrefix(vndksp, "VNDK-SP: ")...)
793 merged = append(merged, addPrefix(filterOutLibClangRt(vndkcore), "VNDK-core: ")...)
794 merged = append(merged, addPrefix(vndkprivate, "VNDK-private: ")...)
Jooyung Han0302a842019-10-30 18:43:49 +0900795 c.vndkLibrariesFile = installListFile(merged, "vndk.libraries.txt")
796}
Jooyung Han097087b2019-10-22 19:32:18 +0900797
Jooyung Han0302a842019-10-30 18:43:49 +0900798func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
799 // Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to avoid installing libraries on /system if
800 // they been moved to an apex.
801 movedToApexLlndkLibraries := []string{}
802 for _, lib := range c.installedLlndkLibraries {
803 // Skip bionic libs, they are handled in different manner
804 if android.DirectlyInAnyApex(&notOnHostContext{}, lib) && !isBionic(lib) {
805 movedToApexLlndkLibraries = append(movedToApexLlndkLibraries, lib)
806 }
807 }
808 ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES", strings.Join(movedToApexLlndkLibraries, " "))
809 ctx.Strict("LLNDK_LIBRARIES", strings.Join(c.installedLlndkLibraries, " "))
810 ctx.Strict("VNDK_CORE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkCoreLibraries(ctx.Config())), " "))
811 ctx.Strict("VNDK_SAMEPROCESS_LIBRARIES", strings.Join(android.SortedStringKeys(vndkSpLibraries(ctx.Config())), " "))
812 ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkPrivateLibraries(ctx.Config())), " "))
813 ctx.Strict("VNDK_USING_CORE_VARIANT_LIBRARIES", strings.Join(android.SortedStringKeys(vndkUsingCoreVariantLibraries(ctx.Config())), " "))
814
Inseob Kim242ef0c2019-10-22 20:15:20 +0900815 ctx.Strict("LLNDK_LIBRARIES_FILE", c.llndkLibrariesFile.String())
Jooyung Han0302a842019-10-30 18:43:49 +0900816 ctx.Strict("VNDKCORE_LIBRARIES_FILE", c.vndkCoreLibrariesFile.String())
817 ctx.Strict("VNDKSP_LIBRARIES_FILE", c.vndkSpLibrariesFile.String())
818 ctx.Strict("VNDKPRIVATE_LIBRARIES_FILE", c.vndkPrivateLibrariesFile.String())
819 ctx.Strict("VNDKCOREVARIANT_LIBRARIES_FILE", c.vndkCoreVariantLibrariesFile.String())
820
821 ctx.Strict("VNDK_LIBRARIES_FILE", c.vndkLibrariesFile.String())
Inseob Kim242ef0c2019-10-22 20:15:20 +0900822 ctx.Strict("SOONG_VNDK_SNAPSHOT_ZIP", c.vndkSnapshotZipFile.String())
Jooyung Han097087b2019-10-22 19:32:18 +0900823}