blob: 678f90d20d72c2b98bfa0d850f626b2f5578cce8 [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
Colin Cross9bd624c2019-05-14 14:07:01 -070054func createTestContext(t *testing.T, config android.Config, bp string, fs map[string][]byte,
55 os android.OsType) *android.TestContext {
56
Doug Hornc32c6b02019-01-17 14:44:05 -080057 ctx := android.NewTestArchContext()
58 ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(BinaryFactory))
Colin Crossfe17f6f2019-03-28 19:30:56 -070059 ctx.RegisterModuleType("cc_binary_host", android.ModuleFactoryAdaptor(binaryHostFactory))
Doug Hornc32c6b02019-01-17 14:44:05 -080060 ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory))
61 ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory))
Jiyong Parke4bb9862019-02-01 00:31:10 +090062 ctx.RegisterModuleType("cc_library_static", android.ModuleFactoryAdaptor(LibraryStaticFactory))
Doug Hornc32c6b02019-01-17 14:44:05 -080063 ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory))
64 ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(ToolchainLibraryFactory))
65 ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(LlndkLibraryFactory))
66 ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory))
67 ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
68 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory))
69 ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
70 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
71 ctx.BottomUp("image", ImageMutator).Parallel()
72 ctx.BottomUp("link", LinkageMutator).Parallel()
73 ctx.BottomUp("vndk", VndkMutator).Parallel()
74 ctx.BottomUp("version", VersionMutator).Parallel()
75 ctx.BottomUp("begin", BeginMutator).Parallel()
76 })
Jooyung Hana70f0672019-01-18 15:20:43 +090077 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
78 ctx.TopDown("double_loadable", checkDoubleLoadableLibraries).Parallel()
79 })
Doug Hornc32c6b02019-01-17 14:44:05 -080080
81 // add some modules that are required by the compiler and/or linker
Inseob Kimc0907f12019-02-08 21:00:45 +090082 bp = bp + GatherRequiredDepsForTest(os)
Jeff Gaston294356f2017-09-27 17:05:30 -070083
Colin Cross9bd624c2019-05-14 14:07:01 -070084 mockFS := map[string][]byte{
Jiyong Park7ed9de32018-10-15 22:25:07 +090085 "Android.bp": []byte(bp),
86 "foo.c": nil,
87 "bar.c": nil,
88 "a.proto": nil,
89 "b.aidl": nil,
90 "my_include": nil,
91 "foo.map.txt": nil,
Colin Cross9bd624c2019-05-14 14:07:01 -070092 "liba.so": nil,
93 }
94
95 for k, v := range fs {
96 mockFS[k] = v
97 }
98
99 ctx.MockFileSystem(mockFS)
Jiyong Park6a43f042017-10-12 23:05:00 +0900100
Logan Chienf3511742017-10-31 18:04:35 +0800101 return ctx
102}
103
104func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Doug Hornc32c6b02019-01-17 14:44:05 -0800105 return testCcWithConfigForOs(t, bp, config, android.Android)
106}
107
108func testCcWithConfigForOs(t *testing.T, bp string, config android.Config, os android.OsType) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800109 t.Helper()
Colin Cross9bd624c2019-05-14 14:07:01 -0700110 ctx := createTestContext(t, config, bp, nil, os)
111 ctx.Register()
Logan Chienf3511742017-10-31 18:04:35 +0800112
Jeff Gastond3e141d2017-08-08 17:46:01 -0700113 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +0800114 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900115 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800116 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900117
118 return ctx
119}
120
Logan Chienf3511742017-10-31 18:04:35 +0800121func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800122 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800123 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700124 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
125 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800126
127 return testCcWithConfig(t, bp, config)
128}
129
130func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800131 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800132 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700133 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800134
135 return testCcWithConfig(t, bp, config)
136}
137
138func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800139 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800140 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700141 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
142 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800143
Colin Cross9bd624c2019-05-14 14:07:01 -0700144 ctx := createTestContext(t, config, bp, nil, android.Android)
145 ctx.Register()
Logan Chienf3511742017-10-31 18:04:35 +0800146
147 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
148 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800149 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800150 return
151 }
152
153 _, errs = ctx.PrepareBuildActions(config)
154 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800155 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800156 return
157 }
158
159 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
160}
161
162const (
Jiyong Park5baac542018-08-28 09:55:37 +0900163 coreVariant = "android_arm64_armv8-a_core_shared"
164 vendorVariant = "android_arm64_armv8-a_vendor_shared"
165 recoveryVariant = "android_arm64_armv8-a_recovery_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800166)
167
Doug Hornc32c6b02019-01-17 14:44:05 -0800168func TestFuchsiaDeps(t *testing.T) {
169 t.Helper()
170
171 bp := `
172 cc_library {
173 name: "libTest",
174 srcs: ["foo.c"],
175 target: {
176 fuchsia: {
177 srcs: ["bar.c"],
178 },
179 },
180 }`
181
182 config := android.TestArchConfigFuchsia(buildDir, nil)
183 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
184
185 rt := false
186 fb := false
187
188 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
189 implicits := ld.Implicits
190 for _, lib := range implicits {
191 if strings.Contains(lib.Rel(), "libcompiler_rt") {
192 rt = true
193 }
194
195 if strings.Contains(lib.Rel(), "libbioniccompat") {
196 fb = true
197 }
198 }
199
200 if !rt || !fb {
201 t.Errorf("fuchsia libs must link libcompiler_rt and libbioniccompat")
202 }
203}
204
205func TestFuchsiaTargetDecl(t *testing.T) {
206 t.Helper()
207
208 bp := `
209 cc_library {
210 name: "libTest",
211 srcs: ["foo.c"],
212 target: {
213 fuchsia: {
214 srcs: ["bar.c"],
215 },
216 },
217 }`
218
219 config := android.TestArchConfigFuchsia(buildDir, nil)
220 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
221 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
222 var objs []string
223 for _, o := range ld.Inputs {
224 objs = append(objs, o.Base())
225 }
226 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
227 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
228 }
229}
230
Jiyong Park6a43f042017-10-12 23:05:00 +0900231func TestVendorSrc(t *testing.T) {
232 ctx := testCc(t, `
233 cc_library {
234 name: "libTest",
235 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800236 no_libgcc: true,
237 nocrt: true,
238 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900239 vendor_available: true,
240 target: {
241 vendor: {
242 srcs: ["bar.c"],
243 },
244 },
245 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900246 `)
247
Logan Chienf3511742017-10-31 18:04:35 +0800248 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900249 var objs []string
250 for _, o := range ld.Inputs {
251 objs = append(objs, o.Base())
252 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800253 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900254 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
255 }
256}
257
Logan Chienf3511742017-10-31 18:04:35 +0800258func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
259 isVndkSp bool, extends string) {
260
Logan Chiend3c59a22018-03-29 14:08:15 +0800261 t.Helper()
262
Logan Chienf3511742017-10-31 18:04:35 +0800263 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
264 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700265 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800266 }
267
268 // Check library properties.
269 lib, ok := mod.compiler.(*libraryDecorator)
270 if !ok {
271 t.Errorf("%q must have libraryDecorator", name)
272 } else if lib.baseInstaller.subDir != subDir {
273 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
274 lib.baseInstaller.subDir)
275 }
276
277 // Check VNDK properties.
278 if mod.vndkdep == nil {
279 t.Fatalf("%q must have `vndkdep`", name)
280 }
281 if !mod.isVndk() {
282 t.Errorf("%q isVndk() must equal to true", name)
283 }
284 if mod.isVndkSp() != isVndkSp {
285 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
286 }
287
288 // Check VNDK extension properties.
289 isVndkExt := extends != ""
290 if mod.isVndkExt() != isVndkExt {
291 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
292 }
293
294 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
295 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
296 }
297}
298
299func TestVndk(t *testing.T) {
300 ctx := testCc(t, `
301 cc_library {
302 name: "libvndk",
303 vendor_available: true,
304 vndk: {
305 enabled: true,
306 },
307 nocrt: true,
308 }
309
310 cc_library {
311 name: "libvndk_private",
312 vendor_available: false,
313 vndk: {
314 enabled: true,
315 },
316 nocrt: true,
317 }
318
319 cc_library {
320 name: "libvndk_sp",
321 vendor_available: true,
322 vndk: {
323 enabled: true,
324 support_system_process: true,
325 },
326 nocrt: true,
327 }
328
329 cc_library {
330 name: "libvndk_sp_private",
331 vendor_available: false,
332 vndk: {
333 enabled: true,
334 support_system_process: true,
335 },
336 nocrt: true,
337 }
338 `)
339
340 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
341 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
342 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
343 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
344}
345
Logan Chiend3c59a22018-03-29 14:08:15 +0800346func TestVndkDepError(t *testing.T) {
347 // Check whether an error is emitted when a VNDK lib depends on a system lib.
348 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
349 cc_library {
350 name: "libvndk",
351 vendor_available: true,
352 vndk: {
353 enabled: true,
354 },
355 shared_libs: ["libfwk"], // Cause error
356 nocrt: true,
357 }
358
359 cc_library {
360 name: "libfwk",
361 nocrt: true,
362 }
363 `)
364
365 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
366 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
367 cc_library {
368 name: "libvndk",
369 vendor_available: true,
370 vndk: {
371 enabled: true,
372 },
373 shared_libs: ["libvendor"], // Cause error
374 nocrt: true,
375 }
376
377 cc_library {
378 name: "libvendor",
379 vendor: true,
380 nocrt: true,
381 }
382 `)
383
384 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
385 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
386 cc_library {
387 name: "libvndk_sp",
388 vendor_available: true,
389 vndk: {
390 enabled: true,
391 support_system_process: true,
392 },
393 shared_libs: ["libfwk"], // Cause error
394 nocrt: true,
395 }
396
397 cc_library {
398 name: "libfwk",
399 nocrt: true,
400 }
401 `)
402
403 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
404 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
405 cc_library {
406 name: "libvndk_sp",
407 vendor_available: true,
408 vndk: {
409 enabled: true,
410 support_system_process: true,
411 },
412 shared_libs: ["libvendor"], // Cause error
413 nocrt: true,
414 }
415
416 cc_library {
417 name: "libvendor",
418 vendor: true,
419 nocrt: true,
420 }
421 `)
422
423 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
424 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
425 cc_library {
426 name: "libvndk_sp",
427 vendor_available: true,
428 vndk: {
429 enabled: true,
430 support_system_process: true,
431 },
432 shared_libs: ["libvndk"], // Cause error
433 nocrt: true,
434 }
435
436 cc_library {
437 name: "libvndk",
438 vendor_available: true,
439 vndk: {
440 enabled: true,
441 },
442 nocrt: true,
443 }
444 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900445
446 // Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib.
447 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
448 cc_library {
449 name: "libvndk",
450 vendor_available: true,
451 vndk: {
452 enabled: true,
453 },
454 shared_libs: ["libnonvndk"],
455 nocrt: true,
456 }
457
458 cc_library {
459 name: "libnonvndk",
460 vendor_available: true,
461 nocrt: true,
462 }
463 `)
464
465 // Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib.
466 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
467 cc_library {
468 name: "libvndkprivate",
469 vendor_available: false,
470 vndk: {
471 enabled: true,
472 },
473 shared_libs: ["libnonvndk"],
474 nocrt: true,
475 }
476
477 cc_library {
478 name: "libnonvndk",
479 vendor_available: true,
480 nocrt: true,
481 }
482 `)
483
484 // Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib.
485 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
486 cc_library {
487 name: "libvndksp",
488 vendor_available: true,
489 vndk: {
490 enabled: true,
491 support_system_process: true,
492 },
493 shared_libs: ["libnonvndk"],
494 nocrt: true,
495 }
496
497 cc_library {
498 name: "libnonvndk",
499 vendor_available: true,
500 nocrt: true,
501 }
502 `)
503
504 // Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib.
505 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
506 cc_library {
507 name: "libvndkspprivate",
508 vendor_available: false,
509 vndk: {
510 enabled: true,
511 support_system_process: true,
512 },
513 shared_libs: ["libnonvndk"],
514 nocrt: true,
515 }
516
517 cc_library {
518 name: "libnonvndk",
519 vendor_available: true,
520 nocrt: true,
521 }
522 `)
523}
524
525func TestDoubleLoadbleDep(t *testing.T) {
526 // okay to link : LLNDK -> double_loadable VNDK
527 testCc(t, `
528 cc_library {
529 name: "libllndk",
530 shared_libs: ["libdoubleloadable"],
531 }
532
533 llndk_library {
534 name: "libllndk",
535 symbol_file: "",
536 }
537
538 cc_library {
539 name: "libdoubleloadable",
540 vendor_available: true,
541 vndk: {
542 enabled: true,
543 },
544 double_loadable: true,
545 }
546 `)
547 // okay to link : LLNDK -> VNDK-SP
548 testCc(t, `
549 cc_library {
550 name: "libllndk",
551 shared_libs: ["libvndksp"],
552 }
553
554 llndk_library {
555 name: "libllndk",
556 symbol_file: "",
557 }
558
559 cc_library {
560 name: "libvndksp",
561 vendor_available: true,
562 vndk: {
563 enabled: true,
564 support_system_process: true,
565 },
566 }
567 `)
568 // okay to link : double_loadable -> double_loadable
569 testCc(t, `
570 cc_library {
571 name: "libdoubleloadable1",
572 shared_libs: ["libdoubleloadable2"],
573 vendor_available: true,
574 double_loadable: true,
575 }
576
577 cc_library {
578 name: "libdoubleloadable2",
579 vendor_available: true,
580 double_loadable: true,
581 }
582 `)
583 // okay to link : double_loadable VNDK -> double_loadable VNDK private
584 testCc(t, `
585 cc_library {
586 name: "libdoubleloadable",
587 vendor_available: true,
588 vndk: {
589 enabled: true,
590 },
591 double_loadable: true,
592 shared_libs: ["libnondoubleloadable"],
593 }
594
595 cc_library {
596 name: "libnondoubleloadable",
597 vendor_available: false,
598 vndk: {
599 enabled: true,
600 },
601 double_loadable: true,
602 }
603 `)
604 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
605 testCc(t, `
606 cc_library {
607 name: "libllndk",
608 shared_libs: ["libcoreonly"],
609 }
610
611 llndk_library {
612 name: "libllndk",
613 symbol_file: "",
614 }
615
616 cc_library {
617 name: "libcoreonly",
618 shared_libs: ["libvendoravailable"],
619 }
620
621 // indirect dependency of LLNDK
622 cc_library {
623 name: "libvendoravailable",
624 vendor_available: true,
625 double_loadable: true,
626 }
627 `)
628}
629
630func TestDoubleLoadableDepError(t *testing.T) {
631 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
632 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
633 cc_library {
634 name: "libllndk",
635 shared_libs: ["libnondoubleloadable"],
636 }
637
638 llndk_library {
639 name: "libllndk",
640 symbol_file: "",
641 }
642
643 cc_library {
644 name: "libnondoubleloadable",
645 vendor_available: true,
646 vndk: {
647 enabled: true,
648 },
649 }
650 `)
651
652 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
653 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
654 cc_library {
655 name: "libllndk",
656 no_libgcc: true,
657 shared_libs: ["libnondoubleloadable"],
658 }
659
660 llndk_library {
661 name: "libllndk",
662 symbol_file: "",
663 }
664
665 cc_library {
666 name: "libnondoubleloadable",
667 vendor_available: true,
668 }
669 `)
670
671 // Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable vendor_available lib.
672 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
673 cc_library {
674 name: "libdoubleloadable",
675 vendor_available: true,
676 double_loadable: true,
677 shared_libs: ["libnondoubleloadable"],
678 }
679
680 cc_library {
681 name: "libnondoubleloadable",
682 vendor_available: true,
683 }
684 `)
685
686 // Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable VNDK lib.
687 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
688 cc_library {
689 name: "libdoubleloadable",
690 vendor_available: true,
691 double_loadable: true,
692 shared_libs: ["libnondoubleloadable"],
693 }
694
695 cc_library {
696 name: "libnondoubleloadable",
697 vendor_available: true,
698 vndk: {
699 enabled: true,
700 },
701 }
702 `)
703
704 // Check whether an error is emitted when a double_loadable VNDK depends on a non-double_loadable VNDK private lib.
705 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
706 cc_library {
707 name: "libdoubleloadable",
708 vendor_available: true,
709 vndk: {
710 enabled: true,
711 },
712 double_loadable: true,
713 shared_libs: ["libnondoubleloadable"],
714 }
715
716 cc_library {
717 name: "libnondoubleloadable",
718 vendor_available: false,
719 vndk: {
720 enabled: true,
721 },
722 }
723 `)
724
725 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
726 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
727 cc_library {
728 name: "libllndk",
729 shared_libs: ["libcoreonly"],
730 }
731
732 llndk_library {
733 name: "libllndk",
734 symbol_file: "",
735 }
736
737 cc_library {
738 name: "libcoreonly",
739 shared_libs: ["libvendoravailable"],
740 }
741
742 // indirect dependency of LLNDK
743 cc_library {
744 name: "libvendoravailable",
745 vendor_available: true,
746 }
747 `)
Logan Chiend3c59a22018-03-29 14:08:15 +0800748}
749
Justin Yun9357f4a2018-11-28 15:14:47 +0900750func TestVndkMustNotBeProductSpecific(t *testing.T) {
751 // Check whether an error is emitted when a vndk lib has 'product_specific: true'.
752 testCcError(t, "product_specific must not be true when `vndk: {enabled: true}`", `
753 cc_library {
754 name: "libvndk",
755 product_specific: true, // Cause error
756 vendor_available: true,
757 vndk: {
758 enabled: true,
759 },
760 nocrt: true,
761 }
762 `)
763}
764
Logan Chienf3511742017-10-31 18:04:35 +0800765func TestVndkExt(t *testing.T) {
766 // This test checks the VNDK-Ext properties.
767 ctx := testCc(t, `
768 cc_library {
769 name: "libvndk",
770 vendor_available: true,
771 vndk: {
772 enabled: true,
773 },
774 nocrt: true,
775 }
776
777 cc_library {
778 name: "libvndk_ext",
779 vendor: true,
780 vndk: {
781 enabled: true,
782 extends: "libvndk",
783 },
784 nocrt: true,
785 }
786 `)
787
788 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
789}
790
Logan Chiend3c59a22018-03-29 14:08:15 +0800791func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800792 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
793 ctx := testCcNoVndk(t, `
794 cc_library {
795 name: "libvndk",
796 vendor_available: true,
797 vndk: {
798 enabled: true,
799 },
800 nocrt: true,
801 }
802
803 cc_library {
804 name: "libvndk_ext",
805 vendor: true,
806 vndk: {
807 enabled: true,
808 extends: "libvndk",
809 },
810 nocrt: true,
811 }
812 `)
813
814 // Ensures that the core variant of "libvndk_ext" can be found.
815 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
816 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
817 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
818 }
819}
820
821func TestVndkExtError(t *testing.T) {
822 // This test ensures an error is emitted in ill-formed vndk-ext definition.
823 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
824 cc_library {
825 name: "libvndk",
826 vendor_available: true,
827 vndk: {
828 enabled: true,
829 },
830 nocrt: true,
831 }
832
833 cc_library {
834 name: "libvndk_ext",
835 vndk: {
836 enabled: true,
837 extends: "libvndk",
838 },
839 nocrt: true,
840 }
841 `)
842
843 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
844 cc_library {
845 name: "libvndk",
846 vendor_available: true,
847 vndk: {
848 enabled: true,
849 },
850 nocrt: true,
851 }
852
853 cc_library {
854 name: "libvndk_ext",
855 vendor: true,
856 vndk: {
857 enabled: true,
858 },
859 nocrt: true,
860 }
861 `)
862}
863
864func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
865 // This test ensures an error is emitted for inconsistent support_system_process.
866 testCcError(t, "module \".*\" with mismatched support_system_process", `
867 cc_library {
868 name: "libvndk",
869 vendor_available: true,
870 vndk: {
871 enabled: true,
872 },
873 nocrt: true,
874 }
875
876 cc_library {
877 name: "libvndk_sp_ext",
878 vendor: true,
879 vndk: {
880 enabled: true,
881 extends: "libvndk",
882 support_system_process: true,
883 },
884 nocrt: true,
885 }
886 `)
887
888 testCcError(t, "module \".*\" with mismatched support_system_process", `
889 cc_library {
890 name: "libvndk_sp",
891 vendor_available: true,
892 vndk: {
893 enabled: true,
894 support_system_process: true,
895 },
896 nocrt: true,
897 }
898
899 cc_library {
900 name: "libvndk_ext",
901 vendor: true,
902 vndk: {
903 enabled: true,
904 extends: "libvndk_sp",
905 },
906 nocrt: true,
907 }
908 `)
909}
910
911func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800912 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800913 // with `vendor_available: false`.
914 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
915 cc_library {
916 name: "libvndk",
917 vendor_available: false,
918 vndk: {
919 enabled: true,
920 },
921 nocrt: true,
922 }
923
924 cc_library {
925 name: "libvndk_ext",
926 vendor: true,
927 vndk: {
928 enabled: true,
929 extends: "libvndk",
930 },
931 nocrt: true,
932 }
933 `)
934}
935
Logan Chiend3c59a22018-03-29 14:08:15 +0800936func TestVendorModuleUseVndkExt(t *testing.T) {
937 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800938 testCc(t, `
939 cc_library {
940 name: "libvndk",
941 vendor_available: true,
942 vndk: {
943 enabled: true,
944 },
945 nocrt: true,
946 }
947
948 cc_library {
949 name: "libvndk_ext",
950 vendor: true,
951 vndk: {
952 enabled: true,
953 extends: "libvndk",
954 },
955 nocrt: true,
956 }
957
958 cc_library {
959
960 name: "libvndk_sp",
961 vendor_available: true,
962 vndk: {
963 enabled: true,
964 support_system_process: true,
965 },
966 nocrt: true,
967 }
968
969 cc_library {
970 name: "libvndk_sp_ext",
971 vendor: true,
972 vndk: {
973 enabled: true,
974 extends: "libvndk_sp",
975 support_system_process: true,
976 },
977 nocrt: true,
978 }
979
980 cc_library {
981 name: "libvendor",
982 vendor: true,
983 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
984 nocrt: true,
985 }
986 `)
987}
988
Logan Chiend3c59a22018-03-29 14:08:15 +0800989func TestVndkExtUseVendorLib(t *testing.T) {
990 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800991 testCc(t, `
992 cc_library {
993 name: "libvndk",
994 vendor_available: true,
995 vndk: {
996 enabled: true,
997 },
998 nocrt: true,
999 }
1000
1001 cc_library {
1002 name: "libvndk_ext",
1003 vendor: true,
1004 vndk: {
1005 enabled: true,
1006 extends: "libvndk",
1007 },
1008 shared_libs: ["libvendor"],
1009 nocrt: true,
1010 }
1011
1012 cc_library {
1013 name: "libvendor",
1014 vendor: true,
1015 nocrt: true,
1016 }
1017 `)
Logan Chienf3511742017-10-31 18:04:35 +08001018
Logan Chiend3c59a22018-03-29 14:08:15 +08001019 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
1020 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +08001021 cc_library {
1022 name: "libvndk_sp",
1023 vendor_available: true,
1024 vndk: {
1025 enabled: true,
1026 support_system_process: true,
1027 },
1028 nocrt: true,
1029 }
1030
1031 cc_library {
1032 name: "libvndk_sp_ext",
1033 vendor: true,
1034 vndk: {
1035 enabled: true,
1036 extends: "libvndk_sp",
1037 support_system_process: true,
1038 },
1039 shared_libs: ["libvendor"], // Cause an error
1040 nocrt: true,
1041 }
1042
1043 cc_library {
1044 name: "libvendor",
1045 vendor: true,
1046 nocrt: true,
1047 }
1048 `)
1049}
1050
Logan Chiend3c59a22018-03-29 14:08:15 +08001051func TestVndkSpExtUseVndkError(t *testing.T) {
1052 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
1053 // library.
1054 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1055 cc_library {
1056 name: "libvndk",
1057 vendor_available: true,
1058 vndk: {
1059 enabled: true,
1060 },
1061 nocrt: true,
1062 }
1063
1064 cc_library {
1065 name: "libvndk_sp",
1066 vendor_available: true,
1067 vndk: {
1068 enabled: true,
1069 support_system_process: true,
1070 },
1071 nocrt: true,
1072 }
1073
1074 cc_library {
1075 name: "libvndk_sp_ext",
1076 vendor: true,
1077 vndk: {
1078 enabled: true,
1079 extends: "libvndk_sp",
1080 support_system_process: true,
1081 },
1082 shared_libs: ["libvndk"], // Cause an error
1083 nocrt: true,
1084 }
1085 `)
1086
1087 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
1088 // library.
1089 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1090 cc_library {
1091 name: "libvndk",
1092 vendor_available: true,
1093 vndk: {
1094 enabled: true,
1095 },
1096 nocrt: true,
1097 }
1098
1099 cc_library {
1100 name: "libvndk_ext",
1101 vendor: true,
1102 vndk: {
1103 enabled: true,
1104 extends: "libvndk",
1105 },
1106 nocrt: true,
1107 }
1108
1109 cc_library {
1110 name: "libvndk_sp",
1111 vendor_available: true,
1112 vndk: {
1113 enabled: true,
1114 support_system_process: true,
1115 },
1116 nocrt: true,
1117 }
1118
1119 cc_library {
1120 name: "libvndk_sp_ext",
1121 vendor: true,
1122 vndk: {
1123 enabled: true,
1124 extends: "libvndk_sp",
1125 support_system_process: true,
1126 },
1127 shared_libs: ["libvndk_ext"], // Cause an error
1128 nocrt: true,
1129 }
1130 `)
1131}
1132
1133func TestVndkUseVndkExtError(t *testing.T) {
1134 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
1135 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +08001136 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1137 cc_library {
1138 name: "libvndk",
1139 vendor_available: true,
1140 vndk: {
1141 enabled: true,
1142 },
1143 nocrt: true,
1144 }
1145
1146 cc_library {
1147 name: "libvndk_ext",
1148 vendor: true,
1149 vndk: {
1150 enabled: true,
1151 extends: "libvndk",
1152 },
1153 nocrt: true,
1154 }
1155
1156 cc_library {
1157 name: "libvndk2",
1158 vendor_available: true,
1159 vndk: {
1160 enabled: true,
1161 },
1162 shared_libs: ["libvndk_ext"],
1163 nocrt: true,
1164 }
1165 `)
1166
Martin Stjernholmef449fe2018-11-06 16:12:13 +00001167 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +08001168 cc_library {
1169 name: "libvndk",
1170 vendor_available: true,
1171 vndk: {
1172 enabled: true,
1173 },
1174 nocrt: true,
1175 }
1176
1177 cc_library {
1178 name: "libvndk_ext",
1179 vendor: true,
1180 vndk: {
1181 enabled: true,
1182 extends: "libvndk",
1183 },
1184 nocrt: true,
1185 }
1186
1187 cc_library {
1188 name: "libvndk2",
1189 vendor_available: true,
1190 vndk: {
1191 enabled: true,
1192 },
1193 target: {
1194 vendor: {
1195 shared_libs: ["libvndk_ext"],
1196 },
1197 },
1198 nocrt: true,
1199 }
1200 `)
1201
1202 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1203 cc_library {
1204 name: "libvndk_sp",
1205 vendor_available: true,
1206 vndk: {
1207 enabled: true,
1208 support_system_process: true,
1209 },
1210 nocrt: true,
1211 }
1212
1213 cc_library {
1214 name: "libvndk_sp_ext",
1215 vendor: true,
1216 vndk: {
1217 enabled: true,
1218 extends: "libvndk_sp",
1219 support_system_process: true,
1220 },
1221 nocrt: true,
1222 }
1223
1224 cc_library {
1225 name: "libvndk_sp_2",
1226 vendor_available: true,
1227 vndk: {
1228 enabled: true,
1229 support_system_process: true,
1230 },
1231 shared_libs: ["libvndk_sp_ext"],
1232 nocrt: true,
1233 }
1234 `)
1235
Martin Stjernholmef449fe2018-11-06 16:12:13 +00001236 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +08001237 cc_library {
1238 name: "libvndk_sp",
1239 vendor_available: true,
1240 vndk: {
1241 enabled: true,
1242 },
1243 nocrt: true,
1244 }
1245
1246 cc_library {
1247 name: "libvndk_sp_ext",
1248 vendor: true,
1249 vndk: {
1250 enabled: true,
1251 extends: "libvndk_sp",
1252 },
1253 nocrt: true,
1254 }
1255
1256 cc_library {
1257 name: "libvndk_sp2",
1258 vendor_available: true,
1259 vndk: {
1260 enabled: true,
1261 },
1262 target: {
1263 vendor: {
1264 shared_libs: ["libvndk_sp_ext"],
1265 },
1266 },
1267 nocrt: true,
1268 }
1269 `)
1270}
1271
Colin Cross0af4b842015-04-30 16:36:18 -07001272var (
1273 str11 = "01234567891"
1274 str10 = str11[:10]
1275 str9 = str11[:9]
1276 str5 = str11[:5]
1277 str4 = str11[:4]
1278)
1279
1280var splitListForSizeTestCases = []struct {
1281 in []string
1282 out [][]string
1283 size int
1284}{
1285 {
1286 in: []string{str10},
1287 out: [][]string{{str10}},
1288 size: 10,
1289 },
1290 {
1291 in: []string{str9},
1292 out: [][]string{{str9}},
1293 size: 10,
1294 },
1295 {
1296 in: []string{str5},
1297 out: [][]string{{str5}},
1298 size: 10,
1299 },
1300 {
1301 in: []string{str11},
1302 out: nil,
1303 size: 10,
1304 },
1305 {
1306 in: []string{str10, str10},
1307 out: [][]string{{str10}, {str10}},
1308 size: 10,
1309 },
1310 {
1311 in: []string{str9, str10},
1312 out: [][]string{{str9}, {str10}},
1313 size: 10,
1314 },
1315 {
1316 in: []string{str10, str9},
1317 out: [][]string{{str10}, {str9}},
1318 size: 10,
1319 },
1320 {
1321 in: []string{str5, str4},
1322 out: [][]string{{str5, str4}},
1323 size: 10,
1324 },
1325 {
1326 in: []string{str5, str4, str5},
1327 out: [][]string{{str5, str4}, {str5}},
1328 size: 10,
1329 },
1330 {
1331 in: []string{str5, str4, str5, str4},
1332 out: [][]string{{str5, str4}, {str5, str4}},
1333 size: 10,
1334 },
1335 {
1336 in: []string{str5, str4, str5, str5},
1337 out: [][]string{{str5, str4}, {str5}, {str5}},
1338 size: 10,
1339 },
1340 {
1341 in: []string{str5, str5, str5, str4},
1342 out: [][]string{{str5}, {str5}, {str5, str4}},
1343 size: 10,
1344 },
1345 {
1346 in: []string{str9, str11},
1347 out: nil,
1348 size: 10,
1349 },
1350 {
1351 in: []string{str11, str9},
1352 out: nil,
1353 size: 10,
1354 },
1355}
1356
1357func TestSplitListForSize(t *testing.T) {
1358 for _, testCase := range splitListForSizeTestCases {
Colin Cross40e33732019-02-15 11:08:35 -08001359 out, _ := splitListForSize(android.PathsForTesting(testCase.in...), testCase.size)
Colin Cross5b529592017-05-09 13:34:34 -07001360
1361 var outStrings [][]string
1362
1363 if len(out) > 0 {
1364 outStrings = make([][]string, len(out))
1365 for i, o := range out {
1366 outStrings[i] = o.Strings()
1367 }
1368 }
1369
1370 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001371 t.Errorf("incorrect output:")
1372 t.Errorf(" input: %#v", testCase.in)
1373 t.Errorf(" size: %d", testCase.size)
1374 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001375 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001376 }
1377 }
1378}
Jeff Gaston294356f2017-09-27 17:05:30 -07001379
1380var staticLinkDepOrderTestCases = []struct {
1381 // This is a string representation of a map[moduleName][]moduleDependency .
1382 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001383 inStatic string
1384
1385 // This is a string representation of a map[moduleName][]moduleDependency .
1386 // It models the dependencies declared in an Android.bp file.
1387 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001388
1389 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1390 // The keys of allOrdered specify which modules we would like to check.
1391 // The values of allOrdered specify the expected result (of the transitive closure of all
1392 // dependencies) for each module to test
1393 allOrdered string
1394
1395 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1396 // The keys of outOrdered specify which modules we would like to check.
1397 // The values of outOrdered specify the expected result (of the ordered linker command line)
1398 // for each module to test.
1399 outOrdered string
1400}{
1401 // Simple tests
1402 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001403 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001404 outOrdered: "",
1405 },
1406 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001407 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001408 outOrdered: "a:",
1409 },
1410 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001411 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001412 outOrdered: "a:b; b:",
1413 },
1414 // Tests of reordering
1415 {
1416 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001417 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001418 outOrdered: "a:b,c,d; b:d; c:d; d:",
1419 },
1420 {
1421 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001422 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001423 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1424 },
1425 {
1426 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001427 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001428 outOrdered: "a:d,b,e,c; d:b; e:c",
1429 },
1430 {
1431 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001432 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001433 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1434 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1435 },
1436 {
1437 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001438 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 -07001439 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1440 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1441 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001442 // shared dependencies
1443 {
1444 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1445 // So, we don't actually have to check that a shared dependency of c will change the order
1446 // of a library that depends statically on b and on c. We only need to check that if c has
1447 // a shared dependency on b, that that shows up in allOrdered.
1448 inShared: "c:b",
1449 allOrdered: "c:b",
1450 outOrdered: "c:",
1451 },
1452 {
1453 // This test doesn't actually include any shared dependencies but it's a reminder of what
1454 // the second phase of the above test would look like
1455 inStatic: "a:b,c; c:b",
1456 allOrdered: "a:c,b; c:b",
1457 outOrdered: "a:c,b; c:b",
1458 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001459 // tiebreakers for when two modules specifying different orderings and there is no dependency
1460 // to dictate an order
1461 {
1462 // 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 -08001463 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001464 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1465 },
1466 {
1467 // 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 -08001468 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 -07001469 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1470 },
1471 // Tests involving duplicate dependencies
1472 {
1473 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001474 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001475 outOrdered: "a:c,b",
1476 },
1477 {
1478 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001479 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001480 outOrdered: "a:d,c,b",
1481 },
1482 // Tests to confirm the nonexistence of infinite loops.
1483 // These cases should never happen, so as long as the test terminates and the
1484 // result is deterministic then that should be fine.
1485 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001486 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001487 outOrdered: "a:a",
1488 },
1489 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001490 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001491 allOrdered: "a:b,c; b:c,a; c:a,b",
1492 outOrdered: "a:b; b:c; c:a",
1493 },
1494 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001495 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001496 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1497 outOrdered: "a:c,b; b:a,c; c:b,a",
1498 },
1499}
1500
1501// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1502func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1503 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1504 strippedText := strings.Replace(text, " ", "", -1)
1505 if len(strippedText) < 1 {
1506 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1507 }
1508 allDeps = make(map[android.Path][]android.Path, 0)
1509
1510 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1511 moduleTexts := strings.Split(strippedText, ";")
1512
1513 outputForModuleName := func(moduleName string) android.Path {
1514 return android.PathForTesting(moduleName)
1515 }
1516
1517 for _, moduleText := range moduleTexts {
1518 // convert from "a:b,c" to ["a", "b,c"]
1519 components := strings.Split(moduleText, ":")
1520 if len(components) != 2 {
1521 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1522 }
1523 moduleName := components[0]
1524 moduleOutput := outputForModuleName(moduleName)
1525 modulesInOrder = append(modulesInOrder, moduleOutput)
1526
1527 depString := components[1]
1528 // convert from "b,c" to ["b", "c"]
1529 depNames := strings.Split(depString, ",")
1530 if len(depString) < 1 {
1531 depNames = []string{}
1532 }
1533 var deps []android.Path
1534 for _, depName := range depNames {
1535 deps = append(deps, outputForModuleName(depName))
1536 }
1537 allDeps[moduleOutput] = deps
1538 }
1539 return modulesInOrder, allDeps
1540}
1541
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001542func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001543 for _, testCase := range staticLinkDepOrderTestCases {
1544 errs := []string{}
1545
1546 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001547 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001548 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1549 if testCase.allOrdered == "" {
1550 // allow the test case to skip specifying allOrdered
1551 testCase.allOrdered = testCase.outOrdered
1552 }
1553 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001554 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001555
1556 // For each module whose post-reordered dependencies were specified, validate that
1557 // reordering the inputs produces the expected outputs.
1558 for _, moduleName := range expectedModuleNames {
1559 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001560 givenSharedDeps := givenAllSharedDeps[moduleName]
1561 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001562
1563 correctAllOrdered := expectedAllDeps[moduleName]
1564 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1565 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001566 "\nin static:%q"+
1567 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001568 "\nmodule: %v"+
1569 "\nexpected: %s"+
1570 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001571 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001572 }
1573
1574 correctOutputDeps := expectedTransitiveDeps[moduleName]
1575 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1576 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001577 "\nin static:%q"+
1578 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001579 "\nmodule: %v"+
1580 "\nexpected: %s"+
1581 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001582 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001583 }
1584 }
1585
1586 if len(errs) > 0 {
1587 sort.Strings(errs)
1588 for _, err := range errs {
1589 t.Error(err)
1590 }
1591 }
1592 }
1593}
Logan Chienf3511742017-10-31 18:04:35 +08001594
Jeff Gaston294356f2017-09-27 17:05:30 -07001595func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1596 for _, moduleName := range moduleNames {
1597 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1598 output := module.outputFile.Path()
1599 paths = append(paths, output)
1600 }
1601 return paths
1602}
1603
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001604func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001605 ctx := testCc(t, `
1606 cc_library {
1607 name: "a",
1608 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001609 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001610 }
1611 cc_library {
1612 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001613 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001614 }
1615 cc_library {
1616 name: "c",
1617 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001618 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001619 }
1620 cc_library {
1621 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001622 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001623 }
1624
1625 `)
1626
1627 variant := "android_arm64_armv8-a_core_static"
1628 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001629 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001630 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1631
1632 if !reflect.DeepEqual(actual, expected) {
1633 t.Errorf("staticDeps orderings were not propagated correctly"+
1634 "\nactual: %v"+
1635 "\nexpected: %v",
1636 actual,
1637 expected,
1638 )
1639 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001640}
Jeff Gaston294356f2017-09-27 17:05:30 -07001641
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001642func TestStaticLibDepReorderingWithShared(t *testing.T) {
1643 ctx := testCc(t, `
1644 cc_library {
1645 name: "a",
1646 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001647 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001648 }
1649 cc_library {
1650 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001651 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001652 }
1653 cc_library {
1654 name: "c",
1655 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001656 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001657 }
1658
1659 `)
1660
1661 variant := "android_arm64_armv8-a_core_static"
1662 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1663 actual := moduleA.depsInLinkOrder
1664 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1665
1666 if !reflect.DeepEqual(actual, expected) {
1667 t.Errorf("staticDeps orderings did not account for shared libs"+
1668 "\nactual: %v"+
1669 "\nexpected: %v",
1670 actual,
1671 expected,
1672 )
1673 }
1674}
1675
Jiyong Parka46a4d52017-12-14 19:54:34 +09001676func TestLlndkHeaders(t *testing.T) {
1677 ctx := testCc(t, `
1678 llndk_headers {
1679 name: "libllndk_headers",
1680 export_include_dirs: ["my_include"],
1681 }
1682 llndk_library {
1683 name: "libllndk",
1684 export_llndk_headers: ["libllndk_headers"],
1685 }
1686 cc_library {
1687 name: "libvendor",
1688 shared_libs: ["libllndk"],
1689 vendor: true,
1690 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001691 no_libgcc: true,
1692 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001693 }
1694 `)
1695
1696 // _static variant is used since _shared reuses *.o from the static variant
1697 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1698 cflags := cc.Args["cFlags"]
1699 if !strings.Contains(cflags, "-Imy_include") {
1700 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1701 }
1702}
1703
Logan Chien43d34c32017-12-20 01:17:32 +08001704func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1705 actual := module.Properties.AndroidMkRuntimeLibs
1706 if !reflect.DeepEqual(actual, expected) {
1707 t.Errorf("incorrect runtime_libs for shared libs"+
1708 "\nactual: %v"+
1709 "\nexpected: %v",
1710 actual,
1711 expected,
1712 )
1713 }
1714}
1715
1716const runtimeLibAndroidBp = `
1717 cc_library {
1718 name: "libvendor_available1",
1719 vendor_available: true,
1720 no_libgcc : true,
1721 nocrt : true,
1722 system_shared_libs : [],
1723 }
1724 cc_library {
1725 name: "libvendor_available2",
1726 vendor_available: true,
1727 runtime_libs: ["libvendor_available1"],
1728 no_libgcc : true,
1729 nocrt : true,
1730 system_shared_libs : [],
1731 }
1732 cc_library {
1733 name: "libvendor_available3",
1734 vendor_available: true,
1735 runtime_libs: ["libvendor_available1"],
1736 target: {
1737 vendor: {
1738 exclude_runtime_libs: ["libvendor_available1"],
1739 }
1740 },
1741 no_libgcc : true,
1742 nocrt : true,
1743 system_shared_libs : [],
1744 }
1745 cc_library {
1746 name: "libcore",
1747 runtime_libs: ["libvendor_available1"],
1748 no_libgcc : true,
1749 nocrt : true,
1750 system_shared_libs : [],
1751 }
1752 cc_library {
1753 name: "libvendor1",
1754 vendor: true,
1755 no_libgcc : true,
1756 nocrt : true,
1757 system_shared_libs : [],
1758 }
1759 cc_library {
1760 name: "libvendor2",
1761 vendor: true,
1762 runtime_libs: ["libvendor_available1", "libvendor1"],
1763 no_libgcc : true,
1764 nocrt : true,
1765 system_shared_libs : [],
1766 }
1767`
1768
1769func TestRuntimeLibs(t *testing.T) {
1770 ctx := testCc(t, runtimeLibAndroidBp)
1771
1772 // runtime_libs for core variants use the module names without suffixes.
1773 variant := "android_arm64_armv8-a_core_shared"
1774
1775 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1776 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1777
1778 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1779 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1780
1781 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1782 // and vendor variants.
1783 variant = "android_arm64_armv8-a_vendor_shared"
1784
1785 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1786 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1787
1788 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1789 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1790}
1791
1792func TestExcludeRuntimeLibs(t *testing.T) {
1793 ctx := testCc(t, runtimeLibAndroidBp)
1794
1795 variant := "android_arm64_armv8-a_core_shared"
1796 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1797 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1798
1799 variant = "android_arm64_armv8-a_vendor_shared"
1800 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1801 checkRuntimeLibs(t, nil, module)
1802}
1803
1804func TestRuntimeLibsNoVndk(t *testing.T) {
1805 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1806
1807 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1808
1809 variant := "android_arm64_armv8-a_core_shared"
1810
1811 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1812 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1813
1814 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1815 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1816}
1817
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001818func checkStaticLibs(t *testing.T, expected []string, module *Module) {
1819 actual := module.Properties.AndroidMkStaticLibs
1820 if !reflect.DeepEqual(actual, expected) {
1821 t.Errorf("incorrect static_libs"+
1822 "\nactual: %v"+
1823 "\nexpected: %v",
1824 actual,
1825 expected,
1826 )
1827 }
1828}
1829
1830const staticLibAndroidBp = `
1831 cc_library {
1832 name: "lib1",
1833 }
1834 cc_library {
1835 name: "lib2",
1836 static_libs: ["lib1"],
1837 }
1838`
1839
1840func TestStaticLibDepExport(t *testing.T) {
1841 ctx := testCc(t, staticLibAndroidBp)
1842
1843 // Check the shared version of lib2.
1844 variant := "android_arm64_armv8-a_core_shared"
1845 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Yi Kongb0e95c12019-05-07 04:46:14 +00001846 checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001847
1848 // Check the static version of lib2.
1849 variant = "android_arm64_armv8-a_core_static"
1850 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1851 // libc++_static is linked additionally.
Yi Kongb0e95c12019-05-07 04:46:14 +00001852 checkStaticLibs(t, []string{"lib1", "libc++_static", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001853}
1854
Jiyong Parkd08b6972017-09-26 10:50:54 +09001855var compilerFlagsTestCases = []struct {
1856 in string
1857 out bool
1858}{
1859 {
1860 in: "a",
1861 out: false,
1862 },
1863 {
1864 in: "-a",
1865 out: true,
1866 },
1867 {
1868 in: "-Ipath/to/something",
1869 out: false,
1870 },
1871 {
1872 in: "-isystempath/to/something",
1873 out: false,
1874 },
1875 {
1876 in: "--coverage",
1877 out: false,
1878 },
1879 {
1880 in: "-include a/b",
1881 out: true,
1882 },
1883 {
1884 in: "-include a/b c/d",
1885 out: false,
1886 },
1887 {
1888 in: "-DMACRO",
1889 out: true,
1890 },
1891 {
1892 in: "-DMAC RO",
1893 out: false,
1894 },
1895 {
1896 in: "-a -b",
1897 out: false,
1898 },
1899 {
1900 in: "-DMACRO=definition",
1901 out: true,
1902 },
1903 {
1904 in: "-DMACRO=defi nition",
1905 out: true, // TODO(jiyong): this should be false
1906 },
1907 {
1908 in: "-DMACRO(x)=x + 1",
1909 out: true,
1910 },
1911 {
1912 in: "-DMACRO=\"defi nition\"",
1913 out: true,
1914 },
1915}
1916
1917type mockContext struct {
1918 BaseModuleContext
1919 result bool
1920}
1921
1922func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1923 // CheckBadCompilerFlags calls this function when the flag should be rejected
1924 ctx.result = false
1925}
1926
1927func TestCompilerFlags(t *testing.T) {
1928 for _, testCase := range compilerFlagsTestCases {
1929 ctx := &mockContext{result: true}
1930 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1931 if ctx.result != testCase.out {
1932 t.Errorf("incorrect output:")
1933 t.Errorf(" input: %#v", testCase.in)
1934 t.Errorf(" expected: %#v", testCase.out)
1935 t.Errorf(" got: %#v", ctx.result)
1936 }
1937 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001938}
Jiyong Park374510b2018-03-19 18:23:01 +09001939
1940func TestVendorPublicLibraries(t *testing.T) {
1941 ctx := testCc(t, `
1942 cc_library_headers {
1943 name: "libvendorpublic_headers",
1944 export_include_dirs: ["my_include"],
1945 }
1946 vendor_public_library {
1947 name: "libvendorpublic",
1948 symbol_file: "",
1949 export_public_headers: ["libvendorpublic_headers"],
1950 }
1951 cc_library {
1952 name: "libvendorpublic",
1953 srcs: ["foo.c"],
1954 vendor: true,
1955 no_libgcc: true,
1956 nocrt: true,
1957 }
1958
1959 cc_library {
1960 name: "libsystem",
1961 shared_libs: ["libvendorpublic"],
1962 vendor: false,
1963 srcs: ["foo.c"],
1964 no_libgcc: true,
1965 nocrt: true,
1966 }
1967 cc_library {
1968 name: "libvendor",
1969 shared_libs: ["libvendorpublic"],
1970 vendor: true,
1971 srcs: ["foo.c"],
1972 no_libgcc: true,
1973 nocrt: true,
1974 }
1975 `)
1976
1977 variant := "android_arm64_armv8-a_core_shared"
1978
1979 // test if header search paths are correctly added
1980 // _static variant is used since _shared reuses *.o from the static variant
1981 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
1982 cflags := cc.Args["cFlags"]
1983 if !strings.Contains(cflags, "-Imy_include") {
1984 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
1985 }
1986
1987 // test if libsystem is linked to the stub
1988 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
1989 libflags := ld.Args["libFlags"]
1990 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
1991 if !strings.Contains(libflags, stubPaths[0].String()) {
1992 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
1993 }
1994
1995 // test if libvendor is linked to the real shared lib
1996 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
1997 libflags = ld.Args["libFlags"]
1998 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
1999 if !strings.Contains(libflags, stubPaths[0].String()) {
2000 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
2001 }
2002
2003}
Jiyong Park37b25202018-07-11 10:49:27 +09002004
2005func TestRecovery(t *testing.T) {
2006 ctx := testCc(t, `
2007 cc_library_shared {
2008 name: "librecovery",
2009 recovery: true,
2010 }
2011 cc_library_shared {
2012 name: "librecovery32",
2013 recovery: true,
2014 compile_multilib:"32",
2015 }
Jiyong Park5baac542018-08-28 09:55:37 +09002016 cc_library_shared {
2017 name: "libHalInRecovery",
2018 recovery_available: true,
2019 vendor: true,
2020 }
Jiyong Park37b25202018-07-11 10:49:27 +09002021 `)
2022
2023 variants := ctx.ModuleVariantsForTests("librecovery")
2024 const arm64 = "android_arm64_armv8-a_recovery_shared"
2025 if len(variants) != 1 || !android.InList(arm64, variants) {
2026 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
2027 }
2028
2029 variants = ctx.ModuleVariantsForTests("librecovery32")
2030 if android.InList(arm64, variants) {
2031 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
2032 }
Jiyong Park5baac542018-08-28 09:55:37 +09002033
2034 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
2035 if !recoveryModule.Platform() {
2036 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
2037 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09002038}
Jiyong Park5baac542018-08-28 09:55:37 +09002039
Jiyong Park7ed9de32018-10-15 22:25:07 +09002040func TestVersionedStubs(t *testing.T) {
2041 ctx := testCc(t, `
2042 cc_library_shared {
2043 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002044 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002045 stubs: {
2046 symbol_file: "foo.map.txt",
2047 versions: ["1", "2", "3"],
2048 },
2049 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002050
Jiyong Park7ed9de32018-10-15 22:25:07 +09002051 cc_library_shared {
2052 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002053 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002054 shared_libs: ["libFoo#1"],
2055 }`)
2056
2057 variants := ctx.ModuleVariantsForTests("libFoo")
2058 expectedVariants := []string{
2059 "android_arm64_armv8-a_core_shared",
2060 "android_arm64_armv8-a_core_shared_1",
2061 "android_arm64_armv8-a_core_shared_2",
2062 "android_arm64_armv8-a_core_shared_3",
2063 "android_arm_armv7-a-neon_core_shared",
2064 "android_arm_armv7-a-neon_core_shared_1",
2065 "android_arm_armv7-a-neon_core_shared_2",
2066 "android_arm_armv7-a-neon_core_shared_3",
2067 }
2068 variantsMismatch := false
2069 if len(variants) != len(expectedVariants) {
2070 variantsMismatch = true
2071 } else {
2072 for _, v := range expectedVariants {
2073 if !inList(v, variants) {
2074 variantsMismatch = false
2075 }
2076 }
2077 }
2078 if variantsMismatch {
2079 t.Errorf("variants of libFoo expected:\n")
2080 for _, v := range expectedVariants {
2081 t.Errorf("%q\n", v)
2082 }
2083 t.Errorf(", but got:\n")
2084 for _, v := range variants {
2085 t.Errorf("%q\n", v)
2086 }
2087 }
2088
2089 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld")
2090 libFlags := libBarLinkRule.Args["libFlags"]
2091 libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so"
2092 if !strings.Contains(libFlags, libFoo1StubPath) {
2093 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
2094 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002095
2096 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("cc")
2097 cFlags := libBarCompileRule.Args["cFlags"]
2098 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
2099 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
2100 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
2101 }
Jiyong Park37b25202018-07-11 10:49:27 +09002102}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002103
2104func TestStaticExecutable(t *testing.T) {
2105 ctx := testCc(t, `
2106 cc_binary {
2107 name: "static_test",
2108 srcs: ["foo.c"],
2109 static_executable: true,
2110 }`)
2111
2112 variant := "android_arm64_armv8-a_core"
2113 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
2114 libFlags := binModuleRule.Args["libFlags"]
2115 systemStaticLibs := []string{"libc.a", "libm.a", "libdl.a"}
2116 for _, lib := range systemStaticLibs {
2117 if !strings.Contains(libFlags, lib) {
2118 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
2119 }
2120 }
2121 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
2122 for _, lib := range systemSharedLibs {
2123 if strings.Contains(libFlags, lib) {
2124 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
2125 }
2126 }
2127}
Jiyong Parke4bb9862019-02-01 00:31:10 +09002128
2129func TestStaticDepsOrderWithStubs(t *testing.T) {
2130 ctx := testCc(t, `
2131 cc_binary {
2132 name: "mybin",
2133 srcs: ["foo.c"],
2134 static_libs: ["libB"],
2135 static_executable: true,
2136 stl: "none",
2137 }
2138
2139 cc_library {
2140 name: "libB",
2141 srcs: ["foo.c"],
2142 shared_libs: ["libC"],
2143 stl: "none",
2144 }
2145
2146 cc_library {
2147 name: "libC",
2148 srcs: ["foo.c"],
2149 stl: "none",
2150 stubs: {
2151 versions: ["1"],
2152 },
2153 }`)
2154
2155 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a_core").Module().(*Module)
2156 actual := mybin.depsInLinkOrder
2157 expected := getOutputPaths(ctx, "android_arm64_armv8-a_core_static", []string{"libB", "libC"})
2158
2159 if !reflect.DeepEqual(actual, expected) {
2160 t.Errorf("staticDeps orderings were not propagated correctly"+
2161 "\nactual: %v"+
2162 "\nexpected: %v",
2163 actual,
2164 expected,
2165 )
2166 }
2167}