blob: 22ac0d949701a7319be175f35c9a0aecf5c418fd [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
Doug Hornc32c6b02019-01-17 14:44:05 -080054func createTestContext(t *testing.T, config android.Config, bp string, os android.OsType) *android.TestContext {
55 ctx := android.NewTestArchContext()
56 ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(BinaryFactory))
57 ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory))
58 ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory))
Jiyong Parke4bb9862019-02-01 00:31:10 +090059 ctx.RegisterModuleType("cc_library_static", android.ModuleFactoryAdaptor(LibraryStaticFactory))
Doug Hornc32c6b02019-01-17 14:44:05 -080060 ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory))
61 ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(ToolchainLibraryFactory))
62 ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(LlndkLibraryFactory))
63 ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory))
64 ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
65 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory))
66 ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
67 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
68 ctx.BottomUp("image", ImageMutator).Parallel()
69 ctx.BottomUp("link", LinkageMutator).Parallel()
70 ctx.BottomUp("vndk", VndkMutator).Parallel()
71 ctx.BottomUp("version", VersionMutator).Parallel()
72 ctx.BottomUp("begin", BeginMutator).Parallel()
73 })
74 ctx.Register()
75
76 // add some modules that are required by the compiler and/or linker
Inseob Kimc0907f12019-02-08 21:00:45 +090077 bp = bp + GatherRequiredDepsForTest(os)
Jeff Gaston294356f2017-09-27 17:05:30 -070078
Jiyong Park6a43f042017-10-12 23:05:00 +090079 ctx.MockFileSystem(map[string][]byte{
Jiyong Park7ed9de32018-10-15 22:25:07 +090080 "Android.bp": []byte(bp),
81 "foo.c": nil,
82 "bar.c": nil,
83 "a.proto": nil,
84 "b.aidl": nil,
85 "my_include": nil,
86 "foo.map.txt": nil,
Jiyong Park6a43f042017-10-12 23:05:00 +090087 })
88
Logan Chienf3511742017-10-31 18:04:35 +080089 return ctx
90}
91
92func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Doug Hornc32c6b02019-01-17 14:44:05 -080093 return testCcWithConfigForOs(t, bp, config, android.Android)
94}
95
96func testCcWithConfigForOs(t *testing.T, bp string, config android.Config, os android.OsType) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080097 t.Helper()
Doug Hornc32c6b02019-01-17 14:44:05 -080098 ctx := createTestContext(t, config, bp, os)
Logan Chienf3511742017-10-31 18:04:35 +080099
Jeff Gastond3e141d2017-08-08 17:46:01 -0700100 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +0800101 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900102 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800103 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900104
105 return ctx
106}
107
Logan Chienf3511742017-10-31 18:04:35 +0800108func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800109 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800110 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700111 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
112 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800113
114 return testCcWithConfig(t, bp, config)
115}
116
117func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800118 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800119 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700120 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800121
122 return testCcWithConfig(t, bp, config)
123}
124
125func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800126 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800127 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700128 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
129 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800130
Doug Hornc32c6b02019-01-17 14:44:05 -0800131 ctx := createTestContext(t, config, bp, android.Android)
Logan Chienf3511742017-10-31 18:04:35 +0800132
133 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
134 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800135 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800136 return
137 }
138
139 _, errs = ctx.PrepareBuildActions(config)
140 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800141 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800142 return
143 }
144
145 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
146}
147
148const (
Jiyong Park5baac542018-08-28 09:55:37 +0900149 coreVariant = "android_arm64_armv8-a_core_shared"
150 vendorVariant = "android_arm64_armv8-a_vendor_shared"
151 recoveryVariant = "android_arm64_armv8-a_recovery_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800152)
153
Doug Hornc32c6b02019-01-17 14:44:05 -0800154func TestFuchsiaDeps(t *testing.T) {
155 t.Helper()
156
157 bp := `
158 cc_library {
159 name: "libTest",
160 srcs: ["foo.c"],
161 target: {
162 fuchsia: {
163 srcs: ["bar.c"],
164 },
165 },
166 }`
167
168 config := android.TestArchConfigFuchsia(buildDir, nil)
169 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
170
171 rt := false
172 fb := false
173
174 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
175 implicits := ld.Implicits
176 for _, lib := range implicits {
177 if strings.Contains(lib.Rel(), "libcompiler_rt") {
178 rt = true
179 }
180
181 if strings.Contains(lib.Rel(), "libbioniccompat") {
182 fb = true
183 }
184 }
185
186 if !rt || !fb {
187 t.Errorf("fuchsia libs must link libcompiler_rt and libbioniccompat")
188 }
189}
190
191func TestFuchsiaTargetDecl(t *testing.T) {
192 t.Helper()
193
194 bp := `
195 cc_library {
196 name: "libTest",
197 srcs: ["foo.c"],
198 target: {
199 fuchsia: {
200 srcs: ["bar.c"],
201 },
202 },
203 }`
204
205 config := android.TestArchConfigFuchsia(buildDir, nil)
206 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
207 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
208 var objs []string
209 for _, o := range ld.Inputs {
210 objs = append(objs, o.Base())
211 }
212 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
213 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
214 }
215}
216
Jiyong Park6a43f042017-10-12 23:05:00 +0900217func TestVendorSrc(t *testing.T) {
218 ctx := testCc(t, `
219 cc_library {
220 name: "libTest",
221 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800222 no_libgcc: true,
223 nocrt: true,
224 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900225 vendor_available: true,
226 target: {
227 vendor: {
228 srcs: ["bar.c"],
229 },
230 },
231 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900232 `)
233
Logan Chienf3511742017-10-31 18:04:35 +0800234 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900235 var objs []string
236 for _, o := range ld.Inputs {
237 objs = append(objs, o.Base())
238 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800239 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900240 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
241 }
242}
243
Logan Chienf3511742017-10-31 18:04:35 +0800244func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
245 isVndkSp bool, extends string) {
246
Logan Chiend3c59a22018-03-29 14:08:15 +0800247 t.Helper()
248
Logan Chienf3511742017-10-31 18:04:35 +0800249 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
250 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700251 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800252 }
253
254 // Check library properties.
255 lib, ok := mod.compiler.(*libraryDecorator)
256 if !ok {
257 t.Errorf("%q must have libraryDecorator", name)
258 } else if lib.baseInstaller.subDir != subDir {
259 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
260 lib.baseInstaller.subDir)
261 }
262
263 // Check VNDK properties.
264 if mod.vndkdep == nil {
265 t.Fatalf("%q must have `vndkdep`", name)
266 }
267 if !mod.isVndk() {
268 t.Errorf("%q isVndk() must equal to true", name)
269 }
270 if mod.isVndkSp() != isVndkSp {
271 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
272 }
273
274 // Check VNDK extension properties.
275 isVndkExt := extends != ""
276 if mod.isVndkExt() != isVndkExt {
277 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
278 }
279
280 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
281 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
282 }
283}
284
285func TestVndk(t *testing.T) {
286 ctx := testCc(t, `
287 cc_library {
288 name: "libvndk",
289 vendor_available: true,
290 vndk: {
291 enabled: true,
292 },
293 nocrt: true,
294 }
295
296 cc_library {
297 name: "libvndk_private",
298 vendor_available: false,
299 vndk: {
300 enabled: true,
301 },
302 nocrt: true,
303 }
304
305 cc_library {
306 name: "libvndk_sp",
307 vendor_available: true,
308 vndk: {
309 enabled: true,
310 support_system_process: true,
311 },
312 nocrt: true,
313 }
314
315 cc_library {
316 name: "libvndk_sp_private",
317 vendor_available: false,
318 vndk: {
319 enabled: true,
320 support_system_process: true,
321 },
322 nocrt: true,
323 }
324 `)
325
326 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
327 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
328 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
329 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
330}
331
Logan Chiend3c59a22018-03-29 14:08:15 +0800332func TestVndkDepError(t *testing.T) {
333 // Check whether an error is emitted when a VNDK lib depends on a system lib.
334 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
335 cc_library {
336 name: "libvndk",
337 vendor_available: true,
338 vndk: {
339 enabled: true,
340 },
341 shared_libs: ["libfwk"], // Cause error
342 nocrt: true,
343 }
344
345 cc_library {
346 name: "libfwk",
347 nocrt: true,
348 }
349 `)
350
351 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
352 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
353 cc_library {
354 name: "libvndk",
355 vendor_available: true,
356 vndk: {
357 enabled: true,
358 },
359 shared_libs: ["libvendor"], // Cause error
360 nocrt: true,
361 }
362
363 cc_library {
364 name: "libvendor",
365 vendor: true,
366 nocrt: true,
367 }
368 `)
369
370 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
371 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
372 cc_library {
373 name: "libvndk_sp",
374 vendor_available: true,
375 vndk: {
376 enabled: true,
377 support_system_process: true,
378 },
379 shared_libs: ["libfwk"], // Cause error
380 nocrt: true,
381 }
382
383 cc_library {
384 name: "libfwk",
385 nocrt: true,
386 }
387 `)
388
389 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
390 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
391 cc_library {
392 name: "libvndk_sp",
393 vendor_available: true,
394 vndk: {
395 enabled: true,
396 support_system_process: true,
397 },
398 shared_libs: ["libvendor"], // Cause error
399 nocrt: true,
400 }
401
402 cc_library {
403 name: "libvendor",
404 vendor: true,
405 nocrt: true,
406 }
407 `)
408
409 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
410 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
411 cc_library {
412 name: "libvndk_sp",
413 vendor_available: true,
414 vndk: {
415 enabled: true,
416 support_system_process: true,
417 },
418 shared_libs: ["libvndk"], // Cause error
419 nocrt: true,
420 }
421
422 cc_library {
423 name: "libvndk",
424 vendor_available: true,
425 vndk: {
426 enabled: true,
427 },
428 nocrt: true,
429 }
430 `)
431}
432
Justin Yun9357f4a2018-11-28 15:14:47 +0900433func TestVndkMustNotBeProductSpecific(t *testing.T) {
434 // Check whether an error is emitted when a vndk lib has 'product_specific: true'.
435 testCcError(t, "product_specific must not be true when `vndk: {enabled: true}`", `
436 cc_library {
437 name: "libvndk",
438 product_specific: true, // Cause error
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
Martin Stjernholmef449fe2018-11-06 16:12:13 +0000850 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +0800851 cc_library {
852 name: "libvndk",
853 vendor_available: true,
854 vndk: {
855 enabled: true,
856 },
857 nocrt: true,
858 }
859
860 cc_library {
861 name: "libvndk_ext",
862 vendor: true,
863 vndk: {
864 enabled: true,
865 extends: "libvndk",
866 },
867 nocrt: true,
868 }
869
870 cc_library {
871 name: "libvndk2",
872 vendor_available: true,
873 vndk: {
874 enabled: true,
875 },
876 target: {
877 vendor: {
878 shared_libs: ["libvndk_ext"],
879 },
880 },
881 nocrt: true,
882 }
883 `)
884
885 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
886 cc_library {
887 name: "libvndk_sp",
888 vendor_available: true,
889 vndk: {
890 enabled: true,
891 support_system_process: true,
892 },
893 nocrt: true,
894 }
895
896 cc_library {
897 name: "libvndk_sp_ext",
898 vendor: true,
899 vndk: {
900 enabled: true,
901 extends: "libvndk_sp",
902 support_system_process: true,
903 },
904 nocrt: true,
905 }
906
907 cc_library {
908 name: "libvndk_sp_2",
909 vendor_available: true,
910 vndk: {
911 enabled: true,
912 support_system_process: true,
913 },
914 shared_libs: ["libvndk_sp_ext"],
915 nocrt: true,
916 }
917 `)
918
Martin Stjernholmef449fe2018-11-06 16:12:13 +0000919 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +0800920 cc_library {
921 name: "libvndk_sp",
922 vendor_available: true,
923 vndk: {
924 enabled: true,
925 },
926 nocrt: true,
927 }
928
929 cc_library {
930 name: "libvndk_sp_ext",
931 vendor: true,
932 vndk: {
933 enabled: true,
934 extends: "libvndk_sp",
935 },
936 nocrt: true,
937 }
938
939 cc_library {
940 name: "libvndk_sp2",
941 vendor_available: true,
942 vndk: {
943 enabled: true,
944 },
945 target: {
946 vendor: {
947 shared_libs: ["libvndk_sp_ext"],
948 },
949 },
950 nocrt: true,
951 }
952 `)
953}
954
Colin Cross0af4b842015-04-30 16:36:18 -0700955var (
956 str11 = "01234567891"
957 str10 = str11[:10]
958 str9 = str11[:9]
959 str5 = str11[:5]
960 str4 = str11[:4]
961)
962
963var splitListForSizeTestCases = []struct {
964 in []string
965 out [][]string
966 size int
967}{
968 {
969 in: []string{str10},
970 out: [][]string{{str10}},
971 size: 10,
972 },
973 {
974 in: []string{str9},
975 out: [][]string{{str9}},
976 size: 10,
977 },
978 {
979 in: []string{str5},
980 out: [][]string{{str5}},
981 size: 10,
982 },
983 {
984 in: []string{str11},
985 out: nil,
986 size: 10,
987 },
988 {
989 in: []string{str10, str10},
990 out: [][]string{{str10}, {str10}},
991 size: 10,
992 },
993 {
994 in: []string{str9, str10},
995 out: [][]string{{str9}, {str10}},
996 size: 10,
997 },
998 {
999 in: []string{str10, str9},
1000 out: [][]string{{str10}, {str9}},
1001 size: 10,
1002 },
1003 {
1004 in: []string{str5, str4},
1005 out: [][]string{{str5, str4}},
1006 size: 10,
1007 },
1008 {
1009 in: []string{str5, str4, str5},
1010 out: [][]string{{str5, str4}, {str5}},
1011 size: 10,
1012 },
1013 {
1014 in: []string{str5, str4, str5, str4},
1015 out: [][]string{{str5, str4}, {str5, str4}},
1016 size: 10,
1017 },
1018 {
1019 in: []string{str5, str4, str5, str5},
1020 out: [][]string{{str5, str4}, {str5}, {str5}},
1021 size: 10,
1022 },
1023 {
1024 in: []string{str5, str5, str5, str4},
1025 out: [][]string{{str5}, {str5}, {str5, str4}},
1026 size: 10,
1027 },
1028 {
1029 in: []string{str9, str11},
1030 out: nil,
1031 size: 10,
1032 },
1033 {
1034 in: []string{str11, str9},
1035 out: nil,
1036 size: 10,
1037 },
1038}
1039
1040func TestSplitListForSize(t *testing.T) {
1041 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -07001042 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
1043
1044 var outStrings [][]string
1045
1046 if len(out) > 0 {
1047 outStrings = make([][]string, len(out))
1048 for i, o := range out {
1049 outStrings[i] = o.Strings()
1050 }
1051 }
1052
1053 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001054 t.Errorf("incorrect output:")
1055 t.Errorf(" input: %#v", testCase.in)
1056 t.Errorf(" size: %d", testCase.size)
1057 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001058 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001059 }
1060 }
1061}
Jeff Gaston294356f2017-09-27 17:05:30 -07001062
1063var staticLinkDepOrderTestCases = []struct {
1064 // This is a string representation of a map[moduleName][]moduleDependency .
1065 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001066 inStatic string
1067
1068 // This is a string representation of a map[moduleName][]moduleDependency .
1069 // It models the dependencies declared in an Android.bp file.
1070 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001071
1072 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1073 // The keys of allOrdered specify which modules we would like to check.
1074 // The values of allOrdered specify the expected result (of the transitive closure of all
1075 // dependencies) for each module to test
1076 allOrdered string
1077
1078 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1079 // The keys of outOrdered specify which modules we would like to check.
1080 // The values of outOrdered specify the expected result (of the ordered linker command line)
1081 // for each module to test.
1082 outOrdered string
1083}{
1084 // Simple tests
1085 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001086 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001087 outOrdered: "",
1088 },
1089 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001090 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001091 outOrdered: "a:",
1092 },
1093 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001094 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001095 outOrdered: "a:b; b:",
1096 },
1097 // Tests of reordering
1098 {
1099 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001100 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001101 outOrdered: "a:b,c,d; b:d; c:d; d:",
1102 },
1103 {
1104 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001105 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001106 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1107 },
1108 {
1109 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001110 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001111 outOrdered: "a:d,b,e,c; d:b; e:c",
1112 },
1113 {
1114 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001115 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001116 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1117 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1118 },
1119 {
1120 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001121 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 -07001122 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1123 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1124 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001125 // shared dependencies
1126 {
1127 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1128 // So, we don't actually have to check that a shared dependency of c will change the order
1129 // of a library that depends statically on b and on c. We only need to check that if c has
1130 // a shared dependency on b, that that shows up in allOrdered.
1131 inShared: "c:b",
1132 allOrdered: "c:b",
1133 outOrdered: "c:",
1134 },
1135 {
1136 // This test doesn't actually include any shared dependencies but it's a reminder of what
1137 // the second phase of the above test would look like
1138 inStatic: "a:b,c; c:b",
1139 allOrdered: "a:c,b; c:b",
1140 outOrdered: "a:c,b; c:b",
1141 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001142 // tiebreakers for when two modules specifying different orderings and there is no dependency
1143 // to dictate an order
1144 {
1145 // 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 -08001146 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001147 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1148 },
1149 {
1150 // 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 -08001151 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 -07001152 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1153 },
1154 // Tests involving duplicate dependencies
1155 {
1156 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001157 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001158 outOrdered: "a:c,b",
1159 },
1160 {
1161 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001162 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001163 outOrdered: "a:d,c,b",
1164 },
1165 // Tests to confirm the nonexistence of infinite loops.
1166 // These cases should never happen, so as long as the test terminates and the
1167 // result is deterministic then that should be fine.
1168 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001169 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001170 outOrdered: "a:a",
1171 },
1172 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001173 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001174 allOrdered: "a:b,c; b:c,a; c:a,b",
1175 outOrdered: "a:b; b:c; c:a",
1176 },
1177 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001178 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001179 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1180 outOrdered: "a:c,b; b:a,c; c:b,a",
1181 },
1182}
1183
1184// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1185func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1186 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1187 strippedText := strings.Replace(text, " ", "", -1)
1188 if len(strippedText) < 1 {
1189 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1190 }
1191 allDeps = make(map[android.Path][]android.Path, 0)
1192
1193 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1194 moduleTexts := strings.Split(strippedText, ";")
1195
1196 outputForModuleName := func(moduleName string) android.Path {
1197 return android.PathForTesting(moduleName)
1198 }
1199
1200 for _, moduleText := range moduleTexts {
1201 // convert from "a:b,c" to ["a", "b,c"]
1202 components := strings.Split(moduleText, ":")
1203 if len(components) != 2 {
1204 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1205 }
1206 moduleName := components[0]
1207 moduleOutput := outputForModuleName(moduleName)
1208 modulesInOrder = append(modulesInOrder, moduleOutput)
1209
1210 depString := components[1]
1211 // convert from "b,c" to ["b", "c"]
1212 depNames := strings.Split(depString, ",")
1213 if len(depString) < 1 {
1214 depNames = []string{}
1215 }
1216 var deps []android.Path
1217 for _, depName := range depNames {
1218 deps = append(deps, outputForModuleName(depName))
1219 }
1220 allDeps[moduleOutput] = deps
1221 }
1222 return modulesInOrder, allDeps
1223}
1224
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001225func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001226 for _, testCase := range staticLinkDepOrderTestCases {
1227 errs := []string{}
1228
1229 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001230 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001231 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1232 if testCase.allOrdered == "" {
1233 // allow the test case to skip specifying allOrdered
1234 testCase.allOrdered = testCase.outOrdered
1235 }
1236 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001237 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001238
1239 // For each module whose post-reordered dependencies were specified, validate that
1240 // reordering the inputs produces the expected outputs.
1241 for _, moduleName := range expectedModuleNames {
1242 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001243 givenSharedDeps := givenAllSharedDeps[moduleName]
1244 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001245
1246 correctAllOrdered := expectedAllDeps[moduleName]
1247 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1248 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001249 "\nin static:%q"+
1250 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001251 "\nmodule: %v"+
1252 "\nexpected: %s"+
1253 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001254 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001255 }
1256
1257 correctOutputDeps := expectedTransitiveDeps[moduleName]
1258 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1259 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001260 "\nin static:%q"+
1261 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001262 "\nmodule: %v"+
1263 "\nexpected: %s"+
1264 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001265 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001266 }
1267 }
1268
1269 if len(errs) > 0 {
1270 sort.Strings(errs)
1271 for _, err := range errs {
1272 t.Error(err)
1273 }
1274 }
1275 }
1276}
Logan Chienf3511742017-10-31 18:04:35 +08001277
Jeff Gaston294356f2017-09-27 17:05:30 -07001278func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1279 for _, moduleName := range moduleNames {
1280 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1281 output := module.outputFile.Path()
1282 paths = append(paths, output)
1283 }
1284 return paths
1285}
1286
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001287func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001288 ctx := testCc(t, `
1289 cc_library {
1290 name: "a",
1291 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001292 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001293 }
1294 cc_library {
1295 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001296 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001297 }
1298 cc_library {
1299 name: "c",
1300 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001301 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001302 }
1303 cc_library {
1304 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001305 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001306 }
1307
1308 `)
1309
1310 variant := "android_arm64_armv8-a_core_static"
1311 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001312 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001313 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1314
1315 if !reflect.DeepEqual(actual, expected) {
1316 t.Errorf("staticDeps orderings were not propagated correctly"+
1317 "\nactual: %v"+
1318 "\nexpected: %v",
1319 actual,
1320 expected,
1321 )
1322 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001323}
Jeff Gaston294356f2017-09-27 17:05:30 -07001324
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001325func TestStaticLibDepReorderingWithShared(t *testing.T) {
1326 ctx := testCc(t, `
1327 cc_library {
1328 name: "a",
1329 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001330 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001331 }
1332 cc_library {
1333 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001334 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001335 }
1336 cc_library {
1337 name: "c",
1338 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001339 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001340 }
1341
1342 `)
1343
1344 variant := "android_arm64_armv8-a_core_static"
1345 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1346 actual := moduleA.depsInLinkOrder
1347 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1348
1349 if !reflect.DeepEqual(actual, expected) {
1350 t.Errorf("staticDeps orderings did not account for shared libs"+
1351 "\nactual: %v"+
1352 "\nexpected: %v",
1353 actual,
1354 expected,
1355 )
1356 }
1357}
1358
Jiyong Parka46a4d52017-12-14 19:54:34 +09001359func TestLlndkHeaders(t *testing.T) {
1360 ctx := testCc(t, `
1361 llndk_headers {
1362 name: "libllndk_headers",
1363 export_include_dirs: ["my_include"],
1364 }
1365 llndk_library {
1366 name: "libllndk",
1367 export_llndk_headers: ["libllndk_headers"],
1368 }
1369 cc_library {
1370 name: "libvendor",
1371 shared_libs: ["libllndk"],
1372 vendor: true,
1373 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001374 no_libgcc: true,
1375 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001376 }
1377 `)
1378
1379 // _static variant is used since _shared reuses *.o from the static variant
1380 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1381 cflags := cc.Args["cFlags"]
1382 if !strings.Contains(cflags, "-Imy_include") {
1383 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1384 }
1385}
1386
Logan Chien43d34c32017-12-20 01:17:32 +08001387func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1388 actual := module.Properties.AndroidMkRuntimeLibs
1389 if !reflect.DeepEqual(actual, expected) {
1390 t.Errorf("incorrect runtime_libs for shared libs"+
1391 "\nactual: %v"+
1392 "\nexpected: %v",
1393 actual,
1394 expected,
1395 )
1396 }
1397}
1398
1399const runtimeLibAndroidBp = `
1400 cc_library {
1401 name: "libvendor_available1",
1402 vendor_available: true,
1403 no_libgcc : true,
1404 nocrt : true,
1405 system_shared_libs : [],
1406 }
1407 cc_library {
1408 name: "libvendor_available2",
1409 vendor_available: true,
1410 runtime_libs: ["libvendor_available1"],
1411 no_libgcc : true,
1412 nocrt : true,
1413 system_shared_libs : [],
1414 }
1415 cc_library {
1416 name: "libvendor_available3",
1417 vendor_available: true,
1418 runtime_libs: ["libvendor_available1"],
1419 target: {
1420 vendor: {
1421 exclude_runtime_libs: ["libvendor_available1"],
1422 }
1423 },
1424 no_libgcc : true,
1425 nocrt : true,
1426 system_shared_libs : [],
1427 }
1428 cc_library {
1429 name: "libcore",
1430 runtime_libs: ["libvendor_available1"],
1431 no_libgcc : true,
1432 nocrt : true,
1433 system_shared_libs : [],
1434 }
1435 cc_library {
1436 name: "libvendor1",
1437 vendor: true,
1438 no_libgcc : true,
1439 nocrt : true,
1440 system_shared_libs : [],
1441 }
1442 cc_library {
1443 name: "libvendor2",
1444 vendor: true,
1445 runtime_libs: ["libvendor_available1", "libvendor1"],
1446 no_libgcc : true,
1447 nocrt : true,
1448 system_shared_libs : [],
1449 }
1450`
1451
1452func TestRuntimeLibs(t *testing.T) {
1453 ctx := testCc(t, runtimeLibAndroidBp)
1454
1455 // runtime_libs for core variants use the module names without suffixes.
1456 variant := "android_arm64_armv8-a_core_shared"
1457
1458 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1459 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1460
1461 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1462 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1463
1464 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1465 // and vendor variants.
1466 variant = "android_arm64_armv8-a_vendor_shared"
1467
1468 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1469 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1470
1471 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1472 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1473}
1474
1475func TestExcludeRuntimeLibs(t *testing.T) {
1476 ctx := testCc(t, runtimeLibAndroidBp)
1477
1478 variant := "android_arm64_armv8-a_core_shared"
1479 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1480 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1481
1482 variant = "android_arm64_armv8-a_vendor_shared"
1483 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1484 checkRuntimeLibs(t, nil, module)
1485}
1486
1487func TestRuntimeLibsNoVndk(t *testing.T) {
1488 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1489
1490 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1491
1492 variant := "android_arm64_armv8-a_core_shared"
1493
1494 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1495 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1496
1497 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1498 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1499}
1500
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001501func checkStaticLibs(t *testing.T, expected []string, module *Module) {
1502 actual := module.Properties.AndroidMkStaticLibs
1503 if !reflect.DeepEqual(actual, expected) {
1504 t.Errorf("incorrect static_libs"+
1505 "\nactual: %v"+
1506 "\nexpected: %v",
1507 actual,
1508 expected,
1509 )
1510 }
1511}
1512
1513const staticLibAndroidBp = `
1514 cc_library {
1515 name: "lib1",
1516 }
1517 cc_library {
1518 name: "lib2",
1519 static_libs: ["lib1"],
1520 }
1521`
1522
1523func TestStaticLibDepExport(t *testing.T) {
1524 ctx := testCc(t, staticLibAndroidBp)
1525
1526 // Check the shared version of lib2.
1527 variant := "android_arm64_armv8-a_core_shared"
1528 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
1529 checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
1530
1531 // Check the static version of lib2.
1532 variant = "android_arm64_armv8-a_core_static"
1533 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1534 // libc++_static is linked additionally.
1535 checkStaticLibs(t, []string{"lib1", "libc++_static", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
1536}
1537
Jiyong Parkd08b6972017-09-26 10:50:54 +09001538var compilerFlagsTestCases = []struct {
1539 in string
1540 out bool
1541}{
1542 {
1543 in: "a",
1544 out: false,
1545 },
1546 {
1547 in: "-a",
1548 out: true,
1549 },
1550 {
1551 in: "-Ipath/to/something",
1552 out: false,
1553 },
1554 {
1555 in: "-isystempath/to/something",
1556 out: false,
1557 },
1558 {
1559 in: "--coverage",
1560 out: false,
1561 },
1562 {
1563 in: "-include a/b",
1564 out: true,
1565 },
1566 {
1567 in: "-include a/b c/d",
1568 out: false,
1569 },
1570 {
1571 in: "-DMACRO",
1572 out: true,
1573 },
1574 {
1575 in: "-DMAC RO",
1576 out: false,
1577 },
1578 {
1579 in: "-a -b",
1580 out: false,
1581 },
1582 {
1583 in: "-DMACRO=definition",
1584 out: true,
1585 },
1586 {
1587 in: "-DMACRO=defi nition",
1588 out: true, // TODO(jiyong): this should be false
1589 },
1590 {
1591 in: "-DMACRO(x)=x + 1",
1592 out: true,
1593 },
1594 {
1595 in: "-DMACRO=\"defi nition\"",
1596 out: true,
1597 },
1598}
1599
1600type mockContext struct {
1601 BaseModuleContext
1602 result bool
1603}
1604
1605func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1606 // CheckBadCompilerFlags calls this function when the flag should be rejected
1607 ctx.result = false
1608}
1609
1610func TestCompilerFlags(t *testing.T) {
1611 for _, testCase := range compilerFlagsTestCases {
1612 ctx := &mockContext{result: true}
1613 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1614 if ctx.result != testCase.out {
1615 t.Errorf("incorrect output:")
1616 t.Errorf(" input: %#v", testCase.in)
1617 t.Errorf(" expected: %#v", testCase.out)
1618 t.Errorf(" got: %#v", ctx.result)
1619 }
1620 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001621}
Jiyong Park374510b2018-03-19 18:23:01 +09001622
1623func TestVendorPublicLibraries(t *testing.T) {
1624 ctx := testCc(t, `
1625 cc_library_headers {
1626 name: "libvendorpublic_headers",
1627 export_include_dirs: ["my_include"],
1628 }
1629 vendor_public_library {
1630 name: "libvendorpublic",
1631 symbol_file: "",
1632 export_public_headers: ["libvendorpublic_headers"],
1633 }
1634 cc_library {
1635 name: "libvendorpublic",
1636 srcs: ["foo.c"],
1637 vendor: true,
1638 no_libgcc: true,
1639 nocrt: true,
1640 }
1641
1642 cc_library {
1643 name: "libsystem",
1644 shared_libs: ["libvendorpublic"],
1645 vendor: false,
1646 srcs: ["foo.c"],
1647 no_libgcc: true,
1648 nocrt: true,
1649 }
1650 cc_library {
1651 name: "libvendor",
1652 shared_libs: ["libvendorpublic"],
1653 vendor: true,
1654 srcs: ["foo.c"],
1655 no_libgcc: true,
1656 nocrt: true,
1657 }
1658 `)
1659
1660 variant := "android_arm64_armv8-a_core_shared"
1661
1662 // test if header search paths are correctly added
1663 // _static variant is used since _shared reuses *.o from the static variant
1664 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
1665 cflags := cc.Args["cFlags"]
1666 if !strings.Contains(cflags, "-Imy_include") {
1667 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
1668 }
1669
1670 // test if libsystem is linked to the stub
1671 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
1672 libflags := ld.Args["libFlags"]
1673 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
1674 if !strings.Contains(libflags, stubPaths[0].String()) {
1675 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
1676 }
1677
1678 // test if libvendor is linked to the real shared lib
1679 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
1680 libflags = ld.Args["libFlags"]
1681 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
1682 if !strings.Contains(libflags, stubPaths[0].String()) {
1683 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
1684 }
1685
1686}
Jiyong Park37b25202018-07-11 10:49:27 +09001687
1688func TestRecovery(t *testing.T) {
1689 ctx := testCc(t, `
1690 cc_library_shared {
1691 name: "librecovery",
1692 recovery: true,
1693 }
1694 cc_library_shared {
1695 name: "librecovery32",
1696 recovery: true,
1697 compile_multilib:"32",
1698 }
Jiyong Park5baac542018-08-28 09:55:37 +09001699 cc_library_shared {
1700 name: "libHalInRecovery",
1701 recovery_available: true,
1702 vendor: true,
1703 }
Jiyong Park37b25202018-07-11 10:49:27 +09001704 `)
1705
1706 variants := ctx.ModuleVariantsForTests("librecovery")
1707 const arm64 = "android_arm64_armv8-a_recovery_shared"
1708 if len(variants) != 1 || !android.InList(arm64, variants) {
1709 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1710 }
1711
1712 variants = ctx.ModuleVariantsForTests("librecovery32")
1713 if android.InList(arm64, variants) {
1714 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1715 }
Jiyong Park5baac542018-08-28 09:55:37 +09001716
1717 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1718 if !recoveryModule.Platform() {
1719 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1720 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09001721}
Jiyong Park5baac542018-08-28 09:55:37 +09001722
Jiyong Park7ed9de32018-10-15 22:25:07 +09001723func TestVersionedStubs(t *testing.T) {
1724 ctx := testCc(t, `
1725 cc_library_shared {
1726 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001727 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001728 stubs: {
1729 symbol_file: "foo.map.txt",
1730 versions: ["1", "2", "3"],
1731 },
1732 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001733
Jiyong Park7ed9de32018-10-15 22:25:07 +09001734 cc_library_shared {
1735 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001736 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001737 shared_libs: ["libFoo#1"],
1738 }`)
1739
1740 variants := ctx.ModuleVariantsForTests("libFoo")
1741 expectedVariants := []string{
1742 "android_arm64_armv8-a_core_shared",
1743 "android_arm64_armv8-a_core_shared_1",
1744 "android_arm64_armv8-a_core_shared_2",
1745 "android_arm64_armv8-a_core_shared_3",
1746 "android_arm_armv7-a-neon_core_shared",
1747 "android_arm_armv7-a-neon_core_shared_1",
1748 "android_arm_armv7-a-neon_core_shared_2",
1749 "android_arm_armv7-a-neon_core_shared_3",
1750 }
1751 variantsMismatch := false
1752 if len(variants) != len(expectedVariants) {
1753 variantsMismatch = true
1754 } else {
1755 for _, v := range expectedVariants {
1756 if !inList(v, variants) {
1757 variantsMismatch = false
1758 }
1759 }
1760 }
1761 if variantsMismatch {
1762 t.Errorf("variants of libFoo expected:\n")
1763 for _, v := range expectedVariants {
1764 t.Errorf("%q\n", v)
1765 }
1766 t.Errorf(", but got:\n")
1767 for _, v := range variants {
1768 t.Errorf("%q\n", v)
1769 }
1770 }
1771
1772 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld")
1773 libFlags := libBarLinkRule.Args["libFlags"]
1774 libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so"
1775 if !strings.Contains(libFlags, libFoo1StubPath) {
1776 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
1777 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001778
1779 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("cc")
1780 cFlags := libBarCompileRule.Args["cFlags"]
1781 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
1782 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
1783 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
1784 }
Jiyong Park37b25202018-07-11 10:49:27 +09001785}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001786
1787func TestStaticExecutable(t *testing.T) {
1788 ctx := testCc(t, `
1789 cc_binary {
1790 name: "static_test",
1791 srcs: ["foo.c"],
1792 static_executable: true,
1793 }`)
1794
1795 variant := "android_arm64_armv8-a_core"
1796 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
1797 libFlags := binModuleRule.Args["libFlags"]
1798 systemStaticLibs := []string{"libc.a", "libm.a", "libdl.a"}
1799 for _, lib := range systemStaticLibs {
1800 if !strings.Contains(libFlags, lib) {
1801 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
1802 }
1803 }
1804 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
1805 for _, lib := range systemSharedLibs {
1806 if strings.Contains(libFlags, lib) {
1807 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
1808 }
1809 }
1810}
Jiyong Parke4bb9862019-02-01 00:31:10 +09001811
1812func TestStaticDepsOrderWithStubs(t *testing.T) {
1813 ctx := testCc(t, `
1814 cc_binary {
1815 name: "mybin",
1816 srcs: ["foo.c"],
1817 static_libs: ["libB"],
1818 static_executable: true,
1819 stl: "none",
1820 }
1821
1822 cc_library {
1823 name: "libB",
1824 srcs: ["foo.c"],
1825 shared_libs: ["libC"],
1826 stl: "none",
1827 }
1828
1829 cc_library {
1830 name: "libC",
1831 srcs: ["foo.c"],
1832 stl: "none",
1833 stubs: {
1834 versions: ["1"],
1835 },
1836 }`)
1837
1838 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a_core").Module().(*Module)
1839 actual := mybin.depsInLinkOrder
1840 expected := getOutputPaths(ctx, "android_arm64_armv8-a_core_static", []string{"libB", "libC"})
1841
1842 if !reflect.DeepEqual(actual, expected) {
1843 t.Errorf("staticDeps orderings were not propagated correctly"+
1844 "\nactual: %v"+
1845 "\nexpected: %v",
1846 actual,
1847 expected,
1848 )
1849 }
1850}