blob: 689aacd84c814ab908584adefaf07abd1fa5c856 [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 (
Jeff Gaston294356f2017-09-27 17:05:30 -070018 "fmt"
Jiyong Park6a43f042017-10-12 23:05:00 +090019 "io/ioutil"
20 "os"
Inseob Kim1f086e22019-05-09 13:29:15 +090021 "path/filepath"
Colin Cross74d1ec02015-04-28 13:30:13 -070022 "reflect"
Jeff Gaston294356f2017-09-27 17:05:30 -070023 "sort"
24 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070025 "testing"
Colin Crosse1bb5d02019-09-24 14:55:04 -070026
27 "android/soong/android"
Colin Cross74d1ec02015-04-28 13:30:13 -070028)
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 {
Colin Crosse1bb5d02019-09-24 14:55:04 -070056 t.Helper()
Doug Hornc32c6b02019-01-17 14:44:05 -080057 return testCcWithConfigForOs(t, bp, config, android.Android)
58}
59
60func testCcWithConfigForOs(t *testing.T, bp string, config android.Config, os android.OsType) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080061 t.Helper()
Colin Cross9a942872019-05-14 15:44:26 -070062 ctx := CreateTestContext(bp, nil, os)
Colin Cross33b2fb72019-05-14 14:07:01 -070063 ctx.Register()
Logan Chienf3511742017-10-31 18:04:35 +080064
Jeff Gastond3e141d2017-08-08 17:46:01 -070065 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +080066 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +090067 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +080068 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +090069
70 return ctx
71}
72
Logan Chienf3511742017-10-31 18:04:35 +080073func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080074 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080075 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070076 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
77 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080078
79 return testCcWithConfig(t, bp, config)
80}
81
82func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080083 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080084 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070085 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080086
87 return testCcWithConfig(t, bp, config)
88}
89
90func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +080091 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080092 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070093 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
94 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080095
Colin Cross9a942872019-05-14 15:44:26 -070096 ctx := CreateTestContext(bp, nil, android.Android)
Colin Cross33b2fb72019-05-14 14:07:01 -070097 ctx.Register()
Logan Chienf3511742017-10-31 18:04:35 +080098
99 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
100 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800101 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800102 return
103 }
104
105 _, errs = ctx.PrepareBuildActions(config)
106 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800107 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800108 return
109 }
110
111 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
112}
113
114const (
Jiyong Park5baac542018-08-28 09:55:37 +0900115 coreVariant = "android_arm64_armv8-a_core_shared"
Inseob Kim64c43952019-08-26 16:52:35 +0900116 vendorVariant = "android_arm64_armv8-a_vendor.VER_shared"
Jiyong Park5baac542018-08-28 09:55:37 +0900117 recoveryVariant = "android_arm64_armv8-a_recovery_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800118)
119
Doug Hornc32c6b02019-01-17 14:44:05 -0800120func TestFuchsiaDeps(t *testing.T) {
121 t.Helper()
122
123 bp := `
124 cc_library {
125 name: "libTest",
126 srcs: ["foo.c"],
127 target: {
128 fuchsia: {
129 srcs: ["bar.c"],
130 },
131 },
132 }`
133
134 config := android.TestArchConfigFuchsia(buildDir, nil)
135 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
136
137 rt := false
138 fb := false
139
140 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
141 implicits := ld.Implicits
142 for _, lib := range implicits {
143 if strings.Contains(lib.Rel(), "libcompiler_rt") {
144 rt = true
145 }
146
147 if strings.Contains(lib.Rel(), "libbioniccompat") {
148 fb = true
149 }
150 }
151
152 if !rt || !fb {
153 t.Errorf("fuchsia libs must link libcompiler_rt and libbioniccompat")
154 }
155}
156
157func TestFuchsiaTargetDecl(t *testing.T) {
158 t.Helper()
159
160 bp := `
161 cc_library {
162 name: "libTest",
163 srcs: ["foo.c"],
164 target: {
165 fuchsia: {
166 srcs: ["bar.c"],
167 },
168 },
169 }`
170
171 config := android.TestArchConfigFuchsia(buildDir, nil)
172 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
173 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
174 var objs []string
175 for _, o := range ld.Inputs {
176 objs = append(objs, o.Base())
177 }
178 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
179 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
180 }
181}
182
Jiyong Park6a43f042017-10-12 23:05:00 +0900183func TestVendorSrc(t *testing.T) {
184 ctx := testCc(t, `
185 cc_library {
186 name: "libTest",
187 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -0700188 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +0800189 nocrt: true,
190 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900191 vendor_available: true,
192 target: {
193 vendor: {
194 srcs: ["bar.c"],
195 },
196 },
197 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900198 `)
199
Logan Chienf3511742017-10-31 18:04:35 +0800200 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900201 var objs []string
202 for _, o := range ld.Inputs {
203 objs = append(objs, o.Base())
204 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800205 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900206 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
207 }
208}
209
Logan Chienf3511742017-10-31 18:04:35 +0800210func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
211 isVndkSp bool, extends string) {
212
Logan Chiend3c59a22018-03-29 14:08:15 +0800213 t.Helper()
214
Logan Chienf3511742017-10-31 18:04:35 +0800215 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
216 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700217 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800218 }
219
220 // Check library properties.
221 lib, ok := mod.compiler.(*libraryDecorator)
222 if !ok {
223 t.Errorf("%q must have libraryDecorator", name)
224 } else if lib.baseInstaller.subDir != subDir {
225 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
226 lib.baseInstaller.subDir)
227 }
228
229 // Check VNDK properties.
230 if mod.vndkdep == nil {
231 t.Fatalf("%q must have `vndkdep`", name)
232 }
233 if !mod.isVndk() {
234 t.Errorf("%q isVndk() must equal to true", name)
235 }
236 if mod.isVndkSp() != isVndkSp {
237 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
238 }
239
240 // Check VNDK extension properties.
241 isVndkExt := extends != ""
242 if mod.isVndkExt() != isVndkExt {
243 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
244 }
245
246 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
247 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
248 }
249}
250
Inseob Kim1f086e22019-05-09 13:29:15 +0900251func checkVndkSnapshot(t *testing.T, ctx *android.TestContext, name, subDir, variant string) {
252 vndkSnapshot := ctx.SingletonForTests("vndk-snapshot")
253
254 snapshotPath := filepath.Join(subDir, name+".so")
255 mod := ctx.ModuleForTests(name, variant).Module().(*Module)
256 if !mod.outputFile.Valid() {
257 t.Errorf("%q must have output\n", name)
258 return
259 }
260
261 out := vndkSnapshot.Output(snapshotPath)
262 if out.Input != mod.outputFile.Path() {
263 t.Errorf("The input of VNDK snapshot must be %q, but %q", out.Input.String(), mod.outputFile.String())
264 }
265}
266
Logan Chienf3511742017-10-31 18:04:35 +0800267func TestVndk(t *testing.T) {
Inseob Kim1f086e22019-05-09 13:29:15 +0900268 config := android.TestArchConfig(buildDir, nil)
269 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
270 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
271
272 ctx := testCcWithConfig(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800273 cc_library {
274 name: "libvndk",
275 vendor_available: true,
276 vndk: {
277 enabled: true,
278 },
279 nocrt: true,
280 }
281
282 cc_library {
283 name: "libvndk_private",
284 vendor_available: false,
285 vndk: {
286 enabled: true,
287 },
288 nocrt: true,
289 }
290
291 cc_library {
292 name: "libvndk_sp",
293 vendor_available: true,
294 vndk: {
295 enabled: true,
296 support_system_process: true,
297 },
298 nocrt: true,
299 }
300
301 cc_library {
302 name: "libvndk_sp_private",
303 vendor_available: false,
304 vndk: {
305 enabled: true,
306 support_system_process: true,
307 },
308 nocrt: true,
309 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900310 `, config)
Logan Chienf3511742017-10-31 18:04:35 +0800311
312 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
313 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
314 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
315 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
Inseob Kim1f086e22019-05-09 13:29:15 +0900316
317 // Check VNDK snapshot output.
318
319 snapshotDir := "vndk-snapshot"
320 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
321
322 vndkLibPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
323 "arm64", "armv8-a"))
324 vndkLib2ndPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
325 "arm", "armv7-a-neon"))
326
327 vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core")
328 vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp")
329 vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
330 vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
331
Inseob Kim64c43952019-08-26 16:52:35 +0900332 variant := "android_arm64_armv8-a_vendor.VER_shared"
333 variant2nd := "android_arm_armv7-a-neon_vendor.VER_shared"
Inseob Kim1f086e22019-05-09 13:29:15 +0900334
335 checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLibPath, variant)
336 checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLib2ndPath, variant2nd)
337 checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLibPath, variant)
338 checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLib2ndPath, variant2nd)
Logan Chienf3511742017-10-31 18:04:35 +0800339}
340
Logan Chiend3c59a22018-03-29 14:08:15 +0800341func TestVndkDepError(t *testing.T) {
342 // Check whether an error is emitted when a VNDK lib depends on a system lib.
343 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
344 cc_library {
345 name: "libvndk",
346 vendor_available: true,
347 vndk: {
348 enabled: true,
349 },
350 shared_libs: ["libfwk"], // Cause error
351 nocrt: true,
352 }
353
354 cc_library {
355 name: "libfwk",
356 nocrt: true,
357 }
358 `)
359
360 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
361 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
362 cc_library {
363 name: "libvndk",
364 vendor_available: true,
365 vndk: {
366 enabled: true,
367 },
368 shared_libs: ["libvendor"], // Cause error
369 nocrt: true,
370 }
371
372 cc_library {
373 name: "libvendor",
374 vendor: true,
375 nocrt: true,
376 }
377 `)
378
379 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
380 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
381 cc_library {
382 name: "libvndk_sp",
383 vendor_available: true,
384 vndk: {
385 enabled: true,
386 support_system_process: true,
387 },
388 shared_libs: ["libfwk"], // Cause error
389 nocrt: true,
390 }
391
392 cc_library {
393 name: "libfwk",
394 nocrt: true,
395 }
396 `)
397
398 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
399 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
400 cc_library {
401 name: "libvndk_sp",
402 vendor_available: true,
403 vndk: {
404 enabled: true,
405 support_system_process: true,
406 },
407 shared_libs: ["libvendor"], // Cause error
408 nocrt: true,
409 }
410
411 cc_library {
412 name: "libvendor",
413 vendor: true,
414 nocrt: true,
415 }
416 `)
417
418 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
419 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
420 cc_library {
421 name: "libvndk_sp",
422 vendor_available: true,
423 vndk: {
424 enabled: true,
425 support_system_process: true,
426 },
427 shared_libs: ["libvndk"], // Cause error
428 nocrt: true,
429 }
430
431 cc_library {
432 name: "libvndk",
433 vendor_available: true,
434 vndk: {
435 enabled: true,
436 },
437 nocrt: true,
438 }
439 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900440
441 // Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib.
442 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
443 cc_library {
444 name: "libvndk",
445 vendor_available: true,
446 vndk: {
447 enabled: true,
448 },
449 shared_libs: ["libnonvndk"],
450 nocrt: true,
451 }
452
453 cc_library {
454 name: "libnonvndk",
455 vendor_available: true,
456 nocrt: true,
457 }
458 `)
459
460 // Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib.
461 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
462 cc_library {
463 name: "libvndkprivate",
464 vendor_available: false,
465 vndk: {
466 enabled: true,
467 },
468 shared_libs: ["libnonvndk"],
469 nocrt: true,
470 }
471
472 cc_library {
473 name: "libnonvndk",
474 vendor_available: true,
475 nocrt: true,
476 }
477 `)
478
479 // Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib.
480 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
481 cc_library {
482 name: "libvndksp",
483 vendor_available: true,
484 vndk: {
485 enabled: true,
486 support_system_process: true,
487 },
488 shared_libs: ["libnonvndk"],
489 nocrt: true,
490 }
491
492 cc_library {
493 name: "libnonvndk",
494 vendor_available: true,
495 nocrt: true,
496 }
497 `)
498
499 // Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib.
500 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
501 cc_library {
502 name: "libvndkspprivate",
503 vendor_available: false,
504 vndk: {
505 enabled: true,
506 support_system_process: true,
507 },
508 shared_libs: ["libnonvndk"],
509 nocrt: true,
510 }
511
512 cc_library {
513 name: "libnonvndk",
514 vendor_available: true,
515 nocrt: true,
516 }
517 `)
518}
519
520func TestDoubleLoadbleDep(t *testing.T) {
521 // okay to link : LLNDK -> double_loadable VNDK
522 testCc(t, `
523 cc_library {
524 name: "libllndk",
525 shared_libs: ["libdoubleloadable"],
526 }
527
528 llndk_library {
529 name: "libllndk",
530 symbol_file: "",
531 }
532
533 cc_library {
534 name: "libdoubleloadable",
535 vendor_available: true,
536 vndk: {
537 enabled: true,
538 },
539 double_loadable: true,
540 }
541 `)
542 // okay to link : LLNDK -> VNDK-SP
543 testCc(t, `
544 cc_library {
545 name: "libllndk",
546 shared_libs: ["libvndksp"],
547 }
548
549 llndk_library {
550 name: "libllndk",
551 symbol_file: "",
552 }
553
554 cc_library {
555 name: "libvndksp",
556 vendor_available: true,
557 vndk: {
558 enabled: true,
559 support_system_process: true,
560 },
561 }
562 `)
563 // okay to link : double_loadable -> double_loadable
564 testCc(t, `
565 cc_library {
566 name: "libdoubleloadable1",
567 shared_libs: ["libdoubleloadable2"],
568 vendor_available: true,
569 double_loadable: true,
570 }
571
572 cc_library {
573 name: "libdoubleloadable2",
574 vendor_available: true,
575 double_loadable: true,
576 }
577 `)
578 // okay to link : double_loadable VNDK -> double_loadable VNDK private
579 testCc(t, `
580 cc_library {
581 name: "libdoubleloadable",
582 vendor_available: true,
583 vndk: {
584 enabled: true,
585 },
586 double_loadable: true,
587 shared_libs: ["libnondoubleloadable"],
588 }
589
590 cc_library {
591 name: "libnondoubleloadable",
592 vendor_available: false,
593 vndk: {
594 enabled: true,
595 },
596 double_loadable: true,
597 }
598 `)
599 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
600 testCc(t, `
601 cc_library {
602 name: "libllndk",
603 shared_libs: ["libcoreonly"],
604 }
605
606 llndk_library {
607 name: "libllndk",
608 symbol_file: "",
609 }
610
611 cc_library {
612 name: "libcoreonly",
613 shared_libs: ["libvendoravailable"],
614 }
615
616 // indirect dependency of LLNDK
617 cc_library {
618 name: "libvendoravailable",
619 vendor_available: true,
620 double_loadable: true,
621 }
622 `)
623}
624
625func TestDoubleLoadableDepError(t *testing.T) {
626 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
627 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
628 cc_library {
629 name: "libllndk",
630 shared_libs: ["libnondoubleloadable"],
631 }
632
633 llndk_library {
634 name: "libllndk",
635 symbol_file: "",
636 }
637
638 cc_library {
639 name: "libnondoubleloadable",
640 vendor_available: true,
641 vndk: {
642 enabled: true,
643 },
644 }
645 `)
646
647 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
648 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
649 cc_library {
650 name: "libllndk",
Yi Konge7fe9912019-06-02 00:53:50 -0700651 no_libcrt: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900652 shared_libs: ["libnondoubleloadable"],
653 }
654
655 llndk_library {
656 name: "libllndk",
657 symbol_file: "",
658 }
659
660 cc_library {
661 name: "libnondoubleloadable",
662 vendor_available: true,
663 }
664 `)
665
666 // Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable vendor_available lib.
667 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
668 cc_library {
669 name: "libdoubleloadable",
670 vendor_available: true,
671 double_loadable: true,
672 shared_libs: ["libnondoubleloadable"],
673 }
674
675 cc_library {
676 name: "libnondoubleloadable",
677 vendor_available: true,
678 }
679 `)
680
681 // Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable VNDK lib.
682 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
683 cc_library {
684 name: "libdoubleloadable",
685 vendor_available: true,
686 double_loadable: true,
687 shared_libs: ["libnondoubleloadable"],
688 }
689
690 cc_library {
691 name: "libnondoubleloadable",
692 vendor_available: true,
693 vndk: {
694 enabled: true,
695 },
696 }
697 `)
698
699 // Check whether an error is emitted when a double_loadable VNDK depends on a non-double_loadable VNDK private lib.
700 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
701 cc_library {
702 name: "libdoubleloadable",
703 vendor_available: true,
704 vndk: {
705 enabled: true,
706 },
707 double_loadable: true,
708 shared_libs: ["libnondoubleloadable"],
709 }
710
711 cc_library {
712 name: "libnondoubleloadable",
713 vendor_available: false,
714 vndk: {
715 enabled: true,
716 },
717 }
718 `)
719
720 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
721 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
722 cc_library {
723 name: "libllndk",
724 shared_libs: ["libcoreonly"],
725 }
726
727 llndk_library {
728 name: "libllndk",
729 symbol_file: "",
730 }
731
732 cc_library {
733 name: "libcoreonly",
734 shared_libs: ["libvendoravailable"],
735 }
736
737 // indirect dependency of LLNDK
738 cc_library {
739 name: "libvendoravailable",
740 vendor_available: true,
741 }
742 `)
Logan Chiend3c59a22018-03-29 14:08:15 +0800743}
744
Justin Yun9357f4a2018-11-28 15:14:47 +0900745func TestVndkMustNotBeProductSpecific(t *testing.T) {
746 // Check whether an error is emitted when a vndk lib has 'product_specific: true'.
747 testCcError(t, "product_specific must not be true when `vndk: {enabled: true}`", `
748 cc_library {
749 name: "libvndk",
750 product_specific: true, // Cause error
751 vendor_available: true,
752 vndk: {
753 enabled: true,
754 },
755 nocrt: true,
756 }
757 `)
758}
759
Logan Chienf3511742017-10-31 18:04:35 +0800760func TestVndkExt(t *testing.T) {
761 // This test checks the VNDK-Ext properties.
762 ctx := testCc(t, `
763 cc_library {
764 name: "libvndk",
765 vendor_available: true,
766 vndk: {
767 enabled: true,
768 },
769 nocrt: true,
770 }
771
772 cc_library {
773 name: "libvndk_ext",
774 vendor: true,
775 vndk: {
776 enabled: true,
777 extends: "libvndk",
778 },
779 nocrt: true,
780 }
781 `)
782
783 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
784}
785
Logan Chiend3c59a22018-03-29 14:08:15 +0800786func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800787 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
788 ctx := testCcNoVndk(t, `
789 cc_library {
790 name: "libvndk",
791 vendor_available: true,
792 vndk: {
793 enabled: true,
794 },
795 nocrt: true,
796 }
797
798 cc_library {
799 name: "libvndk_ext",
800 vendor: true,
801 vndk: {
802 enabled: true,
803 extends: "libvndk",
804 },
805 nocrt: true,
806 }
807 `)
808
809 // Ensures that the core variant of "libvndk_ext" can be found.
810 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
811 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
812 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
813 }
814}
815
816func TestVndkExtError(t *testing.T) {
817 // This test ensures an error is emitted in ill-formed vndk-ext definition.
818 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
819 cc_library {
820 name: "libvndk",
821 vendor_available: true,
822 vndk: {
823 enabled: true,
824 },
825 nocrt: true,
826 }
827
828 cc_library {
829 name: "libvndk_ext",
830 vndk: {
831 enabled: true,
832 extends: "libvndk",
833 },
834 nocrt: true,
835 }
836 `)
837
838 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
839 cc_library {
840 name: "libvndk",
841 vendor_available: true,
842 vndk: {
843 enabled: true,
844 },
845 nocrt: true,
846 }
847
848 cc_library {
849 name: "libvndk_ext",
850 vendor: true,
851 vndk: {
852 enabled: true,
853 },
854 nocrt: true,
855 }
856 `)
857}
858
859func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
860 // This test ensures an error is emitted for inconsistent support_system_process.
861 testCcError(t, "module \".*\" with mismatched support_system_process", `
862 cc_library {
863 name: "libvndk",
864 vendor_available: true,
865 vndk: {
866 enabled: true,
867 },
868 nocrt: true,
869 }
870
871 cc_library {
872 name: "libvndk_sp_ext",
873 vendor: true,
874 vndk: {
875 enabled: true,
876 extends: "libvndk",
877 support_system_process: true,
878 },
879 nocrt: true,
880 }
881 `)
882
883 testCcError(t, "module \".*\" with mismatched support_system_process", `
884 cc_library {
885 name: "libvndk_sp",
886 vendor_available: true,
887 vndk: {
888 enabled: true,
889 support_system_process: true,
890 },
891 nocrt: true,
892 }
893
894 cc_library {
895 name: "libvndk_ext",
896 vendor: true,
897 vndk: {
898 enabled: true,
899 extends: "libvndk_sp",
900 },
901 nocrt: true,
902 }
903 `)
904}
905
906func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800907 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800908 // with `vendor_available: false`.
909 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
910 cc_library {
911 name: "libvndk",
912 vendor_available: false,
913 vndk: {
914 enabled: true,
915 },
916 nocrt: true,
917 }
918
919 cc_library {
920 name: "libvndk_ext",
921 vendor: true,
922 vndk: {
923 enabled: true,
924 extends: "libvndk",
925 },
926 nocrt: true,
927 }
928 `)
929}
930
Logan Chiend3c59a22018-03-29 14:08:15 +0800931func TestVendorModuleUseVndkExt(t *testing.T) {
932 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800933 testCc(t, `
934 cc_library {
935 name: "libvndk",
936 vendor_available: true,
937 vndk: {
938 enabled: true,
939 },
940 nocrt: true,
941 }
942
943 cc_library {
944 name: "libvndk_ext",
945 vendor: true,
946 vndk: {
947 enabled: true,
948 extends: "libvndk",
949 },
950 nocrt: true,
951 }
952
953 cc_library {
954
955 name: "libvndk_sp",
956 vendor_available: true,
957 vndk: {
958 enabled: true,
959 support_system_process: true,
960 },
961 nocrt: true,
962 }
963
964 cc_library {
965 name: "libvndk_sp_ext",
966 vendor: true,
967 vndk: {
968 enabled: true,
969 extends: "libvndk_sp",
970 support_system_process: true,
971 },
972 nocrt: true,
973 }
974
975 cc_library {
976 name: "libvendor",
977 vendor: true,
978 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
979 nocrt: true,
980 }
981 `)
982}
983
Logan Chiend3c59a22018-03-29 14:08:15 +0800984func TestVndkExtUseVendorLib(t *testing.T) {
985 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800986 testCc(t, `
987 cc_library {
988 name: "libvndk",
989 vendor_available: true,
990 vndk: {
991 enabled: true,
992 },
993 nocrt: true,
994 }
995
996 cc_library {
997 name: "libvndk_ext",
998 vendor: true,
999 vndk: {
1000 enabled: true,
1001 extends: "libvndk",
1002 },
1003 shared_libs: ["libvendor"],
1004 nocrt: true,
1005 }
1006
1007 cc_library {
1008 name: "libvendor",
1009 vendor: true,
1010 nocrt: true,
1011 }
1012 `)
Logan Chienf3511742017-10-31 18:04:35 +08001013
Logan Chiend3c59a22018-03-29 14:08:15 +08001014 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
1015 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +08001016 cc_library {
1017 name: "libvndk_sp",
1018 vendor_available: true,
1019 vndk: {
1020 enabled: true,
1021 support_system_process: true,
1022 },
1023 nocrt: true,
1024 }
1025
1026 cc_library {
1027 name: "libvndk_sp_ext",
1028 vendor: true,
1029 vndk: {
1030 enabled: true,
1031 extends: "libvndk_sp",
1032 support_system_process: true,
1033 },
1034 shared_libs: ["libvendor"], // Cause an error
1035 nocrt: true,
1036 }
1037
1038 cc_library {
1039 name: "libvendor",
1040 vendor: true,
1041 nocrt: true,
1042 }
1043 `)
1044}
1045
Logan Chiend3c59a22018-03-29 14:08:15 +08001046func TestVndkSpExtUseVndkError(t *testing.T) {
1047 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
1048 // library.
1049 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1050 cc_library {
1051 name: "libvndk",
1052 vendor_available: true,
1053 vndk: {
1054 enabled: true,
1055 },
1056 nocrt: true,
1057 }
1058
1059 cc_library {
1060 name: "libvndk_sp",
1061 vendor_available: true,
1062 vndk: {
1063 enabled: true,
1064 support_system_process: true,
1065 },
1066 nocrt: true,
1067 }
1068
1069 cc_library {
1070 name: "libvndk_sp_ext",
1071 vendor: true,
1072 vndk: {
1073 enabled: true,
1074 extends: "libvndk_sp",
1075 support_system_process: true,
1076 },
1077 shared_libs: ["libvndk"], // Cause an error
1078 nocrt: true,
1079 }
1080 `)
1081
1082 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
1083 // library.
1084 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1085 cc_library {
1086 name: "libvndk",
1087 vendor_available: true,
1088 vndk: {
1089 enabled: true,
1090 },
1091 nocrt: true,
1092 }
1093
1094 cc_library {
1095 name: "libvndk_ext",
1096 vendor: true,
1097 vndk: {
1098 enabled: true,
1099 extends: "libvndk",
1100 },
1101 nocrt: true,
1102 }
1103
1104 cc_library {
1105 name: "libvndk_sp",
1106 vendor_available: true,
1107 vndk: {
1108 enabled: true,
1109 support_system_process: true,
1110 },
1111 nocrt: true,
1112 }
1113
1114 cc_library {
1115 name: "libvndk_sp_ext",
1116 vendor: true,
1117 vndk: {
1118 enabled: true,
1119 extends: "libvndk_sp",
1120 support_system_process: true,
1121 },
1122 shared_libs: ["libvndk_ext"], // Cause an error
1123 nocrt: true,
1124 }
1125 `)
1126}
1127
1128func TestVndkUseVndkExtError(t *testing.T) {
1129 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
1130 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +08001131 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1132 cc_library {
1133 name: "libvndk",
1134 vendor_available: true,
1135 vndk: {
1136 enabled: true,
1137 },
1138 nocrt: true,
1139 }
1140
1141 cc_library {
1142 name: "libvndk_ext",
1143 vendor: true,
1144 vndk: {
1145 enabled: true,
1146 extends: "libvndk",
1147 },
1148 nocrt: true,
1149 }
1150
1151 cc_library {
1152 name: "libvndk2",
1153 vendor_available: true,
1154 vndk: {
1155 enabled: true,
1156 },
1157 shared_libs: ["libvndk_ext"],
1158 nocrt: true,
1159 }
1160 `)
1161
Martin Stjernholmef449fe2018-11-06 16:12:13 +00001162 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +08001163 cc_library {
1164 name: "libvndk",
1165 vendor_available: true,
1166 vndk: {
1167 enabled: true,
1168 },
1169 nocrt: true,
1170 }
1171
1172 cc_library {
1173 name: "libvndk_ext",
1174 vendor: true,
1175 vndk: {
1176 enabled: true,
1177 extends: "libvndk",
1178 },
1179 nocrt: true,
1180 }
1181
1182 cc_library {
1183 name: "libvndk2",
1184 vendor_available: true,
1185 vndk: {
1186 enabled: true,
1187 },
1188 target: {
1189 vendor: {
1190 shared_libs: ["libvndk_ext"],
1191 },
1192 },
1193 nocrt: true,
1194 }
1195 `)
1196
1197 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1198 cc_library {
1199 name: "libvndk_sp",
1200 vendor_available: true,
1201 vndk: {
1202 enabled: true,
1203 support_system_process: true,
1204 },
1205 nocrt: true,
1206 }
1207
1208 cc_library {
1209 name: "libvndk_sp_ext",
1210 vendor: true,
1211 vndk: {
1212 enabled: true,
1213 extends: "libvndk_sp",
1214 support_system_process: true,
1215 },
1216 nocrt: true,
1217 }
1218
1219 cc_library {
1220 name: "libvndk_sp_2",
1221 vendor_available: true,
1222 vndk: {
1223 enabled: true,
1224 support_system_process: true,
1225 },
1226 shared_libs: ["libvndk_sp_ext"],
1227 nocrt: true,
1228 }
1229 `)
1230
Martin Stjernholmef449fe2018-11-06 16:12:13 +00001231 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +08001232 cc_library {
1233 name: "libvndk_sp",
1234 vendor_available: true,
1235 vndk: {
1236 enabled: true,
1237 },
1238 nocrt: true,
1239 }
1240
1241 cc_library {
1242 name: "libvndk_sp_ext",
1243 vendor: true,
1244 vndk: {
1245 enabled: true,
1246 extends: "libvndk_sp",
1247 },
1248 nocrt: true,
1249 }
1250
1251 cc_library {
1252 name: "libvndk_sp2",
1253 vendor_available: true,
1254 vndk: {
1255 enabled: true,
1256 },
1257 target: {
1258 vendor: {
1259 shared_libs: ["libvndk_sp_ext"],
1260 },
1261 },
1262 nocrt: true,
1263 }
1264 `)
1265}
1266
Jooyung Han38002912019-05-16 04:01:54 +09001267func TestMakeLinkType(t *testing.T) {
1268 config := android.TestArchConfig(buildDir, nil)
1269 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1270 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
1271 // native:vndk
1272 ctx := testCcWithConfig(t, `
1273 cc_library {
1274 name: "libvndk",
1275 vendor_available: true,
1276 vndk: {
1277 enabled: true,
1278 },
1279 }
1280 cc_library {
1281 name: "libvndksp",
1282 vendor_available: true,
1283 vndk: {
1284 enabled: true,
1285 support_system_process: true,
1286 },
1287 }
1288 cc_library {
1289 name: "libvndkprivate",
1290 vendor_available: false,
1291 vndk: {
1292 enabled: true,
1293 },
1294 }
1295 cc_library {
1296 name: "libvendor",
1297 vendor: true,
1298 }
1299 cc_library {
1300 name: "libvndkext",
1301 vendor: true,
1302 vndk: {
1303 enabled: true,
1304 extends: "libvndk",
1305 },
1306 }
1307 vndk_prebuilt_shared {
1308 name: "prevndk",
1309 version: "27",
1310 target_arch: "arm",
1311 binder32bit: true,
1312 vendor_available: true,
1313 vndk: {
1314 enabled: true,
1315 },
1316 arch: {
1317 arm: {
1318 srcs: ["liba.so"],
1319 },
1320 },
1321 }
1322 cc_library {
1323 name: "libllndk",
1324 }
1325 llndk_library {
1326 name: "libllndk",
1327 symbol_file: "",
1328 }
1329 cc_library {
1330 name: "libllndkprivate",
1331 }
1332 llndk_library {
1333 name: "libllndkprivate",
1334 vendor_available: false,
1335 symbol_file: "",
1336 }`, config)
1337
1338 assertArrayString(t, *vndkCoreLibraries(config),
1339 []string{"libvndk", "libvndkprivate"})
1340 assertArrayString(t, *vndkSpLibraries(config),
1341 []string{"libc++", "libvndksp"})
1342 assertArrayString(t, *llndkLibraries(config),
1343 []string{"libc", "libdl", "libllndk", "libllndkprivate", "libm"})
1344 assertArrayString(t, *vndkPrivateLibraries(config),
1345 []string{"libllndkprivate", "libvndkprivate"})
1346
Inseob Kim64c43952019-08-26 16:52:35 +09001347 vendorVariant27 := "android_arm64_armv8-a_vendor.27_shared"
1348
Jooyung Han38002912019-05-16 04:01:54 +09001349 tests := []struct {
1350 variant string
1351 name string
1352 expected string
1353 }{
1354 {vendorVariant, "libvndk", "native:vndk"},
1355 {vendorVariant, "libvndksp", "native:vndk"},
1356 {vendorVariant, "libvndkprivate", "native:vndk_private"},
1357 {vendorVariant, "libvendor", "native:vendor"},
1358 {vendorVariant, "libvndkext", "native:vendor"},
Jooyung Han38002912019-05-16 04:01:54 +09001359 {vendorVariant, "libllndk.llndk", "native:vndk"},
Inseob Kim64c43952019-08-26 16:52:35 +09001360 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
Jooyung Han38002912019-05-16 04:01:54 +09001361 {coreVariant, "libvndk", "native:platform"},
1362 {coreVariant, "libvndkprivate", "native:platform"},
1363 {coreVariant, "libllndk", "native:platform"},
1364 }
1365 for _, test := range tests {
1366 t.Run(test.name, func(t *testing.T) {
1367 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
1368 assertString(t, module.makeLinkType, test.expected)
1369 })
1370 }
1371}
1372
Colin Cross0af4b842015-04-30 16:36:18 -07001373var (
1374 str11 = "01234567891"
1375 str10 = str11[:10]
1376 str9 = str11[:9]
1377 str5 = str11[:5]
1378 str4 = str11[:4]
1379)
1380
1381var splitListForSizeTestCases = []struct {
1382 in []string
1383 out [][]string
1384 size int
1385}{
1386 {
1387 in: []string{str10},
1388 out: [][]string{{str10}},
1389 size: 10,
1390 },
1391 {
1392 in: []string{str9},
1393 out: [][]string{{str9}},
1394 size: 10,
1395 },
1396 {
1397 in: []string{str5},
1398 out: [][]string{{str5}},
1399 size: 10,
1400 },
1401 {
1402 in: []string{str11},
1403 out: nil,
1404 size: 10,
1405 },
1406 {
1407 in: []string{str10, str10},
1408 out: [][]string{{str10}, {str10}},
1409 size: 10,
1410 },
1411 {
1412 in: []string{str9, str10},
1413 out: [][]string{{str9}, {str10}},
1414 size: 10,
1415 },
1416 {
1417 in: []string{str10, str9},
1418 out: [][]string{{str10}, {str9}},
1419 size: 10,
1420 },
1421 {
1422 in: []string{str5, str4},
1423 out: [][]string{{str5, str4}},
1424 size: 10,
1425 },
1426 {
1427 in: []string{str5, str4, str5},
1428 out: [][]string{{str5, str4}, {str5}},
1429 size: 10,
1430 },
1431 {
1432 in: []string{str5, str4, str5, str4},
1433 out: [][]string{{str5, str4}, {str5, str4}},
1434 size: 10,
1435 },
1436 {
1437 in: []string{str5, str4, str5, str5},
1438 out: [][]string{{str5, str4}, {str5}, {str5}},
1439 size: 10,
1440 },
1441 {
1442 in: []string{str5, str5, str5, str4},
1443 out: [][]string{{str5}, {str5}, {str5, str4}},
1444 size: 10,
1445 },
1446 {
1447 in: []string{str9, str11},
1448 out: nil,
1449 size: 10,
1450 },
1451 {
1452 in: []string{str11, str9},
1453 out: nil,
1454 size: 10,
1455 },
1456}
1457
1458func TestSplitListForSize(t *testing.T) {
1459 for _, testCase := range splitListForSizeTestCases {
Colin Cross40e33732019-02-15 11:08:35 -08001460 out, _ := splitListForSize(android.PathsForTesting(testCase.in...), testCase.size)
Colin Cross5b529592017-05-09 13:34:34 -07001461
1462 var outStrings [][]string
1463
1464 if len(out) > 0 {
1465 outStrings = make([][]string, len(out))
1466 for i, o := range out {
1467 outStrings[i] = o.Strings()
1468 }
1469 }
1470
1471 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001472 t.Errorf("incorrect output:")
1473 t.Errorf(" input: %#v", testCase.in)
1474 t.Errorf(" size: %d", testCase.size)
1475 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001476 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001477 }
1478 }
1479}
Jeff Gaston294356f2017-09-27 17:05:30 -07001480
1481var staticLinkDepOrderTestCases = []struct {
1482 // This is a string representation of a map[moduleName][]moduleDependency .
1483 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001484 inStatic string
1485
1486 // This is a string representation of a map[moduleName][]moduleDependency .
1487 // It models the dependencies declared in an Android.bp file.
1488 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001489
1490 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1491 // The keys of allOrdered specify which modules we would like to check.
1492 // The values of allOrdered specify the expected result (of the transitive closure of all
1493 // dependencies) for each module to test
1494 allOrdered string
1495
1496 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1497 // The keys of outOrdered specify which modules we would like to check.
1498 // The values of outOrdered specify the expected result (of the ordered linker command line)
1499 // for each module to test.
1500 outOrdered string
1501}{
1502 // Simple tests
1503 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001504 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001505 outOrdered: "",
1506 },
1507 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001508 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001509 outOrdered: "a:",
1510 },
1511 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001512 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001513 outOrdered: "a:b; b:",
1514 },
1515 // Tests of reordering
1516 {
1517 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001518 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001519 outOrdered: "a:b,c,d; b:d; c:d; d:",
1520 },
1521 {
1522 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001523 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001524 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1525 },
1526 {
1527 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001528 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001529 outOrdered: "a:d,b,e,c; d:b; e:c",
1530 },
1531 {
1532 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001533 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001534 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1535 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1536 },
1537 {
1538 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001539 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 -07001540 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1541 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1542 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001543 // shared dependencies
1544 {
1545 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1546 // So, we don't actually have to check that a shared dependency of c will change the order
1547 // of a library that depends statically on b and on c. We only need to check that if c has
1548 // a shared dependency on b, that that shows up in allOrdered.
1549 inShared: "c:b",
1550 allOrdered: "c:b",
1551 outOrdered: "c:",
1552 },
1553 {
1554 // This test doesn't actually include any shared dependencies but it's a reminder of what
1555 // the second phase of the above test would look like
1556 inStatic: "a:b,c; c:b",
1557 allOrdered: "a:c,b; c:b",
1558 outOrdered: "a:c,b; c:b",
1559 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001560 // tiebreakers for when two modules specifying different orderings and there is no dependency
1561 // to dictate an order
1562 {
1563 // 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 -08001564 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001565 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1566 },
1567 {
1568 // 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 -08001569 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 -07001570 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1571 },
1572 // Tests involving duplicate dependencies
1573 {
1574 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001575 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001576 outOrdered: "a:c,b",
1577 },
1578 {
1579 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001580 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001581 outOrdered: "a:d,c,b",
1582 },
1583 // Tests to confirm the nonexistence of infinite loops.
1584 // These cases should never happen, so as long as the test terminates and the
1585 // result is deterministic then that should be fine.
1586 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001587 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001588 outOrdered: "a:a",
1589 },
1590 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001591 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001592 allOrdered: "a:b,c; b:c,a; c:a,b",
1593 outOrdered: "a:b; b:c; c:a",
1594 },
1595 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001596 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001597 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1598 outOrdered: "a:c,b; b:a,c; c:b,a",
1599 },
1600}
1601
1602// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1603func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1604 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1605 strippedText := strings.Replace(text, " ", "", -1)
1606 if len(strippedText) < 1 {
1607 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1608 }
1609 allDeps = make(map[android.Path][]android.Path, 0)
1610
1611 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1612 moduleTexts := strings.Split(strippedText, ";")
1613
1614 outputForModuleName := func(moduleName string) android.Path {
1615 return android.PathForTesting(moduleName)
1616 }
1617
1618 for _, moduleText := range moduleTexts {
1619 // convert from "a:b,c" to ["a", "b,c"]
1620 components := strings.Split(moduleText, ":")
1621 if len(components) != 2 {
1622 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1623 }
1624 moduleName := components[0]
1625 moduleOutput := outputForModuleName(moduleName)
1626 modulesInOrder = append(modulesInOrder, moduleOutput)
1627
1628 depString := components[1]
1629 // convert from "b,c" to ["b", "c"]
1630 depNames := strings.Split(depString, ",")
1631 if len(depString) < 1 {
1632 depNames = []string{}
1633 }
1634 var deps []android.Path
1635 for _, depName := range depNames {
1636 deps = append(deps, outputForModuleName(depName))
1637 }
1638 allDeps[moduleOutput] = deps
1639 }
1640 return modulesInOrder, allDeps
1641}
1642
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001643func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001644 for _, testCase := range staticLinkDepOrderTestCases {
1645 errs := []string{}
1646
1647 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001648 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001649 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1650 if testCase.allOrdered == "" {
1651 // allow the test case to skip specifying allOrdered
1652 testCase.allOrdered = testCase.outOrdered
1653 }
1654 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001655 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001656
1657 // For each module whose post-reordered dependencies were specified, validate that
1658 // reordering the inputs produces the expected outputs.
1659 for _, moduleName := range expectedModuleNames {
1660 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001661 givenSharedDeps := givenAllSharedDeps[moduleName]
1662 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001663
1664 correctAllOrdered := expectedAllDeps[moduleName]
1665 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1666 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001667 "\nin static:%q"+
1668 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001669 "\nmodule: %v"+
1670 "\nexpected: %s"+
1671 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001672 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001673 }
1674
1675 correctOutputDeps := expectedTransitiveDeps[moduleName]
1676 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1677 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001678 "\nin static:%q"+
1679 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001680 "\nmodule: %v"+
1681 "\nexpected: %s"+
1682 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001683 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001684 }
1685 }
1686
1687 if len(errs) > 0 {
1688 sort.Strings(errs)
1689 for _, err := range errs {
1690 t.Error(err)
1691 }
1692 }
1693 }
1694}
Logan Chienf3511742017-10-31 18:04:35 +08001695
Jeff Gaston294356f2017-09-27 17:05:30 -07001696func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1697 for _, moduleName := range moduleNames {
1698 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1699 output := module.outputFile.Path()
1700 paths = append(paths, output)
1701 }
1702 return paths
1703}
1704
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001705func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001706 ctx := testCc(t, `
1707 cc_library {
1708 name: "a",
1709 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001710 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001711 }
1712 cc_library {
1713 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001714 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001715 }
1716 cc_library {
1717 name: "c",
1718 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001719 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001720 }
1721 cc_library {
1722 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001723 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001724 }
1725
1726 `)
1727
1728 variant := "android_arm64_armv8-a_core_static"
1729 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001730 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001731 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1732
1733 if !reflect.DeepEqual(actual, expected) {
1734 t.Errorf("staticDeps orderings were not propagated correctly"+
1735 "\nactual: %v"+
1736 "\nexpected: %v",
1737 actual,
1738 expected,
1739 )
1740 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001741}
Jeff Gaston294356f2017-09-27 17:05:30 -07001742
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001743func TestStaticLibDepReorderingWithShared(t *testing.T) {
1744 ctx := testCc(t, `
1745 cc_library {
1746 name: "a",
1747 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001748 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001749 }
1750 cc_library {
1751 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001752 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001753 }
1754 cc_library {
1755 name: "c",
1756 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001757 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001758 }
1759
1760 `)
1761
1762 variant := "android_arm64_armv8-a_core_static"
1763 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1764 actual := moduleA.depsInLinkOrder
1765 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1766
1767 if !reflect.DeepEqual(actual, expected) {
1768 t.Errorf("staticDeps orderings did not account for shared libs"+
1769 "\nactual: %v"+
1770 "\nexpected: %v",
1771 actual,
1772 expected,
1773 )
1774 }
1775}
1776
Jiyong Parka46a4d52017-12-14 19:54:34 +09001777func TestLlndkHeaders(t *testing.T) {
1778 ctx := testCc(t, `
1779 llndk_headers {
1780 name: "libllndk_headers",
1781 export_include_dirs: ["my_include"],
1782 }
1783 llndk_library {
1784 name: "libllndk",
1785 export_llndk_headers: ["libllndk_headers"],
1786 }
1787 cc_library {
1788 name: "libvendor",
1789 shared_libs: ["libllndk"],
1790 vendor: true,
1791 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001792 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001793 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001794 }
1795 `)
1796
1797 // _static variant is used since _shared reuses *.o from the static variant
Inseob Kim64c43952019-08-26 16:52:35 +09001798 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor.VER_static").Rule("cc")
Jiyong Parka46a4d52017-12-14 19:54:34 +09001799 cflags := cc.Args["cFlags"]
1800 if !strings.Contains(cflags, "-Imy_include") {
1801 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1802 }
1803}
1804
Logan Chien43d34c32017-12-20 01:17:32 +08001805func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1806 actual := module.Properties.AndroidMkRuntimeLibs
1807 if !reflect.DeepEqual(actual, expected) {
1808 t.Errorf("incorrect runtime_libs for shared libs"+
1809 "\nactual: %v"+
1810 "\nexpected: %v",
1811 actual,
1812 expected,
1813 )
1814 }
1815}
1816
1817const runtimeLibAndroidBp = `
1818 cc_library {
1819 name: "libvendor_available1",
1820 vendor_available: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001821 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001822 nocrt : true,
1823 system_shared_libs : [],
1824 }
1825 cc_library {
1826 name: "libvendor_available2",
1827 vendor_available: true,
1828 runtime_libs: ["libvendor_available1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001829 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001830 nocrt : true,
1831 system_shared_libs : [],
1832 }
1833 cc_library {
1834 name: "libvendor_available3",
1835 vendor_available: true,
1836 runtime_libs: ["libvendor_available1"],
1837 target: {
1838 vendor: {
1839 exclude_runtime_libs: ["libvendor_available1"],
1840 }
1841 },
Yi Konge7fe9912019-06-02 00:53:50 -07001842 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001843 nocrt : true,
1844 system_shared_libs : [],
1845 }
1846 cc_library {
1847 name: "libcore",
1848 runtime_libs: ["libvendor_available1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001849 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001850 nocrt : true,
1851 system_shared_libs : [],
1852 }
1853 cc_library {
1854 name: "libvendor1",
1855 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001856 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001857 nocrt : true,
1858 system_shared_libs : [],
1859 }
1860 cc_library {
1861 name: "libvendor2",
1862 vendor: true,
1863 runtime_libs: ["libvendor_available1", "libvendor1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001864 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001865 nocrt : true,
1866 system_shared_libs : [],
1867 }
1868`
1869
1870func TestRuntimeLibs(t *testing.T) {
1871 ctx := testCc(t, runtimeLibAndroidBp)
1872
1873 // runtime_libs for core variants use the module names without suffixes.
1874 variant := "android_arm64_armv8-a_core_shared"
1875
1876 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1877 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1878
1879 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1880 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1881
1882 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1883 // and vendor variants.
Inseob Kim64c43952019-08-26 16:52:35 +09001884 variant = "android_arm64_armv8-a_vendor.VER_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001885
1886 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1887 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1888
1889 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1890 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1891}
1892
1893func TestExcludeRuntimeLibs(t *testing.T) {
1894 ctx := testCc(t, runtimeLibAndroidBp)
1895
1896 variant := "android_arm64_armv8-a_core_shared"
1897 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1898 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1899
Inseob Kim64c43952019-08-26 16:52:35 +09001900 variant = "android_arm64_armv8-a_vendor.VER_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001901 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1902 checkRuntimeLibs(t, nil, module)
1903}
1904
1905func TestRuntimeLibsNoVndk(t *testing.T) {
1906 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1907
1908 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1909
1910 variant := "android_arm64_armv8-a_core_shared"
1911
1912 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1913 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1914
1915 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1916 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1917}
1918
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001919func checkStaticLibs(t *testing.T, expected []string, module *Module) {
1920 actual := module.Properties.AndroidMkStaticLibs
1921 if !reflect.DeepEqual(actual, expected) {
1922 t.Errorf("incorrect static_libs"+
1923 "\nactual: %v"+
1924 "\nexpected: %v",
1925 actual,
1926 expected,
1927 )
1928 }
1929}
1930
1931const staticLibAndroidBp = `
1932 cc_library {
1933 name: "lib1",
1934 }
1935 cc_library {
1936 name: "lib2",
1937 static_libs: ["lib1"],
1938 }
1939`
1940
1941func TestStaticLibDepExport(t *testing.T) {
1942 ctx := testCc(t, staticLibAndroidBp)
1943
1944 // Check the shared version of lib2.
1945 variant := "android_arm64_armv8-a_core_shared"
1946 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Dan Albert2da19cb2019-07-24 12:17:40 -07001947 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001948
1949 // Check the static version of lib2.
1950 variant = "android_arm64_armv8-a_core_static"
1951 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1952 // libc++_static is linked additionally.
Dan Albert2da19cb2019-07-24 12:17:40 -07001953 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001954}
1955
Jiyong Parkd08b6972017-09-26 10:50:54 +09001956var compilerFlagsTestCases = []struct {
1957 in string
1958 out bool
1959}{
1960 {
1961 in: "a",
1962 out: false,
1963 },
1964 {
1965 in: "-a",
1966 out: true,
1967 },
1968 {
1969 in: "-Ipath/to/something",
1970 out: false,
1971 },
1972 {
1973 in: "-isystempath/to/something",
1974 out: false,
1975 },
1976 {
1977 in: "--coverage",
1978 out: false,
1979 },
1980 {
1981 in: "-include a/b",
1982 out: true,
1983 },
1984 {
1985 in: "-include a/b c/d",
1986 out: false,
1987 },
1988 {
1989 in: "-DMACRO",
1990 out: true,
1991 },
1992 {
1993 in: "-DMAC RO",
1994 out: false,
1995 },
1996 {
1997 in: "-a -b",
1998 out: false,
1999 },
2000 {
2001 in: "-DMACRO=definition",
2002 out: true,
2003 },
2004 {
2005 in: "-DMACRO=defi nition",
2006 out: true, // TODO(jiyong): this should be false
2007 },
2008 {
2009 in: "-DMACRO(x)=x + 1",
2010 out: true,
2011 },
2012 {
2013 in: "-DMACRO=\"defi nition\"",
2014 out: true,
2015 },
2016}
2017
2018type mockContext struct {
2019 BaseModuleContext
2020 result bool
2021}
2022
2023func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
2024 // CheckBadCompilerFlags calls this function when the flag should be rejected
2025 ctx.result = false
2026}
2027
2028func TestCompilerFlags(t *testing.T) {
2029 for _, testCase := range compilerFlagsTestCases {
2030 ctx := &mockContext{result: true}
2031 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
2032 if ctx.result != testCase.out {
2033 t.Errorf("incorrect output:")
2034 t.Errorf(" input: %#v", testCase.in)
2035 t.Errorf(" expected: %#v", testCase.out)
2036 t.Errorf(" got: %#v", ctx.result)
2037 }
2038 }
Jeff Gaston294356f2017-09-27 17:05:30 -07002039}
Jiyong Park374510b2018-03-19 18:23:01 +09002040
2041func TestVendorPublicLibraries(t *testing.T) {
2042 ctx := testCc(t, `
2043 cc_library_headers {
2044 name: "libvendorpublic_headers",
2045 export_include_dirs: ["my_include"],
2046 }
2047 vendor_public_library {
2048 name: "libvendorpublic",
2049 symbol_file: "",
2050 export_public_headers: ["libvendorpublic_headers"],
2051 }
2052 cc_library {
2053 name: "libvendorpublic",
2054 srcs: ["foo.c"],
2055 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07002056 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002057 nocrt: true,
2058 }
2059
2060 cc_library {
2061 name: "libsystem",
2062 shared_libs: ["libvendorpublic"],
2063 vendor: false,
2064 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07002065 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002066 nocrt: true,
2067 }
2068 cc_library {
2069 name: "libvendor",
2070 shared_libs: ["libvendorpublic"],
2071 vendor: true,
2072 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07002073 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002074 nocrt: true,
2075 }
2076 `)
2077
2078 variant := "android_arm64_armv8-a_core_shared"
2079
2080 // test if header search paths are correctly added
2081 // _static variant is used since _shared reuses *.o from the static variant
2082 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
2083 cflags := cc.Args["cFlags"]
2084 if !strings.Contains(cflags, "-Imy_include") {
2085 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
2086 }
2087
2088 // test if libsystem is linked to the stub
2089 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
2090 libflags := ld.Args["libFlags"]
2091 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
2092 if !strings.Contains(libflags, stubPaths[0].String()) {
2093 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
2094 }
2095
2096 // test if libvendor is linked to the real shared lib
Inseob Kim64c43952019-08-26 16:52:35 +09002097 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor.VER", 1)).Rule("ld")
Jiyong Park374510b2018-03-19 18:23:01 +09002098 libflags = ld.Args["libFlags"]
Inseob Kim64c43952019-08-26 16:52:35 +09002099 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor.VER", 1), []string{"libvendorpublic"})
Jiyong Park374510b2018-03-19 18:23:01 +09002100 if !strings.Contains(libflags, stubPaths[0].String()) {
2101 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
2102 }
2103
2104}
Jiyong Park37b25202018-07-11 10:49:27 +09002105
2106func TestRecovery(t *testing.T) {
2107 ctx := testCc(t, `
2108 cc_library_shared {
2109 name: "librecovery",
2110 recovery: true,
2111 }
2112 cc_library_shared {
2113 name: "librecovery32",
2114 recovery: true,
2115 compile_multilib:"32",
2116 }
Jiyong Park5baac542018-08-28 09:55:37 +09002117 cc_library_shared {
2118 name: "libHalInRecovery",
2119 recovery_available: true,
2120 vendor: true,
2121 }
Jiyong Park37b25202018-07-11 10:49:27 +09002122 `)
2123
2124 variants := ctx.ModuleVariantsForTests("librecovery")
2125 const arm64 = "android_arm64_armv8-a_recovery_shared"
2126 if len(variants) != 1 || !android.InList(arm64, variants) {
2127 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
2128 }
2129
2130 variants = ctx.ModuleVariantsForTests("librecovery32")
2131 if android.InList(arm64, variants) {
2132 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
2133 }
Jiyong Park5baac542018-08-28 09:55:37 +09002134
2135 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
2136 if !recoveryModule.Platform() {
2137 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
2138 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09002139}
Jiyong Park5baac542018-08-28 09:55:37 +09002140
Jiyong Park7ed9de32018-10-15 22:25:07 +09002141func TestVersionedStubs(t *testing.T) {
2142 ctx := testCc(t, `
2143 cc_library_shared {
2144 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002145 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002146 stubs: {
2147 symbol_file: "foo.map.txt",
2148 versions: ["1", "2", "3"],
2149 },
2150 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002151
Jiyong Park7ed9de32018-10-15 22:25:07 +09002152 cc_library_shared {
2153 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002154 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002155 shared_libs: ["libFoo#1"],
2156 }`)
2157
2158 variants := ctx.ModuleVariantsForTests("libFoo")
2159 expectedVariants := []string{
2160 "android_arm64_armv8-a_core_shared",
2161 "android_arm64_armv8-a_core_shared_1",
2162 "android_arm64_armv8-a_core_shared_2",
2163 "android_arm64_armv8-a_core_shared_3",
2164 "android_arm_armv7-a-neon_core_shared",
2165 "android_arm_armv7-a-neon_core_shared_1",
2166 "android_arm_armv7-a-neon_core_shared_2",
2167 "android_arm_armv7-a-neon_core_shared_3",
2168 }
2169 variantsMismatch := false
2170 if len(variants) != len(expectedVariants) {
2171 variantsMismatch = true
2172 } else {
2173 for _, v := range expectedVariants {
2174 if !inList(v, variants) {
2175 variantsMismatch = false
2176 }
2177 }
2178 }
2179 if variantsMismatch {
2180 t.Errorf("variants of libFoo expected:\n")
2181 for _, v := range expectedVariants {
2182 t.Errorf("%q\n", v)
2183 }
2184 t.Errorf(", but got:\n")
2185 for _, v := range variants {
2186 t.Errorf("%q\n", v)
2187 }
2188 }
2189
2190 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld")
2191 libFlags := libBarLinkRule.Args["libFlags"]
2192 libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so"
2193 if !strings.Contains(libFlags, libFoo1StubPath) {
2194 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
2195 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002196
2197 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("cc")
2198 cFlags := libBarCompileRule.Args["cFlags"]
2199 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
2200 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
2201 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
2202 }
Jiyong Park37b25202018-07-11 10:49:27 +09002203}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002204
2205func TestStaticExecutable(t *testing.T) {
2206 ctx := testCc(t, `
2207 cc_binary {
2208 name: "static_test",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +01002209 srcs: ["foo.c", "baz.o"],
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002210 static_executable: true,
2211 }`)
2212
2213 variant := "android_arm64_armv8-a_core"
2214 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
2215 libFlags := binModuleRule.Args["libFlags"]
2216 systemStaticLibs := []string{"libc.a", "libm.a", "libdl.a"}
2217 for _, lib := range systemStaticLibs {
2218 if !strings.Contains(libFlags, lib) {
2219 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
2220 }
2221 }
2222 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
2223 for _, lib := range systemSharedLibs {
2224 if strings.Contains(libFlags, lib) {
2225 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
2226 }
2227 }
2228}
Jiyong Parke4bb9862019-02-01 00:31:10 +09002229
2230func TestStaticDepsOrderWithStubs(t *testing.T) {
2231 ctx := testCc(t, `
2232 cc_binary {
2233 name: "mybin",
2234 srcs: ["foo.c"],
2235 static_libs: ["libB"],
2236 static_executable: true,
2237 stl: "none",
2238 }
2239
2240 cc_library {
2241 name: "libB",
2242 srcs: ["foo.c"],
2243 shared_libs: ["libC"],
2244 stl: "none",
2245 }
2246
2247 cc_library {
2248 name: "libC",
2249 srcs: ["foo.c"],
2250 stl: "none",
2251 stubs: {
2252 versions: ["1"],
2253 },
2254 }`)
2255
2256 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a_core").Module().(*Module)
2257 actual := mybin.depsInLinkOrder
2258 expected := getOutputPaths(ctx, "android_arm64_armv8-a_core_static", []string{"libB", "libC"})
2259
2260 if !reflect.DeepEqual(actual, expected) {
2261 t.Errorf("staticDeps orderings were not propagated correctly"+
2262 "\nactual: %v"+
2263 "\nexpected: %v",
2264 actual,
2265 expected,
2266 )
2267 }
2268}
Jooyung Han38002912019-05-16 04:01:54 +09002269
Jooyung Hand48f3c32019-08-23 11:18:57 +09002270func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
2271 testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
2272 cc_library {
2273 name: "libA",
2274 srcs: ["foo.c"],
2275 shared_libs: ["libB"],
2276 stl: "none",
2277 }
2278
2279 cc_library {
2280 name: "libB",
2281 srcs: ["foo.c"],
2282 enabled: false,
2283 stl: "none",
2284 }
2285 `)
2286}
2287
Mitch Phillipsda9a4632019-07-15 09:34:09 -07002288// Simple smoke test for the cc_fuzz target that ensures the rule compiles
2289// correctly.
2290func TestFuzzTarget(t *testing.T) {
2291 ctx := testCc(t, `
2292 cc_fuzz {
2293 name: "fuzz_smoke_test",
2294 srcs: ["foo.c"],
2295 }`)
2296
2297 variant := "android_arm64_armv8-a_core"
2298 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
2299}
2300
Jiyong Park29074592019-07-07 16:27:47 +09002301func TestAidl(t *testing.T) {
2302}
2303
Jooyung Han38002912019-05-16 04:01:54 +09002304func assertString(t *testing.T, got, expected string) {
2305 t.Helper()
2306 if got != expected {
2307 t.Errorf("expected %q got %q", expected, got)
2308 }
2309}
2310
2311func assertArrayString(t *testing.T, got, expected []string) {
2312 t.Helper()
2313 if len(got) != len(expected) {
2314 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
2315 return
2316 }
2317 for i := range got {
2318 if got[i] != expected[i] {
2319 t.Errorf("expected %d-th %q (%q) got %q (%q)",
2320 i, expected[i], expected, got[i], got)
2321 return
2322 }
2323 }
2324}
Colin Crosse1bb5d02019-09-24 14:55:04 -07002325
2326func TestDefaults(t *testing.T) {
2327 ctx := testCc(t, `
2328 cc_defaults {
2329 name: "defaults",
2330 srcs: ["foo.c"],
2331 static: {
2332 srcs: ["bar.c"],
2333 },
2334 shared: {
2335 srcs: ["baz.c"],
2336 },
2337 }
2338
2339 cc_library_static {
2340 name: "libstatic",
2341 defaults: ["defaults"],
2342 }
2343
2344 cc_library_shared {
2345 name: "libshared",
2346 defaults: ["defaults"],
2347 }
2348
2349 cc_library {
2350 name: "libboth",
2351 defaults: ["defaults"],
2352 }
2353
2354 cc_binary {
2355 name: "binary",
2356 defaults: ["defaults"],
2357 }`)
2358
2359 pathsToBase := func(paths android.Paths) []string {
2360 var ret []string
2361 for _, p := range paths {
2362 ret = append(ret, p.Base())
2363 }
2364 return ret
2365 }
2366
2367 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_core_shared").Rule("ld")
2368 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2369 t.Errorf("libshared ld rule wanted %q, got %q", w, g)
2370 }
2371 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_core_shared").Rule("ld")
2372 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2373 t.Errorf("libboth ld rule wanted %q, got %q", w, g)
2374 }
2375 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a_core").Rule("ld")
2376 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
2377 t.Errorf("binary ld rule wanted %q, got %q", w, g)
2378 }
2379
2380 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_core_static").Rule("ar")
2381 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2382 t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
2383 }
2384 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_core_static").Rule("ar")
2385 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2386 t.Errorf("libboth ar rule wanted %q, got %q", w, g)
2387 }
2388}