blob: 6c378a5ad995498b4c9c9e93b383697715d3e20d [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 {
Logan Chien6010adb2018-03-29 14:08:15 +0800146 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800147 ctx := createTestContext(t, config, bp)
148
Jeff Gastond3e141d2017-08-08 17:46:01 -0700149 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chiend44aa3b2018-03-12 16:29:17 +0800150 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900151 _, errs = ctx.PrepareBuildActions(config)
Logan Chiend44aa3b2018-03-12 16:29:17 +0800152 android.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 {
Logan Chien6010adb2018-03-29 14:08:15 +0800158 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800159 config := android.TestArchConfig(buildDir, nil)
160 config.ProductVariables.DeviceVndkVersion = StringPtr("current")
161 config.ProductVariables.Platform_vndk_version = StringPtr("VER")
162
163 return testCcWithConfig(t, bp, config)
164}
165
166func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chien6010adb2018-03-29 14:08:15 +0800167 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800168 config := android.TestArchConfig(buildDir, nil)
169 config.ProductVariables.Platform_vndk_version = StringPtr("VER")
170
171 return testCcWithConfig(t, bp, config)
172}
173
174func testCcError(t *testing.T, pattern string, bp string) {
Logan Chien6010adb2018-03-29 14:08:15 +0800175 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800176 config := android.TestArchConfig(buildDir, nil)
177 config.ProductVariables.DeviceVndkVersion = StringPtr("current")
178 config.ProductVariables.Platform_vndk_version = StringPtr("VER")
179
180 ctx := createTestContext(t, config, bp)
181
182 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
183 if len(errs) > 0 {
Logan Chienb1ed4972018-03-12 16:34:26 +0800184 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800185 return
186 }
187
188 _, errs = ctx.PrepareBuildActions(config)
189 if len(errs) > 0 {
Logan Chienb1ed4972018-03-12 16:34:26 +0800190 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800191 return
192 }
193
194 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
195}
196
197const (
198 coreVariant = "android_arm64_armv8-a_core_shared"
199 vendorVariant = "android_arm64_armv8-a_vendor_shared"
200)
201
Jiyong Park6a43f042017-10-12 23:05:00 +0900202func TestVendorSrc(t *testing.T) {
203 ctx := testCc(t, `
204 cc_library {
205 name: "libTest",
206 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800207 no_libgcc: true,
208 nocrt: true,
209 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900210 vendor_available: true,
211 target: {
212 vendor: {
213 srcs: ["bar.c"],
214 },
215 },
216 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900217 `)
218
Logan Chienf3511742017-10-31 18:04:35 +0800219 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900220 var objs []string
221 for _, o := range ld.Inputs {
222 objs = append(objs, o.Base())
223 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800224 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900225 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
226 }
227}
228
Logan Chienf3511742017-10-31 18:04:35 +0800229func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
230 isVndkSp bool, extends string) {
231
Logan Chien6010adb2018-03-29 14:08:15 +0800232 t.Helper()
233
Logan Chienf3511742017-10-31 18:04:35 +0800234 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
235 if !mod.hasVendorVariant() {
236 t.Error("%q must have vendor variant", name)
237 }
238
239 // Check library properties.
240 lib, ok := mod.compiler.(*libraryDecorator)
241 if !ok {
242 t.Errorf("%q must have libraryDecorator", name)
243 } else if lib.baseInstaller.subDir != subDir {
244 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
245 lib.baseInstaller.subDir)
246 }
247
248 // Check VNDK properties.
249 if mod.vndkdep == nil {
250 t.Fatalf("%q must have `vndkdep`", name)
251 }
252 if !mod.isVndk() {
253 t.Errorf("%q isVndk() must equal to true", name)
254 }
255 if mod.isVndkSp() != isVndkSp {
256 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
257 }
258
259 // Check VNDK extension properties.
260 isVndkExt := extends != ""
261 if mod.isVndkExt() != isVndkExt {
262 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
263 }
264
265 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
266 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
267 }
268}
269
270func TestVndk(t *testing.T) {
271 ctx := testCc(t, `
272 cc_library {
273 name: "libvndk",
274 vendor_available: true,
275 vndk: {
276 enabled: true,
277 },
278 nocrt: true,
279 }
280
281 cc_library {
282 name: "libvndk_private",
283 vendor_available: false,
284 vndk: {
285 enabled: true,
286 },
287 nocrt: true,
288 }
289
290 cc_library {
291 name: "libvndk_sp",
292 vendor_available: true,
293 vndk: {
294 enabled: true,
295 support_system_process: true,
296 },
297 nocrt: true,
298 }
299
300 cc_library {
301 name: "libvndk_sp_private",
302 vendor_available: false,
303 vndk: {
304 enabled: true,
305 support_system_process: true,
306 },
307 nocrt: true,
308 }
309 `)
310
311 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
312 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
313 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
314 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
315}
316
Logan Chien6010adb2018-03-29 14:08:15 +0800317func TestVndkDepError(t *testing.T) {
318 // Check whether an error is emitted when a VNDK lib depends on a system lib.
319 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
320 cc_library {
321 name: "libvndk",
322 vendor_available: true,
323 vndk: {
324 enabled: true,
325 },
326 shared_libs: ["libfwk"], // Cause error
327 nocrt: true,
328 }
329
330 cc_library {
331 name: "libfwk",
332 nocrt: true,
333 }
334 `)
335
336 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
337 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
338 cc_library {
339 name: "libvndk",
340 vendor_available: true,
341 vndk: {
342 enabled: true,
343 },
344 shared_libs: ["libvendor"], // Cause error
345 nocrt: true,
346 }
347
348 cc_library {
349 name: "libvendor",
350 vendor: true,
351 nocrt: true,
352 }
353 `)
354
355 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
356 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
357 cc_library {
358 name: "libvndk_sp",
359 vendor_available: true,
360 vndk: {
361 enabled: true,
362 support_system_process: true,
363 },
364 shared_libs: ["libfwk"], // Cause error
365 nocrt: true,
366 }
367
368 cc_library {
369 name: "libfwk",
370 nocrt: true,
371 }
372 `)
373
374 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
375 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
376 cc_library {
377 name: "libvndk_sp",
378 vendor_available: true,
379 vndk: {
380 enabled: true,
381 support_system_process: true,
382 },
383 shared_libs: ["libvendor"], // Cause error
384 nocrt: true,
385 }
386
387 cc_library {
388 name: "libvendor",
389 vendor: true,
390 nocrt: true,
391 }
392 `)
393
394 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
395 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
396 cc_library {
397 name: "libvndk_sp",
398 vendor_available: true,
399 vndk: {
400 enabled: true,
401 support_system_process: true,
402 },
403 shared_libs: ["libvndk"], // Cause error
404 nocrt: true,
405 }
406
407 cc_library {
408 name: "libvndk",
409 vendor_available: true,
410 vndk: {
411 enabled: true,
412 },
413 nocrt: true,
414 }
415 `)
416}
417
Logan Chienf3511742017-10-31 18:04:35 +0800418func TestVndkExt(t *testing.T) {
419 // This test checks the VNDK-Ext properties.
420 ctx := testCc(t, `
421 cc_library {
422 name: "libvndk",
423 vendor_available: true,
424 vndk: {
425 enabled: true,
426 },
427 nocrt: true,
428 }
429
430 cc_library {
431 name: "libvndk_ext",
432 vendor: true,
433 vndk: {
434 enabled: true,
435 extends: "libvndk",
436 },
437 nocrt: true,
438 }
439 `)
440
441 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
442}
443
Logan Chien6010adb2018-03-29 14:08:15 +0800444func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800445 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
446 ctx := testCcNoVndk(t, `
447 cc_library {
448 name: "libvndk",
449 vendor_available: true,
450 vndk: {
451 enabled: true,
452 },
453 nocrt: true,
454 }
455
456 cc_library {
457 name: "libvndk_ext",
458 vendor: true,
459 vndk: {
460 enabled: true,
461 extends: "libvndk",
462 },
463 nocrt: true,
464 }
465 `)
466
467 // Ensures that the core variant of "libvndk_ext" can be found.
468 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
469 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
470 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
471 }
472}
473
474func TestVndkExtError(t *testing.T) {
475 // This test ensures an error is emitted in ill-formed vndk-ext definition.
476 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
477 cc_library {
478 name: "libvndk",
479 vendor_available: true,
480 vndk: {
481 enabled: true,
482 },
483 nocrt: true,
484 }
485
486 cc_library {
487 name: "libvndk_ext",
488 vndk: {
489 enabled: true,
490 extends: "libvndk",
491 },
492 nocrt: true,
493 }
494 `)
495
496 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
497 cc_library {
498 name: "libvndk",
499 vendor_available: true,
500 vndk: {
501 enabled: true,
502 },
503 nocrt: true,
504 }
505
506 cc_library {
507 name: "libvndk_ext",
508 vendor: true,
509 vndk: {
510 enabled: true,
511 },
512 nocrt: true,
513 }
514 `)
515}
516
517func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
518 // This test ensures an error is emitted for inconsistent support_system_process.
519 testCcError(t, "module \".*\" with mismatched support_system_process", `
520 cc_library {
521 name: "libvndk",
522 vendor_available: true,
523 vndk: {
524 enabled: true,
525 },
526 nocrt: true,
527 }
528
529 cc_library {
530 name: "libvndk_sp_ext",
531 vendor: true,
532 vndk: {
533 enabled: true,
534 extends: "libvndk",
535 support_system_process: true,
536 },
537 nocrt: true,
538 }
539 `)
540
541 testCcError(t, "module \".*\" with mismatched support_system_process", `
542 cc_library {
543 name: "libvndk_sp",
544 vendor_available: true,
545 vndk: {
546 enabled: true,
547 support_system_process: true,
548 },
549 nocrt: true,
550 }
551
552 cc_library {
553 name: "libvndk_ext",
554 vendor: true,
555 vndk: {
556 enabled: true,
557 extends: "libvndk_sp",
558 },
559 nocrt: true,
560 }
561 `)
562}
563
564func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chien6010adb2018-03-29 14:08:15 +0800565 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800566 // with `vendor_available: false`.
567 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
568 cc_library {
569 name: "libvndk",
570 vendor_available: false,
571 vndk: {
572 enabled: true,
573 },
574 nocrt: true,
575 }
576
577 cc_library {
578 name: "libvndk_ext",
579 vendor: true,
580 vndk: {
581 enabled: true,
582 extends: "libvndk",
583 },
584 nocrt: true,
585 }
586 `)
587}
588
Logan Chien6010adb2018-03-29 14:08:15 +0800589func TestVendorModuleUseVndkExt(t *testing.T) {
590 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800591 testCc(t, `
592 cc_library {
593 name: "libvndk",
594 vendor_available: true,
595 vndk: {
596 enabled: true,
597 },
598 nocrt: true,
599 }
600
601 cc_library {
602 name: "libvndk_ext",
603 vendor: true,
604 vndk: {
605 enabled: true,
606 extends: "libvndk",
607 },
608 nocrt: true,
609 }
610
611 cc_library {
612
613 name: "libvndk_sp",
614 vendor_available: true,
615 vndk: {
616 enabled: true,
617 support_system_process: true,
618 },
619 nocrt: true,
620 }
621
622 cc_library {
623 name: "libvndk_sp_ext",
624 vendor: true,
625 vndk: {
626 enabled: true,
627 extends: "libvndk_sp",
628 support_system_process: true,
629 },
630 nocrt: true,
631 }
632
633 cc_library {
634 name: "libvendor",
635 vendor: true,
636 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
637 nocrt: true,
638 }
639 `)
640}
641
Logan Chien6010adb2018-03-29 14:08:15 +0800642func TestVndkExtUseVendorLib(t *testing.T) {
643 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800644 testCc(t, `
645 cc_library {
646 name: "libvndk",
647 vendor_available: true,
648 vndk: {
649 enabled: true,
650 },
651 nocrt: true,
652 }
653
654 cc_library {
655 name: "libvndk_ext",
656 vendor: true,
657 vndk: {
658 enabled: true,
659 extends: "libvndk",
660 },
661 shared_libs: ["libvendor"],
662 nocrt: true,
663 }
664
665 cc_library {
666 name: "libvendor",
667 vendor: true,
668 nocrt: true,
669 }
670 `)
Logan Chienf3511742017-10-31 18:04:35 +0800671
Logan Chien6010adb2018-03-29 14:08:15 +0800672 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
673 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800674 cc_library {
675 name: "libvndk_sp",
676 vendor_available: true,
677 vndk: {
678 enabled: true,
679 support_system_process: true,
680 },
681 nocrt: true,
682 }
683
684 cc_library {
685 name: "libvndk_sp_ext",
686 vendor: true,
687 vndk: {
688 enabled: true,
689 extends: "libvndk_sp",
690 support_system_process: true,
691 },
692 shared_libs: ["libvendor"], // Cause an error
693 nocrt: true,
694 }
695
696 cc_library {
697 name: "libvendor",
698 vendor: true,
699 nocrt: true,
700 }
701 `)
702}
703
Logan Chien6010adb2018-03-29 14:08:15 +0800704func TestVndkSpExtUseVndkError(t *testing.T) {
705 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
706 // library.
707 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
708 cc_library {
709 name: "libvndk",
710 vendor_available: true,
711 vndk: {
712 enabled: true,
713 },
714 nocrt: true,
715 }
716
717 cc_library {
718 name: "libvndk_sp",
719 vendor_available: true,
720 vndk: {
721 enabled: true,
722 support_system_process: true,
723 },
724 nocrt: true,
725 }
726
727 cc_library {
728 name: "libvndk_sp_ext",
729 vendor: true,
730 vndk: {
731 enabled: true,
732 extends: "libvndk_sp",
733 support_system_process: true,
734 },
735 shared_libs: ["libvndk"], // Cause an error
736 nocrt: true,
737 }
738 `)
739
740 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
741 // library.
742 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
743 cc_library {
744 name: "libvndk",
745 vendor_available: true,
746 vndk: {
747 enabled: true,
748 },
749 nocrt: true,
750 }
751
752 cc_library {
753 name: "libvndk_ext",
754 vendor: true,
755 vndk: {
756 enabled: true,
757 extends: "libvndk",
758 },
759 nocrt: true,
760 }
761
762 cc_library {
763 name: "libvndk_sp",
764 vendor_available: true,
765 vndk: {
766 enabled: true,
767 support_system_process: true,
768 },
769 nocrt: true,
770 }
771
772 cc_library {
773 name: "libvndk_sp_ext",
774 vendor: true,
775 vndk: {
776 enabled: true,
777 extends: "libvndk_sp",
778 support_system_process: true,
779 },
780 shared_libs: ["libvndk_ext"], // Cause an error
781 nocrt: true,
782 }
783 `)
784}
785
786func TestVndkUseVndkExtError(t *testing.T) {
787 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
788 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800789 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
790 cc_library {
791 name: "libvndk",
792 vendor_available: true,
793 vndk: {
794 enabled: true,
795 },
796 nocrt: true,
797 }
798
799 cc_library {
800 name: "libvndk_ext",
801 vendor: true,
802 vndk: {
803 enabled: true,
804 extends: "libvndk",
805 },
806 nocrt: true,
807 }
808
809 cc_library {
810 name: "libvndk2",
811 vendor_available: true,
812 vndk: {
813 enabled: true,
814 },
815 shared_libs: ["libvndk_ext"],
816 nocrt: true,
817 }
818 `)
819
820 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
821 // but target.vendor.shared_libs has not been supported yet.
822 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
823 cc_library {
824 name: "libvndk",
825 vendor_available: true,
826 vndk: {
827 enabled: true,
828 },
829 nocrt: true,
830 }
831
832 cc_library {
833 name: "libvndk_ext",
834 vendor: true,
835 vndk: {
836 enabled: true,
837 extends: "libvndk",
838 },
839 nocrt: true,
840 }
841
842 cc_library {
843 name: "libvndk2",
844 vendor_available: true,
845 vndk: {
846 enabled: true,
847 },
848 target: {
849 vendor: {
850 shared_libs: ["libvndk_ext"],
851 },
852 },
853 nocrt: true,
854 }
855 `)
856
857 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
858 cc_library {
859 name: "libvndk_sp",
860 vendor_available: true,
861 vndk: {
862 enabled: true,
863 support_system_process: true,
864 },
865 nocrt: true,
866 }
867
868 cc_library {
869 name: "libvndk_sp_ext",
870 vendor: true,
871 vndk: {
872 enabled: true,
873 extends: "libvndk_sp",
874 support_system_process: true,
875 },
876 nocrt: true,
877 }
878
879 cc_library {
880 name: "libvndk_sp_2",
881 vendor_available: true,
882 vndk: {
883 enabled: true,
884 support_system_process: true,
885 },
886 shared_libs: ["libvndk_sp_ext"],
887 nocrt: true,
888 }
889 `)
890
891 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
892 // but target.vendor.shared_libs has not been supported yet.
893 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
894 cc_library {
895 name: "libvndk_sp",
896 vendor_available: true,
897 vndk: {
898 enabled: true,
899 },
900 nocrt: true,
901 }
902
903 cc_library {
904 name: "libvndk_sp_ext",
905 vendor: true,
906 vndk: {
907 enabled: true,
908 extends: "libvndk_sp",
909 },
910 nocrt: true,
911 }
912
913 cc_library {
914 name: "libvndk_sp2",
915 vendor_available: true,
916 vndk: {
917 enabled: true,
918 },
919 target: {
920 vendor: {
921 shared_libs: ["libvndk_sp_ext"],
922 },
923 },
924 nocrt: true,
925 }
926 `)
927}
928
Colin Cross0af4b842015-04-30 16:36:18 -0700929var (
930 str11 = "01234567891"
931 str10 = str11[:10]
932 str9 = str11[:9]
933 str5 = str11[:5]
934 str4 = str11[:4]
935)
936
937var splitListForSizeTestCases = []struct {
938 in []string
939 out [][]string
940 size int
941}{
942 {
943 in: []string{str10},
944 out: [][]string{{str10}},
945 size: 10,
946 },
947 {
948 in: []string{str9},
949 out: [][]string{{str9}},
950 size: 10,
951 },
952 {
953 in: []string{str5},
954 out: [][]string{{str5}},
955 size: 10,
956 },
957 {
958 in: []string{str11},
959 out: nil,
960 size: 10,
961 },
962 {
963 in: []string{str10, str10},
964 out: [][]string{{str10}, {str10}},
965 size: 10,
966 },
967 {
968 in: []string{str9, str10},
969 out: [][]string{{str9}, {str10}},
970 size: 10,
971 },
972 {
973 in: []string{str10, str9},
974 out: [][]string{{str10}, {str9}},
975 size: 10,
976 },
977 {
978 in: []string{str5, str4},
979 out: [][]string{{str5, str4}},
980 size: 10,
981 },
982 {
983 in: []string{str5, str4, str5},
984 out: [][]string{{str5, str4}, {str5}},
985 size: 10,
986 },
987 {
988 in: []string{str5, str4, str5, str4},
989 out: [][]string{{str5, str4}, {str5, str4}},
990 size: 10,
991 },
992 {
993 in: []string{str5, str4, str5, str5},
994 out: [][]string{{str5, str4}, {str5}, {str5}},
995 size: 10,
996 },
997 {
998 in: []string{str5, str5, str5, str4},
999 out: [][]string{{str5}, {str5}, {str5, str4}},
1000 size: 10,
1001 },
1002 {
1003 in: []string{str9, str11},
1004 out: nil,
1005 size: 10,
1006 },
1007 {
1008 in: []string{str11, str9},
1009 out: nil,
1010 size: 10,
1011 },
1012}
1013
1014func TestSplitListForSize(t *testing.T) {
1015 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -07001016 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
1017
1018 var outStrings [][]string
1019
1020 if len(out) > 0 {
1021 outStrings = make([][]string, len(out))
1022 for i, o := range out {
1023 outStrings[i] = o.Strings()
1024 }
1025 }
1026
1027 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001028 t.Errorf("incorrect output:")
1029 t.Errorf(" input: %#v", testCase.in)
1030 t.Errorf(" size: %d", testCase.size)
1031 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001032 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001033 }
1034 }
1035}
Jeff Gaston294356f2017-09-27 17:05:30 -07001036
1037var staticLinkDepOrderTestCases = []struct {
1038 // This is a string representation of a map[moduleName][]moduleDependency .
1039 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001040 inStatic string
1041
1042 // This is a string representation of a map[moduleName][]moduleDependency .
1043 // It models the dependencies declared in an Android.bp file.
1044 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001045
1046 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1047 // The keys of allOrdered specify which modules we would like to check.
1048 // The values of allOrdered specify the expected result (of the transitive closure of all
1049 // dependencies) for each module to test
1050 allOrdered string
1051
1052 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1053 // The keys of outOrdered specify which modules we would like to check.
1054 // The values of outOrdered specify the expected result (of the ordered linker command line)
1055 // for each module to test.
1056 outOrdered string
1057}{
1058 // Simple tests
1059 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001060 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001061 outOrdered: "",
1062 },
1063 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001064 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001065 outOrdered: "a:",
1066 },
1067 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001068 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001069 outOrdered: "a:b; b:",
1070 },
1071 // Tests of reordering
1072 {
1073 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001074 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001075 outOrdered: "a:b,c,d; b:d; c:d; d:",
1076 },
1077 {
1078 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001079 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001080 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1081 },
1082 {
1083 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001084 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001085 outOrdered: "a:d,b,e,c; d:b; e:c",
1086 },
1087 {
1088 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001089 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001090 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1091 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1092 },
1093 {
1094 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001095 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 -07001096 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1097 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1098 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001099 // shared dependencies
1100 {
1101 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1102 // So, we don't actually have to check that a shared dependency of c will change the order
1103 // of a library that depends statically on b and on c. We only need to check that if c has
1104 // a shared dependency on b, that that shows up in allOrdered.
1105 inShared: "c:b",
1106 allOrdered: "c:b",
1107 outOrdered: "c:",
1108 },
1109 {
1110 // This test doesn't actually include any shared dependencies but it's a reminder of what
1111 // the second phase of the above test would look like
1112 inStatic: "a:b,c; c:b",
1113 allOrdered: "a:c,b; c:b",
1114 outOrdered: "a:c,b; c:b",
1115 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001116 // tiebreakers for when two modules specifying different orderings and there is no dependency
1117 // to dictate an order
1118 {
1119 // 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 -08001120 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001121 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1122 },
1123 {
1124 // 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 -08001125 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 -07001126 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1127 },
1128 // Tests involving duplicate dependencies
1129 {
1130 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001131 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001132 outOrdered: "a:c,b",
1133 },
1134 {
1135 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001136 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001137 outOrdered: "a:d,c,b",
1138 },
1139 // Tests to confirm the nonexistence of infinite loops.
1140 // These cases should never happen, so as long as the test terminates and the
1141 // result is deterministic then that should be fine.
1142 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001143 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001144 outOrdered: "a:a",
1145 },
1146 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001147 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001148 allOrdered: "a:b,c; b:c,a; c:a,b",
1149 outOrdered: "a:b; b:c; c:a",
1150 },
1151 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001152 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001153 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1154 outOrdered: "a:c,b; b:a,c; c:b,a",
1155 },
1156}
1157
1158// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1159func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1160 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1161 strippedText := strings.Replace(text, " ", "", -1)
1162 if len(strippedText) < 1 {
1163 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1164 }
1165 allDeps = make(map[android.Path][]android.Path, 0)
1166
1167 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1168 moduleTexts := strings.Split(strippedText, ";")
1169
1170 outputForModuleName := func(moduleName string) android.Path {
1171 return android.PathForTesting(moduleName)
1172 }
1173
1174 for _, moduleText := range moduleTexts {
1175 // convert from "a:b,c" to ["a", "b,c"]
1176 components := strings.Split(moduleText, ":")
1177 if len(components) != 2 {
1178 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1179 }
1180 moduleName := components[0]
1181 moduleOutput := outputForModuleName(moduleName)
1182 modulesInOrder = append(modulesInOrder, moduleOutput)
1183
1184 depString := components[1]
1185 // convert from "b,c" to ["b", "c"]
1186 depNames := strings.Split(depString, ",")
1187 if len(depString) < 1 {
1188 depNames = []string{}
1189 }
1190 var deps []android.Path
1191 for _, depName := range depNames {
1192 deps = append(deps, outputForModuleName(depName))
1193 }
1194 allDeps[moduleOutput] = deps
1195 }
1196 return modulesInOrder, allDeps
1197}
1198
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001199func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001200 for _, testCase := range staticLinkDepOrderTestCases {
1201 errs := []string{}
1202
1203 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001204 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001205 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1206 if testCase.allOrdered == "" {
1207 // allow the test case to skip specifying allOrdered
1208 testCase.allOrdered = testCase.outOrdered
1209 }
1210 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001211 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001212
1213 // For each module whose post-reordered dependencies were specified, validate that
1214 // reordering the inputs produces the expected outputs.
1215 for _, moduleName := range expectedModuleNames {
1216 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001217 givenSharedDeps := givenAllSharedDeps[moduleName]
1218 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001219
1220 correctAllOrdered := expectedAllDeps[moduleName]
1221 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1222 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001223 "\nin static:%q"+
1224 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001225 "\nmodule: %v"+
1226 "\nexpected: %s"+
1227 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001228 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001229 }
1230
1231 correctOutputDeps := expectedTransitiveDeps[moduleName]
1232 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1233 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001234 "\nin static:%q"+
1235 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001236 "\nmodule: %v"+
1237 "\nexpected: %s"+
1238 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001239 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001240 }
1241 }
1242
1243 if len(errs) > 0 {
1244 sort.Strings(errs)
1245 for _, err := range errs {
1246 t.Error(err)
1247 }
1248 }
1249 }
1250}
Logan Chienf3511742017-10-31 18:04:35 +08001251
Jeff Gaston294356f2017-09-27 17:05:30 -07001252func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1253 for _, moduleName := range moduleNames {
1254 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1255 output := module.outputFile.Path()
1256 paths = append(paths, output)
1257 }
1258 return paths
1259}
1260
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001261func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001262 ctx := testCc(t, `
1263 cc_library {
1264 name: "a",
1265 static_libs: ["b", "c", "d"],
1266 }
1267 cc_library {
1268 name: "b",
1269 }
1270 cc_library {
1271 name: "c",
1272 static_libs: ["b"],
1273 }
1274 cc_library {
1275 name: "d",
1276 }
1277
1278 `)
1279
1280 variant := "android_arm64_armv8-a_core_static"
1281 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001282 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001283 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1284
1285 if !reflect.DeepEqual(actual, expected) {
1286 t.Errorf("staticDeps orderings were not propagated correctly"+
1287 "\nactual: %v"+
1288 "\nexpected: %v",
1289 actual,
1290 expected,
1291 )
1292 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001293}
Jeff Gaston294356f2017-09-27 17:05:30 -07001294
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001295func TestStaticLibDepReorderingWithShared(t *testing.T) {
1296 ctx := testCc(t, `
1297 cc_library {
1298 name: "a",
1299 static_libs: ["b", "c"],
1300 }
1301 cc_library {
1302 name: "b",
1303 }
1304 cc_library {
1305 name: "c",
1306 shared_libs: ["b"],
1307 }
1308
1309 `)
1310
1311 variant := "android_arm64_armv8-a_core_static"
1312 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1313 actual := moduleA.depsInLinkOrder
1314 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1315
1316 if !reflect.DeepEqual(actual, expected) {
1317 t.Errorf("staticDeps orderings did not account for shared libs"+
1318 "\nactual: %v"+
1319 "\nexpected: %v",
1320 actual,
1321 expected,
1322 )
1323 }
1324}
1325
Jiyong Parka46a4d52017-12-14 19:54:34 +09001326func TestLlndkHeaders(t *testing.T) {
1327 ctx := testCc(t, `
1328 llndk_headers {
1329 name: "libllndk_headers",
1330 export_include_dirs: ["my_include"],
1331 }
1332 llndk_library {
1333 name: "libllndk",
1334 export_llndk_headers: ["libllndk_headers"],
1335 }
1336 cc_library {
1337 name: "libvendor",
1338 shared_libs: ["libllndk"],
1339 vendor: true,
1340 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001341 no_libgcc: true,
1342 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001343 }
1344 `)
1345
1346 // _static variant is used since _shared reuses *.o from the static variant
1347 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1348 cflags := cc.Args["cFlags"]
1349 if !strings.Contains(cflags, "-Imy_include") {
1350 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1351 }
1352}
1353
Jiyong Parkd08b6972017-09-26 10:50:54 +09001354var compilerFlagsTestCases = []struct {
1355 in string
1356 out bool
1357}{
1358 {
1359 in: "a",
1360 out: false,
1361 },
1362 {
1363 in: "-a",
1364 out: true,
1365 },
1366 {
1367 in: "-Ipath/to/something",
1368 out: false,
1369 },
1370 {
1371 in: "-isystempath/to/something",
1372 out: false,
1373 },
1374 {
1375 in: "--coverage",
1376 out: false,
1377 },
1378 {
1379 in: "-include a/b",
1380 out: true,
1381 },
1382 {
1383 in: "-include a/b c/d",
1384 out: false,
1385 },
1386 {
1387 in: "-DMACRO",
1388 out: true,
1389 },
1390 {
1391 in: "-DMAC RO",
1392 out: false,
1393 },
1394 {
1395 in: "-a -b",
1396 out: false,
1397 },
1398 {
1399 in: "-DMACRO=definition",
1400 out: true,
1401 },
1402 {
1403 in: "-DMACRO=defi nition",
1404 out: true, // TODO(jiyong): this should be false
1405 },
1406 {
1407 in: "-DMACRO(x)=x + 1",
1408 out: true,
1409 },
1410 {
1411 in: "-DMACRO=\"defi nition\"",
1412 out: true,
1413 },
1414}
1415
1416type mockContext struct {
1417 BaseModuleContext
1418 result bool
1419}
1420
1421func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1422 // CheckBadCompilerFlags calls this function when the flag should be rejected
1423 ctx.result = false
1424}
1425
1426func TestCompilerFlags(t *testing.T) {
1427 for _, testCase := range compilerFlagsTestCases {
1428 ctx := &mockContext{result: true}
1429 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1430 if ctx.result != testCase.out {
1431 t.Errorf("incorrect output:")
1432 t.Errorf(" input: %#v", testCase.in)
1433 t.Errorf(" expected: %#v", testCase.out)
1434 t.Errorf(" got: %#v", ctx.result)
1435 }
1436 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001437}