blob: f5bb12c8f399ac6b7136c0d332cb37b49f298ab9 [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"
Inseob Kim1f086e22019-05-09 13:29:15 +090023 "path/filepath"
Colin Cross74d1ec02015-04-28 13:30:13 -070024 "reflect"
Jeff Gaston294356f2017-09-27 17:05:30 -070025 "sort"
26 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070027 "testing"
28)
29
Jiyong Park6a43f042017-10-12 23:05:00 +090030var buildDir string
31
32func setUp() {
33 var err error
34 buildDir, err = ioutil.TempDir("", "soong_cc_test")
35 if err != nil {
36 panic(err)
37 }
38}
39
40func tearDown() {
41 os.RemoveAll(buildDir)
42}
43
44func TestMain(m *testing.M) {
45 run := func() int {
46 setUp()
47 defer tearDown()
48
49 return m.Run()
50 }
51
52 os.Exit(run())
53}
54
Logan Chienf3511742017-10-31 18:04:35 +080055func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Doug Hornc32c6b02019-01-17 14:44:05 -080056 return testCcWithConfigForOs(t, bp, config, android.Android)
57}
58
59func testCcWithConfigForOs(t *testing.T, bp string, config android.Config, os android.OsType) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080060 t.Helper()
Colin Cross9a942872019-05-14 15:44:26 -070061 ctx := CreateTestContext(bp, nil, os)
Colin Cross33b2fb72019-05-14 14:07:01 -070062 ctx.Register()
Logan Chienf3511742017-10-31 18:04:35 +080063
Jeff Gastond3e141d2017-08-08 17:46:01 -070064 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +080065 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +090066 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +080067 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +090068
69 return ctx
70}
71
Logan Chienf3511742017-10-31 18:04:35 +080072func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080073 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080074 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070075 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
76 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080077
78 return testCcWithConfig(t, bp, config)
79}
80
81func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080082 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080083 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070084 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080085
86 return testCcWithConfig(t, bp, config)
87}
88
89func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +080090 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080091 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070092 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
93 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080094
Colin Cross9a942872019-05-14 15:44:26 -070095 ctx := CreateTestContext(bp, nil, android.Android)
Colin Cross33b2fb72019-05-14 14:07:01 -070096 ctx.Register()
Logan Chienf3511742017-10-31 18:04:35 +080097
98 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
99 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800100 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800101 return
102 }
103
104 _, errs = ctx.PrepareBuildActions(config)
105 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800106 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800107 return
108 }
109
110 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
111}
112
113const (
Jiyong Park5baac542018-08-28 09:55:37 +0900114 coreVariant = "android_arm64_armv8-a_core_shared"
115 vendorVariant = "android_arm64_armv8-a_vendor_shared"
116 recoveryVariant = "android_arm64_armv8-a_recovery_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800117)
118
Doug Hornc32c6b02019-01-17 14:44:05 -0800119func TestFuchsiaDeps(t *testing.T) {
120 t.Helper()
121
122 bp := `
123 cc_library {
124 name: "libTest",
125 srcs: ["foo.c"],
126 target: {
127 fuchsia: {
128 srcs: ["bar.c"],
129 },
130 },
131 }`
132
133 config := android.TestArchConfigFuchsia(buildDir, nil)
134 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
135
136 rt := false
137 fb := false
138
139 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
140 implicits := ld.Implicits
141 for _, lib := range implicits {
142 if strings.Contains(lib.Rel(), "libcompiler_rt") {
143 rt = true
144 }
145
146 if strings.Contains(lib.Rel(), "libbioniccompat") {
147 fb = true
148 }
149 }
150
151 if !rt || !fb {
152 t.Errorf("fuchsia libs must link libcompiler_rt and libbioniccompat")
153 }
154}
155
156func TestFuchsiaTargetDecl(t *testing.T) {
157 t.Helper()
158
159 bp := `
160 cc_library {
161 name: "libTest",
162 srcs: ["foo.c"],
163 target: {
164 fuchsia: {
165 srcs: ["bar.c"],
166 },
167 },
168 }`
169
170 config := android.TestArchConfigFuchsia(buildDir, nil)
171 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
172 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
173 var objs []string
174 for _, o := range ld.Inputs {
175 objs = append(objs, o.Base())
176 }
177 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
178 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
179 }
180}
181
Jiyong Park6a43f042017-10-12 23:05:00 +0900182func TestVendorSrc(t *testing.T) {
183 ctx := testCc(t, `
184 cc_library {
185 name: "libTest",
186 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800187 no_libgcc: true,
188 nocrt: true,
189 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900190 vendor_available: true,
191 target: {
192 vendor: {
193 srcs: ["bar.c"],
194 },
195 },
196 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900197 `)
198
Logan Chienf3511742017-10-31 18:04:35 +0800199 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900200 var objs []string
201 for _, o := range ld.Inputs {
202 objs = append(objs, o.Base())
203 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800204 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900205 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
206 }
207}
208
Logan Chienf3511742017-10-31 18:04:35 +0800209func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
210 isVndkSp bool, extends string) {
211
Logan Chiend3c59a22018-03-29 14:08:15 +0800212 t.Helper()
213
Logan Chienf3511742017-10-31 18:04:35 +0800214 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
215 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700216 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800217 }
218
219 // Check library properties.
220 lib, ok := mod.compiler.(*libraryDecorator)
221 if !ok {
222 t.Errorf("%q must have libraryDecorator", name)
223 } else if lib.baseInstaller.subDir != subDir {
224 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
225 lib.baseInstaller.subDir)
226 }
227
228 // Check VNDK properties.
229 if mod.vndkdep == nil {
230 t.Fatalf("%q must have `vndkdep`", name)
231 }
232 if !mod.isVndk() {
233 t.Errorf("%q isVndk() must equal to true", name)
234 }
235 if mod.isVndkSp() != isVndkSp {
236 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
237 }
238
239 // Check VNDK extension properties.
240 isVndkExt := extends != ""
241 if mod.isVndkExt() != isVndkExt {
242 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
243 }
244
245 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
246 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
247 }
248}
249
Inseob Kim1f086e22019-05-09 13:29:15 +0900250func checkVndkSnapshot(t *testing.T, ctx *android.TestContext, name, subDir, variant string) {
251 vndkSnapshot := ctx.SingletonForTests("vndk-snapshot")
252
253 snapshotPath := filepath.Join(subDir, name+".so")
254 mod := ctx.ModuleForTests(name, variant).Module().(*Module)
255 if !mod.outputFile.Valid() {
256 t.Errorf("%q must have output\n", name)
257 return
258 }
259
260 out := vndkSnapshot.Output(snapshotPath)
261 if out.Input != mod.outputFile.Path() {
262 t.Errorf("The input of VNDK snapshot must be %q, but %q", out.Input.String(), mod.outputFile.String())
263 }
264}
265
Logan Chienf3511742017-10-31 18:04:35 +0800266func TestVndk(t *testing.T) {
Inseob Kim1f086e22019-05-09 13:29:15 +0900267 config := android.TestArchConfig(buildDir, nil)
268 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
269 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
270
271 ctx := testCcWithConfig(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800272 cc_library {
273 name: "libvndk",
274 vendor_available: true,
275 vndk: {
276 enabled: true,
277 },
278 nocrt: true,
279 }
280
281 cc_library {
282 name: "libvndk_private",
283 vendor_available: false,
284 vndk: {
285 enabled: true,
286 },
287 nocrt: true,
288 }
289
290 cc_library {
291 name: "libvndk_sp",
292 vendor_available: true,
293 vndk: {
294 enabled: true,
295 support_system_process: true,
296 },
297 nocrt: true,
298 }
299
300 cc_library {
301 name: "libvndk_sp_private",
302 vendor_available: false,
303 vndk: {
304 enabled: true,
305 support_system_process: true,
306 },
307 nocrt: true,
308 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900309 `, config)
Logan Chienf3511742017-10-31 18:04:35 +0800310
311 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
312 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
313 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
314 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
Inseob Kim1f086e22019-05-09 13:29:15 +0900315
316 // Check VNDK snapshot output.
317
318 snapshotDir := "vndk-snapshot"
319 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
320
321 vndkLibPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
322 "arm64", "armv8-a"))
323 vndkLib2ndPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
324 "arm", "armv7-a-neon"))
325
326 vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core")
327 vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp")
328 vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
329 vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
330
331 variant := "android_arm64_armv8-a_vendor_shared"
332 variant2nd := "android_arm_armv7-a-neon_vendor_shared"
333
334 checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLibPath, variant)
335 checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLib2ndPath, variant2nd)
336 checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLibPath, variant)
337 checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLib2ndPath, variant2nd)
Logan Chienf3511742017-10-31 18:04:35 +0800338}
339
Logan Chiend3c59a22018-03-29 14:08:15 +0800340func TestVndkDepError(t *testing.T) {
341 // Check whether an error is emitted when a VNDK lib depends on a system lib.
342 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
343 cc_library {
344 name: "libvndk",
345 vendor_available: true,
346 vndk: {
347 enabled: true,
348 },
349 shared_libs: ["libfwk"], // Cause error
350 nocrt: true,
351 }
352
353 cc_library {
354 name: "libfwk",
355 nocrt: true,
356 }
357 `)
358
359 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
360 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
361 cc_library {
362 name: "libvndk",
363 vendor_available: true,
364 vndk: {
365 enabled: true,
366 },
367 shared_libs: ["libvendor"], // Cause error
368 nocrt: true,
369 }
370
371 cc_library {
372 name: "libvendor",
373 vendor: true,
374 nocrt: true,
375 }
376 `)
377
378 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
379 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
380 cc_library {
381 name: "libvndk_sp",
382 vendor_available: true,
383 vndk: {
384 enabled: true,
385 support_system_process: true,
386 },
387 shared_libs: ["libfwk"], // Cause error
388 nocrt: true,
389 }
390
391 cc_library {
392 name: "libfwk",
393 nocrt: true,
394 }
395 `)
396
397 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
398 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
399 cc_library {
400 name: "libvndk_sp",
401 vendor_available: true,
402 vndk: {
403 enabled: true,
404 support_system_process: true,
405 },
406 shared_libs: ["libvendor"], // Cause error
407 nocrt: true,
408 }
409
410 cc_library {
411 name: "libvendor",
412 vendor: true,
413 nocrt: true,
414 }
415 `)
416
417 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
418 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
419 cc_library {
420 name: "libvndk_sp",
421 vendor_available: true,
422 vndk: {
423 enabled: true,
424 support_system_process: true,
425 },
426 shared_libs: ["libvndk"], // Cause error
427 nocrt: true,
428 }
429
430 cc_library {
431 name: "libvndk",
432 vendor_available: true,
433 vndk: {
434 enabled: true,
435 },
436 nocrt: true,
437 }
438 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900439
440 // Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib.
441 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
442 cc_library {
443 name: "libvndk",
444 vendor_available: true,
445 vndk: {
446 enabled: true,
447 },
448 shared_libs: ["libnonvndk"],
449 nocrt: true,
450 }
451
452 cc_library {
453 name: "libnonvndk",
454 vendor_available: true,
455 nocrt: true,
456 }
457 `)
458
459 // Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib.
460 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
461 cc_library {
462 name: "libvndkprivate",
463 vendor_available: false,
464 vndk: {
465 enabled: true,
466 },
467 shared_libs: ["libnonvndk"],
468 nocrt: true,
469 }
470
471 cc_library {
472 name: "libnonvndk",
473 vendor_available: true,
474 nocrt: true,
475 }
476 `)
477
478 // Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib.
479 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
480 cc_library {
481 name: "libvndksp",
482 vendor_available: true,
483 vndk: {
484 enabled: true,
485 support_system_process: true,
486 },
487 shared_libs: ["libnonvndk"],
488 nocrt: true,
489 }
490
491 cc_library {
492 name: "libnonvndk",
493 vendor_available: true,
494 nocrt: true,
495 }
496 `)
497
498 // Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib.
499 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
500 cc_library {
501 name: "libvndkspprivate",
502 vendor_available: false,
503 vndk: {
504 enabled: true,
505 support_system_process: true,
506 },
507 shared_libs: ["libnonvndk"],
508 nocrt: true,
509 }
510
511 cc_library {
512 name: "libnonvndk",
513 vendor_available: true,
514 nocrt: true,
515 }
516 `)
517}
518
519func TestDoubleLoadbleDep(t *testing.T) {
520 // okay to link : LLNDK -> double_loadable VNDK
521 testCc(t, `
522 cc_library {
523 name: "libllndk",
524 shared_libs: ["libdoubleloadable"],
525 }
526
527 llndk_library {
528 name: "libllndk",
529 symbol_file: "",
530 }
531
532 cc_library {
533 name: "libdoubleloadable",
534 vendor_available: true,
535 vndk: {
536 enabled: true,
537 },
538 double_loadable: true,
539 }
540 `)
541 // okay to link : LLNDK -> VNDK-SP
542 testCc(t, `
543 cc_library {
544 name: "libllndk",
545 shared_libs: ["libvndksp"],
546 }
547
548 llndk_library {
549 name: "libllndk",
550 symbol_file: "",
551 }
552
553 cc_library {
554 name: "libvndksp",
555 vendor_available: true,
556 vndk: {
557 enabled: true,
558 support_system_process: true,
559 },
560 }
561 `)
562 // okay to link : double_loadable -> double_loadable
563 testCc(t, `
564 cc_library {
565 name: "libdoubleloadable1",
566 shared_libs: ["libdoubleloadable2"],
567 vendor_available: true,
568 double_loadable: true,
569 }
570
571 cc_library {
572 name: "libdoubleloadable2",
573 vendor_available: true,
574 double_loadable: true,
575 }
576 `)
577 // okay to link : double_loadable VNDK -> double_loadable VNDK private
578 testCc(t, `
579 cc_library {
580 name: "libdoubleloadable",
581 vendor_available: true,
582 vndk: {
583 enabled: true,
584 },
585 double_loadable: true,
586 shared_libs: ["libnondoubleloadable"],
587 }
588
589 cc_library {
590 name: "libnondoubleloadable",
591 vendor_available: false,
592 vndk: {
593 enabled: true,
594 },
595 double_loadable: true,
596 }
597 `)
598 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
599 testCc(t, `
600 cc_library {
601 name: "libllndk",
602 shared_libs: ["libcoreonly"],
603 }
604
605 llndk_library {
606 name: "libllndk",
607 symbol_file: "",
608 }
609
610 cc_library {
611 name: "libcoreonly",
612 shared_libs: ["libvendoravailable"],
613 }
614
615 // indirect dependency of LLNDK
616 cc_library {
617 name: "libvendoravailable",
618 vendor_available: true,
619 double_loadable: true,
620 }
621 `)
622}
623
624func TestDoubleLoadableDepError(t *testing.T) {
625 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
626 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
627 cc_library {
628 name: "libllndk",
629 shared_libs: ["libnondoubleloadable"],
630 }
631
632 llndk_library {
633 name: "libllndk",
634 symbol_file: "",
635 }
636
637 cc_library {
638 name: "libnondoubleloadable",
639 vendor_available: true,
640 vndk: {
641 enabled: true,
642 },
643 }
644 `)
645
646 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
647 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
648 cc_library {
649 name: "libllndk",
650 no_libgcc: true,
651 shared_libs: ["libnondoubleloadable"],
652 }
653
654 llndk_library {
655 name: "libllndk",
656 symbol_file: "",
657 }
658
659 cc_library {
660 name: "libnondoubleloadable",
661 vendor_available: true,
662 }
663 `)
664
665 // Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable vendor_available lib.
666 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
667 cc_library {
668 name: "libdoubleloadable",
669 vendor_available: true,
670 double_loadable: true,
671 shared_libs: ["libnondoubleloadable"],
672 }
673
674 cc_library {
675 name: "libnondoubleloadable",
676 vendor_available: true,
677 }
678 `)
679
680 // Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable VNDK lib.
681 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
682 cc_library {
683 name: "libdoubleloadable",
684 vendor_available: true,
685 double_loadable: true,
686 shared_libs: ["libnondoubleloadable"],
687 }
688
689 cc_library {
690 name: "libnondoubleloadable",
691 vendor_available: true,
692 vndk: {
693 enabled: true,
694 },
695 }
696 `)
697
698 // Check whether an error is emitted when a double_loadable VNDK depends on a non-double_loadable VNDK private lib.
699 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
700 cc_library {
701 name: "libdoubleloadable",
702 vendor_available: true,
703 vndk: {
704 enabled: true,
705 },
706 double_loadable: true,
707 shared_libs: ["libnondoubleloadable"],
708 }
709
710 cc_library {
711 name: "libnondoubleloadable",
712 vendor_available: false,
713 vndk: {
714 enabled: true,
715 },
716 }
717 `)
718
719 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
720 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
721 cc_library {
722 name: "libllndk",
723 shared_libs: ["libcoreonly"],
724 }
725
726 llndk_library {
727 name: "libllndk",
728 symbol_file: "",
729 }
730
731 cc_library {
732 name: "libcoreonly",
733 shared_libs: ["libvendoravailable"],
734 }
735
736 // indirect dependency of LLNDK
737 cc_library {
738 name: "libvendoravailable",
739 vendor_available: true,
740 }
741 `)
Logan Chiend3c59a22018-03-29 14:08:15 +0800742}
743
Justin Yun9357f4a2018-11-28 15:14:47 +0900744func TestVndkMustNotBeProductSpecific(t *testing.T) {
745 // Check whether an error is emitted when a vndk lib has 'product_specific: true'.
746 testCcError(t, "product_specific must not be true when `vndk: {enabled: true}`", `
747 cc_library {
748 name: "libvndk",
749 product_specific: true, // Cause error
750 vendor_available: true,
751 vndk: {
752 enabled: true,
753 },
754 nocrt: true,
755 }
756 `)
757}
758
Logan Chienf3511742017-10-31 18:04:35 +0800759func TestVndkExt(t *testing.T) {
760 // This test checks the VNDK-Ext properties.
761 ctx := testCc(t, `
762 cc_library {
763 name: "libvndk",
764 vendor_available: true,
765 vndk: {
766 enabled: true,
767 },
768 nocrt: true,
769 }
770
771 cc_library {
772 name: "libvndk_ext",
773 vendor: true,
774 vndk: {
775 enabled: true,
776 extends: "libvndk",
777 },
778 nocrt: true,
779 }
780 `)
781
782 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
783}
784
Logan Chiend3c59a22018-03-29 14:08:15 +0800785func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800786 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
787 ctx := testCcNoVndk(t, `
788 cc_library {
789 name: "libvndk",
790 vendor_available: true,
791 vndk: {
792 enabled: true,
793 },
794 nocrt: true,
795 }
796
797 cc_library {
798 name: "libvndk_ext",
799 vendor: true,
800 vndk: {
801 enabled: true,
802 extends: "libvndk",
803 },
804 nocrt: true,
805 }
806 `)
807
808 // Ensures that the core variant of "libvndk_ext" can be found.
809 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
810 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
811 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
812 }
813}
814
815func TestVndkExtError(t *testing.T) {
816 // This test ensures an error is emitted in ill-formed vndk-ext definition.
817 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
818 cc_library {
819 name: "libvndk",
820 vendor_available: true,
821 vndk: {
822 enabled: true,
823 },
824 nocrt: true,
825 }
826
827 cc_library {
828 name: "libvndk_ext",
829 vndk: {
830 enabled: true,
831 extends: "libvndk",
832 },
833 nocrt: true,
834 }
835 `)
836
837 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
838 cc_library {
839 name: "libvndk",
840 vendor_available: true,
841 vndk: {
842 enabled: true,
843 },
844 nocrt: true,
845 }
846
847 cc_library {
848 name: "libvndk_ext",
849 vendor: true,
850 vndk: {
851 enabled: true,
852 },
853 nocrt: true,
854 }
855 `)
856}
857
858func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
859 // This test ensures an error is emitted for inconsistent support_system_process.
860 testCcError(t, "module \".*\" with mismatched support_system_process", `
861 cc_library {
862 name: "libvndk",
863 vendor_available: true,
864 vndk: {
865 enabled: true,
866 },
867 nocrt: true,
868 }
869
870 cc_library {
871 name: "libvndk_sp_ext",
872 vendor: true,
873 vndk: {
874 enabled: true,
875 extends: "libvndk",
876 support_system_process: true,
877 },
878 nocrt: true,
879 }
880 `)
881
882 testCcError(t, "module \".*\" with mismatched support_system_process", `
883 cc_library {
884 name: "libvndk_sp",
885 vendor_available: true,
886 vndk: {
887 enabled: true,
888 support_system_process: true,
889 },
890 nocrt: true,
891 }
892
893 cc_library {
894 name: "libvndk_ext",
895 vendor: true,
896 vndk: {
897 enabled: true,
898 extends: "libvndk_sp",
899 },
900 nocrt: true,
901 }
902 `)
903}
904
905func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800906 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800907 // with `vendor_available: false`.
908 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
909 cc_library {
910 name: "libvndk",
911 vendor_available: false,
912 vndk: {
913 enabled: true,
914 },
915 nocrt: true,
916 }
917
918 cc_library {
919 name: "libvndk_ext",
920 vendor: true,
921 vndk: {
922 enabled: true,
923 extends: "libvndk",
924 },
925 nocrt: true,
926 }
927 `)
928}
929
Logan Chiend3c59a22018-03-29 14:08:15 +0800930func TestVendorModuleUseVndkExt(t *testing.T) {
931 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800932 testCc(t, `
933 cc_library {
934 name: "libvndk",
935 vendor_available: true,
936 vndk: {
937 enabled: true,
938 },
939 nocrt: true,
940 }
941
942 cc_library {
943 name: "libvndk_ext",
944 vendor: true,
945 vndk: {
946 enabled: true,
947 extends: "libvndk",
948 },
949 nocrt: true,
950 }
951
952 cc_library {
953
954 name: "libvndk_sp",
955 vendor_available: true,
956 vndk: {
957 enabled: true,
958 support_system_process: true,
959 },
960 nocrt: true,
961 }
962
963 cc_library {
964 name: "libvndk_sp_ext",
965 vendor: true,
966 vndk: {
967 enabled: true,
968 extends: "libvndk_sp",
969 support_system_process: true,
970 },
971 nocrt: true,
972 }
973
974 cc_library {
975 name: "libvendor",
976 vendor: true,
977 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
978 nocrt: true,
979 }
980 `)
981}
982
Logan Chiend3c59a22018-03-29 14:08:15 +0800983func TestVndkExtUseVendorLib(t *testing.T) {
984 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800985 testCc(t, `
986 cc_library {
987 name: "libvndk",
988 vendor_available: true,
989 vndk: {
990 enabled: true,
991 },
992 nocrt: true,
993 }
994
995 cc_library {
996 name: "libvndk_ext",
997 vendor: true,
998 vndk: {
999 enabled: true,
1000 extends: "libvndk",
1001 },
1002 shared_libs: ["libvendor"],
1003 nocrt: true,
1004 }
1005
1006 cc_library {
1007 name: "libvendor",
1008 vendor: true,
1009 nocrt: true,
1010 }
1011 `)
Logan Chienf3511742017-10-31 18:04:35 +08001012
Logan Chiend3c59a22018-03-29 14:08:15 +08001013 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
1014 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +08001015 cc_library {
1016 name: "libvndk_sp",
1017 vendor_available: true,
1018 vndk: {
1019 enabled: true,
1020 support_system_process: true,
1021 },
1022 nocrt: true,
1023 }
1024
1025 cc_library {
1026 name: "libvndk_sp_ext",
1027 vendor: true,
1028 vndk: {
1029 enabled: true,
1030 extends: "libvndk_sp",
1031 support_system_process: true,
1032 },
1033 shared_libs: ["libvendor"], // Cause an error
1034 nocrt: true,
1035 }
1036
1037 cc_library {
1038 name: "libvendor",
1039 vendor: true,
1040 nocrt: true,
1041 }
1042 `)
1043}
1044
Logan Chiend3c59a22018-03-29 14:08:15 +08001045func TestVndkSpExtUseVndkError(t *testing.T) {
1046 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
1047 // library.
1048 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1049 cc_library {
1050 name: "libvndk",
1051 vendor_available: true,
1052 vndk: {
1053 enabled: true,
1054 },
1055 nocrt: true,
1056 }
1057
1058 cc_library {
1059 name: "libvndk_sp",
1060 vendor_available: true,
1061 vndk: {
1062 enabled: true,
1063 support_system_process: true,
1064 },
1065 nocrt: true,
1066 }
1067
1068 cc_library {
1069 name: "libvndk_sp_ext",
1070 vendor: true,
1071 vndk: {
1072 enabled: true,
1073 extends: "libvndk_sp",
1074 support_system_process: true,
1075 },
1076 shared_libs: ["libvndk"], // Cause an error
1077 nocrt: true,
1078 }
1079 `)
1080
1081 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
1082 // library.
1083 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1084 cc_library {
1085 name: "libvndk",
1086 vendor_available: true,
1087 vndk: {
1088 enabled: true,
1089 },
1090 nocrt: true,
1091 }
1092
1093 cc_library {
1094 name: "libvndk_ext",
1095 vendor: true,
1096 vndk: {
1097 enabled: true,
1098 extends: "libvndk",
1099 },
1100 nocrt: true,
1101 }
1102
1103 cc_library {
1104 name: "libvndk_sp",
1105 vendor_available: true,
1106 vndk: {
1107 enabled: true,
1108 support_system_process: true,
1109 },
1110 nocrt: true,
1111 }
1112
1113 cc_library {
1114 name: "libvndk_sp_ext",
1115 vendor: true,
1116 vndk: {
1117 enabled: true,
1118 extends: "libvndk_sp",
1119 support_system_process: true,
1120 },
1121 shared_libs: ["libvndk_ext"], // Cause an error
1122 nocrt: true,
1123 }
1124 `)
1125}
1126
1127func TestVndkUseVndkExtError(t *testing.T) {
1128 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
1129 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +08001130 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1131 cc_library {
1132 name: "libvndk",
1133 vendor_available: true,
1134 vndk: {
1135 enabled: true,
1136 },
1137 nocrt: true,
1138 }
1139
1140 cc_library {
1141 name: "libvndk_ext",
1142 vendor: true,
1143 vndk: {
1144 enabled: true,
1145 extends: "libvndk",
1146 },
1147 nocrt: true,
1148 }
1149
1150 cc_library {
1151 name: "libvndk2",
1152 vendor_available: true,
1153 vndk: {
1154 enabled: true,
1155 },
1156 shared_libs: ["libvndk_ext"],
1157 nocrt: true,
1158 }
1159 `)
1160
Martin Stjernholmef449fe2018-11-06 16:12:13 +00001161 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +08001162 cc_library {
1163 name: "libvndk",
1164 vendor_available: true,
1165 vndk: {
1166 enabled: true,
1167 },
1168 nocrt: true,
1169 }
1170
1171 cc_library {
1172 name: "libvndk_ext",
1173 vendor: true,
1174 vndk: {
1175 enabled: true,
1176 extends: "libvndk",
1177 },
1178 nocrt: true,
1179 }
1180
1181 cc_library {
1182 name: "libvndk2",
1183 vendor_available: true,
1184 vndk: {
1185 enabled: true,
1186 },
1187 target: {
1188 vendor: {
1189 shared_libs: ["libvndk_ext"],
1190 },
1191 },
1192 nocrt: true,
1193 }
1194 `)
1195
1196 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1197 cc_library {
1198 name: "libvndk_sp",
1199 vendor_available: true,
1200 vndk: {
1201 enabled: true,
1202 support_system_process: true,
1203 },
1204 nocrt: true,
1205 }
1206
1207 cc_library {
1208 name: "libvndk_sp_ext",
1209 vendor: true,
1210 vndk: {
1211 enabled: true,
1212 extends: "libvndk_sp",
1213 support_system_process: true,
1214 },
1215 nocrt: true,
1216 }
1217
1218 cc_library {
1219 name: "libvndk_sp_2",
1220 vendor_available: true,
1221 vndk: {
1222 enabled: true,
1223 support_system_process: true,
1224 },
1225 shared_libs: ["libvndk_sp_ext"],
1226 nocrt: true,
1227 }
1228 `)
1229
Martin Stjernholmef449fe2018-11-06 16:12:13 +00001230 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +08001231 cc_library {
1232 name: "libvndk_sp",
1233 vendor_available: true,
1234 vndk: {
1235 enabled: true,
1236 },
1237 nocrt: true,
1238 }
1239
1240 cc_library {
1241 name: "libvndk_sp_ext",
1242 vendor: true,
1243 vndk: {
1244 enabled: true,
1245 extends: "libvndk_sp",
1246 },
1247 nocrt: true,
1248 }
1249
1250 cc_library {
1251 name: "libvndk_sp2",
1252 vendor_available: true,
1253 vndk: {
1254 enabled: true,
1255 },
1256 target: {
1257 vendor: {
1258 shared_libs: ["libvndk_sp_ext"],
1259 },
1260 },
1261 nocrt: true,
1262 }
1263 `)
1264}
1265
Colin Cross0af4b842015-04-30 16:36:18 -07001266var (
1267 str11 = "01234567891"
1268 str10 = str11[:10]
1269 str9 = str11[:9]
1270 str5 = str11[:5]
1271 str4 = str11[:4]
1272)
1273
1274var splitListForSizeTestCases = []struct {
1275 in []string
1276 out [][]string
1277 size int
1278}{
1279 {
1280 in: []string{str10},
1281 out: [][]string{{str10}},
1282 size: 10,
1283 },
1284 {
1285 in: []string{str9},
1286 out: [][]string{{str9}},
1287 size: 10,
1288 },
1289 {
1290 in: []string{str5},
1291 out: [][]string{{str5}},
1292 size: 10,
1293 },
1294 {
1295 in: []string{str11},
1296 out: nil,
1297 size: 10,
1298 },
1299 {
1300 in: []string{str10, str10},
1301 out: [][]string{{str10}, {str10}},
1302 size: 10,
1303 },
1304 {
1305 in: []string{str9, str10},
1306 out: [][]string{{str9}, {str10}},
1307 size: 10,
1308 },
1309 {
1310 in: []string{str10, str9},
1311 out: [][]string{{str10}, {str9}},
1312 size: 10,
1313 },
1314 {
1315 in: []string{str5, str4},
1316 out: [][]string{{str5, str4}},
1317 size: 10,
1318 },
1319 {
1320 in: []string{str5, str4, str5},
1321 out: [][]string{{str5, str4}, {str5}},
1322 size: 10,
1323 },
1324 {
1325 in: []string{str5, str4, str5, str4},
1326 out: [][]string{{str5, str4}, {str5, str4}},
1327 size: 10,
1328 },
1329 {
1330 in: []string{str5, str4, str5, str5},
1331 out: [][]string{{str5, str4}, {str5}, {str5}},
1332 size: 10,
1333 },
1334 {
1335 in: []string{str5, str5, str5, str4},
1336 out: [][]string{{str5}, {str5}, {str5, str4}},
1337 size: 10,
1338 },
1339 {
1340 in: []string{str9, str11},
1341 out: nil,
1342 size: 10,
1343 },
1344 {
1345 in: []string{str11, str9},
1346 out: nil,
1347 size: 10,
1348 },
1349}
1350
1351func TestSplitListForSize(t *testing.T) {
1352 for _, testCase := range splitListForSizeTestCases {
Colin Cross40e33732019-02-15 11:08:35 -08001353 out, _ := splitListForSize(android.PathsForTesting(testCase.in...), testCase.size)
Colin Cross5b529592017-05-09 13:34:34 -07001354
1355 var outStrings [][]string
1356
1357 if len(out) > 0 {
1358 outStrings = make([][]string, len(out))
1359 for i, o := range out {
1360 outStrings[i] = o.Strings()
1361 }
1362 }
1363
1364 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001365 t.Errorf("incorrect output:")
1366 t.Errorf(" input: %#v", testCase.in)
1367 t.Errorf(" size: %d", testCase.size)
1368 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001369 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001370 }
1371 }
1372}
Jeff Gaston294356f2017-09-27 17:05:30 -07001373
1374var staticLinkDepOrderTestCases = []struct {
1375 // This is a string representation of a map[moduleName][]moduleDependency .
1376 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001377 inStatic string
1378
1379 // This is a string representation of a map[moduleName][]moduleDependency .
1380 // It models the dependencies declared in an Android.bp file.
1381 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001382
1383 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1384 // The keys of allOrdered specify which modules we would like to check.
1385 // The values of allOrdered specify the expected result (of the transitive closure of all
1386 // dependencies) for each module to test
1387 allOrdered string
1388
1389 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1390 // The keys of outOrdered specify which modules we would like to check.
1391 // The values of outOrdered specify the expected result (of the ordered linker command line)
1392 // for each module to test.
1393 outOrdered string
1394}{
1395 // Simple tests
1396 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001397 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001398 outOrdered: "",
1399 },
1400 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001401 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001402 outOrdered: "a:",
1403 },
1404 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001405 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001406 outOrdered: "a:b; b:",
1407 },
1408 // Tests of reordering
1409 {
1410 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001411 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001412 outOrdered: "a:b,c,d; b:d; c:d; d:",
1413 },
1414 {
1415 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001416 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001417 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1418 },
1419 {
1420 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001421 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001422 outOrdered: "a:d,b,e,c; d:b; e:c",
1423 },
1424 {
1425 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001426 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001427 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1428 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1429 },
1430 {
1431 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001432 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 -07001433 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1434 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1435 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001436 // shared dependencies
1437 {
1438 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1439 // So, we don't actually have to check that a shared dependency of c will change the order
1440 // of a library that depends statically on b and on c. We only need to check that if c has
1441 // a shared dependency on b, that that shows up in allOrdered.
1442 inShared: "c:b",
1443 allOrdered: "c:b",
1444 outOrdered: "c:",
1445 },
1446 {
1447 // This test doesn't actually include any shared dependencies but it's a reminder of what
1448 // the second phase of the above test would look like
1449 inStatic: "a:b,c; c:b",
1450 allOrdered: "a:c,b; c:b",
1451 outOrdered: "a:c,b; c:b",
1452 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001453 // tiebreakers for when two modules specifying different orderings and there is no dependency
1454 // to dictate an order
1455 {
1456 // 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 -08001457 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001458 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1459 },
1460 {
1461 // 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 -08001462 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 -07001463 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1464 },
1465 // Tests involving duplicate dependencies
1466 {
1467 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001468 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001469 outOrdered: "a:c,b",
1470 },
1471 {
1472 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001473 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001474 outOrdered: "a:d,c,b",
1475 },
1476 // Tests to confirm the nonexistence of infinite loops.
1477 // These cases should never happen, so as long as the test terminates and the
1478 // result is deterministic then that should be fine.
1479 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001480 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001481 outOrdered: "a:a",
1482 },
1483 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001484 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001485 allOrdered: "a:b,c; b:c,a; c:a,b",
1486 outOrdered: "a:b; b:c; c:a",
1487 },
1488 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001489 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001490 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1491 outOrdered: "a:c,b; b:a,c; c:b,a",
1492 },
1493}
1494
1495// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1496func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1497 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1498 strippedText := strings.Replace(text, " ", "", -1)
1499 if len(strippedText) < 1 {
1500 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1501 }
1502 allDeps = make(map[android.Path][]android.Path, 0)
1503
1504 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1505 moduleTexts := strings.Split(strippedText, ";")
1506
1507 outputForModuleName := func(moduleName string) android.Path {
1508 return android.PathForTesting(moduleName)
1509 }
1510
1511 for _, moduleText := range moduleTexts {
1512 // convert from "a:b,c" to ["a", "b,c"]
1513 components := strings.Split(moduleText, ":")
1514 if len(components) != 2 {
1515 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1516 }
1517 moduleName := components[0]
1518 moduleOutput := outputForModuleName(moduleName)
1519 modulesInOrder = append(modulesInOrder, moduleOutput)
1520
1521 depString := components[1]
1522 // convert from "b,c" to ["b", "c"]
1523 depNames := strings.Split(depString, ",")
1524 if len(depString) < 1 {
1525 depNames = []string{}
1526 }
1527 var deps []android.Path
1528 for _, depName := range depNames {
1529 deps = append(deps, outputForModuleName(depName))
1530 }
1531 allDeps[moduleOutput] = deps
1532 }
1533 return modulesInOrder, allDeps
1534}
1535
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001536func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001537 for _, testCase := range staticLinkDepOrderTestCases {
1538 errs := []string{}
1539
1540 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001541 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001542 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1543 if testCase.allOrdered == "" {
1544 // allow the test case to skip specifying allOrdered
1545 testCase.allOrdered = testCase.outOrdered
1546 }
1547 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001548 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001549
1550 // For each module whose post-reordered dependencies were specified, validate that
1551 // reordering the inputs produces the expected outputs.
1552 for _, moduleName := range expectedModuleNames {
1553 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001554 givenSharedDeps := givenAllSharedDeps[moduleName]
1555 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001556
1557 correctAllOrdered := expectedAllDeps[moduleName]
1558 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1559 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001560 "\nin static:%q"+
1561 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001562 "\nmodule: %v"+
1563 "\nexpected: %s"+
1564 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001565 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001566 }
1567
1568 correctOutputDeps := expectedTransitiveDeps[moduleName]
1569 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1570 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001571 "\nin static:%q"+
1572 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001573 "\nmodule: %v"+
1574 "\nexpected: %s"+
1575 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001576 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001577 }
1578 }
1579
1580 if len(errs) > 0 {
1581 sort.Strings(errs)
1582 for _, err := range errs {
1583 t.Error(err)
1584 }
1585 }
1586 }
1587}
Logan Chienf3511742017-10-31 18:04:35 +08001588
Jeff Gaston294356f2017-09-27 17:05:30 -07001589func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1590 for _, moduleName := range moduleNames {
1591 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1592 output := module.outputFile.Path()
1593 paths = append(paths, output)
1594 }
1595 return paths
1596}
1597
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001598func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001599 ctx := testCc(t, `
1600 cc_library {
1601 name: "a",
1602 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001603 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001604 }
1605 cc_library {
1606 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001607 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001608 }
1609 cc_library {
1610 name: "c",
1611 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001612 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001613 }
1614 cc_library {
1615 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001616 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001617 }
1618
1619 `)
1620
1621 variant := "android_arm64_armv8-a_core_static"
1622 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001623 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001624 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1625
1626 if !reflect.DeepEqual(actual, expected) {
1627 t.Errorf("staticDeps orderings were not propagated correctly"+
1628 "\nactual: %v"+
1629 "\nexpected: %v",
1630 actual,
1631 expected,
1632 )
1633 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001634}
Jeff Gaston294356f2017-09-27 17:05:30 -07001635
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001636func TestStaticLibDepReorderingWithShared(t *testing.T) {
1637 ctx := testCc(t, `
1638 cc_library {
1639 name: "a",
1640 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001641 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001642 }
1643 cc_library {
1644 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001645 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001646 }
1647 cc_library {
1648 name: "c",
1649 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001650 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001651 }
1652
1653 `)
1654
1655 variant := "android_arm64_armv8-a_core_static"
1656 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1657 actual := moduleA.depsInLinkOrder
1658 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1659
1660 if !reflect.DeepEqual(actual, expected) {
1661 t.Errorf("staticDeps orderings did not account for shared libs"+
1662 "\nactual: %v"+
1663 "\nexpected: %v",
1664 actual,
1665 expected,
1666 )
1667 }
1668}
1669
Jiyong Parka46a4d52017-12-14 19:54:34 +09001670func TestLlndkHeaders(t *testing.T) {
1671 ctx := testCc(t, `
1672 llndk_headers {
1673 name: "libllndk_headers",
1674 export_include_dirs: ["my_include"],
1675 }
1676 llndk_library {
1677 name: "libllndk",
1678 export_llndk_headers: ["libllndk_headers"],
1679 }
1680 cc_library {
1681 name: "libvendor",
1682 shared_libs: ["libllndk"],
1683 vendor: true,
1684 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001685 no_libgcc: true,
1686 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001687 }
1688 `)
1689
1690 // _static variant is used since _shared reuses *.o from the static variant
1691 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1692 cflags := cc.Args["cFlags"]
1693 if !strings.Contains(cflags, "-Imy_include") {
1694 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1695 }
1696}
1697
Logan Chien43d34c32017-12-20 01:17:32 +08001698func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1699 actual := module.Properties.AndroidMkRuntimeLibs
1700 if !reflect.DeepEqual(actual, expected) {
1701 t.Errorf("incorrect runtime_libs for shared libs"+
1702 "\nactual: %v"+
1703 "\nexpected: %v",
1704 actual,
1705 expected,
1706 )
1707 }
1708}
1709
1710const runtimeLibAndroidBp = `
1711 cc_library {
1712 name: "libvendor_available1",
1713 vendor_available: true,
1714 no_libgcc : true,
1715 nocrt : true,
1716 system_shared_libs : [],
1717 }
1718 cc_library {
1719 name: "libvendor_available2",
1720 vendor_available: true,
1721 runtime_libs: ["libvendor_available1"],
1722 no_libgcc : true,
1723 nocrt : true,
1724 system_shared_libs : [],
1725 }
1726 cc_library {
1727 name: "libvendor_available3",
1728 vendor_available: true,
1729 runtime_libs: ["libvendor_available1"],
1730 target: {
1731 vendor: {
1732 exclude_runtime_libs: ["libvendor_available1"],
1733 }
1734 },
1735 no_libgcc : true,
1736 nocrt : true,
1737 system_shared_libs : [],
1738 }
1739 cc_library {
1740 name: "libcore",
1741 runtime_libs: ["libvendor_available1"],
1742 no_libgcc : true,
1743 nocrt : true,
1744 system_shared_libs : [],
1745 }
1746 cc_library {
1747 name: "libvendor1",
1748 vendor: true,
1749 no_libgcc : true,
1750 nocrt : true,
1751 system_shared_libs : [],
1752 }
1753 cc_library {
1754 name: "libvendor2",
1755 vendor: true,
1756 runtime_libs: ["libvendor_available1", "libvendor1"],
1757 no_libgcc : true,
1758 nocrt : true,
1759 system_shared_libs : [],
1760 }
1761`
1762
1763func TestRuntimeLibs(t *testing.T) {
1764 ctx := testCc(t, runtimeLibAndroidBp)
1765
1766 // runtime_libs for core variants use the module names without suffixes.
1767 variant := "android_arm64_armv8-a_core_shared"
1768
1769 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1770 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1771
1772 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1773 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1774
1775 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1776 // and vendor variants.
1777 variant = "android_arm64_armv8-a_vendor_shared"
1778
1779 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1780 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1781
1782 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1783 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1784}
1785
1786func TestExcludeRuntimeLibs(t *testing.T) {
1787 ctx := testCc(t, runtimeLibAndroidBp)
1788
1789 variant := "android_arm64_armv8-a_core_shared"
1790 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1791 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1792
1793 variant = "android_arm64_armv8-a_vendor_shared"
1794 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1795 checkRuntimeLibs(t, nil, module)
1796}
1797
1798func TestRuntimeLibsNoVndk(t *testing.T) {
1799 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1800
1801 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1802
1803 variant := "android_arm64_armv8-a_core_shared"
1804
1805 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1806 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1807
1808 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1809 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1810}
1811
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001812func checkStaticLibs(t *testing.T, expected []string, module *Module) {
1813 actual := module.Properties.AndroidMkStaticLibs
1814 if !reflect.DeepEqual(actual, expected) {
1815 t.Errorf("incorrect static_libs"+
1816 "\nactual: %v"+
1817 "\nexpected: %v",
1818 actual,
1819 expected,
1820 )
1821 }
1822}
1823
1824const staticLibAndroidBp = `
1825 cc_library {
1826 name: "lib1",
1827 }
1828 cc_library {
1829 name: "lib2",
1830 static_libs: ["lib1"],
1831 }
1832`
1833
1834func TestStaticLibDepExport(t *testing.T) {
1835 ctx := testCc(t, staticLibAndroidBp)
1836
1837 // Check the shared version of lib2.
1838 variant := "android_arm64_armv8-a_core_shared"
1839 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Yi Kongacee27c2019-03-29 20:05:14 -07001840 checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001841
1842 // Check the static version of lib2.
1843 variant = "android_arm64_armv8-a_core_static"
1844 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1845 // libc++_static is linked additionally.
Yi Kongacee27c2019-03-29 20:05:14 -07001846 checkStaticLibs(t, []string{"lib1", "libc++_static", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001847}
1848
Jiyong Parkd08b6972017-09-26 10:50:54 +09001849var compilerFlagsTestCases = []struct {
1850 in string
1851 out bool
1852}{
1853 {
1854 in: "a",
1855 out: false,
1856 },
1857 {
1858 in: "-a",
1859 out: true,
1860 },
1861 {
1862 in: "-Ipath/to/something",
1863 out: false,
1864 },
1865 {
1866 in: "-isystempath/to/something",
1867 out: false,
1868 },
1869 {
1870 in: "--coverage",
1871 out: false,
1872 },
1873 {
1874 in: "-include a/b",
1875 out: true,
1876 },
1877 {
1878 in: "-include a/b c/d",
1879 out: false,
1880 },
1881 {
1882 in: "-DMACRO",
1883 out: true,
1884 },
1885 {
1886 in: "-DMAC RO",
1887 out: false,
1888 },
1889 {
1890 in: "-a -b",
1891 out: false,
1892 },
1893 {
1894 in: "-DMACRO=definition",
1895 out: true,
1896 },
1897 {
1898 in: "-DMACRO=defi nition",
1899 out: true, // TODO(jiyong): this should be false
1900 },
1901 {
1902 in: "-DMACRO(x)=x + 1",
1903 out: true,
1904 },
1905 {
1906 in: "-DMACRO=\"defi nition\"",
1907 out: true,
1908 },
1909}
1910
1911type mockContext struct {
1912 BaseModuleContext
1913 result bool
1914}
1915
1916func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1917 // CheckBadCompilerFlags calls this function when the flag should be rejected
1918 ctx.result = false
1919}
1920
1921func TestCompilerFlags(t *testing.T) {
1922 for _, testCase := range compilerFlagsTestCases {
1923 ctx := &mockContext{result: true}
1924 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1925 if ctx.result != testCase.out {
1926 t.Errorf("incorrect output:")
1927 t.Errorf(" input: %#v", testCase.in)
1928 t.Errorf(" expected: %#v", testCase.out)
1929 t.Errorf(" got: %#v", ctx.result)
1930 }
1931 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001932}
Jiyong Park374510b2018-03-19 18:23:01 +09001933
1934func TestVendorPublicLibraries(t *testing.T) {
1935 ctx := testCc(t, `
1936 cc_library_headers {
1937 name: "libvendorpublic_headers",
1938 export_include_dirs: ["my_include"],
1939 }
1940 vendor_public_library {
1941 name: "libvendorpublic",
1942 symbol_file: "",
1943 export_public_headers: ["libvendorpublic_headers"],
1944 }
1945 cc_library {
1946 name: "libvendorpublic",
1947 srcs: ["foo.c"],
1948 vendor: true,
1949 no_libgcc: true,
1950 nocrt: true,
1951 }
1952
1953 cc_library {
1954 name: "libsystem",
1955 shared_libs: ["libvendorpublic"],
1956 vendor: false,
1957 srcs: ["foo.c"],
1958 no_libgcc: true,
1959 nocrt: true,
1960 }
1961 cc_library {
1962 name: "libvendor",
1963 shared_libs: ["libvendorpublic"],
1964 vendor: true,
1965 srcs: ["foo.c"],
1966 no_libgcc: true,
1967 nocrt: true,
1968 }
1969 `)
1970
1971 variant := "android_arm64_armv8-a_core_shared"
1972
1973 // test if header search paths are correctly added
1974 // _static variant is used since _shared reuses *.o from the static variant
1975 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
1976 cflags := cc.Args["cFlags"]
1977 if !strings.Contains(cflags, "-Imy_include") {
1978 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
1979 }
1980
1981 // test if libsystem is linked to the stub
1982 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
1983 libflags := ld.Args["libFlags"]
1984 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
1985 if !strings.Contains(libflags, stubPaths[0].String()) {
1986 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
1987 }
1988
1989 // test if libvendor is linked to the real shared lib
1990 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
1991 libflags = ld.Args["libFlags"]
1992 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
1993 if !strings.Contains(libflags, stubPaths[0].String()) {
1994 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
1995 }
1996
1997}
Jiyong Park37b25202018-07-11 10:49:27 +09001998
1999func TestRecovery(t *testing.T) {
2000 ctx := testCc(t, `
2001 cc_library_shared {
2002 name: "librecovery",
2003 recovery: true,
2004 }
2005 cc_library_shared {
2006 name: "librecovery32",
2007 recovery: true,
2008 compile_multilib:"32",
2009 }
Jiyong Park5baac542018-08-28 09:55:37 +09002010 cc_library_shared {
2011 name: "libHalInRecovery",
2012 recovery_available: true,
2013 vendor: true,
2014 }
Jiyong Park37b25202018-07-11 10:49:27 +09002015 `)
2016
2017 variants := ctx.ModuleVariantsForTests("librecovery")
2018 const arm64 = "android_arm64_armv8-a_recovery_shared"
2019 if len(variants) != 1 || !android.InList(arm64, variants) {
2020 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
2021 }
2022
2023 variants = ctx.ModuleVariantsForTests("librecovery32")
2024 if android.InList(arm64, variants) {
2025 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
2026 }
Jiyong Park5baac542018-08-28 09:55:37 +09002027
2028 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
2029 if !recoveryModule.Platform() {
2030 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
2031 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09002032}
Jiyong Park5baac542018-08-28 09:55:37 +09002033
Jiyong Park7ed9de32018-10-15 22:25:07 +09002034func TestVersionedStubs(t *testing.T) {
2035 ctx := testCc(t, `
2036 cc_library_shared {
2037 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002038 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002039 stubs: {
2040 symbol_file: "foo.map.txt",
2041 versions: ["1", "2", "3"],
2042 },
2043 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002044
Jiyong Park7ed9de32018-10-15 22:25:07 +09002045 cc_library_shared {
2046 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002047 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002048 shared_libs: ["libFoo#1"],
2049 }`)
2050
2051 variants := ctx.ModuleVariantsForTests("libFoo")
2052 expectedVariants := []string{
2053 "android_arm64_armv8-a_core_shared",
2054 "android_arm64_armv8-a_core_shared_1",
2055 "android_arm64_armv8-a_core_shared_2",
2056 "android_arm64_armv8-a_core_shared_3",
2057 "android_arm_armv7-a-neon_core_shared",
2058 "android_arm_armv7-a-neon_core_shared_1",
2059 "android_arm_armv7-a-neon_core_shared_2",
2060 "android_arm_armv7-a-neon_core_shared_3",
2061 }
2062 variantsMismatch := false
2063 if len(variants) != len(expectedVariants) {
2064 variantsMismatch = true
2065 } else {
2066 for _, v := range expectedVariants {
2067 if !inList(v, variants) {
2068 variantsMismatch = false
2069 }
2070 }
2071 }
2072 if variantsMismatch {
2073 t.Errorf("variants of libFoo expected:\n")
2074 for _, v := range expectedVariants {
2075 t.Errorf("%q\n", v)
2076 }
2077 t.Errorf(", but got:\n")
2078 for _, v := range variants {
2079 t.Errorf("%q\n", v)
2080 }
2081 }
2082
2083 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld")
2084 libFlags := libBarLinkRule.Args["libFlags"]
2085 libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so"
2086 if !strings.Contains(libFlags, libFoo1StubPath) {
2087 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
2088 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002089
2090 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("cc")
2091 cFlags := libBarCompileRule.Args["cFlags"]
2092 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
2093 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
2094 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
2095 }
Jiyong Park37b25202018-07-11 10:49:27 +09002096}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002097
2098func TestStaticExecutable(t *testing.T) {
2099 ctx := testCc(t, `
2100 cc_binary {
2101 name: "static_test",
2102 srcs: ["foo.c"],
2103 static_executable: true,
2104 }`)
2105
2106 variant := "android_arm64_armv8-a_core"
2107 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
2108 libFlags := binModuleRule.Args["libFlags"]
2109 systemStaticLibs := []string{"libc.a", "libm.a", "libdl.a"}
2110 for _, lib := range systemStaticLibs {
2111 if !strings.Contains(libFlags, lib) {
2112 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
2113 }
2114 }
2115 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
2116 for _, lib := range systemSharedLibs {
2117 if strings.Contains(libFlags, lib) {
2118 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
2119 }
2120 }
2121}
Jiyong Parke4bb9862019-02-01 00:31:10 +09002122
2123func TestStaticDepsOrderWithStubs(t *testing.T) {
2124 ctx := testCc(t, `
2125 cc_binary {
2126 name: "mybin",
2127 srcs: ["foo.c"],
2128 static_libs: ["libB"],
2129 static_executable: true,
2130 stl: "none",
2131 }
2132
2133 cc_library {
2134 name: "libB",
2135 srcs: ["foo.c"],
2136 shared_libs: ["libC"],
2137 stl: "none",
2138 }
2139
2140 cc_library {
2141 name: "libC",
2142 srcs: ["foo.c"],
2143 stl: "none",
2144 stubs: {
2145 versions: ["1"],
2146 },
2147 }`)
2148
2149 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a_core").Module().(*Module)
2150 actual := mybin.depsInLinkOrder
2151 expected := getOutputPaths(ctx, "android_arm64_armv8-a_core_static", []string{"libB", "libC"})
2152
2153 if !reflect.DeepEqual(actual, expected) {
2154 t.Errorf("staticDeps orderings were not propagated correctly"+
2155 "\nactual: %v"+
2156 "\nexpected: %v",
2157 actual,
2158 expected,
2159 )
2160 }
2161}