blob: 10c1aba7f74e8303381489c9d16bc0c5e431219c [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 Park374510b2018-03-19 18:23:01 +090059 ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory))
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))
Jiyong Park374510b2018-03-19 18:23:01 +090063 ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
Jeff Gaston294356f2017-09-27 17:05:30 -070064 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(objectFactory))
Colin Crossf18e1102017-11-16 14:33:08 -080065 ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(genrule.FileGroupFactory))
Jiyong Park6a43f042017-10-12 23:05:00 +090066 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
67 ctx.BottomUp("image", vendorMutator).Parallel()
68 ctx.BottomUp("link", linkageMutator).Parallel()
69 ctx.BottomUp("vndk", vndkMutator).Parallel()
Jiyong Park374510b2018-03-19 18:23:01 +090070 ctx.BottomUp("begin", beginMutator).Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +090071 })
72 ctx.Register()
73
Jeff Gaston294356f2017-09-27 17:05:30 -070074 // add some modules that are required by the compiler and/or linker
75 bp = bp + `
76 toolchain_library {
77 name: "libatomic",
78 vendor_available: true,
79 }
80
81 toolchain_library {
82 name: "libcompiler_rt-extras",
83 vendor_available: true,
84 }
85
86 toolchain_library {
87 name: "libgcc",
88 vendor_available: true,
89 }
90
91 cc_library {
92 name: "libc",
Logan Chienf3511742017-10-31 18:04:35 +080093 no_libgcc: true,
94 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -070095 system_shared_libs: [],
96 }
97 llndk_library {
98 name: "libc",
99 symbol_file: "",
100 }
101 cc_library {
102 name: "libm",
Logan Chienf3511742017-10-31 18:04:35 +0800103 no_libgcc: true,
104 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700105 system_shared_libs: [],
106 }
107 llndk_library {
108 name: "libm",
109 symbol_file: "",
110 }
111 cc_library {
112 name: "libdl",
Logan Chienf3511742017-10-31 18:04:35 +0800113 no_libgcc: true,
114 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700115 system_shared_libs: [],
116 }
117 llndk_library {
118 name: "libdl",
119 symbol_file: "",
120 }
Jiyong Park374510b2018-03-19 18:23:01 +0900121 cc_library {
122 name: "libc++_static",
123 no_libgcc: true,
124 nocrt: true,
125 system_shared_libs: [],
126 stl: "none",
127 vendor_available: true,
128 }
129 cc_library {
130 name: "libc++",
131 no_libgcc: true,
132 nocrt: true,
133 system_shared_libs: [],
134 stl: "none",
135 vendor_available: true,
136 vndk: {
137 enabled: true,
138 support_system_process: true,
139 },
140 }
141 cc_library {
142 name: "libunwind_llvm",
143 no_libgcc: true,
144 nocrt: true,
145 system_shared_libs: [],
146 stl: "none",
147 vendor_available: true,
148 }
Jeff Gaston294356f2017-09-27 17:05:30 -0700149
150 cc_object {
151 name: "crtbegin_so",
152 }
153
154 cc_object {
155 name: "crtend_so",
156 }
157
Colin Crossad59e752017-11-16 14:29:11 -0800158 cc_library {
159 name: "libprotobuf-cpp-lite",
160 }
161
Jeff Gaston294356f2017-09-27 17:05:30 -0700162`
163
Jiyong Park6a43f042017-10-12 23:05:00 +0900164 ctx.MockFileSystem(map[string][]byte{
165 "Android.bp": []byte(bp),
166 "foo.c": nil,
167 "bar.c": nil,
Colin Crossad59e752017-11-16 14:29:11 -0800168 "a.proto": nil,
Colin Crossf18e1102017-11-16 14:33:08 -0800169 "b.aidl": nil,
Jiyong Parka46a4d52017-12-14 19:54:34 +0900170 "my_include": nil,
Jiyong Park6a43f042017-10-12 23:05:00 +0900171 })
172
Logan Chienf3511742017-10-31 18:04:35 +0800173 return ctx
174}
175
176func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800177 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800178 ctx := createTestContext(t, config, bp)
179
Jeff Gastond3e141d2017-08-08 17:46:01 -0700180 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +0800181 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900182 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800183 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900184
185 return ctx
186}
187
Logan Chienf3511742017-10-31 18:04:35 +0800188func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800189 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800190 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700191 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
192 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800193
194 return testCcWithConfig(t, bp, config)
195}
196
197func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800198 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800199 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700200 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800201
202 return testCcWithConfig(t, bp, config)
203}
204
205func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800206 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800207 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700208 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
209 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800210
211 ctx := createTestContext(t, config, bp)
212
213 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
214 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800215 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800216 return
217 }
218
219 _, errs = ctx.PrepareBuildActions(config)
220 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800221 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800222 return
223 }
224
225 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
226}
227
228const (
229 coreVariant = "android_arm64_armv8-a_core_shared"
230 vendorVariant = "android_arm64_armv8-a_vendor_shared"
231)
232
Jiyong Park6a43f042017-10-12 23:05:00 +0900233func TestVendorSrc(t *testing.T) {
234 ctx := testCc(t, `
235 cc_library {
236 name: "libTest",
237 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800238 no_libgcc: true,
239 nocrt: true,
240 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900241 vendor_available: true,
242 target: {
243 vendor: {
244 srcs: ["bar.c"],
245 },
246 },
247 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900248 `)
249
Logan Chienf3511742017-10-31 18:04:35 +0800250 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900251 var objs []string
252 for _, o := range ld.Inputs {
253 objs = append(objs, o.Base())
254 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800255 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900256 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
257 }
258}
259
Logan Chienf3511742017-10-31 18:04:35 +0800260func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
261 isVndkSp bool, extends string) {
262
Logan Chiend3c59a22018-03-29 14:08:15 +0800263 t.Helper()
264
Logan Chienf3511742017-10-31 18:04:35 +0800265 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
266 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700267 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800268 }
269
270 // Check library properties.
271 lib, ok := mod.compiler.(*libraryDecorator)
272 if !ok {
273 t.Errorf("%q must have libraryDecorator", name)
274 } else if lib.baseInstaller.subDir != subDir {
275 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
276 lib.baseInstaller.subDir)
277 }
278
279 // Check VNDK properties.
280 if mod.vndkdep == nil {
281 t.Fatalf("%q must have `vndkdep`", name)
282 }
283 if !mod.isVndk() {
284 t.Errorf("%q isVndk() must equal to true", name)
285 }
286 if mod.isVndkSp() != isVndkSp {
287 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
288 }
289
290 // Check VNDK extension properties.
291 isVndkExt := extends != ""
292 if mod.isVndkExt() != isVndkExt {
293 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
294 }
295
296 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
297 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
298 }
299}
300
301func TestVndk(t *testing.T) {
302 ctx := testCc(t, `
303 cc_library {
304 name: "libvndk",
305 vendor_available: true,
306 vndk: {
307 enabled: true,
308 },
309 nocrt: true,
310 }
311
312 cc_library {
313 name: "libvndk_private",
314 vendor_available: false,
315 vndk: {
316 enabled: true,
317 },
318 nocrt: true,
319 }
320
321 cc_library {
322 name: "libvndk_sp",
323 vendor_available: true,
324 vndk: {
325 enabled: true,
326 support_system_process: true,
327 },
328 nocrt: true,
329 }
330
331 cc_library {
332 name: "libvndk_sp_private",
333 vendor_available: false,
334 vndk: {
335 enabled: true,
336 support_system_process: true,
337 },
338 nocrt: true,
339 }
340 `)
341
342 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
343 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
344 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
345 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
346}
347
Logan Chiend3c59a22018-03-29 14:08:15 +0800348func TestVndkDepError(t *testing.T) {
349 // Check whether an error is emitted when a VNDK lib depends on a system lib.
350 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
351 cc_library {
352 name: "libvndk",
353 vendor_available: true,
354 vndk: {
355 enabled: true,
356 },
357 shared_libs: ["libfwk"], // Cause error
358 nocrt: true,
359 }
360
361 cc_library {
362 name: "libfwk",
363 nocrt: true,
364 }
365 `)
366
367 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
368 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
369 cc_library {
370 name: "libvndk",
371 vendor_available: true,
372 vndk: {
373 enabled: true,
374 },
375 shared_libs: ["libvendor"], // Cause error
376 nocrt: true,
377 }
378
379 cc_library {
380 name: "libvendor",
381 vendor: true,
382 nocrt: true,
383 }
384 `)
385
386 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
387 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
388 cc_library {
389 name: "libvndk_sp",
390 vendor_available: true,
391 vndk: {
392 enabled: true,
393 support_system_process: true,
394 },
395 shared_libs: ["libfwk"], // Cause error
396 nocrt: true,
397 }
398
399 cc_library {
400 name: "libfwk",
401 nocrt: true,
402 }
403 `)
404
405 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
406 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
407 cc_library {
408 name: "libvndk_sp",
409 vendor_available: true,
410 vndk: {
411 enabled: true,
412 support_system_process: true,
413 },
414 shared_libs: ["libvendor"], // Cause error
415 nocrt: true,
416 }
417
418 cc_library {
419 name: "libvendor",
420 vendor: true,
421 nocrt: true,
422 }
423 `)
424
425 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
426 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
427 cc_library {
428 name: "libvndk_sp",
429 vendor_available: true,
430 vndk: {
431 enabled: true,
432 support_system_process: true,
433 },
434 shared_libs: ["libvndk"], // Cause error
435 nocrt: true,
436 }
437
438 cc_library {
439 name: "libvndk",
440 vendor_available: true,
441 vndk: {
442 enabled: true,
443 },
444 nocrt: true,
445 }
446 `)
447}
448
Logan Chienf3511742017-10-31 18:04:35 +0800449func TestVndkExt(t *testing.T) {
450 // This test checks the VNDK-Ext properties.
451 ctx := testCc(t, `
452 cc_library {
453 name: "libvndk",
454 vendor_available: true,
455 vndk: {
456 enabled: true,
457 },
458 nocrt: true,
459 }
460
461 cc_library {
462 name: "libvndk_ext",
463 vendor: true,
464 vndk: {
465 enabled: true,
466 extends: "libvndk",
467 },
468 nocrt: true,
469 }
470 `)
471
472 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
473}
474
Logan Chiend3c59a22018-03-29 14:08:15 +0800475func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800476 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
477 ctx := testCcNoVndk(t, `
478 cc_library {
479 name: "libvndk",
480 vendor_available: true,
481 vndk: {
482 enabled: true,
483 },
484 nocrt: true,
485 }
486
487 cc_library {
488 name: "libvndk_ext",
489 vendor: true,
490 vndk: {
491 enabled: true,
492 extends: "libvndk",
493 },
494 nocrt: true,
495 }
496 `)
497
498 // Ensures that the core variant of "libvndk_ext" can be found.
499 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
500 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
501 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
502 }
503}
504
505func TestVndkExtError(t *testing.T) {
506 // This test ensures an error is emitted in ill-formed vndk-ext definition.
507 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
508 cc_library {
509 name: "libvndk",
510 vendor_available: true,
511 vndk: {
512 enabled: true,
513 },
514 nocrt: true,
515 }
516
517 cc_library {
518 name: "libvndk_ext",
519 vndk: {
520 enabled: true,
521 extends: "libvndk",
522 },
523 nocrt: true,
524 }
525 `)
526
527 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
528 cc_library {
529 name: "libvndk",
530 vendor_available: true,
531 vndk: {
532 enabled: true,
533 },
534 nocrt: true,
535 }
536
537 cc_library {
538 name: "libvndk_ext",
539 vendor: true,
540 vndk: {
541 enabled: true,
542 },
543 nocrt: true,
544 }
545 `)
546}
547
548func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
549 // This test ensures an error is emitted for inconsistent support_system_process.
550 testCcError(t, "module \".*\" with mismatched support_system_process", `
551 cc_library {
552 name: "libvndk",
553 vendor_available: true,
554 vndk: {
555 enabled: true,
556 },
557 nocrt: true,
558 }
559
560 cc_library {
561 name: "libvndk_sp_ext",
562 vendor: true,
563 vndk: {
564 enabled: true,
565 extends: "libvndk",
566 support_system_process: true,
567 },
568 nocrt: true,
569 }
570 `)
571
572 testCcError(t, "module \".*\" with mismatched support_system_process", `
573 cc_library {
574 name: "libvndk_sp",
575 vendor_available: true,
576 vndk: {
577 enabled: true,
578 support_system_process: true,
579 },
580 nocrt: true,
581 }
582
583 cc_library {
584 name: "libvndk_ext",
585 vendor: true,
586 vndk: {
587 enabled: true,
588 extends: "libvndk_sp",
589 },
590 nocrt: true,
591 }
592 `)
593}
594
595func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800596 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800597 // with `vendor_available: false`.
598 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
599 cc_library {
600 name: "libvndk",
601 vendor_available: false,
602 vndk: {
603 enabled: true,
604 },
605 nocrt: true,
606 }
607
608 cc_library {
609 name: "libvndk_ext",
610 vendor: true,
611 vndk: {
612 enabled: true,
613 extends: "libvndk",
614 },
615 nocrt: true,
616 }
617 `)
618}
619
Logan Chiend3c59a22018-03-29 14:08:15 +0800620func TestVendorModuleUseVndkExt(t *testing.T) {
621 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800622 testCc(t, `
623 cc_library {
624 name: "libvndk",
625 vendor_available: true,
626 vndk: {
627 enabled: true,
628 },
629 nocrt: true,
630 }
631
632 cc_library {
633 name: "libvndk_ext",
634 vendor: true,
635 vndk: {
636 enabled: true,
637 extends: "libvndk",
638 },
639 nocrt: true,
640 }
641
642 cc_library {
643
644 name: "libvndk_sp",
645 vendor_available: true,
646 vndk: {
647 enabled: true,
648 support_system_process: true,
649 },
650 nocrt: true,
651 }
652
653 cc_library {
654 name: "libvndk_sp_ext",
655 vendor: true,
656 vndk: {
657 enabled: true,
658 extends: "libvndk_sp",
659 support_system_process: true,
660 },
661 nocrt: true,
662 }
663
664 cc_library {
665 name: "libvendor",
666 vendor: true,
667 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
668 nocrt: true,
669 }
670 `)
671}
672
Logan Chiend3c59a22018-03-29 14:08:15 +0800673func TestVndkExtUseVendorLib(t *testing.T) {
674 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800675 testCc(t, `
676 cc_library {
677 name: "libvndk",
678 vendor_available: true,
679 vndk: {
680 enabled: true,
681 },
682 nocrt: true,
683 }
684
685 cc_library {
686 name: "libvndk_ext",
687 vendor: true,
688 vndk: {
689 enabled: true,
690 extends: "libvndk",
691 },
692 shared_libs: ["libvendor"],
693 nocrt: true,
694 }
695
696 cc_library {
697 name: "libvendor",
698 vendor: true,
699 nocrt: true,
700 }
701 `)
Logan Chienf3511742017-10-31 18:04:35 +0800702
Logan Chiend3c59a22018-03-29 14:08:15 +0800703 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
704 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800705 cc_library {
706 name: "libvndk_sp",
707 vendor_available: true,
708 vndk: {
709 enabled: true,
710 support_system_process: true,
711 },
712 nocrt: true,
713 }
714
715 cc_library {
716 name: "libvndk_sp_ext",
717 vendor: true,
718 vndk: {
719 enabled: true,
720 extends: "libvndk_sp",
721 support_system_process: true,
722 },
723 shared_libs: ["libvendor"], // Cause an error
724 nocrt: true,
725 }
726
727 cc_library {
728 name: "libvendor",
729 vendor: true,
730 nocrt: true,
731 }
732 `)
733}
734
Logan Chiend3c59a22018-03-29 14:08:15 +0800735func TestVndkSpExtUseVndkError(t *testing.T) {
736 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
737 // library.
738 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
739 cc_library {
740 name: "libvndk",
741 vendor_available: true,
742 vndk: {
743 enabled: true,
744 },
745 nocrt: true,
746 }
747
748 cc_library {
749 name: "libvndk_sp",
750 vendor_available: true,
751 vndk: {
752 enabled: true,
753 support_system_process: true,
754 },
755 nocrt: true,
756 }
757
758 cc_library {
759 name: "libvndk_sp_ext",
760 vendor: true,
761 vndk: {
762 enabled: true,
763 extends: "libvndk_sp",
764 support_system_process: true,
765 },
766 shared_libs: ["libvndk"], // Cause an error
767 nocrt: true,
768 }
769 `)
770
771 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
772 // library.
773 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
774 cc_library {
775 name: "libvndk",
776 vendor_available: true,
777 vndk: {
778 enabled: true,
779 },
780 nocrt: true,
781 }
782
783 cc_library {
784 name: "libvndk_ext",
785 vendor: true,
786 vndk: {
787 enabled: true,
788 extends: "libvndk",
789 },
790 nocrt: true,
791 }
792
793 cc_library {
794 name: "libvndk_sp",
795 vendor_available: true,
796 vndk: {
797 enabled: true,
798 support_system_process: true,
799 },
800 nocrt: true,
801 }
802
803 cc_library {
804 name: "libvndk_sp_ext",
805 vendor: true,
806 vndk: {
807 enabled: true,
808 extends: "libvndk_sp",
809 support_system_process: true,
810 },
811 shared_libs: ["libvndk_ext"], // Cause an error
812 nocrt: true,
813 }
814 `)
815}
816
817func TestVndkUseVndkExtError(t *testing.T) {
818 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
819 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800820 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
821 cc_library {
822 name: "libvndk",
823 vendor_available: true,
824 vndk: {
825 enabled: true,
826 },
827 nocrt: true,
828 }
829
830 cc_library {
831 name: "libvndk_ext",
832 vendor: true,
833 vndk: {
834 enabled: true,
835 extends: "libvndk",
836 },
837 nocrt: true,
838 }
839
840 cc_library {
841 name: "libvndk2",
842 vendor_available: true,
843 vndk: {
844 enabled: true,
845 },
846 shared_libs: ["libvndk_ext"],
847 nocrt: true,
848 }
849 `)
850
851 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
852 // but target.vendor.shared_libs has not been supported yet.
853 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
854 cc_library {
855 name: "libvndk",
856 vendor_available: true,
857 vndk: {
858 enabled: true,
859 },
860 nocrt: true,
861 }
862
863 cc_library {
864 name: "libvndk_ext",
865 vendor: true,
866 vndk: {
867 enabled: true,
868 extends: "libvndk",
869 },
870 nocrt: true,
871 }
872
873 cc_library {
874 name: "libvndk2",
875 vendor_available: true,
876 vndk: {
877 enabled: true,
878 },
879 target: {
880 vendor: {
881 shared_libs: ["libvndk_ext"],
882 },
883 },
884 nocrt: true,
885 }
886 `)
887
888 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
889 cc_library {
890 name: "libvndk_sp",
891 vendor_available: true,
892 vndk: {
893 enabled: true,
894 support_system_process: true,
895 },
896 nocrt: true,
897 }
898
899 cc_library {
900 name: "libvndk_sp_ext",
901 vendor: true,
902 vndk: {
903 enabled: true,
904 extends: "libvndk_sp",
905 support_system_process: true,
906 },
907 nocrt: true,
908 }
909
910 cc_library {
911 name: "libvndk_sp_2",
912 vendor_available: true,
913 vndk: {
914 enabled: true,
915 support_system_process: true,
916 },
917 shared_libs: ["libvndk_sp_ext"],
918 nocrt: true,
919 }
920 `)
921
922 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
923 // but target.vendor.shared_libs has not been supported yet.
924 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
925 cc_library {
926 name: "libvndk_sp",
927 vendor_available: true,
928 vndk: {
929 enabled: true,
930 },
931 nocrt: true,
932 }
933
934 cc_library {
935 name: "libvndk_sp_ext",
936 vendor: true,
937 vndk: {
938 enabled: true,
939 extends: "libvndk_sp",
940 },
941 nocrt: true,
942 }
943
944 cc_library {
945 name: "libvndk_sp2",
946 vendor_available: true,
947 vndk: {
948 enabled: true,
949 },
950 target: {
951 vendor: {
952 shared_libs: ["libvndk_sp_ext"],
953 },
954 },
955 nocrt: true,
956 }
957 `)
958}
959
Colin Cross0af4b842015-04-30 16:36:18 -0700960var (
961 str11 = "01234567891"
962 str10 = str11[:10]
963 str9 = str11[:9]
964 str5 = str11[:5]
965 str4 = str11[:4]
966)
967
968var splitListForSizeTestCases = []struct {
969 in []string
970 out [][]string
971 size int
972}{
973 {
974 in: []string{str10},
975 out: [][]string{{str10}},
976 size: 10,
977 },
978 {
979 in: []string{str9},
980 out: [][]string{{str9}},
981 size: 10,
982 },
983 {
984 in: []string{str5},
985 out: [][]string{{str5}},
986 size: 10,
987 },
988 {
989 in: []string{str11},
990 out: nil,
991 size: 10,
992 },
993 {
994 in: []string{str10, str10},
995 out: [][]string{{str10}, {str10}},
996 size: 10,
997 },
998 {
999 in: []string{str9, str10},
1000 out: [][]string{{str9}, {str10}},
1001 size: 10,
1002 },
1003 {
1004 in: []string{str10, str9},
1005 out: [][]string{{str10}, {str9}},
1006 size: 10,
1007 },
1008 {
1009 in: []string{str5, str4},
1010 out: [][]string{{str5, str4}},
1011 size: 10,
1012 },
1013 {
1014 in: []string{str5, str4, str5},
1015 out: [][]string{{str5, str4}, {str5}},
1016 size: 10,
1017 },
1018 {
1019 in: []string{str5, str4, str5, str4},
1020 out: [][]string{{str5, str4}, {str5, str4}},
1021 size: 10,
1022 },
1023 {
1024 in: []string{str5, str4, str5, str5},
1025 out: [][]string{{str5, str4}, {str5}, {str5}},
1026 size: 10,
1027 },
1028 {
1029 in: []string{str5, str5, str5, str4},
1030 out: [][]string{{str5}, {str5}, {str5, str4}},
1031 size: 10,
1032 },
1033 {
1034 in: []string{str9, str11},
1035 out: nil,
1036 size: 10,
1037 },
1038 {
1039 in: []string{str11, str9},
1040 out: nil,
1041 size: 10,
1042 },
1043}
1044
1045func TestSplitListForSize(t *testing.T) {
1046 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -07001047 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
1048
1049 var outStrings [][]string
1050
1051 if len(out) > 0 {
1052 outStrings = make([][]string, len(out))
1053 for i, o := range out {
1054 outStrings[i] = o.Strings()
1055 }
1056 }
1057
1058 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001059 t.Errorf("incorrect output:")
1060 t.Errorf(" input: %#v", testCase.in)
1061 t.Errorf(" size: %d", testCase.size)
1062 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001063 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001064 }
1065 }
1066}
Jeff Gaston294356f2017-09-27 17:05:30 -07001067
1068var staticLinkDepOrderTestCases = []struct {
1069 // This is a string representation of a map[moduleName][]moduleDependency .
1070 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001071 inStatic string
1072
1073 // This is a string representation of a map[moduleName][]moduleDependency .
1074 // It models the dependencies declared in an Android.bp file.
1075 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001076
1077 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1078 // The keys of allOrdered specify which modules we would like to check.
1079 // The values of allOrdered specify the expected result (of the transitive closure of all
1080 // dependencies) for each module to test
1081 allOrdered string
1082
1083 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1084 // The keys of outOrdered specify which modules we would like to check.
1085 // The values of outOrdered specify the expected result (of the ordered linker command line)
1086 // for each module to test.
1087 outOrdered string
1088}{
1089 // Simple tests
1090 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001091 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001092 outOrdered: "",
1093 },
1094 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001095 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001096 outOrdered: "a:",
1097 },
1098 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001099 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001100 outOrdered: "a:b; b:",
1101 },
1102 // Tests of reordering
1103 {
1104 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001105 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001106 outOrdered: "a:b,c,d; b:d; c:d; d:",
1107 },
1108 {
1109 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001110 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001111 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1112 },
1113 {
1114 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001115 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001116 outOrdered: "a:d,b,e,c; d:b; e:c",
1117 },
1118 {
1119 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001120 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001121 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1122 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1123 },
1124 {
1125 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001126 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 -07001127 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1128 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1129 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001130 // shared dependencies
1131 {
1132 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1133 // So, we don't actually have to check that a shared dependency of c will change the order
1134 // of a library that depends statically on b and on c. We only need to check that if c has
1135 // a shared dependency on b, that that shows up in allOrdered.
1136 inShared: "c:b",
1137 allOrdered: "c:b",
1138 outOrdered: "c:",
1139 },
1140 {
1141 // This test doesn't actually include any shared dependencies but it's a reminder of what
1142 // the second phase of the above test would look like
1143 inStatic: "a:b,c; c:b",
1144 allOrdered: "a:c,b; c:b",
1145 outOrdered: "a:c,b; c:b",
1146 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001147 // tiebreakers for when two modules specifying different orderings and there is no dependency
1148 // to dictate an order
1149 {
1150 // 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 -08001151 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001152 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1153 },
1154 {
1155 // 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 -08001156 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 -07001157 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1158 },
1159 // Tests involving duplicate dependencies
1160 {
1161 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001162 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001163 outOrdered: "a:c,b",
1164 },
1165 {
1166 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001167 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001168 outOrdered: "a:d,c,b",
1169 },
1170 // Tests to confirm the nonexistence of infinite loops.
1171 // These cases should never happen, so as long as the test terminates and the
1172 // result is deterministic then that should be fine.
1173 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001174 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001175 outOrdered: "a:a",
1176 },
1177 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001178 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001179 allOrdered: "a:b,c; b:c,a; c:a,b",
1180 outOrdered: "a:b; b:c; c:a",
1181 },
1182 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001183 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001184 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1185 outOrdered: "a:c,b; b:a,c; c:b,a",
1186 },
1187}
1188
1189// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1190func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1191 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1192 strippedText := strings.Replace(text, " ", "", -1)
1193 if len(strippedText) < 1 {
1194 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1195 }
1196 allDeps = make(map[android.Path][]android.Path, 0)
1197
1198 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1199 moduleTexts := strings.Split(strippedText, ";")
1200
1201 outputForModuleName := func(moduleName string) android.Path {
1202 return android.PathForTesting(moduleName)
1203 }
1204
1205 for _, moduleText := range moduleTexts {
1206 // convert from "a:b,c" to ["a", "b,c"]
1207 components := strings.Split(moduleText, ":")
1208 if len(components) != 2 {
1209 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1210 }
1211 moduleName := components[0]
1212 moduleOutput := outputForModuleName(moduleName)
1213 modulesInOrder = append(modulesInOrder, moduleOutput)
1214
1215 depString := components[1]
1216 // convert from "b,c" to ["b", "c"]
1217 depNames := strings.Split(depString, ",")
1218 if len(depString) < 1 {
1219 depNames = []string{}
1220 }
1221 var deps []android.Path
1222 for _, depName := range depNames {
1223 deps = append(deps, outputForModuleName(depName))
1224 }
1225 allDeps[moduleOutput] = deps
1226 }
1227 return modulesInOrder, allDeps
1228}
1229
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001230func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001231 for _, testCase := range staticLinkDepOrderTestCases {
1232 errs := []string{}
1233
1234 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001235 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001236 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1237 if testCase.allOrdered == "" {
1238 // allow the test case to skip specifying allOrdered
1239 testCase.allOrdered = testCase.outOrdered
1240 }
1241 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001242 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001243
1244 // For each module whose post-reordered dependencies were specified, validate that
1245 // reordering the inputs produces the expected outputs.
1246 for _, moduleName := range expectedModuleNames {
1247 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001248 givenSharedDeps := givenAllSharedDeps[moduleName]
1249 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001250
1251 correctAllOrdered := expectedAllDeps[moduleName]
1252 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1253 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001254 "\nin static:%q"+
1255 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001256 "\nmodule: %v"+
1257 "\nexpected: %s"+
1258 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001259 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001260 }
1261
1262 correctOutputDeps := expectedTransitiveDeps[moduleName]
1263 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1264 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001265 "\nin static:%q"+
1266 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001267 "\nmodule: %v"+
1268 "\nexpected: %s"+
1269 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001270 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001271 }
1272 }
1273
1274 if len(errs) > 0 {
1275 sort.Strings(errs)
1276 for _, err := range errs {
1277 t.Error(err)
1278 }
1279 }
1280 }
1281}
Logan Chienf3511742017-10-31 18:04:35 +08001282
Jeff Gaston294356f2017-09-27 17:05:30 -07001283func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1284 for _, moduleName := range moduleNames {
1285 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1286 output := module.outputFile.Path()
1287 paths = append(paths, output)
1288 }
1289 return paths
1290}
1291
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001292func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001293 ctx := testCc(t, `
1294 cc_library {
1295 name: "a",
1296 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001297 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001298 }
1299 cc_library {
1300 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001301 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001302 }
1303 cc_library {
1304 name: "c",
1305 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001306 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001307 }
1308 cc_library {
1309 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001310 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001311 }
1312
1313 `)
1314
1315 variant := "android_arm64_armv8-a_core_static"
1316 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001317 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001318 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1319
1320 if !reflect.DeepEqual(actual, expected) {
1321 t.Errorf("staticDeps orderings were not propagated correctly"+
1322 "\nactual: %v"+
1323 "\nexpected: %v",
1324 actual,
1325 expected,
1326 )
1327 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001328}
Jeff Gaston294356f2017-09-27 17:05:30 -07001329
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001330func TestStaticLibDepReorderingWithShared(t *testing.T) {
1331 ctx := testCc(t, `
1332 cc_library {
1333 name: "a",
1334 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001335 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001336 }
1337 cc_library {
1338 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001339 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001340 }
1341 cc_library {
1342 name: "c",
1343 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001344 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001345 }
1346
1347 `)
1348
1349 variant := "android_arm64_armv8-a_core_static"
1350 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1351 actual := moduleA.depsInLinkOrder
1352 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1353
1354 if !reflect.DeepEqual(actual, expected) {
1355 t.Errorf("staticDeps orderings did not account for shared libs"+
1356 "\nactual: %v"+
1357 "\nexpected: %v",
1358 actual,
1359 expected,
1360 )
1361 }
1362}
1363
Jiyong Parka46a4d52017-12-14 19:54:34 +09001364func TestLlndkHeaders(t *testing.T) {
1365 ctx := testCc(t, `
1366 llndk_headers {
1367 name: "libllndk_headers",
1368 export_include_dirs: ["my_include"],
1369 }
1370 llndk_library {
1371 name: "libllndk",
1372 export_llndk_headers: ["libllndk_headers"],
1373 }
1374 cc_library {
1375 name: "libvendor",
1376 shared_libs: ["libllndk"],
1377 vendor: true,
1378 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001379 no_libgcc: true,
1380 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001381 }
1382 `)
1383
1384 // _static variant is used since _shared reuses *.o from the static variant
1385 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1386 cflags := cc.Args["cFlags"]
1387 if !strings.Contains(cflags, "-Imy_include") {
1388 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1389 }
1390}
1391
Jiyong Parkd08b6972017-09-26 10:50:54 +09001392var compilerFlagsTestCases = []struct {
1393 in string
1394 out bool
1395}{
1396 {
1397 in: "a",
1398 out: false,
1399 },
1400 {
1401 in: "-a",
1402 out: true,
1403 },
1404 {
1405 in: "-Ipath/to/something",
1406 out: false,
1407 },
1408 {
1409 in: "-isystempath/to/something",
1410 out: false,
1411 },
1412 {
1413 in: "--coverage",
1414 out: false,
1415 },
1416 {
1417 in: "-include a/b",
1418 out: true,
1419 },
1420 {
1421 in: "-include a/b c/d",
1422 out: false,
1423 },
1424 {
1425 in: "-DMACRO",
1426 out: true,
1427 },
1428 {
1429 in: "-DMAC RO",
1430 out: false,
1431 },
1432 {
1433 in: "-a -b",
1434 out: false,
1435 },
1436 {
1437 in: "-DMACRO=definition",
1438 out: true,
1439 },
1440 {
1441 in: "-DMACRO=defi nition",
1442 out: true, // TODO(jiyong): this should be false
1443 },
1444 {
1445 in: "-DMACRO(x)=x + 1",
1446 out: true,
1447 },
1448 {
1449 in: "-DMACRO=\"defi nition\"",
1450 out: true,
1451 },
1452}
1453
1454type mockContext struct {
1455 BaseModuleContext
1456 result bool
1457}
1458
1459func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1460 // CheckBadCompilerFlags calls this function when the flag should be rejected
1461 ctx.result = false
1462}
1463
1464func TestCompilerFlags(t *testing.T) {
1465 for _, testCase := range compilerFlagsTestCases {
1466 ctx := &mockContext{result: true}
1467 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1468 if ctx.result != testCase.out {
1469 t.Errorf("incorrect output:")
1470 t.Errorf(" input: %#v", testCase.in)
1471 t.Errorf(" expected: %#v", testCase.out)
1472 t.Errorf(" got: %#v", ctx.result)
1473 }
1474 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001475}
Jiyong Park374510b2018-03-19 18:23:01 +09001476
1477func TestVendorPublicLibraries(t *testing.T) {
1478 ctx := testCc(t, `
1479 cc_library_headers {
1480 name: "libvendorpublic_headers",
1481 export_include_dirs: ["my_include"],
1482 }
1483 vendor_public_library {
1484 name: "libvendorpublic",
1485 symbol_file: "",
1486 export_public_headers: ["libvendorpublic_headers"],
1487 }
1488 cc_library {
1489 name: "libvendorpublic",
1490 srcs: ["foo.c"],
1491 vendor: true,
1492 no_libgcc: true,
1493 nocrt: true,
1494 }
1495
1496 cc_library {
1497 name: "libsystem",
1498 shared_libs: ["libvendorpublic"],
1499 vendor: false,
1500 srcs: ["foo.c"],
1501 no_libgcc: true,
1502 nocrt: true,
1503 }
1504 cc_library {
1505 name: "libvendor",
1506 shared_libs: ["libvendorpublic"],
1507 vendor: true,
1508 srcs: ["foo.c"],
1509 no_libgcc: true,
1510 nocrt: true,
1511 }
1512 `)
1513
1514 variant := "android_arm64_armv8-a_core_shared"
1515
1516 // test if header search paths are correctly added
1517 // _static variant is used since _shared reuses *.o from the static variant
1518 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
1519 cflags := cc.Args["cFlags"]
1520 if !strings.Contains(cflags, "-Imy_include") {
1521 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
1522 }
1523
1524 // test if libsystem is linked to the stub
1525 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
1526 libflags := ld.Args["libFlags"]
1527 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
1528 if !strings.Contains(libflags, stubPaths[0].String()) {
1529 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
1530 }
1531
1532 // test if libvendor is linked to the real shared lib
1533 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
1534 libflags = ld.Args["libFlags"]
1535 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
1536 if !strings.Contains(libflags, stubPaths[0].String()) {
1537 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
1538 }
1539
1540}