blob: 437211cd98b961aacc89fdedb275b7dd16ef87f5 [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"
Jeff Gaston294356f2017-09-27 17:05:30 -070025 "sort"
26 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070027 "testing"
28)
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 createTestContext(t *testing.T, config android.Config, bp string) *android.TestContext {
Jiyong Park6a43f042017-10-12 23:05:00 +090056 ctx := android.NewTestArchContext()
Steven Morelandf9e62162017-11-02 17:00:50 -070057 ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory))
Colin Crossf18e1102017-11-16 14:33:08 -080058 ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory))
Jiyong Park6a43f042017-10-12 23:05:00 +090059 ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(toolchainLibraryFactory))
60 ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(llndkLibraryFactory))
Jiyong Parka46a4d52017-12-14 19:54:34 +090061 ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory))
Jeff Gaston294356f2017-09-27 17:05:30 -070062 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(objectFactory))
Colin Crossf18e1102017-11-16 14:33:08 -080063 ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(genrule.FileGroupFactory))
Jiyong Park6a43f042017-10-12 23:05:00 +090064 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
65 ctx.BottomUp("image", vendorMutator).Parallel()
66 ctx.BottomUp("link", linkageMutator).Parallel()
67 ctx.BottomUp("vndk", vndkMutator).Parallel()
68 })
69 ctx.Register()
70
Jeff Gaston294356f2017-09-27 17:05:30 -070071 // add some modules that are required by the compiler and/or linker
72 bp = bp + `
73 toolchain_library {
74 name: "libatomic",
75 vendor_available: true,
76 }
77
78 toolchain_library {
79 name: "libcompiler_rt-extras",
80 vendor_available: true,
81 }
82
83 toolchain_library {
84 name: "libgcc",
85 vendor_available: true,
86 }
87
88 cc_library {
89 name: "libc",
Logan Chienf3511742017-10-31 18:04:35 +080090 no_libgcc: true,
91 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -070092 system_shared_libs: [],
93 }
94 llndk_library {
95 name: "libc",
96 symbol_file: "",
97 }
98 cc_library {
99 name: "libm",
Logan Chienf3511742017-10-31 18:04:35 +0800100 no_libgcc: true,
101 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700102 system_shared_libs: [],
103 }
104 llndk_library {
105 name: "libm",
106 symbol_file: "",
107 }
108 cc_library {
109 name: "libdl",
Logan Chienf3511742017-10-31 18:04:35 +0800110 no_libgcc: true,
111 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700112 system_shared_libs: [],
113 }
114 llndk_library {
115 name: "libdl",
116 symbol_file: "",
117 }
118
119 cc_object {
120 name: "crtbegin_so",
121 }
122
123 cc_object {
124 name: "crtend_so",
125 }
126
Colin Crossad59e752017-11-16 14:29:11 -0800127 cc_library {
128 name: "libprotobuf-cpp-lite",
129 }
130
Jeff Gaston294356f2017-09-27 17:05:30 -0700131`
132
Jiyong Park6a43f042017-10-12 23:05:00 +0900133 ctx.MockFileSystem(map[string][]byte{
134 "Android.bp": []byte(bp),
135 "foo.c": nil,
136 "bar.c": nil,
Colin Crossad59e752017-11-16 14:29:11 -0800137 "a.proto": nil,
Colin Crossf18e1102017-11-16 14:33:08 -0800138 "b.aidl": nil,
Jiyong Parka46a4d52017-12-14 19:54:34 +0900139 "my_include": nil,
Jiyong Park6a43f042017-10-12 23:05:00 +0900140 })
141
Logan Chienf3511742017-10-31 18:04:35 +0800142 return ctx
143}
144
145func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
146 ctx := createTestContext(t, config, bp)
147
Jeff Gastond3e141d2017-08-08 17:46:01 -0700148 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +0800149 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900150 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800151 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900152
153 return ctx
154}
155
Logan Chienf3511742017-10-31 18:04:35 +0800156func testCc(t *testing.T, bp string) *android.TestContext {
157 config := android.TestArchConfig(buildDir, nil)
158 config.ProductVariables.DeviceVndkVersion = StringPtr("current")
159 config.ProductVariables.Platform_vndk_version = StringPtr("VER")
160
161 return testCcWithConfig(t, bp, config)
162}
163
164func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
165 config := android.TestArchConfig(buildDir, nil)
166 config.ProductVariables.Platform_vndk_version = StringPtr("VER")
167
168 return testCcWithConfig(t, bp, config)
169}
170
171func testCcError(t *testing.T, pattern string, bp string) {
172 config := android.TestArchConfig(buildDir, nil)
173 config.ProductVariables.DeviceVndkVersion = StringPtr("current")
174 config.ProductVariables.Platform_vndk_version = StringPtr("VER")
175
176 ctx := createTestContext(t, config, bp)
177
178 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
179 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800180 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800181 return
182 }
183
184 _, errs = ctx.PrepareBuildActions(config)
185 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800186 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800187 return
188 }
189
190 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
191}
192
193const (
194 coreVariant = "android_arm64_armv8-a_core_shared"
195 vendorVariant = "android_arm64_armv8-a_vendor_shared"
196)
197
Jiyong Park6a43f042017-10-12 23:05:00 +0900198func TestVendorSrc(t *testing.T) {
199 ctx := testCc(t, `
200 cc_library {
201 name: "libTest",
202 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800203 no_libgcc: true,
204 nocrt: true,
205 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900206 vendor_available: true,
207 target: {
208 vendor: {
209 srcs: ["bar.c"],
210 },
211 },
212 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900213 `)
214
Logan Chienf3511742017-10-31 18:04:35 +0800215 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900216 var objs []string
217 for _, o := range ld.Inputs {
218 objs = append(objs, o.Base())
219 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800220 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900221 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
222 }
223}
224
Logan Chienf3511742017-10-31 18:04:35 +0800225func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
226 isVndkSp bool, extends string) {
227
228 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
229 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700230 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800231 }
232
233 // Check library properties.
234 lib, ok := mod.compiler.(*libraryDecorator)
235 if !ok {
236 t.Errorf("%q must have libraryDecorator", name)
237 } else if lib.baseInstaller.subDir != subDir {
238 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
239 lib.baseInstaller.subDir)
240 }
241
242 // Check VNDK properties.
243 if mod.vndkdep == nil {
244 t.Fatalf("%q must have `vndkdep`", name)
245 }
246 if !mod.isVndk() {
247 t.Errorf("%q isVndk() must equal to true", name)
248 }
249 if mod.isVndkSp() != isVndkSp {
250 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
251 }
252
253 // Check VNDK extension properties.
254 isVndkExt := extends != ""
255 if mod.isVndkExt() != isVndkExt {
256 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
257 }
258
259 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
260 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
261 }
262}
263
264func TestVndk(t *testing.T) {
265 ctx := testCc(t, `
266 cc_library {
267 name: "libvndk",
268 vendor_available: true,
269 vndk: {
270 enabled: true,
271 },
272 nocrt: true,
273 }
274
275 cc_library {
276 name: "libvndk_private",
277 vendor_available: false,
278 vndk: {
279 enabled: true,
280 },
281 nocrt: true,
282 }
283
284 cc_library {
285 name: "libvndk_sp",
286 vendor_available: true,
287 vndk: {
288 enabled: true,
289 support_system_process: true,
290 },
291 nocrt: true,
292 }
293
294 cc_library {
295 name: "libvndk_sp_private",
296 vendor_available: false,
297 vndk: {
298 enabled: true,
299 support_system_process: true,
300 },
301 nocrt: true,
302 }
303 `)
304
305 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
306 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
307 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
308 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
309}
310
311func TestVndkExt(t *testing.T) {
312 // This test checks the VNDK-Ext properties.
313 ctx := testCc(t, `
314 cc_library {
315 name: "libvndk",
316 vendor_available: true,
317 vndk: {
318 enabled: true,
319 },
320 nocrt: true,
321 }
322
323 cc_library {
324 name: "libvndk_ext",
325 vendor: true,
326 vndk: {
327 enabled: true,
328 extends: "libvndk",
329 },
330 nocrt: true,
331 }
332 `)
333
334 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
335}
336
337func TestVndkExtNoVndk(t *testing.T) {
338 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
339 ctx := testCcNoVndk(t, `
340 cc_library {
341 name: "libvndk",
342 vendor_available: true,
343 vndk: {
344 enabled: true,
345 },
346 nocrt: true,
347 }
348
349 cc_library {
350 name: "libvndk_ext",
351 vendor: true,
352 vndk: {
353 enabled: true,
354 extends: "libvndk",
355 },
356 nocrt: true,
357 }
358 `)
359
360 // Ensures that the core variant of "libvndk_ext" can be found.
361 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
362 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
363 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
364 }
365}
366
367func TestVndkExtError(t *testing.T) {
368 // This test ensures an error is emitted in ill-formed vndk-ext definition.
369 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
370 cc_library {
371 name: "libvndk",
372 vendor_available: true,
373 vndk: {
374 enabled: true,
375 },
376 nocrt: true,
377 }
378
379 cc_library {
380 name: "libvndk_ext",
381 vndk: {
382 enabled: true,
383 extends: "libvndk",
384 },
385 nocrt: true,
386 }
387 `)
388
389 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
390 cc_library {
391 name: "libvndk",
392 vendor_available: true,
393 vndk: {
394 enabled: true,
395 },
396 nocrt: true,
397 }
398
399 cc_library {
400 name: "libvndk_ext",
401 vendor: true,
402 vndk: {
403 enabled: true,
404 },
405 nocrt: true,
406 }
407 `)
408}
409
410func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
411 // This test ensures an error is emitted for inconsistent support_system_process.
412 testCcError(t, "module \".*\" with mismatched support_system_process", `
413 cc_library {
414 name: "libvndk",
415 vendor_available: true,
416 vndk: {
417 enabled: true,
418 },
419 nocrt: true,
420 }
421
422 cc_library {
423 name: "libvndk_sp_ext",
424 vendor: true,
425 vndk: {
426 enabled: true,
427 extends: "libvndk",
428 support_system_process: true,
429 },
430 nocrt: true,
431 }
432 `)
433
434 testCcError(t, "module \".*\" with mismatched support_system_process", `
435 cc_library {
436 name: "libvndk_sp",
437 vendor_available: true,
438 vndk: {
439 enabled: true,
440 support_system_process: true,
441 },
442 nocrt: true,
443 }
444
445 cc_library {
446 name: "libvndk_ext",
447 vendor: true,
448 vndk: {
449 enabled: true,
450 extends: "libvndk_sp",
451 },
452 nocrt: true,
453 }
454 `)
455}
456
457func TestVndkExtVendorAvailableFalseError(t *testing.T) {
458 // This test ensures an error is emitted when a vndk-ext library extends a vndk library
459 // with `vendor_available: false`.
460 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
461 cc_library {
462 name: "libvndk",
463 vendor_available: false,
464 vndk: {
465 enabled: true,
466 },
467 nocrt: true,
468 }
469
470 cc_library {
471 name: "libvndk_ext",
472 vendor: true,
473 vndk: {
474 enabled: true,
475 extends: "libvndk",
476 },
477 nocrt: true,
478 }
479 `)
480}
481
482func TestVendorModuleUsesVndkExt(t *testing.T) {
483 // This test ensures a vendor module can depend on a vndk-ext library.
484 testCc(t, `
485 cc_library {
486 name: "libvndk",
487 vendor_available: true,
488 vndk: {
489 enabled: true,
490 },
491 nocrt: true,
492 }
493
494 cc_library {
495 name: "libvndk_ext",
496 vendor: true,
497 vndk: {
498 enabled: true,
499 extends: "libvndk",
500 },
501 nocrt: true,
502 }
503
504 cc_library {
505
506 name: "libvndk_sp",
507 vendor_available: true,
508 vndk: {
509 enabled: true,
510 support_system_process: true,
511 },
512 nocrt: true,
513 }
514
515 cc_library {
516 name: "libvndk_sp_ext",
517 vendor: true,
518 vndk: {
519 enabled: true,
520 extends: "libvndk_sp",
521 support_system_process: true,
522 },
523 nocrt: true,
524 }
525
526 cc_library {
527 name: "libvendor",
528 vendor: true,
529 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
530 nocrt: true,
531 }
532 `)
533}
534
535func TestVndkExtUsesVendorLib(t *testing.T) {
536 // This test ensures a vndk-ext library can depend on a vendor library.
537 testCc(t, `
538 cc_library {
539 name: "libvndk",
540 vendor_available: true,
541 vndk: {
542 enabled: true,
543 },
544 nocrt: true,
545 }
546
547 cc_library {
548 name: "libvndk_ext",
549 vendor: true,
550 vndk: {
551 enabled: true,
552 extends: "libvndk",
553 },
554 shared_libs: ["libvendor"],
555 nocrt: true,
556 }
557
558 cc_library {
559 name: "libvendor",
560 vendor: true,
561 nocrt: true,
562 }
563 `)
564}
565
566func TestVndkSpExtUsesVendorLibError(t *testing.T) {
567 // This test ensures an error is emitted if a vndk-sp-ext library depends on a vendor
568 // library.
569 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
570 cc_library {
571 name: "libvndk_sp",
572 vendor_available: true,
573 vndk: {
574 enabled: true,
575 support_system_process: true,
576 },
577 nocrt: true,
578 }
579
580 cc_library {
581 name: "libvndk_sp_ext",
582 vendor: true,
583 vndk: {
584 enabled: true,
585 extends: "libvndk_sp",
586 support_system_process: true,
587 },
588 shared_libs: ["libvendor"], // Cause an error
589 nocrt: true,
590 }
591
592 cc_library {
593 name: "libvendor",
594 vendor: true,
595 nocrt: true,
596 }
597 `)
598}
599
600func TestVndkUsesVndkExtError(t *testing.T) {
601 // This test ensures an error is emitted if a vndk/vndk-sp library depends on a
602 // vndk-ext/vndk-sp-ext library.
603 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
604 cc_library {
605 name: "libvndk",
606 vendor_available: true,
607 vndk: {
608 enabled: true,
609 },
610 nocrt: true,
611 }
612
613 cc_library {
614 name: "libvndk_ext",
615 vendor: true,
616 vndk: {
617 enabled: true,
618 extends: "libvndk",
619 },
620 nocrt: true,
621 }
622
623 cc_library {
624 name: "libvndk2",
625 vendor_available: true,
626 vndk: {
627 enabled: true,
628 },
629 shared_libs: ["libvndk_ext"],
630 nocrt: true,
631 }
632 `)
633
634 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
635 // but target.vendor.shared_libs has not been supported yet.
636 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
637 cc_library {
638 name: "libvndk",
639 vendor_available: true,
640 vndk: {
641 enabled: true,
642 },
643 nocrt: true,
644 }
645
646 cc_library {
647 name: "libvndk_ext",
648 vendor: true,
649 vndk: {
650 enabled: true,
651 extends: "libvndk",
652 },
653 nocrt: true,
654 }
655
656 cc_library {
657 name: "libvndk2",
658 vendor_available: true,
659 vndk: {
660 enabled: true,
661 },
662 target: {
663 vendor: {
664 shared_libs: ["libvndk_ext"],
665 },
666 },
667 nocrt: true,
668 }
669 `)
670
671 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
672 cc_library {
673 name: "libvndk_sp",
674 vendor_available: true,
675 vndk: {
676 enabled: true,
677 support_system_process: true,
678 },
679 nocrt: true,
680 }
681
682 cc_library {
683 name: "libvndk_sp_ext",
684 vendor: true,
685 vndk: {
686 enabled: true,
687 extends: "libvndk_sp",
688 support_system_process: true,
689 },
690 nocrt: true,
691 }
692
693 cc_library {
694 name: "libvndk_sp_2",
695 vendor_available: true,
696 vndk: {
697 enabled: true,
698 support_system_process: true,
699 },
700 shared_libs: ["libvndk_sp_ext"],
701 nocrt: true,
702 }
703 `)
704
705 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
706 // but target.vendor.shared_libs has not been supported yet.
707 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
708 cc_library {
709 name: "libvndk_sp",
710 vendor_available: true,
711 vndk: {
712 enabled: true,
713 },
714 nocrt: true,
715 }
716
717 cc_library {
718 name: "libvndk_sp_ext",
719 vendor: true,
720 vndk: {
721 enabled: true,
722 extends: "libvndk_sp",
723 },
724 nocrt: true,
725 }
726
727 cc_library {
728 name: "libvndk_sp2",
729 vendor_available: true,
730 vndk: {
731 enabled: true,
732 },
733 target: {
734 vendor: {
735 shared_libs: ["libvndk_sp_ext"],
736 },
737 },
738 nocrt: true,
739 }
740 `)
741}
742
Colin Cross0af4b842015-04-30 16:36:18 -0700743var (
744 str11 = "01234567891"
745 str10 = str11[:10]
746 str9 = str11[:9]
747 str5 = str11[:5]
748 str4 = str11[:4]
749)
750
751var splitListForSizeTestCases = []struct {
752 in []string
753 out [][]string
754 size int
755}{
756 {
757 in: []string{str10},
758 out: [][]string{{str10}},
759 size: 10,
760 },
761 {
762 in: []string{str9},
763 out: [][]string{{str9}},
764 size: 10,
765 },
766 {
767 in: []string{str5},
768 out: [][]string{{str5}},
769 size: 10,
770 },
771 {
772 in: []string{str11},
773 out: nil,
774 size: 10,
775 },
776 {
777 in: []string{str10, str10},
778 out: [][]string{{str10}, {str10}},
779 size: 10,
780 },
781 {
782 in: []string{str9, str10},
783 out: [][]string{{str9}, {str10}},
784 size: 10,
785 },
786 {
787 in: []string{str10, str9},
788 out: [][]string{{str10}, {str9}},
789 size: 10,
790 },
791 {
792 in: []string{str5, str4},
793 out: [][]string{{str5, str4}},
794 size: 10,
795 },
796 {
797 in: []string{str5, str4, str5},
798 out: [][]string{{str5, str4}, {str5}},
799 size: 10,
800 },
801 {
802 in: []string{str5, str4, str5, str4},
803 out: [][]string{{str5, str4}, {str5, str4}},
804 size: 10,
805 },
806 {
807 in: []string{str5, str4, str5, str5},
808 out: [][]string{{str5, str4}, {str5}, {str5}},
809 size: 10,
810 },
811 {
812 in: []string{str5, str5, str5, str4},
813 out: [][]string{{str5}, {str5}, {str5, str4}},
814 size: 10,
815 },
816 {
817 in: []string{str9, str11},
818 out: nil,
819 size: 10,
820 },
821 {
822 in: []string{str11, str9},
823 out: nil,
824 size: 10,
825 },
826}
827
828func TestSplitListForSize(t *testing.T) {
829 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -0700830 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
831
832 var outStrings [][]string
833
834 if len(out) > 0 {
835 outStrings = make([][]string, len(out))
836 for i, o := range out {
837 outStrings[i] = o.Strings()
838 }
839 }
840
841 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -0700842 t.Errorf("incorrect output:")
843 t.Errorf(" input: %#v", testCase.in)
844 t.Errorf(" size: %d", testCase.size)
845 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -0700846 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -0700847 }
848 }
849}
Jeff Gaston294356f2017-09-27 17:05:30 -0700850
851var staticLinkDepOrderTestCases = []struct {
852 // This is a string representation of a map[moduleName][]moduleDependency .
853 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800854 inStatic string
855
856 // This is a string representation of a map[moduleName][]moduleDependency .
857 // It models the dependencies declared in an Android.bp file.
858 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -0700859
860 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
861 // The keys of allOrdered specify which modules we would like to check.
862 // The values of allOrdered specify the expected result (of the transitive closure of all
863 // dependencies) for each module to test
864 allOrdered string
865
866 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
867 // The keys of outOrdered specify which modules we would like to check.
868 // The values of outOrdered specify the expected result (of the ordered linker command line)
869 // for each module to test.
870 outOrdered string
871}{
872 // Simple tests
873 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800874 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -0700875 outOrdered: "",
876 },
877 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800878 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700879 outOrdered: "a:",
880 },
881 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800882 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700883 outOrdered: "a:b; b:",
884 },
885 // Tests of reordering
886 {
887 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800888 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700889 outOrdered: "a:b,c,d; b:d; c:d; d:",
890 },
891 {
892 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800893 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700894 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
895 },
896 {
897 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800898 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -0700899 outOrdered: "a:d,b,e,c; d:b; e:c",
900 },
901 {
902 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800903 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -0700904 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
905 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
906 },
907 {
908 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800909 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 -0700910 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
911 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
912 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800913 // shared dependencies
914 {
915 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
916 // So, we don't actually have to check that a shared dependency of c will change the order
917 // of a library that depends statically on b and on c. We only need to check that if c has
918 // a shared dependency on b, that that shows up in allOrdered.
919 inShared: "c:b",
920 allOrdered: "c:b",
921 outOrdered: "c:",
922 },
923 {
924 // This test doesn't actually include any shared dependencies but it's a reminder of what
925 // the second phase of the above test would look like
926 inStatic: "a:b,c; c:b",
927 allOrdered: "a:c,b; c:b",
928 outOrdered: "a:c,b; c:b",
929 },
Jeff Gaston294356f2017-09-27 17:05:30 -0700930 // tiebreakers for when two modules specifying different orderings and there is no dependency
931 // to dictate an order
932 {
933 // 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 -0800934 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -0700935 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
936 },
937 {
938 // 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 -0800939 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 -0700940 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
941 },
942 // Tests involving duplicate dependencies
943 {
944 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800945 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700946 outOrdered: "a:c,b",
947 },
948 {
949 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800950 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700951 outOrdered: "a:d,c,b",
952 },
953 // Tests to confirm the nonexistence of infinite loops.
954 // These cases should never happen, so as long as the test terminates and the
955 // result is deterministic then that should be fine.
956 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800957 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700958 outOrdered: "a:a",
959 },
960 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800961 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700962 allOrdered: "a:b,c; b:c,a; c:a,b",
963 outOrdered: "a:b; b:c; c:a",
964 },
965 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800966 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700967 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
968 outOrdered: "a:c,b; b:a,c; c:b,a",
969 },
970}
971
972// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
973func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
974 // convert from "a:b,c; d:e" to "a:b,c;d:e"
975 strippedText := strings.Replace(text, " ", "", -1)
976 if len(strippedText) < 1 {
977 return []android.Path{}, make(map[android.Path][]android.Path, 0)
978 }
979 allDeps = make(map[android.Path][]android.Path, 0)
980
981 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
982 moduleTexts := strings.Split(strippedText, ";")
983
984 outputForModuleName := func(moduleName string) android.Path {
985 return android.PathForTesting(moduleName)
986 }
987
988 for _, moduleText := range moduleTexts {
989 // convert from "a:b,c" to ["a", "b,c"]
990 components := strings.Split(moduleText, ":")
991 if len(components) != 2 {
992 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
993 }
994 moduleName := components[0]
995 moduleOutput := outputForModuleName(moduleName)
996 modulesInOrder = append(modulesInOrder, moduleOutput)
997
998 depString := components[1]
999 // convert from "b,c" to ["b", "c"]
1000 depNames := strings.Split(depString, ",")
1001 if len(depString) < 1 {
1002 depNames = []string{}
1003 }
1004 var deps []android.Path
1005 for _, depName := range depNames {
1006 deps = append(deps, outputForModuleName(depName))
1007 }
1008 allDeps[moduleOutput] = deps
1009 }
1010 return modulesInOrder, allDeps
1011}
1012
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001013func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001014 for _, testCase := range staticLinkDepOrderTestCases {
1015 errs := []string{}
1016
1017 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001018 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001019 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1020 if testCase.allOrdered == "" {
1021 // allow the test case to skip specifying allOrdered
1022 testCase.allOrdered = testCase.outOrdered
1023 }
1024 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001025 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001026
1027 // For each module whose post-reordered dependencies were specified, validate that
1028 // reordering the inputs produces the expected outputs.
1029 for _, moduleName := range expectedModuleNames {
1030 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001031 givenSharedDeps := givenAllSharedDeps[moduleName]
1032 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001033
1034 correctAllOrdered := expectedAllDeps[moduleName]
1035 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1036 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001037 "\nin static:%q"+
1038 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001039 "\nmodule: %v"+
1040 "\nexpected: %s"+
1041 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001042 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001043 }
1044
1045 correctOutputDeps := expectedTransitiveDeps[moduleName]
1046 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1047 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001048 "\nin static:%q"+
1049 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001050 "\nmodule: %v"+
1051 "\nexpected: %s"+
1052 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001053 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001054 }
1055 }
1056
1057 if len(errs) > 0 {
1058 sort.Strings(errs)
1059 for _, err := range errs {
1060 t.Error(err)
1061 }
1062 }
1063 }
1064}
Logan Chienf3511742017-10-31 18:04:35 +08001065
Jeff Gaston294356f2017-09-27 17:05:30 -07001066func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1067 for _, moduleName := range moduleNames {
1068 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1069 output := module.outputFile.Path()
1070 paths = append(paths, output)
1071 }
1072 return paths
1073}
1074
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001075func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001076 ctx := testCc(t, `
1077 cc_library {
1078 name: "a",
1079 static_libs: ["b", "c", "d"],
1080 }
1081 cc_library {
1082 name: "b",
1083 }
1084 cc_library {
1085 name: "c",
1086 static_libs: ["b"],
1087 }
1088 cc_library {
1089 name: "d",
1090 }
1091
1092 `)
1093
1094 variant := "android_arm64_armv8-a_core_static"
1095 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001096 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001097 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1098
1099 if !reflect.DeepEqual(actual, expected) {
1100 t.Errorf("staticDeps orderings were not propagated correctly"+
1101 "\nactual: %v"+
1102 "\nexpected: %v",
1103 actual,
1104 expected,
1105 )
1106 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001107}
Jeff Gaston294356f2017-09-27 17:05:30 -07001108
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001109func TestStaticLibDepReorderingWithShared(t *testing.T) {
1110 ctx := testCc(t, `
1111 cc_library {
1112 name: "a",
1113 static_libs: ["b", "c"],
1114 }
1115 cc_library {
1116 name: "b",
1117 }
1118 cc_library {
1119 name: "c",
1120 shared_libs: ["b"],
1121 }
1122
1123 `)
1124
1125 variant := "android_arm64_armv8-a_core_static"
1126 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1127 actual := moduleA.depsInLinkOrder
1128 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1129
1130 if !reflect.DeepEqual(actual, expected) {
1131 t.Errorf("staticDeps orderings did not account for shared libs"+
1132 "\nactual: %v"+
1133 "\nexpected: %v",
1134 actual,
1135 expected,
1136 )
1137 }
1138}
1139
Jiyong Parka46a4d52017-12-14 19:54:34 +09001140func TestLlndkHeaders(t *testing.T) {
1141 ctx := testCc(t, `
1142 llndk_headers {
1143 name: "libllndk_headers",
1144 export_include_dirs: ["my_include"],
1145 }
1146 llndk_library {
1147 name: "libllndk",
1148 export_llndk_headers: ["libllndk_headers"],
1149 }
1150 cc_library {
1151 name: "libvendor",
1152 shared_libs: ["libllndk"],
1153 vendor: true,
1154 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001155 no_libgcc: true,
1156 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001157 }
1158 `)
1159
1160 // _static variant is used since _shared reuses *.o from the static variant
1161 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1162 cflags := cc.Args["cFlags"]
1163 if !strings.Contains(cflags, "-Imy_include") {
1164 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1165 }
1166}
1167
Jiyong Parkd08b6972017-09-26 10:50:54 +09001168var compilerFlagsTestCases = []struct {
1169 in string
1170 out bool
1171}{
1172 {
1173 in: "a",
1174 out: false,
1175 },
1176 {
1177 in: "-a",
1178 out: true,
1179 },
1180 {
1181 in: "-Ipath/to/something",
1182 out: false,
1183 },
1184 {
1185 in: "-isystempath/to/something",
1186 out: false,
1187 },
1188 {
1189 in: "--coverage",
1190 out: false,
1191 },
1192 {
1193 in: "-include a/b",
1194 out: true,
1195 },
1196 {
1197 in: "-include a/b c/d",
1198 out: false,
1199 },
1200 {
1201 in: "-DMACRO",
1202 out: true,
1203 },
1204 {
1205 in: "-DMAC RO",
1206 out: false,
1207 },
1208 {
1209 in: "-a -b",
1210 out: false,
1211 },
1212 {
1213 in: "-DMACRO=definition",
1214 out: true,
1215 },
1216 {
1217 in: "-DMACRO=defi nition",
1218 out: true, // TODO(jiyong): this should be false
1219 },
1220 {
1221 in: "-DMACRO(x)=x + 1",
1222 out: true,
1223 },
1224 {
1225 in: "-DMACRO=\"defi nition\"",
1226 out: true,
1227 },
1228}
1229
1230type mockContext struct {
1231 BaseModuleContext
1232 result bool
1233}
1234
1235func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1236 // CheckBadCompilerFlags calls this function when the flag should be rejected
1237 ctx.result = false
1238}
1239
1240func TestCompilerFlags(t *testing.T) {
1241 for _, testCase := range compilerFlagsTestCases {
1242 ctx := &mockContext{result: true}
1243 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1244 if ctx.result != testCase.out {
1245 t.Errorf("incorrect output:")
1246 t.Errorf(" input: %#v", testCase.in)
1247 t.Errorf(" expected: %#v", testCase.out)
1248 t.Errorf(" got: %#v", ctx.result)
1249 }
1250 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001251}