blob: 19e4703b3b82fa3e0c65b67a0bd5bcbd1a41f593 [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 (
Colin Cross5b529592017-05-09 13:34:34 -070018 "android/soong/android"
Colin Crossf18e1102017-11-16 14:33:08 -080019 "android/soong/genrule"
20
Jeff Gaston294356f2017-09-27 17:05:30 -070021 "fmt"
Jiyong Park6a43f042017-10-12 23:05:00 +090022 "io/ioutil"
23 "os"
Colin Cross74d1ec02015-04-28 13:30:13 -070024 "reflect"
Logan Chienf3511742017-10-31 18:04:35 +080025 "regexp"
Jeff Gaston294356f2017-09-27 17:05:30 -070026 "sort"
27 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070028 "testing"
29)
30
Jiyong Park6a43f042017-10-12 23:05:00 +090031var buildDir string
32
33func setUp() {
34 var err error
35 buildDir, err = ioutil.TempDir("", "soong_cc_test")
36 if err != nil {
37 panic(err)
38 }
39}
40
41func tearDown() {
42 os.RemoveAll(buildDir)
43}
44
45func TestMain(m *testing.M) {
46 run := func() int {
47 setUp()
48 defer tearDown()
49
50 return m.Run()
51 }
52
53 os.Exit(run())
54}
55
Logan Chienf3511742017-10-31 18:04:35 +080056func createTestContext(t *testing.T, config android.Config, bp string) *android.TestContext {
Jiyong Park6a43f042017-10-12 23:05:00 +090057 ctx := android.NewTestArchContext()
Steven Morelandf9e62162017-11-02 17:00:50 -070058 ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory))
Colin Crossf18e1102017-11-16 14:33:08 -080059 ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory))
Jiyong Park6a43f042017-10-12 23:05:00 +090060 ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(toolchainLibraryFactory))
61 ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(llndkLibraryFactory))
Jiyong Parka46a4d52017-12-14 19:54:34 +090062 ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory))
Jeff Gaston294356f2017-09-27 17:05:30 -070063 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(objectFactory))
Colin Crossf18e1102017-11-16 14:33:08 -080064 ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(genrule.FileGroupFactory))
Jiyong Park6a43f042017-10-12 23:05:00 +090065 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
66 ctx.BottomUp("image", vendorMutator).Parallel()
67 ctx.BottomUp("link", linkageMutator).Parallel()
68 ctx.BottomUp("vndk", vndkMutator).Parallel()
69 })
70 ctx.Register()
71
Jeff Gaston294356f2017-09-27 17:05:30 -070072 // add some modules that are required by the compiler and/or linker
73 bp = bp + `
74 toolchain_library {
75 name: "libatomic",
76 vendor_available: true,
77 }
78
79 toolchain_library {
80 name: "libcompiler_rt-extras",
81 vendor_available: true,
82 }
83
84 toolchain_library {
85 name: "libgcc",
86 vendor_available: true,
87 }
88
89 cc_library {
90 name: "libc",
Logan Chienf3511742017-10-31 18:04:35 +080091 no_libgcc: true,
92 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -070093 system_shared_libs: [],
94 }
95 llndk_library {
96 name: "libc",
97 symbol_file: "",
98 }
99 cc_library {
100 name: "libm",
Logan Chienf3511742017-10-31 18:04:35 +0800101 no_libgcc: true,
102 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700103 system_shared_libs: [],
104 }
105 llndk_library {
106 name: "libm",
107 symbol_file: "",
108 }
109 cc_library {
110 name: "libdl",
Logan Chienf3511742017-10-31 18:04:35 +0800111 no_libgcc: true,
112 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700113 system_shared_libs: [],
114 }
115 llndk_library {
116 name: "libdl",
117 symbol_file: "",
118 }
119
120 cc_object {
121 name: "crtbegin_so",
122 }
123
124 cc_object {
125 name: "crtend_so",
126 }
127
Colin Crossad59e752017-11-16 14:29:11 -0800128 cc_library {
129 name: "libprotobuf-cpp-lite",
130 }
131
Jeff Gaston294356f2017-09-27 17:05:30 -0700132`
133
Jiyong Park6a43f042017-10-12 23:05:00 +0900134 ctx.MockFileSystem(map[string][]byte{
135 "Android.bp": []byte(bp),
136 "foo.c": nil,
137 "bar.c": nil,
Colin Crossad59e752017-11-16 14:29:11 -0800138 "a.proto": nil,
Colin Crossf18e1102017-11-16 14:33:08 -0800139 "b.aidl": nil,
Jiyong Parka46a4d52017-12-14 19:54:34 +0900140 "my_include": nil,
Jiyong Park6a43f042017-10-12 23:05:00 +0900141 })
142
Logan Chienf3511742017-10-31 18:04:35 +0800143 return ctx
144}
145
146func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
147 ctx := createTestContext(t, config, bp)
148
Jeff Gastond3e141d2017-08-08 17:46:01 -0700149 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Jeff Gaston294356f2017-09-27 17:05:30 -0700150 failIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900151 _, errs = ctx.PrepareBuildActions(config)
Jeff Gaston294356f2017-09-27 17:05:30 -0700152 failIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900153
154 return ctx
155}
156
Logan Chienf3511742017-10-31 18:04:35 +0800157func testCc(t *testing.T, bp string) *android.TestContext {
158 config := android.TestArchConfig(buildDir, nil)
159 config.ProductVariables.DeviceVndkVersion = StringPtr("current")
160 config.ProductVariables.Platform_vndk_version = StringPtr("VER")
161
162 return testCcWithConfig(t, bp, config)
163}
164
165func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
166 config := android.TestArchConfig(buildDir, nil)
167 config.ProductVariables.Platform_vndk_version = StringPtr("VER")
168
169 return testCcWithConfig(t, bp, config)
170}
171
172func testCcError(t *testing.T, pattern string, bp string) {
173 config := android.TestArchConfig(buildDir, nil)
174 config.ProductVariables.DeviceVndkVersion = StringPtr("current")
175 config.ProductVariables.Platform_vndk_version = StringPtr("VER")
176
177 ctx := createTestContext(t, config, bp)
178
179 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
180 if len(errs) > 0 {
181 failIfNoMatchingErrors(t, pattern, errs)
182 return
183 }
184
185 _, errs = ctx.PrepareBuildActions(config)
186 if len(errs) > 0 {
187 failIfNoMatchingErrors(t, pattern, errs)
188 return
189 }
190
191 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
192}
193
194const (
195 coreVariant = "android_arm64_armv8-a_core_shared"
196 vendorVariant = "android_arm64_armv8-a_vendor_shared"
197)
198
Jiyong Park6a43f042017-10-12 23:05:00 +0900199func TestVendorSrc(t *testing.T) {
200 ctx := testCc(t, `
201 cc_library {
202 name: "libTest",
203 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800204 no_libgcc: true,
205 nocrt: true,
206 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900207 vendor_available: true,
208 target: {
209 vendor: {
210 srcs: ["bar.c"],
211 },
212 },
213 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900214 `)
215
Logan Chienf3511742017-10-31 18:04:35 +0800216 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900217 var objs []string
218 for _, o := range ld.Inputs {
219 objs = append(objs, o.Base())
220 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800221 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900222 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
223 }
224}
225
Logan Chienf3511742017-10-31 18:04:35 +0800226func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
227 isVndkSp bool, extends string) {
228
229 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
230 if !mod.hasVendorVariant() {
231 t.Error("%q must have vendor variant", name)
232 }
233
234 // Check library properties.
235 lib, ok := mod.compiler.(*libraryDecorator)
236 if !ok {
237 t.Errorf("%q must have libraryDecorator", name)
238 } else if lib.baseInstaller.subDir != subDir {
239 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
240 lib.baseInstaller.subDir)
241 }
242
243 // Check VNDK properties.
244 if mod.vndkdep == nil {
245 t.Fatalf("%q must have `vndkdep`", name)
246 }
247 if !mod.isVndk() {
248 t.Errorf("%q isVndk() must equal to true", name)
249 }
250 if mod.isVndkSp() != isVndkSp {
251 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
252 }
253
254 // Check VNDK extension properties.
255 isVndkExt := extends != ""
256 if mod.isVndkExt() != isVndkExt {
257 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
258 }
259
260 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
261 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
262 }
263}
264
265func TestVndk(t *testing.T) {
266 ctx := testCc(t, `
267 cc_library {
268 name: "libvndk",
269 vendor_available: true,
270 vndk: {
271 enabled: true,
272 },
273 nocrt: true,
274 }
275
276 cc_library {
277 name: "libvndk_private",
278 vendor_available: false,
279 vndk: {
280 enabled: true,
281 },
282 nocrt: true,
283 }
284
285 cc_library {
286 name: "libvndk_sp",
287 vendor_available: true,
288 vndk: {
289 enabled: true,
290 support_system_process: true,
291 },
292 nocrt: true,
293 }
294
295 cc_library {
296 name: "libvndk_sp_private",
297 vendor_available: false,
298 vndk: {
299 enabled: true,
300 support_system_process: true,
301 },
302 nocrt: true,
303 }
304 `)
305
306 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
307 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
308 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
309 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
310}
311
312func TestVndkExt(t *testing.T) {
313 // This test checks the VNDK-Ext properties.
314 ctx := testCc(t, `
315 cc_library {
316 name: "libvndk",
317 vendor_available: true,
318 vndk: {
319 enabled: true,
320 },
321 nocrt: true,
322 }
323
324 cc_library {
325 name: "libvndk_ext",
326 vendor: true,
327 vndk: {
328 enabled: true,
329 extends: "libvndk",
330 },
331 nocrt: true,
332 }
333 `)
334
335 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
336}
337
338func TestVndkExtNoVndk(t *testing.T) {
339 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
340 ctx := testCcNoVndk(t, `
341 cc_library {
342 name: "libvndk",
343 vendor_available: true,
344 vndk: {
345 enabled: true,
346 },
347 nocrt: true,
348 }
349
350 cc_library {
351 name: "libvndk_ext",
352 vendor: true,
353 vndk: {
354 enabled: true,
355 extends: "libvndk",
356 },
357 nocrt: true,
358 }
359 `)
360
361 // Ensures that the core variant of "libvndk_ext" can be found.
362 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
363 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
364 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
365 }
366}
367
368func TestVndkExtError(t *testing.T) {
369 // This test ensures an error is emitted in ill-formed vndk-ext definition.
370 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
371 cc_library {
372 name: "libvndk",
373 vendor_available: true,
374 vndk: {
375 enabled: true,
376 },
377 nocrt: true,
378 }
379
380 cc_library {
381 name: "libvndk_ext",
382 vndk: {
383 enabled: true,
384 extends: "libvndk",
385 },
386 nocrt: true,
387 }
388 `)
389
390 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
391 cc_library {
392 name: "libvndk",
393 vendor_available: true,
394 vndk: {
395 enabled: true,
396 },
397 nocrt: true,
398 }
399
400 cc_library {
401 name: "libvndk_ext",
402 vendor: true,
403 vndk: {
404 enabled: true,
405 },
406 nocrt: true,
407 }
408 `)
409}
410
411func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
412 // This test ensures an error is emitted for inconsistent support_system_process.
413 testCcError(t, "module \".*\" with mismatched support_system_process", `
414 cc_library {
415 name: "libvndk",
416 vendor_available: true,
417 vndk: {
418 enabled: true,
419 },
420 nocrt: true,
421 }
422
423 cc_library {
424 name: "libvndk_sp_ext",
425 vendor: true,
426 vndk: {
427 enabled: true,
428 extends: "libvndk",
429 support_system_process: true,
430 },
431 nocrt: true,
432 }
433 `)
434
435 testCcError(t, "module \".*\" with mismatched support_system_process", `
436 cc_library {
437 name: "libvndk_sp",
438 vendor_available: true,
439 vndk: {
440 enabled: true,
441 support_system_process: true,
442 },
443 nocrt: true,
444 }
445
446 cc_library {
447 name: "libvndk_ext",
448 vendor: true,
449 vndk: {
450 enabled: true,
451 extends: "libvndk_sp",
452 },
453 nocrt: true,
454 }
455 `)
456}
457
458func TestVndkExtVendorAvailableFalseError(t *testing.T) {
459 // This test ensures an error is emitted when a vndk-ext library extends a vndk library
460 // with `vendor_available: false`.
461 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
462 cc_library {
463 name: "libvndk",
464 vendor_available: false,
465 vndk: {
466 enabled: true,
467 },
468 nocrt: true,
469 }
470
471 cc_library {
472 name: "libvndk_ext",
473 vendor: true,
474 vndk: {
475 enabled: true,
476 extends: "libvndk",
477 },
478 nocrt: true,
479 }
480 `)
481}
482
483func TestVendorModuleUsesVndkExt(t *testing.T) {
484 // This test ensures a vendor module can depend on a vndk-ext library.
485 testCc(t, `
486 cc_library {
487 name: "libvndk",
488 vendor_available: true,
489 vndk: {
490 enabled: true,
491 },
492 nocrt: true,
493 }
494
495 cc_library {
496 name: "libvndk_ext",
497 vendor: true,
498 vndk: {
499 enabled: true,
500 extends: "libvndk",
501 },
502 nocrt: true,
503 }
504
505 cc_library {
506
507 name: "libvndk_sp",
508 vendor_available: true,
509 vndk: {
510 enabled: true,
511 support_system_process: true,
512 },
513 nocrt: true,
514 }
515
516 cc_library {
517 name: "libvndk_sp_ext",
518 vendor: true,
519 vndk: {
520 enabled: true,
521 extends: "libvndk_sp",
522 support_system_process: true,
523 },
524 nocrt: true,
525 }
526
527 cc_library {
528 name: "libvendor",
529 vendor: true,
530 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
531 nocrt: true,
532 }
533 `)
534}
535
536func TestVndkExtUsesVendorLib(t *testing.T) {
537 // This test ensures a vndk-ext library can depend on a vendor library.
538 testCc(t, `
539 cc_library {
540 name: "libvndk",
541 vendor_available: true,
542 vndk: {
543 enabled: true,
544 },
545 nocrt: true,
546 }
547
548 cc_library {
549 name: "libvndk_ext",
550 vendor: true,
551 vndk: {
552 enabled: true,
553 extends: "libvndk",
554 },
555 shared_libs: ["libvendor"],
556 nocrt: true,
557 }
558
559 cc_library {
560 name: "libvendor",
561 vendor: true,
562 nocrt: true,
563 }
564 `)
565}
566
567func TestVndkSpExtUsesVendorLibError(t *testing.T) {
568 // This test ensures an error is emitted if a vndk-sp-ext library depends on a vendor
569 // library.
570 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
571 cc_library {
572 name: "libvndk_sp",
573 vendor_available: true,
574 vndk: {
575 enabled: true,
576 support_system_process: true,
577 },
578 nocrt: true,
579 }
580
581 cc_library {
582 name: "libvndk_sp_ext",
583 vendor: true,
584 vndk: {
585 enabled: true,
586 extends: "libvndk_sp",
587 support_system_process: true,
588 },
589 shared_libs: ["libvendor"], // Cause an error
590 nocrt: true,
591 }
592
593 cc_library {
594 name: "libvendor",
595 vendor: true,
596 nocrt: true,
597 }
598 `)
599}
600
601func TestVndkUsesVndkExtError(t *testing.T) {
602 // This test ensures an error is emitted if a vndk/vndk-sp library depends on a
603 // vndk-ext/vndk-sp-ext library.
604 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
605 cc_library {
606 name: "libvndk",
607 vendor_available: true,
608 vndk: {
609 enabled: true,
610 },
611 nocrt: true,
612 }
613
614 cc_library {
615 name: "libvndk_ext",
616 vendor: true,
617 vndk: {
618 enabled: true,
619 extends: "libvndk",
620 },
621 nocrt: true,
622 }
623
624 cc_library {
625 name: "libvndk2",
626 vendor_available: true,
627 vndk: {
628 enabled: true,
629 },
630 shared_libs: ["libvndk_ext"],
631 nocrt: true,
632 }
633 `)
634
635 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
636 // but target.vendor.shared_libs has not been supported yet.
637 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
638 cc_library {
639 name: "libvndk",
640 vendor_available: true,
641 vndk: {
642 enabled: true,
643 },
644 nocrt: true,
645 }
646
647 cc_library {
648 name: "libvndk_ext",
649 vendor: true,
650 vndk: {
651 enabled: true,
652 extends: "libvndk",
653 },
654 nocrt: true,
655 }
656
657 cc_library {
658 name: "libvndk2",
659 vendor_available: true,
660 vndk: {
661 enabled: true,
662 },
663 target: {
664 vendor: {
665 shared_libs: ["libvndk_ext"],
666 },
667 },
668 nocrt: true,
669 }
670 `)
671
672 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
673 cc_library {
674 name: "libvndk_sp",
675 vendor_available: true,
676 vndk: {
677 enabled: true,
678 support_system_process: true,
679 },
680 nocrt: true,
681 }
682
683 cc_library {
684 name: "libvndk_sp_ext",
685 vendor: true,
686 vndk: {
687 enabled: true,
688 extends: "libvndk_sp",
689 support_system_process: true,
690 },
691 nocrt: true,
692 }
693
694 cc_library {
695 name: "libvndk_sp_2",
696 vendor_available: true,
697 vndk: {
698 enabled: true,
699 support_system_process: true,
700 },
701 shared_libs: ["libvndk_sp_ext"],
702 nocrt: true,
703 }
704 `)
705
706 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
707 // but target.vendor.shared_libs has not been supported yet.
708 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
709 cc_library {
710 name: "libvndk_sp",
711 vendor_available: true,
712 vndk: {
713 enabled: true,
714 },
715 nocrt: true,
716 }
717
718 cc_library {
719 name: "libvndk_sp_ext",
720 vendor: true,
721 vndk: {
722 enabled: true,
723 extends: "libvndk_sp",
724 },
725 nocrt: true,
726 }
727
728 cc_library {
729 name: "libvndk_sp2",
730 vendor_available: true,
731 vndk: {
732 enabled: true,
733 },
734 target: {
735 vendor: {
736 shared_libs: ["libvndk_sp_ext"],
737 },
738 },
739 nocrt: true,
740 }
741 `)
742}
743
Colin Cross0af4b842015-04-30 16:36:18 -0700744var (
745 str11 = "01234567891"
746 str10 = str11[:10]
747 str9 = str11[:9]
748 str5 = str11[:5]
749 str4 = str11[:4]
750)
751
752var splitListForSizeTestCases = []struct {
753 in []string
754 out [][]string
755 size int
756}{
757 {
758 in: []string{str10},
759 out: [][]string{{str10}},
760 size: 10,
761 },
762 {
763 in: []string{str9},
764 out: [][]string{{str9}},
765 size: 10,
766 },
767 {
768 in: []string{str5},
769 out: [][]string{{str5}},
770 size: 10,
771 },
772 {
773 in: []string{str11},
774 out: nil,
775 size: 10,
776 },
777 {
778 in: []string{str10, str10},
779 out: [][]string{{str10}, {str10}},
780 size: 10,
781 },
782 {
783 in: []string{str9, str10},
784 out: [][]string{{str9}, {str10}},
785 size: 10,
786 },
787 {
788 in: []string{str10, str9},
789 out: [][]string{{str10}, {str9}},
790 size: 10,
791 },
792 {
793 in: []string{str5, str4},
794 out: [][]string{{str5, str4}},
795 size: 10,
796 },
797 {
798 in: []string{str5, str4, str5},
799 out: [][]string{{str5, str4}, {str5}},
800 size: 10,
801 },
802 {
803 in: []string{str5, str4, str5, str4},
804 out: [][]string{{str5, str4}, {str5, str4}},
805 size: 10,
806 },
807 {
808 in: []string{str5, str4, str5, str5},
809 out: [][]string{{str5, str4}, {str5}, {str5}},
810 size: 10,
811 },
812 {
813 in: []string{str5, str5, str5, str4},
814 out: [][]string{{str5}, {str5}, {str5, str4}},
815 size: 10,
816 },
817 {
818 in: []string{str9, str11},
819 out: nil,
820 size: 10,
821 },
822 {
823 in: []string{str11, str9},
824 out: nil,
825 size: 10,
826 },
827}
828
829func TestSplitListForSize(t *testing.T) {
830 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -0700831 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
832
833 var outStrings [][]string
834
835 if len(out) > 0 {
836 outStrings = make([][]string, len(out))
837 for i, o := range out {
838 outStrings[i] = o.Strings()
839 }
840 }
841
842 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -0700843 t.Errorf("incorrect output:")
844 t.Errorf(" input: %#v", testCase.in)
845 t.Errorf(" size: %d", testCase.size)
846 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -0700847 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -0700848 }
849 }
850}
Jeff Gaston294356f2017-09-27 17:05:30 -0700851
852var staticLinkDepOrderTestCases = []struct {
853 // This is a string representation of a map[moduleName][]moduleDependency .
854 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800855 inStatic string
856
857 // This is a string representation of a map[moduleName][]moduleDependency .
858 // It models the dependencies declared in an Android.bp file.
859 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -0700860
861 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
862 // The keys of allOrdered specify which modules we would like to check.
863 // The values of allOrdered specify the expected result (of the transitive closure of all
864 // dependencies) for each module to test
865 allOrdered string
866
867 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
868 // The keys of outOrdered specify which modules we would like to check.
869 // The values of outOrdered specify the expected result (of the ordered linker command line)
870 // for each module to test.
871 outOrdered string
872}{
873 // Simple tests
874 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800875 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -0700876 outOrdered: "",
877 },
878 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800879 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700880 outOrdered: "a:",
881 },
882 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800883 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700884 outOrdered: "a:b; b:",
885 },
886 // Tests of reordering
887 {
888 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800889 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700890 outOrdered: "a:b,c,d; b:d; c:d; d:",
891 },
892 {
893 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800894 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700895 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
896 },
897 {
898 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800899 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -0700900 outOrdered: "a:d,b,e,c; d:b; e:c",
901 },
902 {
903 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800904 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -0700905 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
906 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
907 },
908 {
909 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800910 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 -0700911 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
912 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
913 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800914 // shared dependencies
915 {
916 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
917 // So, we don't actually have to check that a shared dependency of c will change the order
918 // of a library that depends statically on b and on c. We only need to check that if c has
919 // a shared dependency on b, that that shows up in allOrdered.
920 inShared: "c:b",
921 allOrdered: "c:b",
922 outOrdered: "c:",
923 },
924 {
925 // This test doesn't actually include any shared dependencies but it's a reminder of what
926 // the second phase of the above test would look like
927 inStatic: "a:b,c; c:b",
928 allOrdered: "a:c,b; c:b",
929 outOrdered: "a:c,b; c:b",
930 },
Jeff Gaston294356f2017-09-27 17:05:30 -0700931 // tiebreakers for when two modules specifying different orderings and there is no dependency
932 // to dictate an order
933 {
934 // 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 -0800935 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -0700936 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
937 },
938 {
939 // 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 -0800940 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 -0700941 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
942 },
943 // Tests involving duplicate dependencies
944 {
945 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800946 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700947 outOrdered: "a:c,b",
948 },
949 {
950 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800951 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700952 outOrdered: "a:d,c,b",
953 },
954 // Tests to confirm the nonexistence of infinite loops.
955 // These cases should never happen, so as long as the test terminates and the
956 // result is deterministic then that should be fine.
957 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800958 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700959 outOrdered: "a:a",
960 },
961 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800962 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700963 allOrdered: "a:b,c; b:c,a; c:a,b",
964 outOrdered: "a:b; b:c; c:a",
965 },
966 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800967 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700968 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
969 outOrdered: "a:c,b; b:a,c; c:b,a",
970 },
971}
972
973// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
974func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
975 // convert from "a:b,c; d:e" to "a:b,c;d:e"
976 strippedText := strings.Replace(text, " ", "", -1)
977 if len(strippedText) < 1 {
978 return []android.Path{}, make(map[android.Path][]android.Path, 0)
979 }
980 allDeps = make(map[android.Path][]android.Path, 0)
981
982 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
983 moduleTexts := strings.Split(strippedText, ";")
984
985 outputForModuleName := func(moduleName string) android.Path {
986 return android.PathForTesting(moduleName)
987 }
988
989 for _, moduleText := range moduleTexts {
990 // convert from "a:b,c" to ["a", "b,c"]
991 components := strings.Split(moduleText, ":")
992 if len(components) != 2 {
993 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
994 }
995 moduleName := components[0]
996 moduleOutput := outputForModuleName(moduleName)
997 modulesInOrder = append(modulesInOrder, moduleOutput)
998
999 depString := components[1]
1000 // convert from "b,c" to ["b", "c"]
1001 depNames := strings.Split(depString, ",")
1002 if len(depString) < 1 {
1003 depNames = []string{}
1004 }
1005 var deps []android.Path
1006 for _, depName := range depNames {
1007 deps = append(deps, outputForModuleName(depName))
1008 }
1009 allDeps[moduleOutput] = deps
1010 }
1011 return modulesInOrder, allDeps
1012}
1013
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001014func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001015 for _, testCase := range staticLinkDepOrderTestCases {
1016 errs := []string{}
1017
1018 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001019 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001020 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1021 if testCase.allOrdered == "" {
1022 // allow the test case to skip specifying allOrdered
1023 testCase.allOrdered = testCase.outOrdered
1024 }
1025 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001026 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001027
1028 // For each module whose post-reordered dependencies were specified, validate that
1029 // reordering the inputs produces the expected outputs.
1030 for _, moduleName := range expectedModuleNames {
1031 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001032 givenSharedDeps := givenAllSharedDeps[moduleName]
1033 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001034
1035 correctAllOrdered := expectedAllDeps[moduleName]
1036 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1037 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001038 "\nin static:%q"+
1039 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001040 "\nmodule: %v"+
1041 "\nexpected: %s"+
1042 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001043 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001044 }
1045
1046 correctOutputDeps := expectedTransitiveDeps[moduleName]
1047 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1048 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001049 "\nin static:%q"+
1050 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001051 "\nmodule: %v"+
1052 "\nexpected: %s"+
1053 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001054 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001055 }
1056 }
1057
1058 if len(errs) > 0 {
1059 sort.Strings(errs)
1060 for _, err := range errs {
1061 t.Error(err)
1062 }
1063 }
1064 }
1065}
Logan Chienf3511742017-10-31 18:04:35 +08001066
Jeff Gaston294356f2017-09-27 17:05:30 -07001067func failIfErrored(t *testing.T, errs []error) {
1068 if len(errs) > 0 {
1069 for _, err := range errs {
1070 t.Error(err)
1071 }
1072 t.FailNow()
1073 }
1074}
1075
Logan Chienf3511742017-10-31 18:04:35 +08001076func failIfNoMatchingErrors(t *testing.T, pattern string, errs []error) {
1077 matcher, err := regexp.Compile(pattern)
1078 if err != nil {
1079 t.Errorf("failed to compile regular expression %q because %s", pattern, err)
1080 }
1081
1082 found := false
1083
1084 for _, err := range errs {
1085 if matcher.FindStringIndex(err.Error()) != nil {
1086 found = true
1087 break
1088 }
1089 }
1090
1091 if !found {
1092 t.Errorf("missing the expected error %q (checked %d error(s))", pattern, len(errs))
1093 for i, err := range errs {
1094 t.Errorf("errs[%d] = %s", i, err)
1095 }
1096 }
1097}
1098
Jeff Gaston294356f2017-09-27 17:05:30 -07001099func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1100 for _, moduleName := range moduleNames {
1101 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1102 output := module.outputFile.Path()
1103 paths = append(paths, output)
1104 }
1105 return paths
1106}
1107
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001108func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001109 ctx := testCc(t, `
1110 cc_library {
1111 name: "a",
1112 static_libs: ["b", "c", "d"],
1113 }
1114 cc_library {
1115 name: "b",
1116 }
1117 cc_library {
1118 name: "c",
1119 static_libs: ["b"],
1120 }
1121 cc_library {
1122 name: "d",
1123 }
1124
1125 `)
1126
1127 variant := "android_arm64_armv8-a_core_static"
1128 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001129 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001130 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1131
1132 if !reflect.DeepEqual(actual, expected) {
1133 t.Errorf("staticDeps orderings were not propagated correctly"+
1134 "\nactual: %v"+
1135 "\nexpected: %v",
1136 actual,
1137 expected,
1138 )
1139 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001140}
Jeff Gaston294356f2017-09-27 17:05:30 -07001141
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001142func TestStaticLibDepReorderingWithShared(t *testing.T) {
1143 ctx := testCc(t, `
1144 cc_library {
1145 name: "a",
1146 static_libs: ["b", "c"],
1147 }
1148 cc_library {
1149 name: "b",
1150 }
1151 cc_library {
1152 name: "c",
1153 shared_libs: ["b"],
1154 }
1155
1156 `)
1157
1158 variant := "android_arm64_armv8-a_core_static"
1159 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1160 actual := moduleA.depsInLinkOrder
1161 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1162
1163 if !reflect.DeepEqual(actual, expected) {
1164 t.Errorf("staticDeps orderings did not account for shared libs"+
1165 "\nactual: %v"+
1166 "\nexpected: %v",
1167 actual,
1168 expected,
1169 )
1170 }
1171}
1172
Jiyong Parka46a4d52017-12-14 19:54:34 +09001173func TestLlndkHeaders(t *testing.T) {
1174 ctx := testCc(t, `
1175 llndk_headers {
1176 name: "libllndk_headers",
1177 export_include_dirs: ["my_include"],
1178 }
1179 llndk_library {
1180 name: "libllndk",
1181 export_llndk_headers: ["libllndk_headers"],
1182 }
1183 cc_library {
1184 name: "libvendor",
1185 shared_libs: ["libllndk"],
1186 vendor: true,
1187 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001188 no_libgcc: true,
1189 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001190 }
1191 `)
1192
1193 // _static variant is used since _shared reuses *.o from the static variant
1194 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1195 cflags := cc.Args["cFlags"]
1196 if !strings.Contains(cflags, "-Imy_include") {
1197 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1198 }
1199}
1200
Jiyong Parkd08b6972017-09-26 10:50:54 +09001201var compilerFlagsTestCases = []struct {
1202 in string
1203 out bool
1204}{
1205 {
1206 in: "a",
1207 out: false,
1208 },
1209 {
1210 in: "-a",
1211 out: true,
1212 },
1213 {
1214 in: "-Ipath/to/something",
1215 out: false,
1216 },
1217 {
1218 in: "-isystempath/to/something",
1219 out: false,
1220 },
1221 {
1222 in: "--coverage",
1223 out: false,
1224 },
1225 {
1226 in: "-include a/b",
1227 out: true,
1228 },
1229 {
1230 in: "-include a/b c/d",
1231 out: false,
1232 },
1233 {
1234 in: "-DMACRO",
1235 out: true,
1236 },
1237 {
1238 in: "-DMAC RO",
1239 out: false,
1240 },
1241 {
1242 in: "-a -b",
1243 out: false,
1244 },
1245 {
1246 in: "-DMACRO=definition",
1247 out: true,
1248 },
1249 {
1250 in: "-DMACRO=defi nition",
1251 out: true, // TODO(jiyong): this should be false
1252 },
1253 {
1254 in: "-DMACRO(x)=x + 1",
1255 out: true,
1256 },
1257 {
1258 in: "-DMACRO=\"defi nition\"",
1259 out: true,
1260 },
1261}
1262
1263type mockContext struct {
1264 BaseModuleContext
1265 result bool
1266}
1267
1268func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1269 // CheckBadCompilerFlags calls this function when the flag should be rejected
1270 ctx.result = false
1271}
1272
1273func TestCompilerFlags(t *testing.T) {
1274 for _, testCase := range compilerFlagsTestCases {
1275 ctx := &mockContext{result: true}
1276 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1277 if ctx.result != testCase.out {
1278 t.Errorf("incorrect output:")
1279 t.Errorf(" input: %#v", testCase.in)
1280 t.Errorf(" expected: %#v", testCase.out)
1281 t.Errorf(" got: %#v", ctx.result)
1282 }
1283 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001284}