blob: 7859fa21f59631912e76209398fd23496ced087b [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 (
Martin Stjernholm257eb0c2018-10-15 13:05:27 +010018 "errors"
Colin Cross766efbc2017-08-17 14:55:15 -070019 "sort"
Jiyong Parkd5b18a52017-08-03 21:22:50 +090020 "strings"
21 "sync"
22
Justin Yun8effde42017-06-23 19:24:43 +090023 "android/soong/android"
Vic Yangefd249e2018-11-12 20:19:56 -080024 "android/soong/cc/config"
Justin Yun8effde42017-06-23 19:24:43 +090025)
26
27type VndkProperties struct {
28 Vndk struct {
29 // declared as a VNDK or VNDK-SP module. The vendor variant
30 // will be installed in /system instead of /vendor partition.
31 //
Jiyong Park82e2bf32017-08-16 14:05:54 +090032 // `vendor_vailable` must be explicitly set to either true or
33 // false together with `vndk: {enabled: true}`.
Justin Yun8effde42017-06-23 19:24:43 +090034 Enabled *bool
35
36 // declared as a VNDK-SP module, which is a subset of VNDK.
37 //
38 // `vndk: { enabled: true }` must set together.
39 //
40 // All these modules are allowed to link to VNDK-SP or LL-NDK
41 // modules only. Other dependency will cause link-type errors.
42 //
43 // If `support_system_process` is not set or set to false,
44 // the module is VNDK-core and can link to other VNDK-core,
45 // VNDK-SP or LL-NDK modules only.
46 Support_system_process *bool
Logan Chienf3511742017-10-31 18:04:35 +080047
48 // Extending another module
49 Extends *string
Justin Yun8effde42017-06-23 19:24:43 +090050 }
51}
52
53type vndkdep struct {
54 Properties VndkProperties
55}
56
57func (vndk *vndkdep) props() []interface{} {
58 return []interface{}{&vndk.Properties}
59}
60
61func (vndk *vndkdep) begin(ctx BaseModuleContext) {}
62
63func (vndk *vndkdep) deps(ctx BaseModuleContext, deps Deps) Deps {
64 return deps
65}
66
67func (vndk *vndkdep) isVndk() bool {
68 return Bool(vndk.Properties.Vndk.Enabled)
69}
70
71func (vndk *vndkdep) isVndkSp() bool {
72 return Bool(vndk.Properties.Vndk.Support_system_process)
73}
74
Logan Chienf3511742017-10-31 18:04:35 +080075func (vndk *vndkdep) isVndkExt() bool {
76 return vndk.Properties.Vndk.Extends != nil
77}
78
79func (vndk *vndkdep) getVndkExtendsModuleName() string {
80 return String(vndk.Properties.Vndk.Extends)
81}
82
Justin Yun8effde42017-06-23 19:24:43 +090083func (vndk *vndkdep) typeName() string {
84 if !vndk.isVndk() {
85 return "native:vendor"
86 }
Logan Chienf3511742017-10-31 18:04:35 +080087 if !vndk.isVndkExt() {
88 if !vndk.isVndkSp() {
89 return "native:vendor:vndk"
90 }
91 return "native:vendor:vndksp"
Justin Yun8effde42017-06-23 19:24:43 +090092 }
Logan Chienf3511742017-10-31 18:04:35 +080093 if !vndk.isVndkSp() {
94 return "native:vendor:vndkext"
95 }
96 return "native:vendor:vndkspext"
Justin Yun8effde42017-06-23 19:24:43 +090097}
98
Logan Chienf3511742017-10-31 18:04:35 +080099func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, tag dependencyTag) {
Justin Yun8effde42017-06-23 19:24:43 +0900100 if to.linker == nil {
101 return
102 }
Jiyong Park82e2bf32017-08-16 14:05:54 +0900103 if !vndk.isVndk() {
104 // Non-VNDK modules (those installed to /vendor) can't depend on modules marked with
105 // vendor_available: false.
106 violation := false
Nan Zhang0007d812017-11-07 10:57:05 -0800107 if lib, ok := to.linker.(*llndkStubDecorator); ok && !Bool(lib.Properties.Vendor_available) {
Jiyong Park82e2bf32017-08-16 14:05:54 +0900108 violation = true
109 } else {
110 if _, ok := to.linker.(libraryInterface); ok && to.VendorProperties.Vendor_available != nil && !Bool(to.VendorProperties.Vendor_available) {
111 // Vendor_available == nil && !Bool(Vendor_available) should be okay since
112 // it means a vendor-only library which is a valid dependency for non-VNDK
113 // modules.
114 violation = true
115 }
116 }
117 if violation {
118 ctx.ModuleErrorf("Vendor module that is not VNDK should not link to %q which is marked as `vendor_available: false`", to.Name())
119 }
120 }
Justin Yun8effde42017-06-23 19:24:43 +0900121 if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() {
122 // Check only shared libraries.
123 // Other (static and LL-NDK) libraries are allowed to link.
124 return
125 }
126 if !to.Properties.UseVndk {
127 ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library",
128 vndk.typeName(), to.Name())
129 return
130 }
Logan Chienf3511742017-10-31 18:04:35 +0800131 if tag == vndkExtDepTag {
132 // Ensure `extends: "name"` property refers a vndk module that has vendor_available
133 // and has identical vndk properties.
134 if to.vndkdep == nil || !to.vndkdep.isVndk() {
135 ctx.ModuleErrorf("`extends` refers a non-vndk module %q", to.Name())
136 return
137 }
138 if vndk.isVndkSp() != to.vndkdep.isVndkSp() {
139 ctx.ModuleErrorf(
140 "`extends` refers a module %q with mismatched support_system_process",
141 to.Name())
142 return
143 }
144 if !Bool(to.VendorProperties.Vendor_available) {
145 ctx.ModuleErrorf(
146 "`extends` refers module %q which does not have `vendor_available: true`",
147 to.Name())
148 return
149 }
150 }
Justin Yun8effde42017-06-23 19:24:43 +0900151 if to.vndkdep == nil {
152 return
153 }
Logan Chienf3511742017-10-31 18:04:35 +0800154
Logan Chiend3c59a22018-03-29 14:08:15 +0800155 // Check the dependencies of VNDK shared libraries.
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100156 if err := vndkIsVndkDepAllowed(vndk, to.vndkdep); err != nil {
157 ctx.ModuleErrorf("(%s) should not link to %q (%s): %v",
158 vndk.typeName(), to.Name(), to.vndkdep.typeName(), err)
Logan Chienf3511742017-10-31 18:04:35 +0800159 return
160 }
Logan Chiend3c59a22018-03-29 14:08:15 +0800161}
Logan Chienf3511742017-10-31 18:04:35 +0800162
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100163func vndkIsVndkDepAllowed(from *vndkdep, to *vndkdep) error {
Logan Chiend3c59a22018-03-29 14:08:15 +0800164 // Check the dependencies of VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext and vendor modules.
165 if from.isVndkExt() {
166 if from.isVndkSp() {
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100167 if to.isVndk() && !to.isVndkSp() {
168 return errors.New("VNDK-SP extensions must not depend on VNDK or VNDK extensions")
169 }
170 return nil
Logan Chiend3c59a22018-03-29 14:08:15 +0800171 }
172 // VNDK-Ext may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100173 return nil
Justin Yun8effde42017-06-23 19:24:43 +0900174 }
Logan Chiend3c59a22018-03-29 14:08:15 +0800175 if from.isVndk() {
176 if to.isVndkExt() {
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100177 return errors.New("VNDK-core and VNDK-SP must not depend on VNDK extensions")
Logan Chiend3c59a22018-03-29 14:08:15 +0800178 }
179 if from.isVndkSp() {
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100180 if !to.isVndkSp() {
181 return errors.New("VNDK-SP must only depend on VNDK-SP")
182 }
183 return nil
Logan Chiend3c59a22018-03-29 14:08:15 +0800184 }
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100185 if !to.isVndk() {
186 return errors.New("VNDK-core must only depend on VNDK-core or VNDK-SP")
187 }
188 return nil
Logan Chiend3c59a22018-03-29 14:08:15 +0800189 }
190 // Vendor modules may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
Martin Stjernholm257eb0c2018-10-15 13:05:27 +0100191 return nil
Justin Yun8effde42017-06-23 19:24:43 +0900192}
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900193
194var (
Inseob Kim9516ee92019-05-09 10:56:13 +0900195 vndkCoreLibrariesKey = android.NewOnceKey("vndkCoreLibrarires")
196 vndkSpLibrariesKey = android.NewOnceKey("vndkSpLibrarires")
197 llndkLibrariesKey = android.NewOnceKey("llndkLibrarires")
198 vndkPrivateLibrariesKey = android.NewOnceKey("vndkPrivateLibrarires")
199 vndkUsingCoreVariantLibrariesKey = android.NewOnceKey("vndkUsingCoreVariantLibrarires")
200 vndkLibrariesLock sync.Mutex
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900201)
202
Inseob Kim9516ee92019-05-09 10:56:13 +0900203func vndkCoreLibraries(config android.Config) *[]string {
204 return config.Once(vndkCoreLibrariesKey, func() interface{} {
205 return &[]string{}
206 }).(*[]string)
207}
208
209func vndkSpLibraries(config android.Config) *[]string {
210 return config.Once(vndkSpLibrariesKey, func() interface{} {
211 return &[]string{}
212 }).(*[]string)
213}
214
215func llndkLibraries(config android.Config) *[]string {
216 return config.Once(llndkLibrariesKey, func() interface{} {
217 return &[]string{}
218 }).(*[]string)
219}
220
221func vndkPrivateLibraries(config android.Config) *[]string {
222 return config.Once(vndkPrivateLibrariesKey, func() interface{} {
223 return &[]string{}
224 }).(*[]string)
225}
226
227func vndkUsingCoreVariantLibraries(config android.Config) *[]string {
228 return config.Once(vndkUsingCoreVariantLibrariesKey, func() interface{} {
229 return &[]string{}
230 }).(*[]string)
231}
232
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900233// gather list of vndk-core, vndk-sp, and ll-ndk libs
Jiyong Parkda6eb592018-12-19 17:12:36 +0900234func VndkMutator(mctx android.BottomUpMutatorContext) {
Jiyong Park4b032222018-02-16 22:14:07 +0900235 if m, ok := mctx.Module().(*Module); ok && m.Enabled() {
Jiyong Park82e2bf32017-08-16 14:05:54 +0900236 if lib, ok := m.linker.(*llndkStubDecorator); ok {
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900237 vndkLibrariesLock.Lock()
238 defer vndkLibrariesLock.Unlock()
Inseob Kim9516ee92019-05-09 10:56:13 +0900239
240 llndkLibraries := llndkLibraries(mctx.Config())
241 vndkPrivateLibraries := vndkPrivateLibraries(mctx.Config())
242
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900243 name := strings.TrimSuffix(m.Name(), llndkLibrarySuffix)
Inseob Kim9516ee92019-05-09 10:56:13 +0900244 if !inList(name, *llndkLibraries) {
245 *llndkLibraries = append(*llndkLibraries, name)
246 sort.Strings(*llndkLibraries)
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900247 }
Nan Zhang0007d812017-11-07 10:57:05 -0800248 if !Bool(lib.Properties.Vendor_available) {
Inseob Kim9516ee92019-05-09 10:56:13 +0900249 if !inList(name, *vndkPrivateLibraries) {
250 *vndkPrivateLibraries = append(*vndkPrivateLibraries, name)
251 sort.Strings(*vndkPrivateLibraries)
Jiyong Park82e2bf32017-08-16 14:05:54 +0900252 }
253 }
254 } else {
255 lib, is_lib := m.linker.(*libraryDecorator)
256 prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker)
257 if (is_lib && lib.shared()) || (is_prebuilt_lib && prebuilt_lib.shared()) {
258 name := strings.TrimPrefix(m.Name(), "prebuilt_")
Logan Chienf3511742017-10-31 18:04:35 +0800259 if m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
Jiyong Park82e2bf32017-08-16 14:05:54 +0900260 vndkLibrariesLock.Lock()
261 defer vndkLibrariesLock.Unlock()
Inseob Kim9516ee92019-05-09 10:56:13 +0900262
263 vndkUsingCoreVariantLibraries := vndkUsingCoreVariantLibraries(mctx.Config())
264 vndkSpLibraries := vndkSpLibraries(mctx.Config())
265 vndkCoreLibraries := vndkCoreLibraries(mctx.Config())
266 vndkPrivateLibraries := vndkPrivateLibraries(mctx.Config())
267
Vic Yangefd249e2018-11-12 20:19:56 -0800268 if mctx.DeviceConfig().VndkUseCoreVariant() && !inList(name, config.VndkMustUseVendorVariantList) {
Inseob Kim9516ee92019-05-09 10:56:13 +0900269 if !inList(name, *vndkUsingCoreVariantLibraries) {
270 *vndkUsingCoreVariantLibraries = append(*vndkUsingCoreVariantLibraries, name)
271 sort.Strings(*vndkUsingCoreVariantLibraries)
Vic Yangefd249e2018-11-12 20:19:56 -0800272 }
273 }
Jiyong Park82e2bf32017-08-16 14:05:54 +0900274 if m.vndkdep.isVndkSp() {
Inseob Kim9516ee92019-05-09 10:56:13 +0900275 if !inList(name, *vndkSpLibraries) {
276 *vndkSpLibraries = append(*vndkSpLibraries, name)
277 sort.Strings(*vndkSpLibraries)
Jiyong Park82e2bf32017-08-16 14:05:54 +0900278 }
279 } else {
Inseob Kim9516ee92019-05-09 10:56:13 +0900280 if !inList(name, *vndkCoreLibraries) {
281 *vndkCoreLibraries = append(*vndkCoreLibraries, name)
282 sort.Strings(*vndkCoreLibraries)
Jiyong Park82e2bf32017-08-16 14:05:54 +0900283 }
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900284 }
Jiyong Park82e2bf32017-08-16 14:05:54 +0900285 if !Bool(m.VendorProperties.Vendor_available) {
Inseob Kim9516ee92019-05-09 10:56:13 +0900286 if !inList(name, *vndkPrivateLibraries) {
287 *vndkPrivateLibraries = append(*vndkPrivateLibraries, name)
288 sort.Strings(*vndkPrivateLibraries)
Jiyong Park82e2bf32017-08-16 14:05:54 +0900289 }
Jiyong Parkd5b18a52017-08-03 21:22:50 +0900290 }
291 }
292 }
293 }
294 }
295}