blob: 064b1a25cd06bf4af3fc0d672673c422070275c8 [file] [log] [blame]
Colin Crossd00350c2017-11-17 10:55:38 -08001// 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
Colin Cross74d1ec02015-04-28 13:30:13 -070015package cc
16
17import (
Jeff Gaston294356f2017-09-27 17:05:30 -070018 "fmt"
Jiyong Park6a43f042017-10-12 23:05:00 +090019 "io/ioutil"
20 "os"
Inseob Kim1f086e22019-05-09 13:29:15 +090021 "path/filepath"
Colin Cross74d1ec02015-04-28 13:30:13 -070022 "reflect"
Jeff Gaston294356f2017-09-27 17:05:30 -070023 "sort"
24 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070025 "testing"
Colin Crosse1bb5d02019-09-24 14:55:04 -070026
27 "android/soong/android"
Colin Cross74d1ec02015-04-28 13:30:13 -070028)
29
Jiyong Park6a43f042017-10-12 23:05:00 +090030var buildDir string
31
32func setUp() {
33 var err error
34 buildDir, err = ioutil.TempDir("", "soong_cc_test")
35 if err != nil {
36 panic(err)
37 }
38}
39
40func tearDown() {
41 os.RemoveAll(buildDir)
42}
43
44func TestMain(m *testing.M) {
45 run := func() int {
46 setUp()
47 defer tearDown()
48
49 return m.Run()
50 }
51
52 os.Exit(run())
53}
54
Logan Chienf3511742017-10-31 18:04:35 +080055func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Colin Crosse1bb5d02019-09-24 14:55:04 -070056 t.Helper()
Doug Hornc32c6b02019-01-17 14:44:05 -080057 return testCcWithConfigForOs(t, bp, config, android.Android)
58}
59
60func testCcWithConfigForOs(t *testing.T, bp string, config android.Config, os android.OsType) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080061 t.Helper()
Colin Cross9a942872019-05-14 15:44:26 -070062 ctx := CreateTestContext(bp, nil, os)
Colin Cross33b2fb72019-05-14 14:07:01 -070063 ctx.Register()
Logan Chienf3511742017-10-31 18:04:35 +080064
Jeff Gastond3e141d2017-08-08 17:46:01 -070065 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +080066 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +090067 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +080068 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +090069
70 return ctx
71}
72
Logan Chienf3511742017-10-31 18:04:35 +080073func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080074 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080075 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070076 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
77 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080078
79 return testCcWithConfig(t, bp, config)
80}
81
82func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080083 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080084 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070085 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080086
87 return testCcWithConfig(t, bp, config)
88}
89
90func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +080091 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080092 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070093 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
94 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080095
Colin Cross9a942872019-05-14 15:44:26 -070096 ctx := CreateTestContext(bp, nil, android.Android)
Colin Cross33b2fb72019-05-14 14:07:01 -070097 ctx.Register()
Logan Chienf3511742017-10-31 18:04:35 +080098
99 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
100 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800101 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800102 return
103 }
104
105 _, errs = ctx.PrepareBuildActions(config)
106 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800107 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800108 return
109 }
110
111 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
112}
113
114const (
Jiyong Park5baac542018-08-28 09:55:37 +0900115 coreVariant = "android_arm64_armv8-a_core_shared"
Inseob Kim64c43952019-08-26 16:52:35 +0900116 vendorVariant = "android_arm64_armv8-a_vendor.VER_shared"
Jiyong Park5baac542018-08-28 09:55:37 +0900117 recoveryVariant = "android_arm64_armv8-a_recovery_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800118)
119
Doug Hornc32c6b02019-01-17 14:44:05 -0800120func TestFuchsiaDeps(t *testing.T) {
121 t.Helper()
122
123 bp := `
124 cc_library {
125 name: "libTest",
126 srcs: ["foo.c"],
127 target: {
128 fuchsia: {
129 srcs: ["bar.c"],
130 },
131 },
132 }`
133
134 config := android.TestArchConfigFuchsia(buildDir, nil)
135 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
136
137 rt := false
138 fb := false
139
140 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
141 implicits := ld.Implicits
142 for _, lib := range implicits {
143 if strings.Contains(lib.Rel(), "libcompiler_rt") {
144 rt = true
145 }
146
147 if strings.Contains(lib.Rel(), "libbioniccompat") {
148 fb = true
149 }
150 }
151
152 if !rt || !fb {
153 t.Errorf("fuchsia libs must link libcompiler_rt and libbioniccompat")
154 }
155}
156
157func TestFuchsiaTargetDecl(t *testing.T) {
158 t.Helper()
159
160 bp := `
161 cc_library {
162 name: "libTest",
163 srcs: ["foo.c"],
164 target: {
165 fuchsia: {
166 srcs: ["bar.c"],
167 },
168 },
169 }`
170
171 config := android.TestArchConfigFuchsia(buildDir, nil)
172 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
173 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
174 var objs []string
175 for _, o := range ld.Inputs {
176 objs = append(objs, o.Base())
177 }
178 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
179 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
180 }
181}
182
Jiyong Park6a43f042017-10-12 23:05:00 +0900183func TestVendorSrc(t *testing.T) {
184 ctx := testCc(t, `
185 cc_library {
186 name: "libTest",
187 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -0700188 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +0800189 nocrt: true,
190 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900191 vendor_available: true,
192 target: {
193 vendor: {
194 srcs: ["bar.c"],
195 },
196 },
197 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900198 `)
199
Logan Chienf3511742017-10-31 18:04:35 +0800200 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900201 var objs []string
202 for _, o := range ld.Inputs {
203 objs = append(objs, o.Base())
204 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800205 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900206 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
207 }
208}
209
Logan Chienf3511742017-10-31 18:04:35 +0800210func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
211 isVndkSp bool, extends string) {
212
Logan Chiend3c59a22018-03-29 14:08:15 +0800213 t.Helper()
214
Logan Chienf3511742017-10-31 18:04:35 +0800215 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
Ivan Lozano52767be2019-10-18 14:49:46 -0700216 if !mod.HasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700217 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800218 }
219
220 // Check library properties.
221 lib, ok := mod.compiler.(*libraryDecorator)
222 if !ok {
223 t.Errorf("%q must have libraryDecorator", name)
224 } else if lib.baseInstaller.subDir != subDir {
225 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
226 lib.baseInstaller.subDir)
227 }
228
229 // Check VNDK properties.
230 if mod.vndkdep == nil {
231 t.Fatalf("%q must have `vndkdep`", name)
232 }
Ivan Lozano52767be2019-10-18 14:49:46 -0700233 if !mod.IsVndk() {
234 t.Errorf("%q IsVndk() must equal to true", name)
Logan Chienf3511742017-10-31 18:04:35 +0800235 }
236 if mod.isVndkSp() != isVndkSp {
237 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
238 }
239
240 // Check VNDK extension properties.
241 isVndkExt := extends != ""
242 if mod.isVndkExt() != isVndkExt {
243 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
244 }
245
246 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
247 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
248 }
249}
250
Inseob Kim1f086e22019-05-09 13:29:15 +0900251func checkVndkSnapshot(t *testing.T, ctx *android.TestContext, name, subDir, variant string) {
252 vndkSnapshot := ctx.SingletonForTests("vndk-snapshot")
253
254 snapshotPath := filepath.Join(subDir, name+".so")
255 mod := ctx.ModuleForTests(name, variant).Module().(*Module)
256 if !mod.outputFile.Valid() {
257 t.Errorf("%q must have output\n", name)
258 return
259 }
260
261 out := vndkSnapshot.Output(snapshotPath)
262 if out.Input != mod.outputFile.Path() {
263 t.Errorf("The input of VNDK snapshot must be %q, but %q", out.Input.String(), mod.outputFile.String())
264 }
265}
266
Jooyung Han097087b2019-10-22 19:32:18 +0900267func checkVndkOutput(t *testing.T, ctx *android.TestContext, output string, expected []string) {
268 t.Helper()
269 vndkSnapshot := ctx.SingletonForTests("vndk-snapshot")
270 actual := strings.FieldsFunc(strings.ReplaceAll(vndkSnapshot.Output(output).Args["content"], "\\n", "\n"), func(r rune) bool { return r == '\n' })
271 assertArrayString(t, actual, expected)
272}
273
Logan Chienf3511742017-10-31 18:04:35 +0800274func TestVndk(t *testing.T) {
Inseob Kim1f086e22019-05-09 13:29:15 +0900275 config := android.TestArchConfig(buildDir, nil)
276 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
277 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
278
279 ctx := testCcWithConfig(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800280 cc_library {
281 name: "libvndk",
282 vendor_available: true,
283 vndk: {
284 enabled: true,
285 },
286 nocrt: true,
287 }
288
289 cc_library {
290 name: "libvndk_private",
291 vendor_available: false,
292 vndk: {
293 enabled: true,
294 },
295 nocrt: true,
296 }
297
298 cc_library {
299 name: "libvndk_sp",
300 vendor_available: true,
301 vndk: {
302 enabled: true,
303 support_system_process: true,
304 },
305 nocrt: true,
306 }
307
308 cc_library {
309 name: "libvndk_sp_private",
310 vendor_available: false,
311 vndk: {
312 enabled: true,
313 support_system_process: true,
314 },
315 nocrt: true,
316 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900317 `, config)
Logan Chienf3511742017-10-31 18:04:35 +0800318
319 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
320 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
321 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
322 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
Inseob Kim1f086e22019-05-09 13:29:15 +0900323
324 // Check VNDK snapshot output.
325
326 snapshotDir := "vndk-snapshot"
327 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
328
329 vndkLibPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
330 "arm64", "armv8-a"))
331 vndkLib2ndPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
332 "arm", "armv7-a-neon"))
333
334 vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core")
335 vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp")
336 vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
337 vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
338
Inseob Kim64c43952019-08-26 16:52:35 +0900339 variant := "android_arm64_armv8-a_vendor.VER_shared"
340 variant2nd := "android_arm_armv7-a-neon_vendor.VER_shared"
Inseob Kim1f086e22019-05-09 13:29:15 +0900341
342 checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLibPath, variant)
343 checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLib2ndPath, variant2nd)
344 checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLibPath, variant)
345 checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLib2ndPath, variant2nd)
Jooyung Han097087b2019-10-22 19:32:18 +0900346
347 checkVndkOutput(t, ctx, "vndk/llndk.libraries.txt", []string{"libc.so", "libdl.so", "libft2.so", "libm.so"})
348 checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{"libvndk.so", "libvndk_private.so"})
349 checkVndkOutput(t, ctx, "vndk/vndkprivate.libraries.txt", []string{"libft2.so", "libvndk_private.so", "libvndk_sp_private.so"})
350 checkVndkOutput(t, ctx, "vndk/vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp.so", "libvndk_sp_private.so"})
351 checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", nil)
352 // merged & tagged & filtered-out(libclang_rt)
353 checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
354 "LLNDK: libc.so",
355 "LLNDK: libdl.so",
356 "LLNDK: libft2.so",
357 "LLNDK: libm.so",
358 "VNDK-SP: libc++.so",
359 "VNDK-SP: libvndk_sp.so",
360 "VNDK-SP: libvndk_sp_private.so",
361 "VNDK-core: libvndk.so",
362 "VNDK-core: libvndk_private.so",
363 "VNDK-private: libft2.so",
364 "VNDK-private: libvndk_private.so",
365 "VNDK-private: libvndk_sp_private.so",
366 })
367}
368
369func TestVndkUsingCoreVariant(t *testing.T) {
370 config := android.TestArchConfig(buildDir, nil)
371 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
372 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
373 config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
374
375 setVndkMustUseVendorVariantListForTest(config, []string{"libvndk"})
376
377 ctx := testCcWithConfig(t, `
378 cc_library {
379 name: "libvndk",
380 vendor_available: true,
381 vndk: {
382 enabled: true,
383 },
384 nocrt: true,
385 }
386
387 cc_library {
388 name: "libvndk_sp",
389 vendor_available: true,
390 vndk: {
391 enabled: true,
392 support_system_process: true,
393 },
394 nocrt: true,
395 }
396
397 cc_library {
398 name: "libvndk2",
399 vendor_available: false,
400 vndk: {
401 enabled: true,
402 },
403 nocrt: true,
404 }
405 `, config)
406
407 checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{"libvndk.so", "libvndk2.so"})
408 checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", []string{"libvndk2.so"})
Logan Chienf3511742017-10-31 18:04:35 +0800409}
410
Logan Chiend3c59a22018-03-29 14:08:15 +0800411func TestVndkDepError(t *testing.T) {
412 // Check whether an error is emitted when a VNDK lib depends on a system lib.
413 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
414 cc_library {
415 name: "libvndk",
416 vendor_available: true,
417 vndk: {
418 enabled: true,
419 },
420 shared_libs: ["libfwk"], // Cause error
421 nocrt: true,
422 }
423
424 cc_library {
425 name: "libfwk",
426 nocrt: true,
427 }
428 `)
429
430 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
431 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
432 cc_library {
433 name: "libvndk",
434 vendor_available: true,
435 vndk: {
436 enabled: true,
437 },
438 shared_libs: ["libvendor"], // Cause error
439 nocrt: true,
440 }
441
442 cc_library {
443 name: "libvendor",
444 vendor: true,
445 nocrt: true,
446 }
447 `)
448
449 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
450 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
451 cc_library {
452 name: "libvndk_sp",
453 vendor_available: true,
454 vndk: {
455 enabled: true,
456 support_system_process: true,
457 },
458 shared_libs: ["libfwk"], // Cause error
459 nocrt: true,
460 }
461
462 cc_library {
463 name: "libfwk",
464 nocrt: true,
465 }
466 `)
467
468 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
469 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
470 cc_library {
471 name: "libvndk_sp",
472 vendor_available: true,
473 vndk: {
474 enabled: true,
475 support_system_process: true,
476 },
477 shared_libs: ["libvendor"], // Cause error
478 nocrt: true,
479 }
480
481 cc_library {
482 name: "libvendor",
483 vendor: true,
484 nocrt: true,
485 }
486 `)
487
488 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
489 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
490 cc_library {
491 name: "libvndk_sp",
492 vendor_available: true,
493 vndk: {
494 enabled: true,
495 support_system_process: true,
496 },
497 shared_libs: ["libvndk"], // Cause error
498 nocrt: true,
499 }
500
501 cc_library {
502 name: "libvndk",
503 vendor_available: true,
504 vndk: {
505 enabled: true,
506 },
507 nocrt: true,
508 }
509 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900510
511 // Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib.
512 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
513 cc_library {
514 name: "libvndk",
515 vendor_available: true,
516 vndk: {
517 enabled: true,
518 },
519 shared_libs: ["libnonvndk"],
520 nocrt: true,
521 }
522
523 cc_library {
524 name: "libnonvndk",
525 vendor_available: true,
526 nocrt: true,
527 }
528 `)
529
530 // Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib.
531 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
532 cc_library {
533 name: "libvndkprivate",
534 vendor_available: false,
535 vndk: {
536 enabled: true,
537 },
538 shared_libs: ["libnonvndk"],
539 nocrt: true,
540 }
541
542 cc_library {
543 name: "libnonvndk",
544 vendor_available: true,
545 nocrt: true,
546 }
547 `)
548
549 // Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib.
550 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
551 cc_library {
552 name: "libvndksp",
553 vendor_available: true,
554 vndk: {
555 enabled: true,
556 support_system_process: true,
557 },
558 shared_libs: ["libnonvndk"],
559 nocrt: true,
560 }
561
562 cc_library {
563 name: "libnonvndk",
564 vendor_available: true,
565 nocrt: true,
566 }
567 `)
568
569 // Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib.
570 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
571 cc_library {
572 name: "libvndkspprivate",
573 vendor_available: false,
574 vndk: {
575 enabled: true,
576 support_system_process: true,
577 },
578 shared_libs: ["libnonvndk"],
579 nocrt: true,
580 }
581
582 cc_library {
583 name: "libnonvndk",
584 vendor_available: true,
585 nocrt: true,
586 }
587 `)
588}
589
590func TestDoubleLoadbleDep(t *testing.T) {
591 // okay to link : LLNDK -> double_loadable VNDK
592 testCc(t, `
593 cc_library {
594 name: "libllndk",
595 shared_libs: ["libdoubleloadable"],
596 }
597
598 llndk_library {
599 name: "libllndk",
600 symbol_file: "",
601 }
602
603 cc_library {
604 name: "libdoubleloadable",
605 vendor_available: true,
606 vndk: {
607 enabled: true,
608 },
609 double_loadable: true,
610 }
611 `)
612 // okay to link : LLNDK -> VNDK-SP
613 testCc(t, `
614 cc_library {
615 name: "libllndk",
616 shared_libs: ["libvndksp"],
617 }
618
619 llndk_library {
620 name: "libllndk",
621 symbol_file: "",
622 }
623
624 cc_library {
625 name: "libvndksp",
626 vendor_available: true,
627 vndk: {
628 enabled: true,
629 support_system_process: true,
630 },
631 }
632 `)
633 // okay to link : double_loadable -> double_loadable
634 testCc(t, `
635 cc_library {
636 name: "libdoubleloadable1",
637 shared_libs: ["libdoubleloadable2"],
638 vendor_available: true,
639 double_loadable: true,
640 }
641
642 cc_library {
643 name: "libdoubleloadable2",
644 vendor_available: true,
645 double_loadable: true,
646 }
647 `)
648 // okay to link : double_loadable VNDK -> double_loadable VNDK private
649 testCc(t, `
650 cc_library {
651 name: "libdoubleloadable",
652 vendor_available: true,
653 vndk: {
654 enabled: true,
655 },
656 double_loadable: true,
657 shared_libs: ["libnondoubleloadable"],
658 }
659
660 cc_library {
661 name: "libnondoubleloadable",
662 vendor_available: false,
663 vndk: {
664 enabled: true,
665 },
666 double_loadable: true,
667 }
668 `)
669 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
670 testCc(t, `
671 cc_library {
672 name: "libllndk",
673 shared_libs: ["libcoreonly"],
674 }
675
676 llndk_library {
677 name: "libllndk",
678 symbol_file: "",
679 }
680
681 cc_library {
682 name: "libcoreonly",
683 shared_libs: ["libvendoravailable"],
684 }
685
686 // indirect dependency of LLNDK
687 cc_library {
688 name: "libvendoravailable",
689 vendor_available: true,
690 double_loadable: true,
691 }
692 `)
693}
694
695func TestDoubleLoadableDepError(t *testing.T) {
696 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
697 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
698 cc_library {
699 name: "libllndk",
700 shared_libs: ["libnondoubleloadable"],
701 }
702
703 llndk_library {
704 name: "libllndk",
705 symbol_file: "",
706 }
707
708 cc_library {
709 name: "libnondoubleloadable",
710 vendor_available: true,
711 vndk: {
712 enabled: true,
713 },
714 }
715 `)
716
717 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
718 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
719 cc_library {
720 name: "libllndk",
Yi Konge7fe9912019-06-02 00:53:50 -0700721 no_libcrt: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900722 shared_libs: ["libnondoubleloadable"],
723 }
724
725 llndk_library {
726 name: "libllndk",
727 symbol_file: "",
728 }
729
730 cc_library {
731 name: "libnondoubleloadable",
732 vendor_available: true,
733 }
734 `)
735
736 // Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable vendor_available lib.
737 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
738 cc_library {
739 name: "libdoubleloadable",
740 vendor_available: true,
741 double_loadable: true,
742 shared_libs: ["libnondoubleloadable"],
743 }
744
745 cc_library {
746 name: "libnondoubleloadable",
747 vendor_available: true,
748 }
749 `)
750
751 // Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable VNDK lib.
752 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
753 cc_library {
754 name: "libdoubleloadable",
755 vendor_available: true,
756 double_loadable: true,
757 shared_libs: ["libnondoubleloadable"],
758 }
759
760 cc_library {
761 name: "libnondoubleloadable",
762 vendor_available: true,
763 vndk: {
764 enabled: true,
765 },
766 }
767 `)
768
769 // Check whether an error is emitted when a double_loadable VNDK depends on a non-double_loadable VNDK private lib.
770 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
771 cc_library {
772 name: "libdoubleloadable",
773 vendor_available: true,
774 vndk: {
775 enabled: true,
776 },
777 double_loadable: true,
778 shared_libs: ["libnondoubleloadable"],
779 }
780
781 cc_library {
782 name: "libnondoubleloadable",
783 vendor_available: false,
784 vndk: {
785 enabled: true,
786 },
787 }
788 `)
789
790 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
791 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
792 cc_library {
793 name: "libllndk",
794 shared_libs: ["libcoreonly"],
795 }
796
797 llndk_library {
798 name: "libllndk",
799 symbol_file: "",
800 }
801
802 cc_library {
803 name: "libcoreonly",
804 shared_libs: ["libvendoravailable"],
805 }
806
807 // indirect dependency of LLNDK
808 cc_library {
809 name: "libvendoravailable",
810 vendor_available: true,
811 }
812 `)
Logan Chiend3c59a22018-03-29 14:08:15 +0800813}
814
Justin Yun9357f4a2018-11-28 15:14:47 +0900815func TestVndkMustNotBeProductSpecific(t *testing.T) {
816 // Check whether an error is emitted when a vndk lib has 'product_specific: true'.
817 testCcError(t, "product_specific must not be true when `vndk: {enabled: true}`", `
818 cc_library {
819 name: "libvndk",
820 product_specific: true, // Cause error
821 vendor_available: true,
822 vndk: {
823 enabled: true,
824 },
825 nocrt: true,
826 }
827 `)
828}
829
Logan Chienf3511742017-10-31 18:04:35 +0800830func TestVndkExt(t *testing.T) {
831 // This test checks the VNDK-Ext properties.
832 ctx := testCc(t, `
833 cc_library {
834 name: "libvndk",
835 vendor_available: true,
836 vndk: {
837 enabled: true,
838 },
839 nocrt: true,
840 }
Jooyung Han4c2b9422019-10-22 19:53:47 +0900841 cc_library {
842 name: "libvndk2",
843 vendor_available: true,
844 vndk: {
845 enabled: true,
846 },
847 target: {
848 vendor: {
849 suffix: "-suffix",
850 },
851 },
852 nocrt: true,
853 }
Logan Chienf3511742017-10-31 18:04:35 +0800854
855 cc_library {
856 name: "libvndk_ext",
857 vendor: true,
858 vndk: {
859 enabled: true,
860 extends: "libvndk",
861 },
862 nocrt: true,
863 }
Jooyung Han4c2b9422019-10-22 19:53:47 +0900864
865 cc_library {
866 name: "libvndk2_ext",
867 vendor: true,
868 vndk: {
869 enabled: true,
870 extends: "libvndk2",
871 },
872 nocrt: true,
873 }
Logan Chienf3511742017-10-31 18:04:35 +0800874 `)
875
876 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
Jooyung Han4c2b9422019-10-22 19:53:47 +0900877
878 mod := ctx.ModuleForTests("libvndk2_ext", vendorVariant).Module().(*Module)
879 assertString(t, mod.outputFile.Path().Base(), "libvndk2-suffix.so")
Logan Chienf3511742017-10-31 18:04:35 +0800880}
881
Logan Chiend3c59a22018-03-29 14:08:15 +0800882func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800883 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
884 ctx := testCcNoVndk(t, `
885 cc_library {
886 name: "libvndk",
887 vendor_available: true,
888 vndk: {
889 enabled: true,
890 },
891 nocrt: true,
892 }
893
894 cc_library {
895 name: "libvndk_ext",
896 vendor: true,
897 vndk: {
898 enabled: true,
899 extends: "libvndk",
900 },
901 nocrt: true,
902 }
903 `)
904
905 // Ensures that the core variant of "libvndk_ext" can be found.
906 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
907 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
908 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
909 }
910}
911
912func TestVndkExtError(t *testing.T) {
913 // This test ensures an error is emitted in ill-formed vndk-ext definition.
914 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
915 cc_library {
916 name: "libvndk",
917 vendor_available: true,
918 vndk: {
919 enabled: true,
920 },
921 nocrt: true,
922 }
923
924 cc_library {
925 name: "libvndk_ext",
926 vndk: {
927 enabled: true,
928 extends: "libvndk",
929 },
930 nocrt: true,
931 }
932 `)
933
934 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
935 cc_library {
936 name: "libvndk",
937 vendor_available: true,
938 vndk: {
939 enabled: true,
940 },
941 nocrt: true,
942 }
943
944 cc_library {
945 name: "libvndk_ext",
946 vendor: true,
947 vndk: {
948 enabled: true,
949 },
950 nocrt: true,
951 }
952 `)
953}
954
955func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
956 // This test ensures an error is emitted for inconsistent support_system_process.
957 testCcError(t, "module \".*\" with mismatched support_system_process", `
958 cc_library {
959 name: "libvndk",
960 vendor_available: true,
961 vndk: {
962 enabled: true,
963 },
964 nocrt: true,
965 }
966
967 cc_library {
968 name: "libvndk_sp_ext",
969 vendor: true,
970 vndk: {
971 enabled: true,
972 extends: "libvndk",
973 support_system_process: true,
974 },
975 nocrt: true,
976 }
977 `)
978
979 testCcError(t, "module \".*\" with mismatched support_system_process", `
980 cc_library {
981 name: "libvndk_sp",
982 vendor_available: true,
983 vndk: {
984 enabled: true,
985 support_system_process: true,
986 },
987 nocrt: true,
988 }
989
990 cc_library {
991 name: "libvndk_ext",
992 vendor: true,
993 vndk: {
994 enabled: true,
995 extends: "libvndk_sp",
996 },
997 nocrt: true,
998 }
999 `)
1000}
1001
1002func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +08001003 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +08001004 // with `vendor_available: false`.
1005 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
1006 cc_library {
1007 name: "libvndk",
1008 vendor_available: false,
1009 vndk: {
1010 enabled: true,
1011 },
1012 nocrt: true,
1013 }
1014
1015 cc_library {
1016 name: "libvndk_ext",
1017 vendor: true,
1018 vndk: {
1019 enabled: true,
1020 extends: "libvndk",
1021 },
1022 nocrt: true,
1023 }
1024 `)
1025}
1026
Logan Chiend3c59a22018-03-29 14:08:15 +08001027func TestVendorModuleUseVndkExt(t *testing.T) {
1028 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +08001029 testCc(t, `
1030 cc_library {
1031 name: "libvndk",
1032 vendor_available: true,
1033 vndk: {
1034 enabled: true,
1035 },
1036 nocrt: true,
1037 }
1038
1039 cc_library {
1040 name: "libvndk_ext",
1041 vendor: true,
1042 vndk: {
1043 enabled: true,
1044 extends: "libvndk",
1045 },
1046 nocrt: true,
1047 }
1048
1049 cc_library {
1050
1051 name: "libvndk_sp",
1052 vendor_available: true,
1053 vndk: {
1054 enabled: true,
1055 support_system_process: true,
1056 },
1057 nocrt: true,
1058 }
1059
1060 cc_library {
1061 name: "libvndk_sp_ext",
1062 vendor: true,
1063 vndk: {
1064 enabled: true,
1065 extends: "libvndk_sp",
1066 support_system_process: true,
1067 },
1068 nocrt: true,
1069 }
1070
1071 cc_library {
1072 name: "libvendor",
1073 vendor: true,
1074 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
1075 nocrt: true,
1076 }
1077 `)
1078}
1079
Logan Chiend3c59a22018-03-29 14:08:15 +08001080func TestVndkExtUseVendorLib(t *testing.T) {
1081 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +08001082 testCc(t, `
1083 cc_library {
1084 name: "libvndk",
1085 vendor_available: true,
1086 vndk: {
1087 enabled: true,
1088 },
1089 nocrt: true,
1090 }
1091
1092 cc_library {
1093 name: "libvndk_ext",
1094 vendor: true,
1095 vndk: {
1096 enabled: true,
1097 extends: "libvndk",
1098 },
1099 shared_libs: ["libvendor"],
1100 nocrt: true,
1101 }
1102
1103 cc_library {
1104 name: "libvendor",
1105 vendor: true,
1106 nocrt: true,
1107 }
1108 `)
Logan Chienf3511742017-10-31 18:04:35 +08001109
Logan Chiend3c59a22018-03-29 14:08:15 +08001110 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
1111 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +08001112 cc_library {
1113 name: "libvndk_sp",
1114 vendor_available: true,
1115 vndk: {
1116 enabled: true,
1117 support_system_process: true,
1118 },
1119 nocrt: true,
1120 }
1121
1122 cc_library {
1123 name: "libvndk_sp_ext",
1124 vendor: true,
1125 vndk: {
1126 enabled: true,
1127 extends: "libvndk_sp",
1128 support_system_process: true,
1129 },
1130 shared_libs: ["libvendor"], // Cause an error
1131 nocrt: true,
1132 }
1133
1134 cc_library {
1135 name: "libvendor",
1136 vendor: true,
1137 nocrt: true,
1138 }
1139 `)
1140}
1141
Logan Chiend3c59a22018-03-29 14:08:15 +08001142func TestVndkSpExtUseVndkError(t *testing.T) {
1143 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
1144 // library.
1145 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1146 cc_library {
1147 name: "libvndk",
1148 vendor_available: true,
1149 vndk: {
1150 enabled: true,
1151 },
1152 nocrt: true,
1153 }
1154
1155 cc_library {
1156 name: "libvndk_sp",
1157 vendor_available: true,
1158 vndk: {
1159 enabled: true,
1160 support_system_process: true,
1161 },
1162 nocrt: true,
1163 }
1164
1165 cc_library {
1166 name: "libvndk_sp_ext",
1167 vendor: true,
1168 vndk: {
1169 enabled: true,
1170 extends: "libvndk_sp",
1171 support_system_process: true,
1172 },
1173 shared_libs: ["libvndk"], // Cause an error
1174 nocrt: true,
1175 }
1176 `)
1177
1178 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
1179 // library.
1180 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1181 cc_library {
1182 name: "libvndk",
1183 vendor_available: true,
1184 vndk: {
1185 enabled: true,
1186 },
1187 nocrt: true,
1188 }
1189
1190 cc_library {
1191 name: "libvndk_ext",
1192 vendor: true,
1193 vndk: {
1194 enabled: true,
1195 extends: "libvndk",
1196 },
1197 nocrt: true,
1198 }
1199
1200 cc_library {
1201 name: "libvndk_sp",
1202 vendor_available: true,
1203 vndk: {
1204 enabled: true,
1205 support_system_process: true,
1206 },
1207 nocrt: true,
1208 }
1209
1210 cc_library {
1211 name: "libvndk_sp_ext",
1212 vendor: true,
1213 vndk: {
1214 enabled: true,
1215 extends: "libvndk_sp",
1216 support_system_process: true,
1217 },
1218 shared_libs: ["libvndk_ext"], // Cause an error
1219 nocrt: true,
1220 }
1221 `)
1222}
1223
1224func TestVndkUseVndkExtError(t *testing.T) {
1225 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
1226 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +08001227 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1228 cc_library {
1229 name: "libvndk",
1230 vendor_available: true,
1231 vndk: {
1232 enabled: true,
1233 },
1234 nocrt: true,
1235 }
1236
1237 cc_library {
1238 name: "libvndk_ext",
1239 vendor: true,
1240 vndk: {
1241 enabled: true,
1242 extends: "libvndk",
1243 },
1244 nocrt: true,
1245 }
1246
1247 cc_library {
1248 name: "libvndk2",
1249 vendor_available: true,
1250 vndk: {
1251 enabled: true,
1252 },
1253 shared_libs: ["libvndk_ext"],
1254 nocrt: true,
1255 }
1256 `)
1257
Martin Stjernholmef449fe2018-11-06 16:12:13 +00001258 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +08001259 cc_library {
1260 name: "libvndk",
1261 vendor_available: true,
1262 vndk: {
1263 enabled: true,
1264 },
1265 nocrt: true,
1266 }
1267
1268 cc_library {
1269 name: "libvndk_ext",
1270 vendor: true,
1271 vndk: {
1272 enabled: true,
1273 extends: "libvndk",
1274 },
1275 nocrt: true,
1276 }
1277
1278 cc_library {
1279 name: "libvndk2",
1280 vendor_available: true,
1281 vndk: {
1282 enabled: true,
1283 },
1284 target: {
1285 vendor: {
1286 shared_libs: ["libvndk_ext"],
1287 },
1288 },
1289 nocrt: true,
1290 }
1291 `)
1292
1293 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1294 cc_library {
1295 name: "libvndk_sp",
1296 vendor_available: true,
1297 vndk: {
1298 enabled: true,
1299 support_system_process: true,
1300 },
1301 nocrt: true,
1302 }
1303
1304 cc_library {
1305 name: "libvndk_sp_ext",
1306 vendor: true,
1307 vndk: {
1308 enabled: true,
1309 extends: "libvndk_sp",
1310 support_system_process: true,
1311 },
1312 nocrt: true,
1313 }
1314
1315 cc_library {
1316 name: "libvndk_sp_2",
1317 vendor_available: true,
1318 vndk: {
1319 enabled: true,
1320 support_system_process: true,
1321 },
1322 shared_libs: ["libvndk_sp_ext"],
1323 nocrt: true,
1324 }
1325 `)
1326
Martin Stjernholmef449fe2018-11-06 16:12:13 +00001327 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +08001328 cc_library {
1329 name: "libvndk_sp",
1330 vendor_available: true,
1331 vndk: {
1332 enabled: true,
1333 },
1334 nocrt: true,
1335 }
1336
1337 cc_library {
1338 name: "libvndk_sp_ext",
1339 vendor: true,
1340 vndk: {
1341 enabled: true,
1342 extends: "libvndk_sp",
1343 },
1344 nocrt: true,
1345 }
1346
1347 cc_library {
1348 name: "libvndk_sp2",
1349 vendor_available: true,
1350 vndk: {
1351 enabled: true,
1352 },
1353 target: {
1354 vendor: {
1355 shared_libs: ["libvndk_sp_ext"],
1356 },
1357 },
1358 nocrt: true,
1359 }
1360 `)
1361}
1362
Jooyung Han38002912019-05-16 04:01:54 +09001363func TestMakeLinkType(t *testing.T) {
1364 config := android.TestArchConfig(buildDir, nil)
1365 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1366 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
1367 // native:vndk
1368 ctx := testCcWithConfig(t, `
1369 cc_library {
1370 name: "libvndk",
1371 vendor_available: true,
1372 vndk: {
1373 enabled: true,
1374 },
1375 }
1376 cc_library {
1377 name: "libvndksp",
1378 vendor_available: true,
1379 vndk: {
1380 enabled: true,
1381 support_system_process: true,
1382 },
1383 }
1384 cc_library {
1385 name: "libvndkprivate",
1386 vendor_available: false,
1387 vndk: {
1388 enabled: true,
1389 },
1390 }
1391 cc_library {
1392 name: "libvendor",
1393 vendor: true,
1394 }
1395 cc_library {
1396 name: "libvndkext",
1397 vendor: true,
1398 vndk: {
1399 enabled: true,
1400 extends: "libvndk",
1401 },
1402 }
1403 vndk_prebuilt_shared {
1404 name: "prevndk",
1405 version: "27",
1406 target_arch: "arm",
1407 binder32bit: true,
1408 vendor_available: true,
1409 vndk: {
1410 enabled: true,
1411 },
1412 arch: {
1413 arm: {
1414 srcs: ["liba.so"],
1415 },
1416 },
1417 }
1418 cc_library {
1419 name: "libllndk",
1420 }
1421 llndk_library {
1422 name: "libllndk",
1423 symbol_file: "",
1424 }
1425 cc_library {
1426 name: "libllndkprivate",
1427 }
1428 llndk_library {
1429 name: "libllndkprivate",
1430 vendor_available: false,
1431 symbol_file: "",
1432 }`, config)
1433
1434 assertArrayString(t, *vndkCoreLibraries(config),
1435 []string{"libvndk", "libvndkprivate"})
1436 assertArrayString(t, *vndkSpLibraries(config),
1437 []string{"libc++", "libvndksp"})
1438 assertArrayString(t, *llndkLibraries(config),
Jooyung Han097087b2019-10-22 19:32:18 +09001439 []string{"libc", "libdl", "libft2", "libllndk", "libllndkprivate", "libm"})
Jooyung Han38002912019-05-16 04:01:54 +09001440 assertArrayString(t, *vndkPrivateLibraries(config),
Jooyung Han097087b2019-10-22 19:32:18 +09001441 []string{"libft2", "libllndkprivate", "libvndkprivate"})
Jooyung Han38002912019-05-16 04:01:54 +09001442
Inseob Kim64c43952019-08-26 16:52:35 +09001443 vendorVariant27 := "android_arm64_armv8-a_vendor.27_shared"
1444
Jooyung Han38002912019-05-16 04:01:54 +09001445 tests := []struct {
1446 variant string
1447 name string
1448 expected string
1449 }{
1450 {vendorVariant, "libvndk", "native:vndk"},
1451 {vendorVariant, "libvndksp", "native:vndk"},
1452 {vendorVariant, "libvndkprivate", "native:vndk_private"},
1453 {vendorVariant, "libvendor", "native:vendor"},
1454 {vendorVariant, "libvndkext", "native:vendor"},
Jooyung Han38002912019-05-16 04:01:54 +09001455 {vendorVariant, "libllndk.llndk", "native:vndk"},
Inseob Kim64c43952019-08-26 16:52:35 +09001456 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
Jooyung Han38002912019-05-16 04:01:54 +09001457 {coreVariant, "libvndk", "native:platform"},
1458 {coreVariant, "libvndkprivate", "native:platform"},
1459 {coreVariant, "libllndk", "native:platform"},
1460 }
1461 for _, test := range tests {
1462 t.Run(test.name, func(t *testing.T) {
1463 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
1464 assertString(t, module.makeLinkType, test.expected)
1465 })
1466 }
1467}
1468
Colin Cross0af4b842015-04-30 16:36:18 -07001469var (
1470 str11 = "01234567891"
1471 str10 = str11[:10]
1472 str9 = str11[:9]
1473 str5 = str11[:5]
1474 str4 = str11[:4]
1475)
1476
1477var splitListForSizeTestCases = []struct {
1478 in []string
1479 out [][]string
1480 size int
1481}{
1482 {
1483 in: []string{str10},
1484 out: [][]string{{str10}},
1485 size: 10,
1486 },
1487 {
1488 in: []string{str9},
1489 out: [][]string{{str9}},
1490 size: 10,
1491 },
1492 {
1493 in: []string{str5},
1494 out: [][]string{{str5}},
1495 size: 10,
1496 },
1497 {
1498 in: []string{str11},
1499 out: nil,
1500 size: 10,
1501 },
1502 {
1503 in: []string{str10, str10},
1504 out: [][]string{{str10}, {str10}},
1505 size: 10,
1506 },
1507 {
1508 in: []string{str9, str10},
1509 out: [][]string{{str9}, {str10}},
1510 size: 10,
1511 },
1512 {
1513 in: []string{str10, str9},
1514 out: [][]string{{str10}, {str9}},
1515 size: 10,
1516 },
1517 {
1518 in: []string{str5, str4},
1519 out: [][]string{{str5, str4}},
1520 size: 10,
1521 },
1522 {
1523 in: []string{str5, str4, str5},
1524 out: [][]string{{str5, str4}, {str5}},
1525 size: 10,
1526 },
1527 {
1528 in: []string{str5, str4, str5, str4},
1529 out: [][]string{{str5, str4}, {str5, str4}},
1530 size: 10,
1531 },
1532 {
1533 in: []string{str5, str4, str5, str5},
1534 out: [][]string{{str5, str4}, {str5}, {str5}},
1535 size: 10,
1536 },
1537 {
1538 in: []string{str5, str5, str5, str4},
1539 out: [][]string{{str5}, {str5}, {str5, str4}},
1540 size: 10,
1541 },
1542 {
1543 in: []string{str9, str11},
1544 out: nil,
1545 size: 10,
1546 },
1547 {
1548 in: []string{str11, str9},
1549 out: nil,
1550 size: 10,
1551 },
1552}
1553
1554func TestSplitListForSize(t *testing.T) {
1555 for _, testCase := range splitListForSizeTestCases {
Colin Cross40e33732019-02-15 11:08:35 -08001556 out, _ := splitListForSize(android.PathsForTesting(testCase.in...), testCase.size)
Colin Cross5b529592017-05-09 13:34:34 -07001557
1558 var outStrings [][]string
1559
1560 if len(out) > 0 {
1561 outStrings = make([][]string, len(out))
1562 for i, o := range out {
1563 outStrings[i] = o.Strings()
1564 }
1565 }
1566
1567 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001568 t.Errorf("incorrect output:")
1569 t.Errorf(" input: %#v", testCase.in)
1570 t.Errorf(" size: %d", testCase.size)
1571 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001572 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001573 }
1574 }
1575}
Jeff Gaston294356f2017-09-27 17:05:30 -07001576
1577var staticLinkDepOrderTestCases = []struct {
1578 // This is a string representation of a map[moduleName][]moduleDependency .
1579 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001580 inStatic string
1581
1582 // This is a string representation of a map[moduleName][]moduleDependency .
1583 // It models the dependencies declared in an Android.bp file.
1584 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001585
1586 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1587 // The keys of allOrdered specify which modules we would like to check.
1588 // The values of allOrdered specify the expected result (of the transitive closure of all
1589 // dependencies) for each module to test
1590 allOrdered string
1591
1592 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1593 // The keys of outOrdered specify which modules we would like to check.
1594 // The values of outOrdered specify the expected result (of the ordered linker command line)
1595 // for each module to test.
1596 outOrdered string
1597}{
1598 // Simple tests
1599 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001600 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001601 outOrdered: "",
1602 },
1603 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001604 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001605 outOrdered: "a:",
1606 },
1607 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001608 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001609 outOrdered: "a:b; b:",
1610 },
1611 // Tests of reordering
1612 {
1613 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001614 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001615 outOrdered: "a:b,c,d; b:d; c:d; d:",
1616 },
1617 {
1618 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001619 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001620 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1621 },
1622 {
1623 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001624 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001625 outOrdered: "a:d,b,e,c; d:b; e:c",
1626 },
1627 {
1628 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001629 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001630 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1631 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1632 },
1633 {
1634 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001635 inStatic: "a:b,c,d,e,f,g,h; f:b,c,d; b:c,d; c:d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001636 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1637 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1638 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001639 // shared dependencies
1640 {
1641 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1642 // So, we don't actually have to check that a shared dependency of c will change the order
1643 // of a library that depends statically on b and on c. We only need to check that if c has
1644 // a shared dependency on b, that that shows up in allOrdered.
1645 inShared: "c:b",
1646 allOrdered: "c:b",
1647 outOrdered: "c:",
1648 },
1649 {
1650 // This test doesn't actually include any shared dependencies but it's a reminder of what
1651 // the second phase of the above test would look like
1652 inStatic: "a:b,c; c:b",
1653 allOrdered: "a:c,b; c:b",
1654 outOrdered: "a:c,b; c:b",
1655 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001656 // tiebreakers for when two modules specifying different orderings and there is no dependency
1657 // to dictate an order
1658 {
1659 // if the tie is between two modules at the end of a's deps, then a's order wins
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001660 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001661 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1662 },
1663 {
1664 // if the tie is between two modules at the start of a's deps, then c's order is used
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001665 inStatic: "a1:d,e,b1,c1; b1:d,e; c1:e,d; a2:d,e,b2,c2; b2:d,e; c2:d,e",
Jeff Gaston294356f2017-09-27 17:05:30 -07001666 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1667 },
1668 // Tests involving duplicate dependencies
1669 {
1670 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001671 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001672 outOrdered: "a:c,b",
1673 },
1674 {
1675 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001676 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001677 outOrdered: "a:d,c,b",
1678 },
1679 // Tests to confirm the nonexistence of infinite loops.
1680 // These cases should never happen, so as long as the test terminates and the
1681 // result is deterministic then that should be fine.
1682 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001683 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001684 outOrdered: "a:a",
1685 },
1686 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001687 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001688 allOrdered: "a:b,c; b:c,a; c:a,b",
1689 outOrdered: "a:b; b:c; c:a",
1690 },
1691 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001692 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001693 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1694 outOrdered: "a:c,b; b:a,c; c:b,a",
1695 },
1696}
1697
1698// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1699func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1700 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1701 strippedText := strings.Replace(text, " ", "", -1)
1702 if len(strippedText) < 1 {
1703 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1704 }
1705 allDeps = make(map[android.Path][]android.Path, 0)
1706
1707 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1708 moduleTexts := strings.Split(strippedText, ";")
1709
1710 outputForModuleName := func(moduleName string) android.Path {
1711 return android.PathForTesting(moduleName)
1712 }
1713
1714 for _, moduleText := range moduleTexts {
1715 // convert from "a:b,c" to ["a", "b,c"]
1716 components := strings.Split(moduleText, ":")
1717 if len(components) != 2 {
1718 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1719 }
1720 moduleName := components[0]
1721 moduleOutput := outputForModuleName(moduleName)
1722 modulesInOrder = append(modulesInOrder, moduleOutput)
1723
1724 depString := components[1]
1725 // convert from "b,c" to ["b", "c"]
1726 depNames := strings.Split(depString, ",")
1727 if len(depString) < 1 {
1728 depNames = []string{}
1729 }
1730 var deps []android.Path
1731 for _, depName := range depNames {
1732 deps = append(deps, outputForModuleName(depName))
1733 }
1734 allDeps[moduleOutput] = deps
1735 }
1736 return modulesInOrder, allDeps
1737}
1738
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001739func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001740 for _, testCase := range staticLinkDepOrderTestCases {
1741 errs := []string{}
1742
1743 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001744 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001745 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1746 if testCase.allOrdered == "" {
1747 // allow the test case to skip specifying allOrdered
1748 testCase.allOrdered = testCase.outOrdered
1749 }
1750 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001751 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001752
1753 // For each module whose post-reordered dependencies were specified, validate that
1754 // reordering the inputs produces the expected outputs.
1755 for _, moduleName := range expectedModuleNames {
1756 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001757 givenSharedDeps := givenAllSharedDeps[moduleName]
1758 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001759
1760 correctAllOrdered := expectedAllDeps[moduleName]
1761 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1762 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001763 "\nin static:%q"+
1764 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001765 "\nmodule: %v"+
1766 "\nexpected: %s"+
1767 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001768 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001769 }
1770
1771 correctOutputDeps := expectedTransitiveDeps[moduleName]
1772 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1773 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001774 "\nin static:%q"+
1775 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001776 "\nmodule: %v"+
1777 "\nexpected: %s"+
1778 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001779 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001780 }
1781 }
1782
1783 if len(errs) > 0 {
1784 sort.Strings(errs)
1785 for _, err := range errs {
1786 t.Error(err)
1787 }
1788 }
1789 }
1790}
Logan Chienf3511742017-10-31 18:04:35 +08001791
Jeff Gaston294356f2017-09-27 17:05:30 -07001792func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1793 for _, moduleName := range moduleNames {
1794 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1795 output := module.outputFile.Path()
1796 paths = append(paths, output)
1797 }
1798 return paths
1799}
1800
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001801func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001802 ctx := testCc(t, `
1803 cc_library {
1804 name: "a",
1805 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001806 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001807 }
1808 cc_library {
1809 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001810 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001811 }
1812 cc_library {
1813 name: "c",
1814 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001815 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001816 }
1817 cc_library {
1818 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001819 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001820 }
1821
1822 `)
1823
1824 variant := "android_arm64_armv8-a_core_static"
1825 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001826 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001827 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1828
1829 if !reflect.DeepEqual(actual, expected) {
1830 t.Errorf("staticDeps orderings were not propagated correctly"+
1831 "\nactual: %v"+
1832 "\nexpected: %v",
1833 actual,
1834 expected,
1835 )
1836 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001837}
Jeff Gaston294356f2017-09-27 17:05:30 -07001838
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001839func TestStaticLibDepReorderingWithShared(t *testing.T) {
1840 ctx := testCc(t, `
1841 cc_library {
1842 name: "a",
1843 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001844 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001845 }
1846 cc_library {
1847 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001848 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001849 }
1850 cc_library {
1851 name: "c",
1852 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001853 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001854 }
1855
1856 `)
1857
1858 variant := "android_arm64_armv8-a_core_static"
1859 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1860 actual := moduleA.depsInLinkOrder
1861 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1862
1863 if !reflect.DeepEqual(actual, expected) {
1864 t.Errorf("staticDeps orderings did not account for shared libs"+
1865 "\nactual: %v"+
1866 "\nexpected: %v",
1867 actual,
1868 expected,
1869 )
1870 }
1871}
1872
Jiyong Parka46a4d52017-12-14 19:54:34 +09001873func TestLlndkHeaders(t *testing.T) {
1874 ctx := testCc(t, `
1875 llndk_headers {
1876 name: "libllndk_headers",
1877 export_include_dirs: ["my_include"],
1878 }
1879 llndk_library {
1880 name: "libllndk",
1881 export_llndk_headers: ["libllndk_headers"],
1882 }
1883 cc_library {
1884 name: "libvendor",
1885 shared_libs: ["libllndk"],
1886 vendor: true,
1887 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001888 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001889 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001890 }
1891 `)
1892
1893 // _static variant is used since _shared reuses *.o from the static variant
Inseob Kim64c43952019-08-26 16:52:35 +09001894 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor.VER_static").Rule("cc")
Jiyong Parka46a4d52017-12-14 19:54:34 +09001895 cflags := cc.Args["cFlags"]
1896 if !strings.Contains(cflags, "-Imy_include") {
1897 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1898 }
1899}
1900
Logan Chien43d34c32017-12-20 01:17:32 +08001901func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1902 actual := module.Properties.AndroidMkRuntimeLibs
1903 if !reflect.DeepEqual(actual, expected) {
1904 t.Errorf("incorrect runtime_libs for shared libs"+
1905 "\nactual: %v"+
1906 "\nexpected: %v",
1907 actual,
1908 expected,
1909 )
1910 }
1911}
1912
1913const runtimeLibAndroidBp = `
1914 cc_library {
1915 name: "libvendor_available1",
1916 vendor_available: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001917 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001918 nocrt : true,
1919 system_shared_libs : [],
1920 }
1921 cc_library {
1922 name: "libvendor_available2",
1923 vendor_available: true,
1924 runtime_libs: ["libvendor_available1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001925 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001926 nocrt : true,
1927 system_shared_libs : [],
1928 }
1929 cc_library {
1930 name: "libvendor_available3",
1931 vendor_available: true,
1932 runtime_libs: ["libvendor_available1"],
1933 target: {
1934 vendor: {
1935 exclude_runtime_libs: ["libvendor_available1"],
1936 }
1937 },
Yi Konge7fe9912019-06-02 00:53:50 -07001938 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001939 nocrt : true,
1940 system_shared_libs : [],
1941 }
1942 cc_library {
1943 name: "libcore",
1944 runtime_libs: ["libvendor_available1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001945 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001946 nocrt : true,
1947 system_shared_libs : [],
1948 }
1949 cc_library {
1950 name: "libvendor1",
1951 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001952 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001953 nocrt : true,
1954 system_shared_libs : [],
1955 }
1956 cc_library {
1957 name: "libvendor2",
1958 vendor: true,
1959 runtime_libs: ["libvendor_available1", "libvendor1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001960 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001961 nocrt : true,
1962 system_shared_libs : [],
1963 }
1964`
1965
1966func TestRuntimeLibs(t *testing.T) {
1967 ctx := testCc(t, runtimeLibAndroidBp)
1968
1969 // runtime_libs for core variants use the module names without suffixes.
1970 variant := "android_arm64_armv8-a_core_shared"
1971
1972 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1973 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1974
1975 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1976 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1977
1978 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1979 // and vendor variants.
Inseob Kim64c43952019-08-26 16:52:35 +09001980 variant = "android_arm64_armv8-a_vendor.VER_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001981
1982 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1983 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1984
1985 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1986 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1987}
1988
1989func TestExcludeRuntimeLibs(t *testing.T) {
1990 ctx := testCc(t, runtimeLibAndroidBp)
1991
1992 variant := "android_arm64_armv8-a_core_shared"
1993 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1994 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1995
Inseob Kim64c43952019-08-26 16:52:35 +09001996 variant = "android_arm64_armv8-a_vendor.VER_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001997 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1998 checkRuntimeLibs(t, nil, module)
1999}
2000
2001func TestRuntimeLibsNoVndk(t *testing.T) {
2002 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
2003
2004 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
2005
2006 variant := "android_arm64_armv8-a_core_shared"
2007
2008 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
2009 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
2010
2011 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
2012 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
2013}
2014
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00002015func checkStaticLibs(t *testing.T, expected []string, module *Module) {
2016 actual := module.Properties.AndroidMkStaticLibs
2017 if !reflect.DeepEqual(actual, expected) {
2018 t.Errorf("incorrect static_libs"+
2019 "\nactual: %v"+
2020 "\nexpected: %v",
2021 actual,
2022 expected,
2023 )
2024 }
2025}
2026
2027const staticLibAndroidBp = `
2028 cc_library {
2029 name: "lib1",
2030 }
2031 cc_library {
2032 name: "lib2",
2033 static_libs: ["lib1"],
2034 }
2035`
2036
2037func TestStaticLibDepExport(t *testing.T) {
2038 ctx := testCc(t, staticLibAndroidBp)
2039
2040 // Check the shared version of lib2.
2041 variant := "android_arm64_armv8-a_core_shared"
2042 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Dan Albert2da19cb2019-07-24 12:17:40 -07002043 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00002044
2045 // Check the static version of lib2.
2046 variant = "android_arm64_armv8-a_core_static"
2047 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
2048 // libc++_static is linked additionally.
Dan Albert2da19cb2019-07-24 12:17:40 -07002049 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00002050}
2051
Jiyong Parkd08b6972017-09-26 10:50:54 +09002052var compilerFlagsTestCases = []struct {
2053 in string
2054 out bool
2055}{
2056 {
2057 in: "a",
2058 out: false,
2059 },
2060 {
2061 in: "-a",
2062 out: true,
2063 },
2064 {
2065 in: "-Ipath/to/something",
2066 out: false,
2067 },
2068 {
2069 in: "-isystempath/to/something",
2070 out: false,
2071 },
2072 {
2073 in: "--coverage",
2074 out: false,
2075 },
2076 {
2077 in: "-include a/b",
2078 out: true,
2079 },
2080 {
2081 in: "-include a/b c/d",
2082 out: false,
2083 },
2084 {
2085 in: "-DMACRO",
2086 out: true,
2087 },
2088 {
2089 in: "-DMAC RO",
2090 out: false,
2091 },
2092 {
2093 in: "-a -b",
2094 out: false,
2095 },
2096 {
2097 in: "-DMACRO=definition",
2098 out: true,
2099 },
2100 {
2101 in: "-DMACRO=defi nition",
2102 out: true, // TODO(jiyong): this should be false
2103 },
2104 {
2105 in: "-DMACRO(x)=x + 1",
2106 out: true,
2107 },
2108 {
2109 in: "-DMACRO=\"defi nition\"",
2110 out: true,
2111 },
2112}
2113
2114type mockContext struct {
2115 BaseModuleContext
2116 result bool
2117}
2118
2119func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
2120 // CheckBadCompilerFlags calls this function when the flag should be rejected
2121 ctx.result = false
2122}
2123
2124func TestCompilerFlags(t *testing.T) {
2125 for _, testCase := range compilerFlagsTestCases {
2126 ctx := &mockContext{result: true}
2127 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
2128 if ctx.result != testCase.out {
2129 t.Errorf("incorrect output:")
2130 t.Errorf(" input: %#v", testCase.in)
2131 t.Errorf(" expected: %#v", testCase.out)
2132 t.Errorf(" got: %#v", ctx.result)
2133 }
2134 }
Jeff Gaston294356f2017-09-27 17:05:30 -07002135}
Jiyong Park374510b2018-03-19 18:23:01 +09002136
2137func TestVendorPublicLibraries(t *testing.T) {
2138 ctx := testCc(t, `
2139 cc_library_headers {
2140 name: "libvendorpublic_headers",
2141 export_include_dirs: ["my_include"],
2142 }
2143 vendor_public_library {
2144 name: "libvendorpublic",
2145 symbol_file: "",
2146 export_public_headers: ["libvendorpublic_headers"],
2147 }
2148 cc_library {
2149 name: "libvendorpublic",
2150 srcs: ["foo.c"],
2151 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07002152 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002153 nocrt: true,
2154 }
2155
2156 cc_library {
2157 name: "libsystem",
2158 shared_libs: ["libvendorpublic"],
2159 vendor: false,
2160 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07002161 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002162 nocrt: true,
2163 }
2164 cc_library {
2165 name: "libvendor",
2166 shared_libs: ["libvendorpublic"],
2167 vendor: true,
2168 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07002169 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002170 nocrt: true,
2171 }
2172 `)
2173
2174 variant := "android_arm64_armv8-a_core_shared"
2175
2176 // test if header search paths are correctly added
2177 // _static variant is used since _shared reuses *.o from the static variant
2178 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
2179 cflags := cc.Args["cFlags"]
2180 if !strings.Contains(cflags, "-Imy_include") {
2181 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
2182 }
2183
2184 // test if libsystem is linked to the stub
2185 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
2186 libflags := ld.Args["libFlags"]
2187 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
2188 if !strings.Contains(libflags, stubPaths[0].String()) {
2189 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
2190 }
2191
2192 // test if libvendor is linked to the real shared lib
Inseob Kim64c43952019-08-26 16:52:35 +09002193 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor.VER", 1)).Rule("ld")
Jiyong Park374510b2018-03-19 18:23:01 +09002194 libflags = ld.Args["libFlags"]
Inseob Kim64c43952019-08-26 16:52:35 +09002195 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor.VER", 1), []string{"libvendorpublic"})
Jiyong Park374510b2018-03-19 18:23:01 +09002196 if !strings.Contains(libflags, stubPaths[0].String()) {
2197 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
2198 }
2199
2200}
Jiyong Park37b25202018-07-11 10:49:27 +09002201
2202func TestRecovery(t *testing.T) {
2203 ctx := testCc(t, `
2204 cc_library_shared {
2205 name: "librecovery",
2206 recovery: true,
2207 }
2208 cc_library_shared {
2209 name: "librecovery32",
2210 recovery: true,
2211 compile_multilib:"32",
2212 }
Jiyong Park5baac542018-08-28 09:55:37 +09002213 cc_library_shared {
2214 name: "libHalInRecovery",
2215 recovery_available: true,
2216 vendor: true,
2217 }
Jiyong Park37b25202018-07-11 10:49:27 +09002218 `)
2219
2220 variants := ctx.ModuleVariantsForTests("librecovery")
2221 const arm64 = "android_arm64_armv8-a_recovery_shared"
2222 if len(variants) != 1 || !android.InList(arm64, variants) {
2223 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
2224 }
2225
2226 variants = ctx.ModuleVariantsForTests("librecovery32")
2227 if android.InList(arm64, variants) {
2228 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
2229 }
Jiyong Park5baac542018-08-28 09:55:37 +09002230
2231 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
2232 if !recoveryModule.Platform() {
2233 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
2234 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09002235}
Jiyong Park5baac542018-08-28 09:55:37 +09002236
Jiyong Park7ed9de32018-10-15 22:25:07 +09002237func TestVersionedStubs(t *testing.T) {
2238 ctx := testCc(t, `
2239 cc_library_shared {
2240 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002241 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002242 stubs: {
2243 symbol_file: "foo.map.txt",
2244 versions: ["1", "2", "3"],
2245 },
2246 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002247
Jiyong Park7ed9de32018-10-15 22:25:07 +09002248 cc_library_shared {
2249 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002250 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002251 shared_libs: ["libFoo#1"],
2252 }`)
2253
2254 variants := ctx.ModuleVariantsForTests("libFoo")
2255 expectedVariants := []string{
2256 "android_arm64_armv8-a_core_shared",
2257 "android_arm64_armv8-a_core_shared_1",
2258 "android_arm64_armv8-a_core_shared_2",
2259 "android_arm64_armv8-a_core_shared_3",
2260 "android_arm_armv7-a-neon_core_shared",
2261 "android_arm_armv7-a-neon_core_shared_1",
2262 "android_arm_armv7-a-neon_core_shared_2",
2263 "android_arm_armv7-a-neon_core_shared_3",
2264 }
2265 variantsMismatch := false
2266 if len(variants) != len(expectedVariants) {
2267 variantsMismatch = true
2268 } else {
2269 for _, v := range expectedVariants {
2270 if !inList(v, variants) {
2271 variantsMismatch = false
2272 }
2273 }
2274 }
2275 if variantsMismatch {
2276 t.Errorf("variants of libFoo expected:\n")
2277 for _, v := range expectedVariants {
2278 t.Errorf("%q\n", v)
2279 }
2280 t.Errorf(", but got:\n")
2281 for _, v := range variants {
2282 t.Errorf("%q\n", v)
2283 }
2284 }
2285
2286 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld")
2287 libFlags := libBarLinkRule.Args["libFlags"]
2288 libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so"
2289 if !strings.Contains(libFlags, libFoo1StubPath) {
2290 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
2291 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002292
2293 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("cc")
2294 cFlags := libBarCompileRule.Args["cFlags"]
2295 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
2296 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
2297 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
2298 }
Jiyong Park37b25202018-07-11 10:49:27 +09002299}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002300
2301func TestStaticExecutable(t *testing.T) {
2302 ctx := testCc(t, `
2303 cc_binary {
2304 name: "static_test",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +01002305 srcs: ["foo.c", "baz.o"],
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002306 static_executable: true,
2307 }`)
2308
2309 variant := "android_arm64_armv8-a_core"
2310 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
2311 libFlags := binModuleRule.Args["libFlags"]
Ryan Prichardb49fe1b2019-10-11 15:03:34 -07002312 systemStaticLibs := []string{"libc.a", "libm.a"}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002313 for _, lib := range systemStaticLibs {
2314 if !strings.Contains(libFlags, lib) {
2315 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
2316 }
2317 }
2318 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
2319 for _, lib := range systemSharedLibs {
2320 if strings.Contains(libFlags, lib) {
2321 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
2322 }
2323 }
2324}
Jiyong Parke4bb9862019-02-01 00:31:10 +09002325
2326func TestStaticDepsOrderWithStubs(t *testing.T) {
2327 ctx := testCc(t, `
2328 cc_binary {
2329 name: "mybin",
2330 srcs: ["foo.c"],
2331 static_libs: ["libB"],
2332 static_executable: true,
2333 stl: "none",
2334 }
2335
2336 cc_library {
2337 name: "libB",
2338 srcs: ["foo.c"],
2339 shared_libs: ["libC"],
2340 stl: "none",
2341 }
2342
2343 cc_library {
2344 name: "libC",
2345 srcs: ["foo.c"],
2346 stl: "none",
2347 stubs: {
2348 versions: ["1"],
2349 },
2350 }`)
2351
2352 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a_core").Module().(*Module)
2353 actual := mybin.depsInLinkOrder
2354 expected := getOutputPaths(ctx, "android_arm64_armv8-a_core_static", []string{"libB", "libC"})
2355
2356 if !reflect.DeepEqual(actual, expected) {
2357 t.Errorf("staticDeps orderings were not propagated correctly"+
2358 "\nactual: %v"+
2359 "\nexpected: %v",
2360 actual,
2361 expected,
2362 )
2363 }
2364}
Jooyung Han38002912019-05-16 04:01:54 +09002365
Jooyung Hand48f3c32019-08-23 11:18:57 +09002366func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
2367 testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
2368 cc_library {
2369 name: "libA",
2370 srcs: ["foo.c"],
2371 shared_libs: ["libB"],
2372 stl: "none",
2373 }
2374
2375 cc_library {
2376 name: "libB",
2377 srcs: ["foo.c"],
2378 enabled: false,
2379 stl: "none",
2380 }
2381 `)
2382}
2383
Mitch Phillipsda9a4632019-07-15 09:34:09 -07002384// Simple smoke test for the cc_fuzz target that ensures the rule compiles
2385// correctly.
2386func TestFuzzTarget(t *testing.T) {
2387 ctx := testCc(t, `
2388 cc_fuzz {
2389 name: "fuzz_smoke_test",
2390 srcs: ["foo.c"],
2391 }`)
2392
2393 variant := "android_arm64_armv8-a_core"
2394 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
2395}
2396
Jiyong Park29074592019-07-07 16:27:47 +09002397func TestAidl(t *testing.T) {
2398}
2399
Jooyung Han38002912019-05-16 04:01:54 +09002400func assertString(t *testing.T, got, expected string) {
2401 t.Helper()
2402 if got != expected {
2403 t.Errorf("expected %q got %q", expected, got)
2404 }
2405}
2406
2407func assertArrayString(t *testing.T, got, expected []string) {
2408 t.Helper()
2409 if len(got) != len(expected) {
2410 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
2411 return
2412 }
2413 for i := range got {
2414 if got[i] != expected[i] {
2415 t.Errorf("expected %d-th %q (%q) got %q (%q)",
2416 i, expected[i], expected, got[i], got)
2417 return
2418 }
2419 }
2420}
Colin Crosse1bb5d02019-09-24 14:55:04 -07002421
2422func TestDefaults(t *testing.T) {
2423 ctx := testCc(t, `
2424 cc_defaults {
2425 name: "defaults",
2426 srcs: ["foo.c"],
2427 static: {
2428 srcs: ["bar.c"],
2429 },
2430 shared: {
2431 srcs: ["baz.c"],
2432 },
2433 }
2434
2435 cc_library_static {
2436 name: "libstatic",
2437 defaults: ["defaults"],
2438 }
2439
2440 cc_library_shared {
2441 name: "libshared",
2442 defaults: ["defaults"],
2443 }
2444
2445 cc_library {
2446 name: "libboth",
2447 defaults: ["defaults"],
2448 }
2449
2450 cc_binary {
2451 name: "binary",
2452 defaults: ["defaults"],
2453 }`)
2454
2455 pathsToBase := func(paths android.Paths) []string {
2456 var ret []string
2457 for _, p := range paths {
2458 ret = append(ret, p.Base())
2459 }
2460 return ret
2461 }
2462
2463 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_core_shared").Rule("ld")
2464 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2465 t.Errorf("libshared ld rule wanted %q, got %q", w, g)
2466 }
2467 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_core_shared").Rule("ld")
2468 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2469 t.Errorf("libboth ld rule wanted %q, got %q", w, g)
2470 }
2471 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a_core").Rule("ld")
2472 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
2473 t.Errorf("binary ld rule wanted %q, got %q", w, g)
2474 }
2475
2476 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_core_static").Rule("ar")
2477 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2478 t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
2479 }
2480 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_core_static").Rule("ar")
2481 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2482 t.Errorf("libboth ar rule wanted %q, got %q", w, g)
2483 }
2484}