blob: 9b4cc0fa17d093cc021a4c362a44eaeb54d8cb53 [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
Jeff Gaston294356f2017-09-27 17:05:30 -070020 "fmt"
Jiyong Park6a43f042017-10-12 23:05:00 +090021 "io/ioutil"
22 "os"
Colin Cross74d1ec02015-04-28 13:30:13 -070023 "reflect"
Jeff Gaston294356f2017-09-27 17:05:30 -070024 "sort"
25 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070026 "testing"
27)
28
Jiyong Park6a43f042017-10-12 23:05:00 +090029var buildDir string
30
31func setUp() {
32 var err error
33 buildDir, err = ioutil.TempDir("", "soong_cc_test")
34 if err != nil {
35 panic(err)
36 }
37}
38
39func tearDown() {
40 os.RemoveAll(buildDir)
41}
42
43func TestMain(m *testing.M) {
44 run := func() int {
45 setUp()
46 defer tearDown()
47
48 return m.Run()
49 }
50
51 os.Exit(run())
52}
53
Logan Chienf3511742017-10-31 18:04:35 +080054func createTestContext(t *testing.T, config android.Config, bp string) *android.TestContext {
Jiyong Park6a43f042017-10-12 23:05:00 +090055 ctx := android.NewTestArchContext()
Steven Morelandf9e62162017-11-02 17:00:50 -070056 ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory))
Colin Crossf18e1102017-11-16 14:33:08 -080057 ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory))
Jiyong Park374510b2018-03-19 18:23:01 +090058 ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory))
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))
Jiyong Park374510b2018-03-19 18:23:01 +090062 ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
Jeff Gaston294356f2017-09-27 17:05:30 -070063 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(objectFactory))
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -070064 ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
Jiyong Park6a43f042017-10-12 23:05:00 +090065 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
66 ctx.BottomUp("image", vendorMutator).Parallel()
67 ctx.BottomUp("link", linkageMutator).Parallel()
68 ctx.BottomUp("vndk", vndkMutator).Parallel()
Jiyong Park374510b2018-03-19 18:23:01 +090069 ctx.BottomUp("begin", beginMutator).Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +090070 })
71 ctx.Register()
72
Jeff Gaston294356f2017-09-27 17:05:30 -070073 // add some modules that are required by the compiler and/or linker
74 bp = bp + `
75 toolchain_library {
76 name: "libatomic",
77 vendor_available: true,
78 }
79
80 toolchain_library {
81 name: "libcompiler_rt-extras",
82 vendor_available: true,
83 }
84
85 toolchain_library {
86 name: "libgcc",
87 vendor_available: true,
88 }
89
90 cc_library {
91 name: "libc",
Logan Chienf3511742017-10-31 18:04:35 +080092 no_libgcc: true,
93 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -070094 system_shared_libs: [],
95 }
96 llndk_library {
97 name: "libc",
98 symbol_file: "",
99 }
100 cc_library {
101 name: "libm",
Logan Chienf3511742017-10-31 18:04:35 +0800102 no_libgcc: true,
103 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700104 system_shared_libs: [],
105 }
106 llndk_library {
107 name: "libm",
108 symbol_file: "",
109 }
110 cc_library {
111 name: "libdl",
Logan Chienf3511742017-10-31 18:04:35 +0800112 no_libgcc: true,
113 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700114 system_shared_libs: [],
115 }
116 llndk_library {
117 name: "libdl",
118 symbol_file: "",
119 }
Jiyong Park374510b2018-03-19 18:23:01 +0900120 cc_library {
121 name: "libc++_static",
122 no_libgcc: true,
123 nocrt: true,
124 system_shared_libs: [],
125 stl: "none",
126 vendor_available: true,
127 }
128 cc_library {
129 name: "libc++",
130 no_libgcc: true,
131 nocrt: true,
132 system_shared_libs: [],
133 stl: "none",
134 vendor_available: true,
135 vndk: {
136 enabled: true,
137 support_system_process: true,
138 },
139 }
140 cc_library {
141 name: "libunwind_llvm",
142 no_libgcc: true,
143 nocrt: true,
144 system_shared_libs: [],
145 stl: "none",
146 vendor_available: true,
147 }
Jeff Gaston294356f2017-09-27 17:05:30 -0700148
149 cc_object {
150 name: "crtbegin_so",
151 }
152
153 cc_object {
154 name: "crtend_so",
155 }
156
Colin Crossad59e752017-11-16 14:29:11 -0800157 cc_library {
158 name: "libprotobuf-cpp-lite",
159 }
160
Jeff Gaston294356f2017-09-27 17:05:30 -0700161`
162
Jiyong Park6a43f042017-10-12 23:05:00 +0900163 ctx.MockFileSystem(map[string][]byte{
164 "Android.bp": []byte(bp),
165 "foo.c": nil,
166 "bar.c": nil,
Colin Crossad59e752017-11-16 14:29:11 -0800167 "a.proto": nil,
Colin Crossf18e1102017-11-16 14:33:08 -0800168 "b.aidl": nil,
Jiyong Parka46a4d52017-12-14 19:54:34 +0900169 "my_include": nil,
Jiyong Park6a43f042017-10-12 23:05:00 +0900170 })
171
Logan Chienf3511742017-10-31 18:04:35 +0800172 return ctx
173}
174
175func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800176 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800177 ctx := createTestContext(t, config, bp)
178
Jeff Gastond3e141d2017-08-08 17:46:01 -0700179 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +0800180 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900181 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800182 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900183
184 return ctx
185}
186
Logan Chienf3511742017-10-31 18:04:35 +0800187func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800188 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800189 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700190 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
191 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800192
193 return testCcWithConfig(t, bp, config)
194}
195
196func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800197 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800198 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700199 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800200
201 return testCcWithConfig(t, bp, config)
202}
203
204func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800205 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800206 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700207 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
208 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800209
210 ctx := createTestContext(t, config, bp)
211
212 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
213 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800214 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800215 return
216 }
217
218 _, errs = ctx.PrepareBuildActions(config)
219 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800220 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800221 return
222 }
223
224 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
225}
226
227const (
228 coreVariant = "android_arm64_armv8-a_core_shared"
229 vendorVariant = "android_arm64_armv8-a_vendor_shared"
230)
231
Jiyong Park6a43f042017-10-12 23:05:00 +0900232func TestVendorSrc(t *testing.T) {
233 ctx := testCc(t, `
234 cc_library {
235 name: "libTest",
236 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800237 no_libgcc: true,
238 nocrt: true,
239 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900240 vendor_available: true,
241 target: {
242 vendor: {
243 srcs: ["bar.c"],
244 },
245 },
246 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900247 `)
248
Logan Chienf3511742017-10-31 18:04:35 +0800249 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900250 var objs []string
251 for _, o := range ld.Inputs {
252 objs = append(objs, o.Base())
253 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800254 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900255 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
256 }
257}
258
Logan Chienf3511742017-10-31 18:04:35 +0800259func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
260 isVndkSp bool, extends string) {
261
Logan Chiend3c59a22018-03-29 14:08:15 +0800262 t.Helper()
263
Logan Chienf3511742017-10-31 18:04:35 +0800264 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
265 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700266 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800267 }
268
269 // Check library properties.
270 lib, ok := mod.compiler.(*libraryDecorator)
271 if !ok {
272 t.Errorf("%q must have libraryDecorator", name)
273 } else if lib.baseInstaller.subDir != subDir {
274 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
275 lib.baseInstaller.subDir)
276 }
277
278 // Check VNDK properties.
279 if mod.vndkdep == nil {
280 t.Fatalf("%q must have `vndkdep`", name)
281 }
282 if !mod.isVndk() {
283 t.Errorf("%q isVndk() must equal to true", name)
284 }
285 if mod.isVndkSp() != isVndkSp {
286 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
287 }
288
289 // Check VNDK extension properties.
290 isVndkExt := extends != ""
291 if mod.isVndkExt() != isVndkExt {
292 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
293 }
294
295 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
296 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
297 }
298}
299
300func TestVndk(t *testing.T) {
301 ctx := testCc(t, `
302 cc_library {
303 name: "libvndk",
304 vendor_available: true,
305 vndk: {
306 enabled: true,
307 },
308 nocrt: true,
309 }
310
311 cc_library {
312 name: "libvndk_private",
313 vendor_available: false,
314 vndk: {
315 enabled: true,
316 },
317 nocrt: true,
318 }
319
320 cc_library {
321 name: "libvndk_sp",
322 vendor_available: true,
323 vndk: {
324 enabled: true,
325 support_system_process: true,
326 },
327 nocrt: true,
328 }
329
330 cc_library {
331 name: "libvndk_sp_private",
332 vendor_available: false,
333 vndk: {
334 enabled: true,
335 support_system_process: true,
336 },
337 nocrt: true,
338 }
339 `)
340
341 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
342 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
343 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
344 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
345}
346
Logan Chiend3c59a22018-03-29 14:08:15 +0800347func TestVndkDepError(t *testing.T) {
348 // Check whether an error is emitted when a VNDK lib depends on a system lib.
349 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
350 cc_library {
351 name: "libvndk",
352 vendor_available: true,
353 vndk: {
354 enabled: true,
355 },
356 shared_libs: ["libfwk"], // Cause error
357 nocrt: true,
358 }
359
360 cc_library {
361 name: "libfwk",
362 nocrt: true,
363 }
364 `)
365
366 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
367 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
368 cc_library {
369 name: "libvndk",
370 vendor_available: true,
371 vndk: {
372 enabled: true,
373 },
374 shared_libs: ["libvendor"], // Cause error
375 nocrt: true,
376 }
377
378 cc_library {
379 name: "libvendor",
380 vendor: true,
381 nocrt: true,
382 }
383 `)
384
385 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
386 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
387 cc_library {
388 name: "libvndk_sp",
389 vendor_available: true,
390 vndk: {
391 enabled: true,
392 support_system_process: true,
393 },
394 shared_libs: ["libfwk"], // Cause error
395 nocrt: true,
396 }
397
398 cc_library {
399 name: "libfwk",
400 nocrt: true,
401 }
402 `)
403
404 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
405 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
406 cc_library {
407 name: "libvndk_sp",
408 vendor_available: true,
409 vndk: {
410 enabled: true,
411 support_system_process: true,
412 },
413 shared_libs: ["libvendor"], // Cause error
414 nocrt: true,
415 }
416
417 cc_library {
418 name: "libvendor",
419 vendor: true,
420 nocrt: true,
421 }
422 `)
423
424 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
425 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
426 cc_library {
427 name: "libvndk_sp",
428 vendor_available: true,
429 vndk: {
430 enabled: true,
431 support_system_process: true,
432 },
433 shared_libs: ["libvndk"], // Cause error
434 nocrt: true,
435 }
436
437 cc_library {
438 name: "libvndk",
439 vendor_available: true,
440 vndk: {
441 enabled: true,
442 },
443 nocrt: true,
444 }
445 `)
446}
447
Logan Chienf3511742017-10-31 18:04:35 +0800448func TestVndkExt(t *testing.T) {
449 // This test checks the VNDK-Ext properties.
450 ctx := testCc(t, `
451 cc_library {
452 name: "libvndk",
453 vendor_available: true,
454 vndk: {
455 enabled: true,
456 },
457 nocrt: true,
458 }
459
460 cc_library {
461 name: "libvndk_ext",
462 vendor: true,
463 vndk: {
464 enabled: true,
465 extends: "libvndk",
466 },
467 nocrt: true,
468 }
469 `)
470
471 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
472}
473
Logan Chiend3c59a22018-03-29 14:08:15 +0800474func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800475 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
476 ctx := testCcNoVndk(t, `
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 vendor: true,
489 vndk: {
490 enabled: true,
491 extends: "libvndk",
492 },
493 nocrt: true,
494 }
495 `)
496
497 // Ensures that the core variant of "libvndk_ext" can be found.
498 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
499 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
500 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
501 }
502}
503
504func TestVndkExtError(t *testing.T) {
505 // This test ensures an error is emitted in ill-formed vndk-ext definition.
506 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
507 cc_library {
508 name: "libvndk",
509 vendor_available: true,
510 vndk: {
511 enabled: true,
512 },
513 nocrt: true,
514 }
515
516 cc_library {
517 name: "libvndk_ext",
518 vndk: {
519 enabled: true,
520 extends: "libvndk",
521 },
522 nocrt: true,
523 }
524 `)
525
526 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
527 cc_library {
528 name: "libvndk",
529 vendor_available: true,
530 vndk: {
531 enabled: true,
532 },
533 nocrt: true,
534 }
535
536 cc_library {
537 name: "libvndk_ext",
538 vendor: true,
539 vndk: {
540 enabled: true,
541 },
542 nocrt: true,
543 }
544 `)
545}
546
547func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
548 // This test ensures an error is emitted for inconsistent support_system_process.
549 testCcError(t, "module \".*\" with mismatched support_system_process", `
550 cc_library {
551 name: "libvndk",
552 vendor_available: true,
553 vndk: {
554 enabled: true,
555 },
556 nocrt: true,
557 }
558
559 cc_library {
560 name: "libvndk_sp_ext",
561 vendor: true,
562 vndk: {
563 enabled: true,
564 extends: "libvndk",
565 support_system_process: true,
566 },
567 nocrt: true,
568 }
569 `)
570
571 testCcError(t, "module \".*\" with mismatched support_system_process", `
572 cc_library {
573 name: "libvndk_sp",
574 vendor_available: true,
575 vndk: {
576 enabled: true,
577 support_system_process: true,
578 },
579 nocrt: true,
580 }
581
582 cc_library {
583 name: "libvndk_ext",
584 vendor: true,
585 vndk: {
586 enabled: true,
587 extends: "libvndk_sp",
588 },
589 nocrt: true,
590 }
591 `)
592}
593
594func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800595 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800596 // with `vendor_available: false`.
597 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
598 cc_library {
599 name: "libvndk",
600 vendor_available: false,
601 vndk: {
602 enabled: true,
603 },
604 nocrt: true,
605 }
606
607 cc_library {
608 name: "libvndk_ext",
609 vendor: true,
610 vndk: {
611 enabled: true,
612 extends: "libvndk",
613 },
614 nocrt: true,
615 }
616 `)
617}
618
Logan Chiend3c59a22018-03-29 14:08:15 +0800619func TestVendorModuleUseVndkExt(t *testing.T) {
620 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800621 testCc(t, `
622 cc_library {
623 name: "libvndk",
624 vendor_available: true,
625 vndk: {
626 enabled: true,
627 },
628 nocrt: true,
629 }
630
631 cc_library {
632 name: "libvndk_ext",
633 vendor: true,
634 vndk: {
635 enabled: true,
636 extends: "libvndk",
637 },
638 nocrt: true,
639 }
640
641 cc_library {
642
643 name: "libvndk_sp",
644 vendor_available: true,
645 vndk: {
646 enabled: true,
647 support_system_process: true,
648 },
649 nocrt: true,
650 }
651
652 cc_library {
653 name: "libvndk_sp_ext",
654 vendor: true,
655 vndk: {
656 enabled: true,
657 extends: "libvndk_sp",
658 support_system_process: true,
659 },
660 nocrt: true,
661 }
662
663 cc_library {
664 name: "libvendor",
665 vendor: true,
666 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
667 nocrt: true,
668 }
669 `)
670}
671
Logan Chiend3c59a22018-03-29 14:08:15 +0800672func TestVndkExtUseVendorLib(t *testing.T) {
673 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800674 testCc(t, `
675 cc_library {
676 name: "libvndk",
677 vendor_available: true,
678 vndk: {
679 enabled: true,
680 },
681 nocrt: true,
682 }
683
684 cc_library {
685 name: "libvndk_ext",
686 vendor: true,
687 vndk: {
688 enabled: true,
689 extends: "libvndk",
690 },
691 shared_libs: ["libvendor"],
692 nocrt: true,
693 }
694
695 cc_library {
696 name: "libvendor",
697 vendor: true,
698 nocrt: true,
699 }
700 `)
Logan Chienf3511742017-10-31 18:04:35 +0800701
Logan Chiend3c59a22018-03-29 14:08:15 +0800702 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
703 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800704 cc_library {
705 name: "libvndk_sp",
706 vendor_available: true,
707 vndk: {
708 enabled: true,
709 support_system_process: true,
710 },
711 nocrt: true,
712 }
713
714 cc_library {
715 name: "libvndk_sp_ext",
716 vendor: true,
717 vndk: {
718 enabled: true,
719 extends: "libvndk_sp",
720 support_system_process: true,
721 },
722 shared_libs: ["libvendor"], // Cause an error
723 nocrt: true,
724 }
725
726 cc_library {
727 name: "libvendor",
728 vendor: true,
729 nocrt: true,
730 }
731 `)
732}
733
Logan Chiend3c59a22018-03-29 14:08:15 +0800734func TestVndkSpExtUseVndkError(t *testing.T) {
735 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
736 // library.
737 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
738 cc_library {
739 name: "libvndk",
740 vendor_available: true,
741 vndk: {
742 enabled: true,
743 },
744 nocrt: true,
745 }
746
747 cc_library {
748 name: "libvndk_sp",
749 vendor_available: true,
750 vndk: {
751 enabled: true,
752 support_system_process: true,
753 },
754 nocrt: true,
755 }
756
757 cc_library {
758 name: "libvndk_sp_ext",
759 vendor: true,
760 vndk: {
761 enabled: true,
762 extends: "libvndk_sp",
763 support_system_process: true,
764 },
765 shared_libs: ["libvndk"], // Cause an error
766 nocrt: true,
767 }
768 `)
769
770 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
771 // library.
772 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
773 cc_library {
774 name: "libvndk",
775 vendor_available: true,
776 vndk: {
777 enabled: true,
778 },
779 nocrt: true,
780 }
781
782 cc_library {
783 name: "libvndk_ext",
784 vendor: true,
785 vndk: {
786 enabled: true,
787 extends: "libvndk",
788 },
789 nocrt: true,
790 }
791
792 cc_library {
793 name: "libvndk_sp",
794 vendor_available: true,
795 vndk: {
796 enabled: true,
797 support_system_process: true,
798 },
799 nocrt: true,
800 }
801
802 cc_library {
803 name: "libvndk_sp_ext",
804 vendor: true,
805 vndk: {
806 enabled: true,
807 extends: "libvndk_sp",
808 support_system_process: true,
809 },
810 shared_libs: ["libvndk_ext"], // Cause an error
811 nocrt: true,
812 }
813 `)
814}
815
816func TestVndkUseVndkExtError(t *testing.T) {
817 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
818 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800819 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
820 cc_library {
821 name: "libvndk",
822 vendor_available: true,
823 vndk: {
824 enabled: true,
825 },
826 nocrt: true,
827 }
828
829 cc_library {
830 name: "libvndk_ext",
831 vendor: true,
832 vndk: {
833 enabled: true,
834 extends: "libvndk",
835 },
836 nocrt: true,
837 }
838
839 cc_library {
840 name: "libvndk2",
841 vendor_available: true,
842 vndk: {
843 enabled: true,
844 },
845 shared_libs: ["libvndk_ext"],
846 nocrt: true,
847 }
848 `)
849
850 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
851 // but target.vendor.shared_libs has not been supported yet.
852 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
853 cc_library {
854 name: "libvndk",
855 vendor_available: true,
856 vndk: {
857 enabled: true,
858 },
859 nocrt: true,
860 }
861
862 cc_library {
863 name: "libvndk_ext",
864 vendor: true,
865 vndk: {
866 enabled: true,
867 extends: "libvndk",
868 },
869 nocrt: true,
870 }
871
872 cc_library {
873 name: "libvndk2",
874 vendor_available: true,
875 vndk: {
876 enabled: true,
877 },
878 target: {
879 vendor: {
880 shared_libs: ["libvndk_ext"],
881 },
882 },
883 nocrt: true,
884 }
885 `)
886
887 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
888 cc_library {
889 name: "libvndk_sp",
890 vendor_available: true,
891 vndk: {
892 enabled: true,
893 support_system_process: true,
894 },
895 nocrt: true,
896 }
897
898 cc_library {
899 name: "libvndk_sp_ext",
900 vendor: true,
901 vndk: {
902 enabled: true,
903 extends: "libvndk_sp",
904 support_system_process: true,
905 },
906 nocrt: true,
907 }
908
909 cc_library {
910 name: "libvndk_sp_2",
911 vendor_available: true,
912 vndk: {
913 enabled: true,
914 support_system_process: true,
915 },
916 shared_libs: ["libvndk_sp_ext"],
917 nocrt: true,
918 }
919 `)
920
921 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
922 // but target.vendor.shared_libs has not been supported yet.
923 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
924 cc_library {
925 name: "libvndk_sp",
926 vendor_available: true,
927 vndk: {
928 enabled: true,
929 },
930 nocrt: true,
931 }
932
933 cc_library {
934 name: "libvndk_sp_ext",
935 vendor: true,
936 vndk: {
937 enabled: true,
938 extends: "libvndk_sp",
939 },
940 nocrt: true,
941 }
942
943 cc_library {
944 name: "libvndk_sp2",
945 vendor_available: true,
946 vndk: {
947 enabled: true,
948 },
949 target: {
950 vendor: {
951 shared_libs: ["libvndk_sp_ext"],
952 },
953 },
954 nocrt: true,
955 }
956 `)
957}
958
Colin Cross0af4b842015-04-30 16:36:18 -0700959var (
960 str11 = "01234567891"
961 str10 = str11[:10]
962 str9 = str11[:9]
963 str5 = str11[:5]
964 str4 = str11[:4]
965)
966
967var splitListForSizeTestCases = []struct {
968 in []string
969 out [][]string
970 size int
971}{
972 {
973 in: []string{str10},
974 out: [][]string{{str10}},
975 size: 10,
976 },
977 {
978 in: []string{str9},
979 out: [][]string{{str9}},
980 size: 10,
981 },
982 {
983 in: []string{str5},
984 out: [][]string{{str5}},
985 size: 10,
986 },
987 {
988 in: []string{str11},
989 out: nil,
990 size: 10,
991 },
992 {
993 in: []string{str10, str10},
994 out: [][]string{{str10}, {str10}},
995 size: 10,
996 },
997 {
998 in: []string{str9, str10},
999 out: [][]string{{str9}, {str10}},
1000 size: 10,
1001 },
1002 {
1003 in: []string{str10, str9},
1004 out: [][]string{{str10}, {str9}},
1005 size: 10,
1006 },
1007 {
1008 in: []string{str5, str4},
1009 out: [][]string{{str5, str4}},
1010 size: 10,
1011 },
1012 {
1013 in: []string{str5, str4, str5},
1014 out: [][]string{{str5, str4}, {str5}},
1015 size: 10,
1016 },
1017 {
1018 in: []string{str5, str4, str5, str4},
1019 out: [][]string{{str5, str4}, {str5, str4}},
1020 size: 10,
1021 },
1022 {
1023 in: []string{str5, str4, str5, str5},
1024 out: [][]string{{str5, str4}, {str5}, {str5}},
1025 size: 10,
1026 },
1027 {
1028 in: []string{str5, str5, str5, str4},
1029 out: [][]string{{str5}, {str5}, {str5, str4}},
1030 size: 10,
1031 },
1032 {
1033 in: []string{str9, str11},
1034 out: nil,
1035 size: 10,
1036 },
1037 {
1038 in: []string{str11, str9},
1039 out: nil,
1040 size: 10,
1041 },
1042}
1043
1044func TestSplitListForSize(t *testing.T) {
1045 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -07001046 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
1047
1048 var outStrings [][]string
1049
1050 if len(out) > 0 {
1051 outStrings = make([][]string, len(out))
1052 for i, o := range out {
1053 outStrings[i] = o.Strings()
1054 }
1055 }
1056
1057 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001058 t.Errorf("incorrect output:")
1059 t.Errorf(" input: %#v", testCase.in)
1060 t.Errorf(" size: %d", testCase.size)
1061 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001062 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001063 }
1064 }
1065}
Jeff Gaston294356f2017-09-27 17:05:30 -07001066
1067var staticLinkDepOrderTestCases = []struct {
1068 // This is a string representation of a map[moduleName][]moduleDependency .
1069 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001070 inStatic string
1071
1072 // This is a string representation of a map[moduleName][]moduleDependency .
1073 // It models the dependencies declared in an Android.bp file.
1074 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001075
1076 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1077 // The keys of allOrdered specify which modules we would like to check.
1078 // The values of allOrdered specify the expected result (of the transitive closure of all
1079 // dependencies) for each module to test
1080 allOrdered string
1081
1082 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1083 // The keys of outOrdered specify which modules we would like to check.
1084 // The values of outOrdered specify the expected result (of the ordered linker command line)
1085 // for each module to test.
1086 outOrdered string
1087}{
1088 // Simple tests
1089 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001090 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001091 outOrdered: "",
1092 },
1093 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001094 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001095 outOrdered: "a:",
1096 },
1097 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001098 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001099 outOrdered: "a:b; b:",
1100 },
1101 // Tests of reordering
1102 {
1103 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001104 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001105 outOrdered: "a:b,c,d; b:d; c:d; d:",
1106 },
1107 {
1108 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001109 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001110 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1111 },
1112 {
1113 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001114 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001115 outOrdered: "a:d,b,e,c; d:b; e:c",
1116 },
1117 {
1118 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001119 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001120 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1121 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1122 },
1123 {
1124 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001125 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 -07001126 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1127 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1128 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001129 // shared dependencies
1130 {
1131 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1132 // So, we don't actually have to check that a shared dependency of c will change the order
1133 // of a library that depends statically on b and on c. We only need to check that if c has
1134 // a shared dependency on b, that that shows up in allOrdered.
1135 inShared: "c:b",
1136 allOrdered: "c:b",
1137 outOrdered: "c:",
1138 },
1139 {
1140 // This test doesn't actually include any shared dependencies but it's a reminder of what
1141 // the second phase of the above test would look like
1142 inStatic: "a:b,c; c:b",
1143 allOrdered: "a:c,b; c:b",
1144 outOrdered: "a:c,b; c:b",
1145 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001146 // tiebreakers for when two modules specifying different orderings and there is no dependency
1147 // to dictate an order
1148 {
1149 // 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 -08001150 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001151 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1152 },
1153 {
1154 // 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 -08001155 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 -07001156 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1157 },
1158 // Tests involving duplicate dependencies
1159 {
1160 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001161 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001162 outOrdered: "a:c,b",
1163 },
1164 {
1165 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001166 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001167 outOrdered: "a:d,c,b",
1168 },
1169 // Tests to confirm the nonexistence of infinite loops.
1170 // These cases should never happen, so as long as the test terminates and the
1171 // result is deterministic then that should be fine.
1172 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001173 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001174 outOrdered: "a:a",
1175 },
1176 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001177 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001178 allOrdered: "a:b,c; b:c,a; c:a,b",
1179 outOrdered: "a:b; b:c; c:a",
1180 },
1181 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001182 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001183 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1184 outOrdered: "a:c,b; b:a,c; c:b,a",
1185 },
1186}
1187
1188// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1189func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1190 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1191 strippedText := strings.Replace(text, " ", "", -1)
1192 if len(strippedText) < 1 {
1193 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1194 }
1195 allDeps = make(map[android.Path][]android.Path, 0)
1196
1197 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1198 moduleTexts := strings.Split(strippedText, ";")
1199
1200 outputForModuleName := func(moduleName string) android.Path {
1201 return android.PathForTesting(moduleName)
1202 }
1203
1204 for _, moduleText := range moduleTexts {
1205 // convert from "a:b,c" to ["a", "b,c"]
1206 components := strings.Split(moduleText, ":")
1207 if len(components) != 2 {
1208 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1209 }
1210 moduleName := components[0]
1211 moduleOutput := outputForModuleName(moduleName)
1212 modulesInOrder = append(modulesInOrder, moduleOutput)
1213
1214 depString := components[1]
1215 // convert from "b,c" to ["b", "c"]
1216 depNames := strings.Split(depString, ",")
1217 if len(depString) < 1 {
1218 depNames = []string{}
1219 }
1220 var deps []android.Path
1221 for _, depName := range depNames {
1222 deps = append(deps, outputForModuleName(depName))
1223 }
1224 allDeps[moduleOutput] = deps
1225 }
1226 return modulesInOrder, allDeps
1227}
1228
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001229func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001230 for _, testCase := range staticLinkDepOrderTestCases {
1231 errs := []string{}
1232
1233 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001234 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001235 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1236 if testCase.allOrdered == "" {
1237 // allow the test case to skip specifying allOrdered
1238 testCase.allOrdered = testCase.outOrdered
1239 }
1240 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001241 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001242
1243 // For each module whose post-reordered dependencies were specified, validate that
1244 // reordering the inputs produces the expected outputs.
1245 for _, moduleName := range expectedModuleNames {
1246 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001247 givenSharedDeps := givenAllSharedDeps[moduleName]
1248 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001249
1250 correctAllOrdered := expectedAllDeps[moduleName]
1251 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1252 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001253 "\nin static:%q"+
1254 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001255 "\nmodule: %v"+
1256 "\nexpected: %s"+
1257 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001258 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001259 }
1260
1261 correctOutputDeps := expectedTransitiveDeps[moduleName]
1262 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1263 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001264 "\nin static:%q"+
1265 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001266 "\nmodule: %v"+
1267 "\nexpected: %s"+
1268 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001269 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001270 }
1271 }
1272
1273 if len(errs) > 0 {
1274 sort.Strings(errs)
1275 for _, err := range errs {
1276 t.Error(err)
1277 }
1278 }
1279 }
1280}
Logan Chienf3511742017-10-31 18:04:35 +08001281
Jeff Gaston294356f2017-09-27 17:05:30 -07001282func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1283 for _, moduleName := range moduleNames {
1284 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1285 output := module.outputFile.Path()
1286 paths = append(paths, output)
1287 }
1288 return paths
1289}
1290
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001291func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001292 ctx := testCc(t, `
1293 cc_library {
1294 name: "a",
1295 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001296 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001297 }
1298 cc_library {
1299 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001300 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001301 }
1302 cc_library {
1303 name: "c",
1304 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001305 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001306 }
1307 cc_library {
1308 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001309 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001310 }
1311
1312 `)
1313
1314 variant := "android_arm64_armv8-a_core_static"
1315 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001316 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001317 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1318
1319 if !reflect.DeepEqual(actual, expected) {
1320 t.Errorf("staticDeps orderings were not propagated correctly"+
1321 "\nactual: %v"+
1322 "\nexpected: %v",
1323 actual,
1324 expected,
1325 )
1326 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001327}
Jeff Gaston294356f2017-09-27 17:05:30 -07001328
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001329func TestStaticLibDepReorderingWithShared(t *testing.T) {
1330 ctx := testCc(t, `
1331 cc_library {
1332 name: "a",
1333 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001334 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001335 }
1336 cc_library {
1337 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001338 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001339 }
1340 cc_library {
1341 name: "c",
1342 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001343 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001344 }
1345
1346 `)
1347
1348 variant := "android_arm64_armv8-a_core_static"
1349 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1350 actual := moduleA.depsInLinkOrder
1351 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1352
1353 if !reflect.DeepEqual(actual, expected) {
1354 t.Errorf("staticDeps orderings did not account for shared libs"+
1355 "\nactual: %v"+
1356 "\nexpected: %v",
1357 actual,
1358 expected,
1359 )
1360 }
1361}
1362
Jiyong Parka46a4d52017-12-14 19:54:34 +09001363func TestLlndkHeaders(t *testing.T) {
1364 ctx := testCc(t, `
1365 llndk_headers {
1366 name: "libllndk_headers",
1367 export_include_dirs: ["my_include"],
1368 }
1369 llndk_library {
1370 name: "libllndk",
1371 export_llndk_headers: ["libllndk_headers"],
1372 }
1373 cc_library {
1374 name: "libvendor",
1375 shared_libs: ["libllndk"],
1376 vendor: true,
1377 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001378 no_libgcc: true,
1379 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001380 }
1381 `)
1382
1383 // _static variant is used since _shared reuses *.o from the static variant
1384 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1385 cflags := cc.Args["cFlags"]
1386 if !strings.Contains(cflags, "-Imy_include") {
1387 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1388 }
1389}
1390
Jiyong Parkd08b6972017-09-26 10:50:54 +09001391var compilerFlagsTestCases = []struct {
1392 in string
1393 out bool
1394}{
1395 {
1396 in: "a",
1397 out: false,
1398 },
1399 {
1400 in: "-a",
1401 out: true,
1402 },
1403 {
1404 in: "-Ipath/to/something",
1405 out: false,
1406 },
1407 {
1408 in: "-isystempath/to/something",
1409 out: false,
1410 },
1411 {
1412 in: "--coverage",
1413 out: false,
1414 },
1415 {
1416 in: "-include a/b",
1417 out: true,
1418 },
1419 {
1420 in: "-include a/b c/d",
1421 out: false,
1422 },
1423 {
1424 in: "-DMACRO",
1425 out: true,
1426 },
1427 {
1428 in: "-DMAC RO",
1429 out: false,
1430 },
1431 {
1432 in: "-a -b",
1433 out: false,
1434 },
1435 {
1436 in: "-DMACRO=definition",
1437 out: true,
1438 },
1439 {
1440 in: "-DMACRO=defi nition",
1441 out: true, // TODO(jiyong): this should be false
1442 },
1443 {
1444 in: "-DMACRO(x)=x + 1",
1445 out: true,
1446 },
1447 {
1448 in: "-DMACRO=\"defi nition\"",
1449 out: true,
1450 },
1451}
1452
1453type mockContext struct {
1454 BaseModuleContext
1455 result bool
1456}
1457
1458func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1459 // CheckBadCompilerFlags calls this function when the flag should be rejected
1460 ctx.result = false
1461}
1462
1463func TestCompilerFlags(t *testing.T) {
1464 for _, testCase := range compilerFlagsTestCases {
1465 ctx := &mockContext{result: true}
1466 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1467 if ctx.result != testCase.out {
1468 t.Errorf("incorrect output:")
1469 t.Errorf(" input: %#v", testCase.in)
1470 t.Errorf(" expected: %#v", testCase.out)
1471 t.Errorf(" got: %#v", ctx.result)
1472 }
1473 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001474}
Jiyong Park374510b2018-03-19 18:23:01 +09001475
1476func TestVendorPublicLibraries(t *testing.T) {
1477 ctx := testCc(t, `
1478 cc_library_headers {
1479 name: "libvendorpublic_headers",
1480 export_include_dirs: ["my_include"],
1481 }
1482 vendor_public_library {
1483 name: "libvendorpublic",
1484 symbol_file: "",
1485 export_public_headers: ["libvendorpublic_headers"],
1486 }
1487 cc_library {
1488 name: "libvendorpublic",
1489 srcs: ["foo.c"],
1490 vendor: true,
1491 no_libgcc: true,
1492 nocrt: true,
1493 }
1494
1495 cc_library {
1496 name: "libsystem",
1497 shared_libs: ["libvendorpublic"],
1498 vendor: false,
1499 srcs: ["foo.c"],
1500 no_libgcc: true,
1501 nocrt: true,
1502 }
1503 cc_library {
1504 name: "libvendor",
1505 shared_libs: ["libvendorpublic"],
1506 vendor: true,
1507 srcs: ["foo.c"],
1508 no_libgcc: true,
1509 nocrt: true,
1510 }
1511 `)
1512
1513 variant := "android_arm64_armv8-a_core_shared"
1514
1515 // test if header search paths are correctly added
1516 // _static variant is used since _shared reuses *.o from the static variant
1517 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
1518 cflags := cc.Args["cFlags"]
1519 if !strings.Contains(cflags, "-Imy_include") {
1520 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
1521 }
1522
1523 // test if libsystem is linked to the stub
1524 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
1525 libflags := ld.Args["libFlags"]
1526 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
1527 if !strings.Contains(libflags, stubPaths[0].String()) {
1528 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
1529 }
1530
1531 // test if libvendor is linked to the real shared lib
1532 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
1533 libflags = ld.Args["libFlags"]
1534 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
1535 if !strings.Contains(libflags, stubPaths[0].String()) {
1536 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
1537 }
1538
1539}