blob: 528577a21640b0874be178a40ad01702ca620ccf [file] [log] [blame]
Inseob Kim5eb7ee92022-04-27 10:30:34 +09001// Copyright 2021 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
18 _ "fmt"
19 _ "sort"
20
21 "testing"
22
23 "android/soong/android"
Kiyoung Kim487689e2022-07-26 09:48:22 +090024
25 "github.com/google/blueprint"
Inseob Kim5eb7ee92022-04-27 10:30:34 +090026)
27
Kiyoung Kim487689e2022-07-26 09:48:22 +090028func hasDirectDependency(t *testing.T, ctx *android.TestResult, from android.Module, to android.Module) bool {
29 t.Helper()
30 var found bool
31 ctx.VisitDirectDeps(from, func(dep blueprint.Module) {
32 if dep == to {
33 found = true
34 }
35 })
36 return found
37}
38
39func TestApiLibraryReplacesExistingModule(t *testing.T) {
40 bp := `
41 cc_library {
42 name: "libfoo",
43 shared_libs: ["libbar"],
Kiyoung Kim76b06f32023-02-06 22:08:13 +090044 vendor_available: true,
Kiyoung Kim487689e2022-07-26 09:48:22 +090045 }
46
47 cc_library {
48 name: "libbar",
49 }
50
51 cc_api_library {
52 name: "libbar",
Kiyoung Kim76b06f32023-02-06 22:08:13 +090053 vendor_available: true,
Kiyoung Kim487689e2022-07-26 09:48:22 +090054 src: "libbar.so",
55 }
56
57 api_imports {
58 name: "api_imports",
59 shared_libs: [
60 "libbar",
61 ],
Kiyoung Kim487689e2022-07-26 09:48:22 +090062 }
63 `
64
65 ctx := prepareForCcTest.RunTestWithBp(t, bp)
66
67 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
68 libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
69 libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
70
Kiyoung Kim76b06f32023-02-06 22:08:13 +090071 android.AssertBoolEquals(t, "original library should be linked with non-stub variant", true, hasDirectDependency(t, ctx, libfoo, libbar))
72 android.AssertBoolEquals(t, "Stub library from API surface should be not linked with non-stub variant", false, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
73
74 libfooVendor := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
75 libbarApiImportVendor := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
76
77 android.AssertBoolEquals(t, "original library should not be linked", false, hasDirectDependency(t, ctx, libfooVendor, libbar))
78 android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfooVendor, libbarApiImportVendor))
Kiyoung Kim487689e2022-07-26 09:48:22 +090079}
80
81func TestApiLibraryDoNotRequireOriginalModule(t *testing.T) {
82 bp := `
83 cc_library {
84 name: "libfoo",
85 shared_libs: ["libbar"],
Kiyoung Kim76b06f32023-02-06 22:08:13 +090086 vendor: true,
Kiyoung Kim487689e2022-07-26 09:48:22 +090087 }
88
89 cc_api_library {
90 name: "libbar",
91 src: "libbar.so",
Kiyoung Kim76b06f32023-02-06 22:08:13 +090092 vendor_available: true,
Kiyoung Kim487689e2022-07-26 09:48:22 +090093 }
94
95 api_imports {
96 name: "api_imports",
97 shared_libs: [
98 "libbar",
99 ],
Kiyoung Kim487689e2022-07-26 09:48:22 +0900100 }
101 `
102
103 ctx := prepareForCcTest.RunTestWithBp(t, bp)
104
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900105 libfoo := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
106 libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
Kiyoung Kim487689e2022-07-26 09:48:22 +0900107
108 android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
109}
110
111func TestApiLibraryShouldNotReplaceWithoutApiImport(t *testing.T) {
112 bp := `
113 cc_library {
114 name: "libfoo",
115 shared_libs: ["libbar"],
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900116 vendor_available: true,
Kiyoung Kim487689e2022-07-26 09:48:22 +0900117 }
118
119 cc_library {
120 name: "libbar",
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900121 vendor_available: true,
Kiyoung Kim487689e2022-07-26 09:48:22 +0900122 }
123
124 cc_api_library {
125 name: "libbar",
126 src: "libbar.so",
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900127 vendor_available: true,
Kiyoung Kim487689e2022-07-26 09:48:22 +0900128 }
129
130 api_imports {
131 name: "api_imports",
132 shared_libs: [],
Kiyoung Kim487689e2022-07-26 09:48:22 +0900133 }
134 `
135
136 ctx := prepareForCcTest.RunTestWithBp(t, bp)
137
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900138 libfoo := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
139 libbar := ctx.ModuleForTests("libbar", "android_vendor.29_arm64_armv8-a_shared").Module()
140 libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
Kiyoung Kim487689e2022-07-26 09:48:22 +0900141
142 android.AssertBoolEquals(t, "original library should be linked", true, hasDirectDependency(t, ctx, libfoo, libbar))
143 android.AssertBoolEquals(t, "Stub library from API surface should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
144}
Kiyoung Kim51279d32022-08-24 14:10:46 +0900145
Spandan Dasf0beebc2022-10-18 18:23:28 +0000146func TestExportDirFromStubLibrary(t *testing.T) {
147 bp := `
148 cc_library {
149 name: "libfoo",
150 export_include_dirs: ["source_include_dir"],
151 export_system_include_dirs: ["source_system_include_dir"],
152 vendor_available: true,
153 }
154 cc_api_library {
155 name: "libfoo",
156 export_include_dirs: ["stub_include_dir"],
157 export_system_include_dirs: ["stub_system_include_dir"],
158 vendor_available: true,
159 src: "libfoo.so",
160 }
161 api_imports {
162 name: "api_imports",
163 shared_libs: [
164 "libfoo",
165 ],
166 header_libs: [],
167 }
168 // vendor binary
169 cc_binary {
170 name: "vendorbin",
171 vendor: true,
172 srcs: ["vendor.cc"],
173 shared_libs: ["libfoo"],
174 }
175 `
176 ctx := prepareForCcTest.RunTestWithBp(t, bp)
177 vendorCFlags := ctx.ModuleForTests("vendorbin", "android_vendor.29_arm64_armv8-a").Rule("cc").Args["cFlags"]
178 android.AssertStringDoesContain(t, "Vendor binary should compile using headers provided by stub", vendorCFlags, "-Istub_include_dir")
179 android.AssertStringDoesNotContain(t, "Vendor binary should not compile using headers of source", vendorCFlags, "-Isource_include_dir")
180 android.AssertStringDoesContain(t, "Vendor binary should compile using system headers provided by stub", vendorCFlags, "-isystem stub_system_include_dir")
181 android.AssertStringDoesNotContain(t, "Vendor binary should not compile using system headers of source", vendorCFlags, "-isystem source_system_include_dir")
Spandan Dasa3c8a172022-10-26 20:54:32 +0000182
183 vendorImplicits := ctx.ModuleForTests("vendorbin", "android_vendor.29_arm64_armv8-a").Rule("cc").OrderOnly.Strings()
184 // Building the stub.so file first assembles its .h files in multi-tree out.
185 // These header files are required for compiling the other API domain (vendor in this case)
186 android.AssertStringListContains(t, "Vendor binary compilation should have an implicit dep on the stub .so file", vendorImplicits, "libfoo.so")
Spandan Dasf0beebc2022-10-18 18:23:28 +0000187}
Kiyoung Kimee58c932022-10-25 22:59:41 +0900188
189func TestApiLibraryWithLlndkVariant(t *testing.T) {
190 bp := `
191 cc_binary {
192 name: "binfoo",
193 vendor: true,
194 srcs: ["binfoo.cc"],
195 shared_libs: ["libbar"],
196 }
197
198 cc_api_library {
199 name: "libbar",
200 // TODO(b/244244438) Remove src property once all variants are implemented.
201 src: "libbar.so",
202 vendor_available: true,
203 variants: [
204 "llndk",
205 ],
206 }
207
208 cc_api_variant {
209 name: "libbar",
210 variant: "llndk",
211 src: "libbar_llndk.so",
Kiyoung Kim62ed3dd2022-12-02 10:20:55 +0900212 export_include_dirs: ["libbar_llndk_include"]
Kiyoung Kimee58c932022-10-25 22:59:41 +0900213 }
214
215 api_imports {
216 name: "api_imports",
217 shared_libs: [
218 "libbar",
219 ],
220 header_libs: [],
221 }
222 `
223
224 ctx := prepareForCcTest.RunTestWithBp(t, bp)
225
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900226 binfoo := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Module()
Kiyoung Kimee58c932022-10-25 22:59:41 +0900227 libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
228 libbarApiVariant := ctx.ModuleForTests("libbar.llndk.apiimport", "android_vendor.29_arm64_armv8-a").Module()
229
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900230 android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, binfoo, libbarApiImport))
Kiyoung Kimee58c932022-10-25 22:59:41 +0900231 android.AssertBoolEquals(t, "Stub library variant from API surface should be linked", true, hasDirectDependency(t, ctx, libbarApiImport, libbarApiVariant))
232
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900233 binFooLibFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("ld").Args["libFlags"]
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900234 android.AssertStringDoesContain(t, "Vendor binary should be linked with LLNDK variant source", binFooLibFlags, "libbar.llndk.apiimport.so")
Kiyoung Kimee58c932022-10-25 22:59:41 +0900235
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900236 binFooCFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("cc").Args["cFlags"]
237 android.AssertStringDoesContain(t, "Vendor binary should include headers from the LLNDK variant source", binFooCFlags, "-Ilibbar_llndk_include")
238}
239
240func TestApiLibraryWithNdkVariant(t *testing.T) {
241 bp := `
242 cc_binary {
243 name: "binfoo",
244 sdk_version: "29",
245 srcs: ["binfoo.cc"],
246 shared_libs: ["libbar"],
247 stl: "c++_shared",
248 }
249
250 cc_binary {
251 name: "binbaz",
252 sdk_version: "30",
253 srcs: ["binbaz.cc"],
254 shared_libs: ["libbar"],
255 stl: "c++_shared",
256 }
257
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900258 cc_binary {
259 name: "binqux",
260 srcs: ["binfoo.cc"],
261 shared_libs: ["libbar"],
262 }
263
264 cc_library {
265 name: "libbar",
266 srcs: ["libbar.cc"],
267 }
268
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900269 cc_api_library {
270 name: "libbar",
271 // TODO(b/244244438) Remove src property once all variants are implemented.
272 src: "libbar.so",
273 variants: [
274 "ndk.29",
275 "ndk.30",
276 "ndk.current",
277 ],
278 }
279
280 cc_api_variant {
281 name: "libbar",
282 variant: "ndk",
283 version: "29",
284 src: "libbar_ndk_29.so",
Kiyoung Kim62ed3dd2022-12-02 10:20:55 +0900285 export_include_dirs: ["libbar_ndk_29_include"]
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900286 }
287
288 cc_api_variant {
289 name: "libbar",
290 variant: "ndk",
291 version: "30",
292 src: "libbar_ndk_30.so",
Kiyoung Kim62ed3dd2022-12-02 10:20:55 +0900293 export_include_dirs: ["libbar_ndk_30_include"]
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900294 }
295
296 cc_api_variant {
297 name: "libbar",
298 variant: "ndk",
299 version: "current",
300 src: "libbar_ndk_current.so",
Kiyoung Kim62ed3dd2022-12-02 10:20:55 +0900301 export_include_dirs: ["libbar_ndk_current_include"]
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900302 }
303
304 api_imports {
305 name: "api_imports",
306 shared_libs: [
307 "libbar",
308 ],
309 header_libs: [],
310 }
311 `
312
313 ctx := prepareForCcTest.RunTestWithBp(t, bp)
314
315 binfoo := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Module()
316 libbarApiImportv29 := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_sdk_shared_29").Module()
317 libbarApiVariantv29 := ctx.ModuleForTests("libbar.ndk.29.apiimport", "android_arm64_armv8-a_sdk").Module()
318 libbarApiImportv30 := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_sdk_shared_30").Module()
319 libbarApiVariantv30 := ctx.ModuleForTests("libbar.ndk.30.apiimport", "android_arm64_armv8-a_sdk").Module()
320
321 android.AssertBoolEquals(t, "Stub library from API surface should be linked with target version", true, hasDirectDependency(t, ctx, binfoo, libbarApiImportv29))
322 android.AssertBoolEquals(t, "Stub library variant from API surface should be linked with target version", true, hasDirectDependency(t, ctx, libbarApiImportv29, libbarApiVariantv29))
323 android.AssertBoolEquals(t, "Stub library from API surface should not be linked with different version", false, hasDirectDependency(t, ctx, binfoo, libbarApiImportv30))
324 android.AssertBoolEquals(t, "Stub library variant from API surface should not be linked with different version", false, hasDirectDependency(t, ctx, libbarApiImportv29, libbarApiVariantv30))
325
326 binbaz := ctx.ModuleForTests("binbaz", "android_arm64_armv8-a_sdk").Module()
327
328 android.AssertBoolEquals(t, "Stub library from API surface should be linked with target version", true, hasDirectDependency(t, ctx, binbaz, libbarApiImportv30))
329 android.AssertBoolEquals(t, "Stub library from API surface should not be linked with different version", false, hasDirectDependency(t, ctx, binbaz, libbarApiImportv29))
330
331 binFooLibFlags := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Rule("ld").Args["libFlags"]
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900332 android.AssertStringDoesContain(t, "Binary using sdk should be linked with NDK variant source", binFooLibFlags, "libbar.ndk.29.apiimport.so")
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900333
334 binFooCFlags := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Rule("cc").Args["cFlags"]
335 android.AssertStringDoesContain(t, "Binary using sdk should include headers from the NDK variant source", binFooCFlags, "-Ilibbar_ndk_29_include")
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900336
337 binQux := ctx.ModuleForTests("binqux", "android_arm64_armv8-a").Module()
338 android.AssertBoolEquals(t, "NDK Stub library from API surface should not be linked with nonSdk binary", false,
339 (hasDirectDependency(t, ctx, binQux, libbarApiImportv30) || hasDirectDependency(t, ctx, binQux, libbarApiImportv29)))
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900340}
341
342func TestApiLibraryWithMultipleVariants(t *testing.T) {
343 bp := `
344 cc_binary {
345 name: "binfoo",
346 sdk_version: "29",
347 srcs: ["binfoo.cc"],
348 shared_libs: ["libbar"],
349 stl: "c++_shared",
350 }
351
352 cc_binary {
353 name: "binbaz",
354 vendor: true,
355 srcs: ["binbaz.cc"],
356 shared_libs: ["libbar"],
357 }
358
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900359 cc_library {
360 name: "libbar",
361 srcs: ["libbar.cc"],
362 }
363
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900364 cc_api_library {
365 name: "libbar",
366 // TODO(b/244244438) Remove src property once all variants are implemented.
367 src: "libbar.so",
368 vendor_available: true,
369 variants: [
370 "llndk",
371 "ndk.29",
372 "ndk.30",
373 "ndk.current",
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900374 "apex.29",
375 "apex.30",
376 "apex.current",
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900377 ],
378 }
379
380 cc_api_variant {
381 name: "libbar",
382 variant: "ndk",
383 version: "29",
384 src: "libbar_ndk_29.so",
Kiyoung Kim62ed3dd2022-12-02 10:20:55 +0900385 export_include_dirs: ["libbar_ndk_29_include"]
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900386 }
387
388 cc_api_variant {
389 name: "libbar",
390 variant: "ndk",
391 version: "30",
392 src: "libbar_ndk_30.so",
Kiyoung Kim62ed3dd2022-12-02 10:20:55 +0900393 export_include_dirs: ["libbar_ndk_30_include"]
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900394 }
395
396 cc_api_variant {
397 name: "libbar",
398 variant: "ndk",
399 version: "current",
400 src: "libbar_ndk_current.so",
Kiyoung Kim62ed3dd2022-12-02 10:20:55 +0900401 export_include_dirs: ["libbar_ndk_current_include"]
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900402 }
403
404 cc_api_variant {
405 name: "libbar",
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900406 variant: "apex",
407 version: "29",
408 src: "libbar_apex_29.so",
409 export_include_dirs: ["libbar_apex_29_include"]
410 }
411
412 cc_api_variant {
413 name: "libbar",
414 variant: "apex",
415 version: "30",
416 src: "libbar_apex_30.so",
417 export_include_dirs: ["libbar_apex_30_include"]
418 }
419
420 cc_api_variant {
421 name: "libbar",
422 variant: "apex",
423 version: "current",
424 src: "libbar_apex_current.so",
425 export_include_dirs: ["libbar_apex_current_include"]
426 }
427
428 cc_api_variant {
429 name: "libbar",
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900430 variant: "llndk",
431 src: "libbar_llndk.so",
Kiyoung Kim62ed3dd2022-12-02 10:20:55 +0900432 export_include_dirs: ["libbar_llndk_include"]
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900433 }
434
435 api_imports {
436 name: "api_imports",
437 shared_libs: [
438 "libbar",
439 ],
Kiyoung Kim76b06f32023-02-06 22:08:13 +0900440 apex_shared_libs: [
441 "libbar",
442 ],
Kiyoung Kimd5d1ab12022-11-28 16:47:10 +0900443 }
444 `
445 ctx := prepareForCcTest.RunTestWithBp(t, bp)
446
447 binfoo := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Module()
448 libbarApiImportv29 := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_sdk_shared_29").Module()
449 libbarApiImportLlndk := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
450
451 android.AssertBoolEquals(t, "Binary using SDK should be linked with API library from NDK variant", true, hasDirectDependency(t, ctx, binfoo, libbarApiImportv29))
452 android.AssertBoolEquals(t, "Binary using SDK should not be linked with API library from LLNDK variant", false, hasDirectDependency(t, ctx, binfoo, libbarApiImportLlndk))
453
454 binbaz := ctx.ModuleForTests("binbaz", "android_vendor.29_arm64_armv8-a").Module()
455
456 android.AssertBoolEquals(t, "Vendor binary should be linked with API library from LLNDK variant", true, hasDirectDependency(t, ctx, binbaz, libbarApiImportLlndk))
457 android.AssertBoolEquals(t, "Vendor binary should not be linked with API library from NDK variant", false, hasDirectDependency(t, ctx, binbaz, libbarApiImportv29))
458
Kiyoung Kimee58c932022-10-25 22:59:41 +0900459}