blob: 56078d94847e0e265e07fb573236571b32769669 [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)
216 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 }
233 if !mod.isVndk() {
234 t.Errorf("%q isVndk() must equal to true", name)
235 }
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
Logan Chienf3511742017-10-31 18:04:35 +0800267func TestVndk(t *testing.T) {
Inseob Kim1f086e22019-05-09 13:29:15 +0900268 config := android.TestArchConfig(buildDir, nil)
269 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
270 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
271
272 ctx := testCcWithConfig(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800273 cc_library {
274 name: "libvndk",
275 vendor_available: true,
276 vndk: {
277 enabled: true,
278 },
279 nocrt: true,
280 }
281
282 cc_library {
283 name: "libvndk_private",
284 vendor_available: false,
285 vndk: {
286 enabled: true,
287 },
288 nocrt: true,
289 }
290
291 cc_library {
292 name: "libvndk_sp",
293 vendor_available: true,
294 vndk: {
295 enabled: true,
296 support_system_process: true,
297 },
298 nocrt: true,
299 }
300
301 cc_library {
302 name: "libvndk_sp_private",
303 vendor_available: false,
304 vndk: {
305 enabled: true,
306 support_system_process: true,
307 },
308 nocrt: true,
309 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900310 `, config)
Logan Chienf3511742017-10-31 18:04:35 +0800311
312 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
313 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
314 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
315 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
Inseob Kim1f086e22019-05-09 13:29:15 +0900316
317 // Check VNDK snapshot output.
318
319 snapshotDir := "vndk-snapshot"
320 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
321
322 vndkLibPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
323 "arm64", "armv8-a"))
324 vndkLib2ndPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
325 "arm", "armv7-a-neon"))
326
327 vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core")
328 vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp")
329 vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
330 vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
331
Inseob Kim64c43952019-08-26 16:52:35 +0900332 variant := "android_arm64_armv8-a_vendor.VER_shared"
333 variant2nd := "android_arm_armv7-a-neon_vendor.VER_shared"
Inseob Kim1f086e22019-05-09 13:29:15 +0900334
335 checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLibPath, variant)
336 checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLib2ndPath, variant2nd)
337 checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLibPath, variant)
338 checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLib2ndPath, variant2nd)
Logan Chienf3511742017-10-31 18:04:35 +0800339}
340
Logan Chiend3c59a22018-03-29 14:08:15 +0800341func TestVndkDepError(t *testing.T) {
342 // Check whether an error is emitted when a VNDK lib depends on a system lib.
343 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
344 cc_library {
345 name: "libvndk",
346 vendor_available: true,
347 vndk: {
348 enabled: true,
349 },
350 shared_libs: ["libfwk"], // Cause error
351 nocrt: true,
352 }
353
354 cc_library {
355 name: "libfwk",
356 nocrt: true,
357 }
358 `)
359
360 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
361 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
362 cc_library {
363 name: "libvndk",
364 vendor_available: true,
365 vndk: {
366 enabled: true,
367 },
368 shared_libs: ["libvendor"], // Cause error
369 nocrt: true,
370 }
371
372 cc_library {
373 name: "libvendor",
374 vendor: true,
375 nocrt: true,
376 }
377 `)
378
379 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
380 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
381 cc_library {
382 name: "libvndk_sp",
383 vendor_available: true,
384 vndk: {
385 enabled: true,
386 support_system_process: true,
387 },
388 shared_libs: ["libfwk"], // Cause error
389 nocrt: true,
390 }
391
392 cc_library {
393 name: "libfwk",
394 nocrt: true,
395 }
396 `)
397
398 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
399 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
400 cc_library {
401 name: "libvndk_sp",
402 vendor_available: true,
403 vndk: {
404 enabled: true,
405 support_system_process: true,
406 },
407 shared_libs: ["libvendor"], // Cause error
408 nocrt: true,
409 }
410
411 cc_library {
412 name: "libvendor",
413 vendor: true,
414 nocrt: true,
415 }
416 `)
417
418 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
419 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
420 cc_library {
421 name: "libvndk_sp",
422 vendor_available: true,
423 vndk: {
424 enabled: true,
425 support_system_process: true,
426 },
427 shared_libs: ["libvndk"], // Cause error
428 nocrt: true,
429 }
430
431 cc_library {
432 name: "libvndk",
433 vendor_available: true,
434 vndk: {
435 enabled: true,
436 },
437 nocrt: true,
438 }
439 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900440
441 // Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib.
442 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
443 cc_library {
444 name: "libvndk",
445 vendor_available: true,
446 vndk: {
447 enabled: true,
448 },
449 shared_libs: ["libnonvndk"],
450 nocrt: true,
451 }
452
453 cc_library {
454 name: "libnonvndk",
455 vendor_available: true,
456 nocrt: true,
457 }
458 `)
459
460 // Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib.
461 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
462 cc_library {
463 name: "libvndkprivate",
464 vendor_available: false,
465 vndk: {
466 enabled: true,
467 },
468 shared_libs: ["libnonvndk"],
469 nocrt: true,
470 }
471
472 cc_library {
473 name: "libnonvndk",
474 vendor_available: true,
475 nocrt: true,
476 }
477 `)
478
479 // Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib.
480 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
481 cc_library {
482 name: "libvndksp",
483 vendor_available: true,
484 vndk: {
485 enabled: true,
486 support_system_process: true,
487 },
488 shared_libs: ["libnonvndk"],
489 nocrt: true,
490 }
491
492 cc_library {
493 name: "libnonvndk",
494 vendor_available: true,
495 nocrt: true,
496 }
497 `)
498
499 // Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib.
500 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
501 cc_library {
502 name: "libvndkspprivate",
503 vendor_available: false,
504 vndk: {
505 enabled: true,
506 support_system_process: true,
507 },
508 shared_libs: ["libnonvndk"],
509 nocrt: true,
510 }
511
512 cc_library {
513 name: "libnonvndk",
514 vendor_available: true,
515 nocrt: true,
516 }
517 `)
518}
519
520func TestDoubleLoadbleDep(t *testing.T) {
521 // okay to link : LLNDK -> double_loadable VNDK
522 testCc(t, `
523 cc_library {
524 name: "libllndk",
525 shared_libs: ["libdoubleloadable"],
526 }
527
528 llndk_library {
529 name: "libllndk",
530 symbol_file: "",
531 }
532
533 cc_library {
534 name: "libdoubleloadable",
535 vendor_available: true,
536 vndk: {
537 enabled: true,
538 },
539 double_loadable: true,
540 }
541 `)
542 // okay to link : LLNDK -> VNDK-SP
543 testCc(t, `
544 cc_library {
545 name: "libllndk",
546 shared_libs: ["libvndksp"],
547 }
548
549 llndk_library {
550 name: "libllndk",
551 symbol_file: "",
552 }
553
554 cc_library {
555 name: "libvndksp",
556 vendor_available: true,
557 vndk: {
558 enabled: true,
559 support_system_process: true,
560 },
561 }
562 `)
563 // okay to link : double_loadable -> double_loadable
564 testCc(t, `
565 cc_library {
566 name: "libdoubleloadable1",
567 shared_libs: ["libdoubleloadable2"],
568 vendor_available: true,
569 double_loadable: true,
570 }
571
572 cc_library {
573 name: "libdoubleloadable2",
574 vendor_available: true,
575 double_loadable: true,
576 }
577 `)
578 // okay to link : double_loadable VNDK -> double_loadable VNDK private
579 testCc(t, `
580 cc_library {
581 name: "libdoubleloadable",
582 vendor_available: true,
583 vndk: {
584 enabled: true,
585 },
586 double_loadable: true,
587 shared_libs: ["libnondoubleloadable"],
588 }
589
590 cc_library {
591 name: "libnondoubleloadable",
592 vendor_available: false,
593 vndk: {
594 enabled: true,
595 },
596 double_loadable: true,
597 }
598 `)
599 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
600 testCc(t, `
601 cc_library {
602 name: "libllndk",
603 shared_libs: ["libcoreonly"],
604 }
605
606 llndk_library {
607 name: "libllndk",
608 symbol_file: "",
609 }
610
611 cc_library {
612 name: "libcoreonly",
613 shared_libs: ["libvendoravailable"],
614 }
615
616 // indirect dependency of LLNDK
617 cc_library {
618 name: "libvendoravailable",
619 vendor_available: true,
620 double_loadable: true,
621 }
622 `)
623}
624
625func TestDoubleLoadableDepError(t *testing.T) {
626 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
627 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
628 cc_library {
629 name: "libllndk",
630 shared_libs: ["libnondoubleloadable"],
631 }
632
633 llndk_library {
634 name: "libllndk",
635 symbol_file: "",
636 }
637
638 cc_library {
639 name: "libnondoubleloadable",
640 vendor_available: true,
641 vndk: {
642 enabled: true,
643 },
644 }
645 `)
646
647 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
648 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
649 cc_library {
650 name: "libllndk",
Yi Konge7fe9912019-06-02 00:53:50 -0700651 no_libcrt: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900652 shared_libs: ["libnondoubleloadable"],
653 }
654
655 llndk_library {
656 name: "libllndk",
657 symbol_file: "",
658 }
659
660 cc_library {
661 name: "libnondoubleloadable",
662 vendor_available: true,
663 }
664 `)
665
666 // Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable vendor_available lib.
667 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
668 cc_library {
669 name: "libdoubleloadable",
670 vendor_available: true,
671 double_loadable: true,
672 shared_libs: ["libnondoubleloadable"],
673 }
674
675 cc_library {
676 name: "libnondoubleloadable",
677 vendor_available: true,
678 }
679 `)
680
681 // Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable VNDK lib.
682 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
683 cc_library {
684 name: "libdoubleloadable",
685 vendor_available: true,
686 double_loadable: true,
687 shared_libs: ["libnondoubleloadable"],
688 }
689
690 cc_library {
691 name: "libnondoubleloadable",
692 vendor_available: true,
693 vndk: {
694 enabled: true,
695 },
696 }
697 `)
698
699 // Check whether an error is emitted when a double_loadable VNDK depends on a non-double_loadable VNDK private lib.
700 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
701 cc_library {
702 name: "libdoubleloadable",
703 vendor_available: true,
704 vndk: {
705 enabled: true,
706 },
707 double_loadable: true,
708 shared_libs: ["libnondoubleloadable"],
709 }
710
711 cc_library {
712 name: "libnondoubleloadable",
713 vendor_available: false,
714 vndk: {
715 enabled: true,
716 },
717 }
718 `)
719
720 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
721 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
722 cc_library {
723 name: "libllndk",
724 shared_libs: ["libcoreonly"],
725 }
726
727 llndk_library {
728 name: "libllndk",
729 symbol_file: "",
730 }
731
732 cc_library {
733 name: "libcoreonly",
734 shared_libs: ["libvendoravailable"],
735 }
736
737 // indirect dependency of LLNDK
738 cc_library {
739 name: "libvendoravailable",
740 vendor_available: true,
741 }
742 `)
Logan Chiend3c59a22018-03-29 14:08:15 +0800743}
744
Justin Yun9357f4a2018-11-28 15:14:47 +0900745func TestVndkMustNotBeProductSpecific(t *testing.T) {
746 // Check whether an error is emitted when a vndk lib has 'product_specific: true'.
747 testCcError(t, "product_specific must not be true when `vndk: {enabled: true}`", `
748 cc_library {
749 name: "libvndk",
750 product_specific: true, // Cause error
751 vendor_available: true,
752 vndk: {
753 enabled: true,
754 },
755 nocrt: true,
756 }
757 `)
758}
759
Logan Chienf3511742017-10-31 18:04:35 +0800760func TestVndkExt(t *testing.T) {
761 // This test checks the VNDK-Ext properties.
762 ctx := testCc(t, `
763 cc_library {
764 name: "libvndk",
765 vendor_available: true,
766 vndk: {
767 enabled: true,
768 },
769 nocrt: true,
770 }
Jooyung Han4c2b9422019-10-22 19:53:47 +0900771 cc_library {
772 name: "libvndk2",
773 vendor_available: true,
774 vndk: {
775 enabled: true,
776 },
777 target: {
778 vendor: {
779 suffix: "-suffix",
780 },
781 },
782 nocrt: true,
783 }
Logan Chienf3511742017-10-31 18:04:35 +0800784
785 cc_library {
786 name: "libvndk_ext",
787 vendor: true,
788 vndk: {
789 enabled: true,
790 extends: "libvndk",
791 },
792 nocrt: true,
793 }
Jooyung Han4c2b9422019-10-22 19:53:47 +0900794
795 cc_library {
796 name: "libvndk2_ext",
797 vendor: true,
798 vndk: {
799 enabled: true,
800 extends: "libvndk2",
801 },
802 nocrt: true,
803 }
Logan Chienf3511742017-10-31 18:04:35 +0800804 `)
805
806 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
Jooyung Han4c2b9422019-10-22 19:53:47 +0900807
808 mod := ctx.ModuleForTests("libvndk2_ext", vendorVariant).Module().(*Module)
809 assertString(t, mod.outputFile.Path().Base(), "libvndk2-suffix.so")
Logan Chienf3511742017-10-31 18:04:35 +0800810}
811
Logan Chiend3c59a22018-03-29 14:08:15 +0800812func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800813 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
814 ctx := testCcNoVndk(t, `
815 cc_library {
816 name: "libvndk",
817 vendor_available: true,
818 vndk: {
819 enabled: true,
820 },
821 nocrt: true,
822 }
823
824 cc_library {
825 name: "libvndk_ext",
826 vendor: true,
827 vndk: {
828 enabled: true,
829 extends: "libvndk",
830 },
831 nocrt: true,
832 }
833 `)
834
835 // Ensures that the core variant of "libvndk_ext" can be found.
836 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
837 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
838 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
839 }
840}
841
842func TestVndkExtError(t *testing.T) {
843 // This test ensures an error is emitted in ill-formed vndk-ext definition.
844 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
845 cc_library {
846 name: "libvndk",
847 vendor_available: true,
848 vndk: {
849 enabled: true,
850 },
851 nocrt: true,
852 }
853
854 cc_library {
855 name: "libvndk_ext",
856 vndk: {
857 enabled: true,
858 extends: "libvndk",
859 },
860 nocrt: true,
861 }
862 `)
863
864 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
865 cc_library {
866 name: "libvndk",
867 vendor_available: true,
868 vndk: {
869 enabled: true,
870 },
871 nocrt: true,
872 }
873
874 cc_library {
875 name: "libvndk_ext",
876 vendor: true,
877 vndk: {
878 enabled: true,
879 },
880 nocrt: true,
881 }
882 `)
883}
884
885func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
886 // This test ensures an error is emitted for inconsistent support_system_process.
887 testCcError(t, "module \".*\" with mismatched support_system_process", `
888 cc_library {
889 name: "libvndk",
890 vendor_available: true,
891 vndk: {
892 enabled: true,
893 },
894 nocrt: true,
895 }
896
897 cc_library {
898 name: "libvndk_sp_ext",
899 vendor: true,
900 vndk: {
901 enabled: true,
902 extends: "libvndk",
903 support_system_process: true,
904 },
905 nocrt: true,
906 }
907 `)
908
909 testCcError(t, "module \".*\" with mismatched support_system_process", `
910 cc_library {
911 name: "libvndk_sp",
912 vendor_available: true,
913 vndk: {
914 enabled: true,
915 support_system_process: true,
916 },
917 nocrt: true,
918 }
919
920 cc_library {
921 name: "libvndk_ext",
922 vendor: true,
923 vndk: {
924 enabled: true,
925 extends: "libvndk_sp",
926 },
927 nocrt: true,
928 }
929 `)
930}
931
932func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800933 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800934 // with `vendor_available: false`.
935 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
936 cc_library {
937 name: "libvndk",
938 vendor_available: false,
939 vndk: {
940 enabled: true,
941 },
942 nocrt: true,
943 }
944
945 cc_library {
946 name: "libvndk_ext",
947 vendor: true,
948 vndk: {
949 enabled: true,
950 extends: "libvndk",
951 },
952 nocrt: true,
953 }
954 `)
955}
956
Logan Chiend3c59a22018-03-29 14:08:15 +0800957func TestVendorModuleUseVndkExt(t *testing.T) {
958 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800959 testCc(t, `
960 cc_library {
961 name: "libvndk",
962 vendor_available: true,
963 vndk: {
964 enabled: true,
965 },
966 nocrt: true,
967 }
968
969 cc_library {
970 name: "libvndk_ext",
971 vendor: true,
972 vndk: {
973 enabled: true,
974 extends: "libvndk",
975 },
976 nocrt: true,
977 }
978
979 cc_library {
980
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_sp_ext",
992 vendor: true,
993 vndk: {
994 enabled: true,
995 extends: "libvndk_sp",
996 support_system_process: true,
997 },
998 nocrt: true,
999 }
1000
1001 cc_library {
1002 name: "libvendor",
1003 vendor: true,
1004 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
1005 nocrt: true,
1006 }
1007 `)
1008}
1009
Logan Chiend3c59a22018-03-29 14:08:15 +08001010func TestVndkExtUseVendorLib(t *testing.T) {
1011 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +08001012 testCc(t, `
1013 cc_library {
1014 name: "libvndk",
1015 vendor_available: true,
1016 vndk: {
1017 enabled: true,
1018 },
1019 nocrt: true,
1020 }
1021
1022 cc_library {
1023 name: "libvndk_ext",
1024 vendor: true,
1025 vndk: {
1026 enabled: true,
1027 extends: "libvndk",
1028 },
1029 shared_libs: ["libvendor"],
1030 nocrt: true,
1031 }
1032
1033 cc_library {
1034 name: "libvendor",
1035 vendor: true,
1036 nocrt: true,
1037 }
1038 `)
Logan Chienf3511742017-10-31 18:04:35 +08001039
Logan Chiend3c59a22018-03-29 14:08:15 +08001040 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
1041 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +08001042 cc_library {
1043 name: "libvndk_sp",
1044 vendor_available: true,
1045 vndk: {
1046 enabled: true,
1047 support_system_process: true,
1048 },
1049 nocrt: true,
1050 }
1051
1052 cc_library {
1053 name: "libvndk_sp_ext",
1054 vendor: true,
1055 vndk: {
1056 enabled: true,
1057 extends: "libvndk_sp",
1058 support_system_process: true,
1059 },
1060 shared_libs: ["libvendor"], // Cause an error
1061 nocrt: true,
1062 }
1063
1064 cc_library {
1065 name: "libvendor",
1066 vendor: true,
1067 nocrt: true,
1068 }
1069 `)
1070}
1071
Logan Chiend3c59a22018-03-29 14:08:15 +08001072func TestVndkSpExtUseVndkError(t *testing.T) {
1073 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
1074 // library.
1075 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1076 cc_library {
1077 name: "libvndk",
1078 vendor_available: true,
1079 vndk: {
1080 enabled: true,
1081 },
1082 nocrt: true,
1083 }
1084
1085 cc_library {
1086 name: "libvndk_sp",
1087 vendor_available: true,
1088 vndk: {
1089 enabled: true,
1090 support_system_process: true,
1091 },
1092 nocrt: true,
1093 }
1094
1095 cc_library {
1096 name: "libvndk_sp_ext",
1097 vendor: true,
1098 vndk: {
1099 enabled: true,
1100 extends: "libvndk_sp",
1101 support_system_process: true,
1102 },
1103 shared_libs: ["libvndk"], // Cause an error
1104 nocrt: true,
1105 }
1106 `)
1107
1108 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
1109 // library.
1110 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1111 cc_library {
1112 name: "libvndk",
1113 vendor_available: true,
1114 vndk: {
1115 enabled: true,
1116 },
1117 nocrt: true,
1118 }
1119
1120 cc_library {
1121 name: "libvndk_ext",
1122 vendor: true,
1123 vndk: {
1124 enabled: true,
1125 extends: "libvndk",
1126 },
1127 nocrt: true,
1128 }
1129
1130 cc_library {
1131 name: "libvndk_sp",
1132 vendor_available: true,
1133 vndk: {
1134 enabled: true,
1135 support_system_process: true,
1136 },
1137 nocrt: true,
1138 }
1139
1140 cc_library {
1141 name: "libvndk_sp_ext",
1142 vendor: true,
1143 vndk: {
1144 enabled: true,
1145 extends: "libvndk_sp",
1146 support_system_process: true,
1147 },
1148 shared_libs: ["libvndk_ext"], // Cause an error
1149 nocrt: true,
1150 }
1151 `)
1152}
1153
1154func TestVndkUseVndkExtError(t *testing.T) {
1155 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
1156 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +08001157 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1158 cc_library {
1159 name: "libvndk",
1160 vendor_available: true,
1161 vndk: {
1162 enabled: true,
1163 },
1164 nocrt: true,
1165 }
1166
1167 cc_library {
1168 name: "libvndk_ext",
1169 vendor: true,
1170 vndk: {
1171 enabled: true,
1172 extends: "libvndk",
1173 },
1174 nocrt: true,
1175 }
1176
1177 cc_library {
1178 name: "libvndk2",
1179 vendor_available: true,
1180 vndk: {
1181 enabled: true,
1182 },
1183 shared_libs: ["libvndk_ext"],
1184 nocrt: true,
1185 }
1186 `)
1187
Martin Stjernholmef449fe2018-11-06 16:12:13 +00001188 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +08001189 cc_library {
1190 name: "libvndk",
1191 vendor_available: true,
1192 vndk: {
1193 enabled: true,
1194 },
1195 nocrt: true,
1196 }
1197
1198 cc_library {
1199 name: "libvndk_ext",
1200 vendor: true,
1201 vndk: {
1202 enabled: true,
1203 extends: "libvndk",
1204 },
1205 nocrt: true,
1206 }
1207
1208 cc_library {
1209 name: "libvndk2",
1210 vendor_available: true,
1211 vndk: {
1212 enabled: true,
1213 },
1214 target: {
1215 vendor: {
1216 shared_libs: ["libvndk_ext"],
1217 },
1218 },
1219 nocrt: true,
1220 }
1221 `)
1222
1223 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1224 cc_library {
1225 name: "libvndk_sp",
1226 vendor_available: true,
1227 vndk: {
1228 enabled: true,
1229 support_system_process: true,
1230 },
1231 nocrt: true,
1232 }
1233
1234 cc_library {
1235 name: "libvndk_sp_ext",
1236 vendor: true,
1237 vndk: {
1238 enabled: true,
1239 extends: "libvndk_sp",
1240 support_system_process: true,
1241 },
1242 nocrt: true,
1243 }
1244
1245 cc_library {
1246 name: "libvndk_sp_2",
1247 vendor_available: true,
1248 vndk: {
1249 enabled: true,
1250 support_system_process: true,
1251 },
1252 shared_libs: ["libvndk_sp_ext"],
1253 nocrt: true,
1254 }
1255 `)
1256
Martin Stjernholmef449fe2018-11-06 16:12:13 +00001257 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +08001258 cc_library {
1259 name: "libvndk_sp",
1260 vendor_available: true,
1261 vndk: {
1262 enabled: true,
1263 },
1264 nocrt: true,
1265 }
1266
1267 cc_library {
1268 name: "libvndk_sp_ext",
1269 vendor: true,
1270 vndk: {
1271 enabled: true,
1272 extends: "libvndk_sp",
1273 },
1274 nocrt: true,
1275 }
1276
1277 cc_library {
1278 name: "libvndk_sp2",
1279 vendor_available: true,
1280 vndk: {
1281 enabled: true,
1282 },
1283 target: {
1284 vendor: {
1285 shared_libs: ["libvndk_sp_ext"],
1286 },
1287 },
1288 nocrt: true,
1289 }
1290 `)
1291}
1292
Jooyung Han38002912019-05-16 04:01:54 +09001293func TestMakeLinkType(t *testing.T) {
1294 config := android.TestArchConfig(buildDir, nil)
1295 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1296 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
1297 // native:vndk
1298 ctx := testCcWithConfig(t, `
1299 cc_library {
1300 name: "libvndk",
1301 vendor_available: true,
1302 vndk: {
1303 enabled: true,
1304 },
1305 }
1306 cc_library {
1307 name: "libvndksp",
1308 vendor_available: true,
1309 vndk: {
1310 enabled: true,
1311 support_system_process: true,
1312 },
1313 }
1314 cc_library {
1315 name: "libvndkprivate",
1316 vendor_available: false,
1317 vndk: {
1318 enabled: true,
1319 },
1320 }
1321 cc_library {
1322 name: "libvendor",
1323 vendor: true,
1324 }
1325 cc_library {
1326 name: "libvndkext",
1327 vendor: true,
1328 vndk: {
1329 enabled: true,
1330 extends: "libvndk",
1331 },
1332 }
1333 vndk_prebuilt_shared {
1334 name: "prevndk",
1335 version: "27",
1336 target_arch: "arm",
1337 binder32bit: true,
1338 vendor_available: true,
1339 vndk: {
1340 enabled: true,
1341 },
1342 arch: {
1343 arm: {
1344 srcs: ["liba.so"],
1345 },
1346 },
1347 }
1348 cc_library {
1349 name: "libllndk",
1350 }
1351 llndk_library {
1352 name: "libllndk",
1353 symbol_file: "",
1354 }
1355 cc_library {
1356 name: "libllndkprivate",
1357 }
1358 llndk_library {
1359 name: "libllndkprivate",
1360 vendor_available: false,
1361 symbol_file: "",
1362 }`, config)
1363
1364 assertArrayString(t, *vndkCoreLibraries(config),
1365 []string{"libvndk", "libvndkprivate"})
1366 assertArrayString(t, *vndkSpLibraries(config),
1367 []string{"libc++", "libvndksp"})
1368 assertArrayString(t, *llndkLibraries(config),
1369 []string{"libc", "libdl", "libllndk", "libllndkprivate", "libm"})
1370 assertArrayString(t, *vndkPrivateLibraries(config),
1371 []string{"libllndkprivate", "libvndkprivate"})
1372
Inseob Kim64c43952019-08-26 16:52:35 +09001373 vendorVariant27 := "android_arm64_armv8-a_vendor.27_shared"
1374
Jooyung Han38002912019-05-16 04:01:54 +09001375 tests := []struct {
1376 variant string
1377 name string
1378 expected string
1379 }{
1380 {vendorVariant, "libvndk", "native:vndk"},
1381 {vendorVariant, "libvndksp", "native:vndk"},
1382 {vendorVariant, "libvndkprivate", "native:vndk_private"},
1383 {vendorVariant, "libvendor", "native:vendor"},
1384 {vendorVariant, "libvndkext", "native:vendor"},
Jooyung Han38002912019-05-16 04:01:54 +09001385 {vendorVariant, "libllndk.llndk", "native:vndk"},
Inseob Kim64c43952019-08-26 16:52:35 +09001386 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
Jooyung Han38002912019-05-16 04:01:54 +09001387 {coreVariant, "libvndk", "native:platform"},
1388 {coreVariant, "libvndkprivate", "native:platform"},
1389 {coreVariant, "libllndk", "native:platform"},
1390 }
1391 for _, test := range tests {
1392 t.Run(test.name, func(t *testing.T) {
1393 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
1394 assertString(t, module.makeLinkType, test.expected)
1395 })
1396 }
1397}
1398
Colin Cross0af4b842015-04-30 16:36:18 -07001399var (
1400 str11 = "01234567891"
1401 str10 = str11[:10]
1402 str9 = str11[:9]
1403 str5 = str11[:5]
1404 str4 = str11[:4]
1405)
1406
1407var splitListForSizeTestCases = []struct {
1408 in []string
1409 out [][]string
1410 size int
1411}{
1412 {
1413 in: []string{str10},
1414 out: [][]string{{str10}},
1415 size: 10,
1416 },
1417 {
1418 in: []string{str9},
1419 out: [][]string{{str9}},
1420 size: 10,
1421 },
1422 {
1423 in: []string{str5},
1424 out: [][]string{{str5}},
1425 size: 10,
1426 },
1427 {
1428 in: []string{str11},
1429 out: nil,
1430 size: 10,
1431 },
1432 {
1433 in: []string{str10, str10},
1434 out: [][]string{{str10}, {str10}},
1435 size: 10,
1436 },
1437 {
1438 in: []string{str9, str10},
1439 out: [][]string{{str9}, {str10}},
1440 size: 10,
1441 },
1442 {
1443 in: []string{str10, str9},
1444 out: [][]string{{str10}, {str9}},
1445 size: 10,
1446 },
1447 {
1448 in: []string{str5, str4},
1449 out: [][]string{{str5, str4}},
1450 size: 10,
1451 },
1452 {
1453 in: []string{str5, str4, str5},
1454 out: [][]string{{str5, str4}, {str5}},
1455 size: 10,
1456 },
1457 {
1458 in: []string{str5, str4, str5, str4},
1459 out: [][]string{{str5, str4}, {str5, str4}},
1460 size: 10,
1461 },
1462 {
1463 in: []string{str5, str4, str5, str5},
1464 out: [][]string{{str5, str4}, {str5}, {str5}},
1465 size: 10,
1466 },
1467 {
1468 in: []string{str5, str5, str5, str4},
1469 out: [][]string{{str5}, {str5}, {str5, str4}},
1470 size: 10,
1471 },
1472 {
1473 in: []string{str9, str11},
1474 out: nil,
1475 size: 10,
1476 },
1477 {
1478 in: []string{str11, str9},
1479 out: nil,
1480 size: 10,
1481 },
1482}
1483
1484func TestSplitListForSize(t *testing.T) {
1485 for _, testCase := range splitListForSizeTestCases {
Colin Cross40e33732019-02-15 11:08:35 -08001486 out, _ := splitListForSize(android.PathsForTesting(testCase.in...), testCase.size)
Colin Cross5b529592017-05-09 13:34:34 -07001487
1488 var outStrings [][]string
1489
1490 if len(out) > 0 {
1491 outStrings = make([][]string, len(out))
1492 for i, o := range out {
1493 outStrings[i] = o.Strings()
1494 }
1495 }
1496
1497 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001498 t.Errorf("incorrect output:")
1499 t.Errorf(" input: %#v", testCase.in)
1500 t.Errorf(" size: %d", testCase.size)
1501 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001502 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001503 }
1504 }
1505}
Jeff Gaston294356f2017-09-27 17:05:30 -07001506
1507var staticLinkDepOrderTestCases = []struct {
1508 // This is a string representation of a map[moduleName][]moduleDependency .
1509 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001510 inStatic string
1511
1512 // This is a string representation of a map[moduleName][]moduleDependency .
1513 // It models the dependencies declared in an Android.bp file.
1514 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001515
1516 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1517 // The keys of allOrdered specify which modules we would like to check.
1518 // The values of allOrdered specify the expected result (of the transitive closure of all
1519 // dependencies) for each module to test
1520 allOrdered string
1521
1522 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1523 // The keys of outOrdered specify which modules we would like to check.
1524 // The values of outOrdered specify the expected result (of the ordered linker command line)
1525 // for each module to test.
1526 outOrdered string
1527}{
1528 // Simple tests
1529 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001530 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001531 outOrdered: "",
1532 },
1533 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001534 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001535 outOrdered: "a:",
1536 },
1537 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001538 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001539 outOrdered: "a:b; b:",
1540 },
1541 // Tests of reordering
1542 {
1543 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001544 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001545 outOrdered: "a:b,c,d; b:d; c:d; d:",
1546 },
1547 {
1548 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001549 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001550 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1551 },
1552 {
1553 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001554 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001555 outOrdered: "a:d,b,e,c; d:b; e:c",
1556 },
1557 {
1558 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001559 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001560 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1561 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1562 },
1563 {
1564 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001565 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 -07001566 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1567 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1568 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001569 // shared dependencies
1570 {
1571 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1572 // So, we don't actually have to check that a shared dependency of c will change the order
1573 // of a library that depends statically on b and on c. We only need to check that if c has
1574 // a shared dependency on b, that that shows up in allOrdered.
1575 inShared: "c:b",
1576 allOrdered: "c:b",
1577 outOrdered: "c:",
1578 },
1579 {
1580 // This test doesn't actually include any shared dependencies but it's a reminder of what
1581 // the second phase of the above test would look like
1582 inStatic: "a:b,c; c:b",
1583 allOrdered: "a:c,b; c:b",
1584 outOrdered: "a:c,b; c:b",
1585 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001586 // tiebreakers for when two modules specifying different orderings and there is no dependency
1587 // to dictate an order
1588 {
1589 // 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 -08001590 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001591 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1592 },
1593 {
1594 // 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 -08001595 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 -07001596 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1597 },
1598 // Tests involving duplicate dependencies
1599 {
1600 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001601 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001602 outOrdered: "a:c,b",
1603 },
1604 {
1605 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001606 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001607 outOrdered: "a:d,c,b",
1608 },
1609 // Tests to confirm the nonexistence of infinite loops.
1610 // These cases should never happen, so as long as the test terminates and the
1611 // result is deterministic then that should be fine.
1612 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001613 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001614 outOrdered: "a:a",
1615 },
1616 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001617 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001618 allOrdered: "a:b,c; b:c,a; c:a,b",
1619 outOrdered: "a:b; b:c; c:a",
1620 },
1621 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001622 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001623 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1624 outOrdered: "a:c,b; b:a,c; c:b,a",
1625 },
1626}
1627
1628// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1629func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1630 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1631 strippedText := strings.Replace(text, " ", "", -1)
1632 if len(strippedText) < 1 {
1633 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1634 }
1635 allDeps = make(map[android.Path][]android.Path, 0)
1636
1637 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1638 moduleTexts := strings.Split(strippedText, ";")
1639
1640 outputForModuleName := func(moduleName string) android.Path {
1641 return android.PathForTesting(moduleName)
1642 }
1643
1644 for _, moduleText := range moduleTexts {
1645 // convert from "a:b,c" to ["a", "b,c"]
1646 components := strings.Split(moduleText, ":")
1647 if len(components) != 2 {
1648 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1649 }
1650 moduleName := components[0]
1651 moduleOutput := outputForModuleName(moduleName)
1652 modulesInOrder = append(modulesInOrder, moduleOutput)
1653
1654 depString := components[1]
1655 // convert from "b,c" to ["b", "c"]
1656 depNames := strings.Split(depString, ",")
1657 if len(depString) < 1 {
1658 depNames = []string{}
1659 }
1660 var deps []android.Path
1661 for _, depName := range depNames {
1662 deps = append(deps, outputForModuleName(depName))
1663 }
1664 allDeps[moduleOutput] = deps
1665 }
1666 return modulesInOrder, allDeps
1667}
1668
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001669func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001670 for _, testCase := range staticLinkDepOrderTestCases {
1671 errs := []string{}
1672
1673 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001674 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001675 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1676 if testCase.allOrdered == "" {
1677 // allow the test case to skip specifying allOrdered
1678 testCase.allOrdered = testCase.outOrdered
1679 }
1680 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001681 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001682
1683 // For each module whose post-reordered dependencies were specified, validate that
1684 // reordering the inputs produces the expected outputs.
1685 for _, moduleName := range expectedModuleNames {
1686 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001687 givenSharedDeps := givenAllSharedDeps[moduleName]
1688 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001689
1690 correctAllOrdered := expectedAllDeps[moduleName]
1691 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1692 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001693 "\nin static:%q"+
1694 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001695 "\nmodule: %v"+
1696 "\nexpected: %s"+
1697 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001698 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001699 }
1700
1701 correctOutputDeps := expectedTransitiveDeps[moduleName]
1702 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1703 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001704 "\nin static:%q"+
1705 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001706 "\nmodule: %v"+
1707 "\nexpected: %s"+
1708 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001709 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001710 }
1711 }
1712
1713 if len(errs) > 0 {
1714 sort.Strings(errs)
1715 for _, err := range errs {
1716 t.Error(err)
1717 }
1718 }
1719 }
1720}
Logan Chienf3511742017-10-31 18:04:35 +08001721
Jeff Gaston294356f2017-09-27 17:05:30 -07001722func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1723 for _, moduleName := range moduleNames {
1724 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1725 output := module.outputFile.Path()
1726 paths = append(paths, output)
1727 }
1728 return paths
1729}
1730
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001731func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001732 ctx := testCc(t, `
1733 cc_library {
1734 name: "a",
1735 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001736 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001737 }
1738 cc_library {
1739 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001740 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001741 }
1742 cc_library {
1743 name: "c",
1744 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001745 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001746 }
1747 cc_library {
1748 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001749 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001750 }
1751
1752 `)
1753
1754 variant := "android_arm64_armv8-a_core_static"
1755 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001756 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001757 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1758
1759 if !reflect.DeepEqual(actual, expected) {
1760 t.Errorf("staticDeps orderings were not propagated correctly"+
1761 "\nactual: %v"+
1762 "\nexpected: %v",
1763 actual,
1764 expected,
1765 )
1766 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001767}
Jeff Gaston294356f2017-09-27 17:05:30 -07001768
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001769func TestStaticLibDepReorderingWithShared(t *testing.T) {
1770 ctx := testCc(t, `
1771 cc_library {
1772 name: "a",
1773 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001774 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001775 }
1776 cc_library {
1777 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001778 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001779 }
1780 cc_library {
1781 name: "c",
1782 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001783 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001784 }
1785
1786 `)
1787
1788 variant := "android_arm64_armv8-a_core_static"
1789 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1790 actual := moduleA.depsInLinkOrder
1791 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1792
1793 if !reflect.DeepEqual(actual, expected) {
1794 t.Errorf("staticDeps orderings did not account for shared libs"+
1795 "\nactual: %v"+
1796 "\nexpected: %v",
1797 actual,
1798 expected,
1799 )
1800 }
1801}
1802
Jiyong Parka46a4d52017-12-14 19:54:34 +09001803func TestLlndkHeaders(t *testing.T) {
1804 ctx := testCc(t, `
1805 llndk_headers {
1806 name: "libllndk_headers",
1807 export_include_dirs: ["my_include"],
1808 }
1809 llndk_library {
1810 name: "libllndk",
1811 export_llndk_headers: ["libllndk_headers"],
1812 }
1813 cc_library {
1814 name: "libvendor",
1815 shared_libs: ["libllndk"],
1816 vendor: true,
1817 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001818 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001819 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001820 }
1821 `)
1822
1823 // _static variant is used since _shared reuses *.o from the static variant
Inseob Kim64c43952019-08-26 16:52:35 +09001824 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor.VER_static").Rule("cc")
Jiyong Parka46a4d52017-12-14 19:54:34 +09001825 cflags := cc.Args["cFlags"]
1826 if !strings.Contains(cflags, "-Imy_include") {
1827 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1828 }
1829}
1830
Logan Chien43d34c32017-12-20 01:17:32 +08001831func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1832 actual := module.Properties.AndroidMkRuntimeLibs
1833 if !reflect.DeepEqual(actual, expected) {
1834 t.Errorf("incorrect runtime_libs for shared libs"+
1835 "\nactual: %v"+
1836 "\nexpected: %v",
1837 actual,
1838 expected,
1839 )
1840 }
1841}
1842
1843const runtimeLibAndroidBp = `
1844 cc_library {
1845 name: "libvendor_available1",
1846 vendor_available: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001847 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001848 nocrt : true,
1849 system_shared_libs : [],
1850 }
1851 cc_library {
1852 name: "libvendor_available2",
1853 vendor_available: true,
1854 runtime_libs: ["libvendor_available1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001855 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001856 nocrt : true,
1857 system_shared_libs : [],
1858 }
1859 cc_library {
1860 name: "libvendor_available3",
1861 vendor_available: true,
1862 runtime_libs: ["libvendor_available1"],
1863 target: {
1864 vendor: {
1865 exclude_runtime_libs: ["libvendor_available1"],
1866 }
1867 },
Yi Konge7fe9912019-06-02 00:53:50 -07001868 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001869 nocrt : true,
1870 system_shared_libs : [],
1871 }
1872 cc_library {
1873 name: "libcore",
1874 runtime_libs: ["libvendor_available1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001875 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001876 nocrt : true,
1877 system_shared_libs : [],
1878 }
1879 cc_library {
1880 name: "libvendor1",
1881 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001882 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001883 nocrt : true,
1884 system_shared_libs : [],
1885 }
1886 cc_library {
1887 name: "libvendor2",
1888 vendor: true,
1889 runtime_libs: ["libvendor_available1", "libvendor1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001890 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001891 nocrt : true,
1892 system_shared_libs : [],
1893 }
1894`
1895
1896func TestRuntimeLibs(t *testing.T) {
1897 ctx := testCc(t, runtimeLibAndroidBp)
1898
1899 // runtime_libs for core variants use the module names without suffixes.
1900 variant := "android_arm64_armv8-a_core_shared"
1901
1902 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1903 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1904
1905 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1906 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1907
1908 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1909 // and vendor variants.
Inseob Kim64c43952019-08-26 16:52:35 +09001910 variant = "android_arm64_armv8-a_vendor.VER_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001911
1912 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1913 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1914
1915 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1916 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1917}
1918
1919func TestExcludeRuntimeLibs(t *testing.T) {
1920 ctx := testCc(t, runtimeLibAndroidBp)
1921
1922 variant := "android_arm64_armv8-a_core_shared"
1923 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1924 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1925
Inseob Kim64c43952019-08-26 16:52:35 +09001926 variant = "android_arm64_armv8-a_vendor.VER_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001927 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1928 checkRuntimeLibs(t, nil, module)
1929}
1930
1931func TestRuntimeLibsNoVndk(t *testing.T) {
1932 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1933
1934 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1935
1936 variant := "android_arm64_armv8-a_core_shared"
1937
1938 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1939 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1940
1941 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1942 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1943}
1944
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001945func checkStaticLibs(t *testing.T, expected []string, module *Module) {
1946 actual := module.Properties.AndroidMkStaticLibs
1947 if !reflect.DeepEqual(actual, expected) {
1948 t.Errorf("incorrect static_libs"+
1949 "\nactual: %v"+
1950 "\nexpected: %v",
1951 actual,
1952 expected,
1953 )
1954 }
1955}
1956
1957const staticLibAndroidBp = `
1958 cc_library {
1959 name: "lib1",
1960 }
1961 cc_library {
1962 name: "lib2",
1963 static_libs: ["lib1"],
1964 }
1965`
1966
1967func TestStaticLibDepExport(t *testing.T) {
1968 ctx := testCc(t, staticLibAndroidBp)
1969
1970 // Check the shared version of lib2.
1971 variant := "android_arm64_armv8-a_core_shared"
1972 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Dan Albert2da19cb2019-07-24 12:17:40 -07001973 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001974
1975 // Check the static version of lib2.
1976 variant = "android_arm64_armv8-a_core_static"
1977 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1978 // libc++_static is linked additionally.
Dan Albert2da19cb2019-07-24 12:17:40 -07001979 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001980}
1981
Jiyong Parkd08b6972017-09-26 10:50:54 +09001982var compilerFlagsTestCases = []struct {
1983 in string
1984 out bool
1985}{
1986 {
1987 in: "a",
1988 out: false,
1989 },
1990 {
1991 in: "-a",
1992 out: true,
1993 },
1994 {
1995 in: "-Ipath/to/something",
1996 out: false,
1997 },
1998 {
1999 in: "-isystempath/to/something",
2000 out: false,
2001 },
2002 {
2003 in: "--coverage",
2004 out: false,
2005 },
2006 {
2007 in: "-include a/b",
2008 out: true,
2009 },
2010 {
2011 in: "-include a/b c/d",
2012 out: false,
2013 },
2014 {
2015 in: "-DMACRO",
2016 out: true,
2017 },
2018 {
2019 in: "-DMAC RO",
2020 out: false,
2021 },
2022 {
2023 in: "-a -b",
2024 out: false,
2025 },
2026 {
2027 in: "-DMACRO=definition",
2028 out: true,
2029 },
2030 {
2031 in: "-DMACRO=defi nition",
2032 out: true, // TODO(jiyong): this should be false
2033 },
2034 {
2035 in: "-DMACRO(x)=x + 1",
2036 out: true,
2037 },
2038 {
2039 in: "-DMACRO=\"defi nition\"",
2040 out: true,
2041 },
2042}
2043
2044type mockContext struct {
2045 BaseModuleContext
2046 result bool
2047}
2048
2049func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
2050 // CheckBadCompilerFlags calls this function when the flag should be rejected
2051 ctx.result = false
2052}
2053
2054func TestCompilerFlags(t *testing.T) {
2055 for _, testCase := range compilerFlagsTestCases {
2056 ctx := &mockContext{result: true}
2057 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
2058 if ctx.result != testCase.out {
2059 t.Errorf("incorrect output:")
2060 t.Errorf(" input: %#v", testCase.in)
2061 t.Errorf(" expected: %#v", testCase.out)
2062 t.Errorf(" got: %#v", ctx.result)
2063 }
2064 }
Jeff Gaston294356f2017-09-27 17:05:30 -07002065}
Jiyong Park374510b2018-03-19 18:23:01 +09002066
2067func TestVendorPublicLibraries(t *testing.T) {
2068 ctx := testCc(t, `
2069 cc_library_headers {
2070 name: "libvendorpublic_headers",
2071 export_include_dirs: ["my_include"],
2072 }
2073 vendor_public_library {
2074 name: "libvendorpublic",
2075 symbol_file: "",
2076 export_public_headers: ["libvendorpublic_headers"],
2077 }
2078 cc_library {
2079 name: "libvendorpublic",
2080 srcs: ["foo.c"],
2081 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07002082 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002083 nocrt: true,
2084 }
2085
2086 cc_library {
2087 name: "libsystem",
2088 shared_libs: ["libvendorpublic"],
2089 vendor: false,
2090 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07002091 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002092 nocrt: true,
2093 }
2094 cc_library {
2095 name: "libvendor",
2096 shared_libs: ["libvendorpublic"],
2097 vendor: true,
2098 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07002099 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002100 nocrt: true,
2101 }
2102 `)
2103
2104 variant := "android_arm64_armv8-a_core_shared"
2105
2106 // test if header search paths are correctly added
2107 // _static variant is used since _shared reuses *.o from the static variant
2108 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
2109 cflags := cc.Args["cFlags"]
2110 if !strings.Contains(cflags, "-Imy_include") {
2111 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
2112 }
2113
2114 // test if libsystem is linked to the stub
2115 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
2116 libflags := ld.Args["libFlags"]
2117 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
2118 if !strings.Contains(libflags, stubPaths[0].String()) {
2119 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
2120 }
2121
2122 // test if libvendor is linked to the real shared lib
Inseob Kim64c43952019-08-26 16:52:35 +09002123 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor.VER", 1)).Rule("ld")
Jiyong Park374510b2018-03-19 18:23:01 +09002124 libflags = ld.Args["libFlags"]
Inseob Kim64c43952019-08-26 16:52:35 +09002125 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor.VER", 1), []string{"libvendorpublic"})
Jiyong Park374510b2018-03-19 18:23:01 +09002126 if !strings.Contains(libflags, stubPaths[0].String()) {
2127 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
2128 }
2129
2130}
Jiyong Park37b25202018-07-11 10:49:27 +09002131
2132func TestRecovery(t *testing.T) {
2133 ctx := testCc(t, `
2134 cc_library_shared {
2135 name: "librecovery",
2136 recovery: true,
2137 }
2138 cc_library_shared {
2139 name: "librecovery32",
2140 recovery: true,
2141 compile_multilib:"32",
2142 }
Jiyong Park5baac542018-08-28 09:55:37 +09002143 cc_library_shared {
2144 name: "libHalInRecovery",
2145 recovery_available: true,
2146 vendor: true,
2147 }
Jiyong Park37b25202018-07-11 10:49:27 +09002148 `)
2149
2150 variants := ctx.ModuleVariantsForTests("librecovery")
2151 const arm64 = "android_arm64_armv8-a_recovery_shared"
2152 if len(variants) != 1 || !android.InList(arm64, variants) {
2153 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
2154 }
2155
2156 variants = ctx.ModuleVariantsForTests("librecovery32")
2157 if android.InList(arm64, variants) {
2158 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
2159 }
Jiyong Park5baac542018-08-28 09:55:37 +09002160
2161 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
2162 if !recoveryModule.Platform() {
2163 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
2164 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09002165}
Jiyong Park5baac542018-08-28 09:55:37 +09002166
Jiyong Park7ed9de32018-10-15 22:25:07 +09002167func TestVersionedStubs(t *testing.T) {
2168 ctx := testCc(t, `
2169 cc_library_shared {
2170 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002171 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002172 stubs: {
2173 symbol_file: "foo.map.txt",
2174 versions: ["1", "2", "3"],
2175 },
2176 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002177
Jiyong Park7ed9de32018-10-15 22:25:07 +09002178 cc_library_shared {
2179 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002180 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002181 shared_libs: ["libFoo#1"],
2182 }`)
2183
2184 variants := ctx.ModuleVariantsForTests("libFoo")
2185 expectedVariants := []string{
2186 "android_arm64_armv8-a_core_shared",
2187 "android_arm64_armv8-a_core_shared_1",
2188 "android_arm64_armv8-a_core_shared_2",
2189 "android_arm64_armv8-a_core_shared_3",
2190 "android_arm_armv7-a-neon_core_shared",
2191 "android_arm_armv7-a-neon_core_shared_1",
2192 "android_arm_armv7-a-neon_core_shared_2",
2193 "android_arm_armv7-a-neon_core_shared_3",
2194 }
2195 variantsMismatch := false
2196 if len(variants) != len(expectedVariants) {
2197 variantsMismatch = true
2198 } else {
2199 for _, v := range expectedVariants {
2200 if !inList(v, variants) {
2201 variantsMismatch = false
2202 }
2203 }
2204 }
2205 if variantsMismatch {
2206 t.Errorf("variants of libFoo expected:\n")
2207 for _, v := range expectedVariants {
2208 t.Errorf("%q\n", v)
2209 }
2210 t.Errorf(", but got:\n")
2211 for _, v := range variants {
2212 t.Errorf("%q\n", v)
2213 }
2214 }
2215
2216 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld")
2217 libFlags := libBarLinkRule.Args["libFlags"]
2218 libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so"
2219 if !strings.Contains(libFlags, libFoo1StubPath) {
2220 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
2221 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002222
2223 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("cc")
2224 cFlags := libBarCompileRule.Args["cFlags"]
2225 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
2226 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
2227 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
2228 }
Jiyong Park37b25202018-07-11 10:49:27 +09002229}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002230
2231func TestStaticExecutable(t *testing.T) {
2232 ctx := testCc(t, `
2233 cc_binary {
2234 name: "static_test",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +01002235 srcs: ["foo.c", "baz.o"],
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002236 static_executable: true,
2237 }`)
2238
2239 variant := "android_arm64_armv8-a_core"
2240 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
2241 libFlags := binModuleRule.Args["libFlags"]
Ryan Prichardb49fe1b2019-10-11 15:03:34 -07002242 systemStaticLibs := []string{"libc.a", "libm.a"}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002243 for _, lib := range systemStaticLibs {
2244 if !strings.Contains(libFlags, lib) {
2245 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
2246 }
2247 }
2248 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
2249 for _, lib := range systemSharedLibs {
2250 if strings.Contains(libFlags, lib) {
2251 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
2252 }
2253 }
2254}
Jiyong Parke4bb9862019-02-01 00:31:10 +09002255
2256func TestStaticDepsOrderWithStubs(t *testing.T) {
2257 ctx := testCc(t, `
2258 cc_binary {
2259 name: "mybin",
2260 srcs: ["foo.c"],
2261 static_libs: ["libB"],
2262 static_executable: true,
2263 stl: "none",
2264 }
2265
2266 cc_library {
2267 name: "libB",
2268 srcs: ["foo.c"],
2269 shared_libs: ["libC"],
2270 stl: "none",
2271 }
2272
2273 cc_library {
2274 name: "libC",
2275 srcs: ["foo.c"],
2276 stl: "none",
2277 stubs: {
2278 versions: ["1"],
2279 },
2280 }`)
2281
2282 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a_core").Module().(*Module)
2283 actual := mybin.depsInLinkOrder
2284 expected := getOutputPaths(ctx, "android_arm64_armv8-a_core_static", []string{"libB", "libC"})
2285
2286 if !reflect.DeepEqual(actual, expected) {
2287 t.Errorf("staticDeps orderings were not propagated correctly"+
2288 "\nactual: %v"+
2289 "\nexpected: %v",
2290 actual,
2291 expected,
2292 )
2293 }
2294}
Jooyung Han38002912019-05-16 04:01:54 +09002295
Jooyung Hand48f3c32019-08-23 11:18:57 +09002296func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
2297 testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
2298 cc_library {
2299 name: "libA",
2300 srcs: ["foo.c"],
2301 shared_libs: ["libB"],
2302 stl: "none",
2303 }
2304
2305 cc_library {
2306 name: "libB",
2307 srcs: ["foo.c"],
2308 enabled: false,
2309 stl: "none",
2310 }
2311 `)
2312}
2313
Mitch Phillipsda9a4632019-07-15 09:34:09 -07002314// Simple smoke test for the cc_fuzz target that ensures the rule compiles
2315// correctly.
2316func TestFuzzTarget(t *testing.T) {
2317 ctx := testCc(t, `
2318 cc_fuzz {
2319 name: "fuzz_smoke_test",
2320 srcs: ["foo.c"],
2321 }`)
2322
2323 variant := "android_arm64_armv8-a_core"
2324 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
2325}
2326
Jiyong Park29074592019-07-07 16:27:47 +09002327func TestAidl(t *testing.T) {
2328}
2329
Jooyung Han38002912019-05-16 04:01:54 +09002330func assertString(t *testing.T, got, expected string) {
2331 t.Helper()
2332 if got != expected {
2333 t.Errorf("expected %q got %q", expected, got)
2334 }
2335}
2336
2337func assertArrayString(t *testing.T, got, expected []string) {
2338 t.Helper()
2339 if len(got) != len(expected) {
2340 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
2341 return
2342 }
2343 for i := range got {
2344 if got[i] != expected[i] {
2345 t.Errorf("expected %d-th %q (%q) got %q (%q)",
2346 i, expected[i], expected, got[i], got)
2347 return
2348 }
2349 }
2350}
Colin Crosse1bb5d02019-09-24 14:55:04 -07002351
2352func TestDefaults(t *testing.T) {
2353 ctx := testCc(t, `
2354 cc_defaults {
2355 name: "defaults",
2356 srcs: ["foo.c"],
2357 static: {
2358 srcs: ["bar.c"],
2359 },
2360 shared: {
2361 srcs: ["baz.c"],
2362 },
2363 }
2364
2365 cc_library_static {
2366 name: "libstatic",
2367 defaults: ["defaults"],
2368 }
2369
2370 cc_library_shared {
2371 name: "libshared",
2372 defaults: ["defaults"],
2373 }
2374
2375 cc_library {
2376 name: "libboth",
2377 defaults: ["defaults"],
2378 }
2379
2380 cc_binary {
2381 name: "binary",
2382 defaults: ["defaults"],
2383 }`)
2384
2385 pathsToBase := func(paths android.Paths) []string {
2386 var ret []string
2387 for _, p := range paths {
2388 ret = append(ret, p.Base())
2389 }
2390 return ret
2391 }
2392
2393 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_core_shared").Rule("ld")
2394 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2395 t.Errorf("libshared ld rule wanted %q, got %q", w, g)
2396 }
2397 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_core_shared").Rule("ld")
2398 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2399 t.Errorf("libboth ld rule wanted %q, got %q", w, g)
2400 }
2401 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a_core").Rule("ld")
2402 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
2403 t.Errorf("binary ld rule wanted %q, got %q", w, g)
2404 }
2405
2406 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_core_static").Rule("ar")
2407 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2408 t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
2409 }
2410 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_core_static").Rule("ar")
2411 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2412 t.Errorf("libboth ar rule wanted %q, got %q", w, g)
2413 }
2414}