blob: 62758223f564afb5ce10db06421b46b9150dd9d1 [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"
Inseob Kim64c43952019-08-26 16:52:35 +0900115 vendorVariant = "android_arm64_armv8-a_vendor.VER_shared"
Jiyong Park5baac542018-08-28 09:55:37 +0900116 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"],
Yi Konge7fe9912019-06-02 00:53:50 -0700187 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +0800188 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
Inseob Kim64c43952019-08-26 16:52:35 +0900331 variant := "android_arm64_armv8-a_vendor.VER_shared"
332 variant2nd := "android_arm_armv7-a-neon_vendor.VER_shared"
Inseob Kim1f086e22019-05-09 13:29:15 +0900333
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",
Yi Konge7fe9912019-06-02 00:53:50 -0700650 no_libcrt: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900651 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
Jooyung Han38002912019-05-16 04:01:54 +09001266func TestMakeLinkType(t *testing.T) {
1267 config := android.TestArchConfig(buildDir, nil)
1268 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1269 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
1270 // native:vndk
1271 ctx := testCcWithConfig(t, `
1272 cc_library {
1273 name: "libvndk",
1274 vendor_available: true,
1275 vndk: {
1276 enabled: true,
1277 },
1278 }
1279 cc_library {
1280 name: "libvndksp",
1281 vendor_available: true,
1282 vndk: {
1283 enabled: true,
1284 support_system_process: true,
1285 },
1286 }
1287 cc_library {
1288 name: "libvndkprivate",
1289 vendor_available: false,
1290 vndk: {
1291 enabled: true,
1292 },
1293 }
1294 cc_library {
1295 name: "libvendor",
1296 vendor: true,
1297 }
1298 cc_library {
1299 name: "libvndkext",
1300 vendor: true,
1301 vndk: {
1302 enabled: true,
1303 extends: "libvndk",
1304 },
1305 }
1306 vndk_prebuilt_shared {
1307 name: "prevndk",
1308 version: "27",
1309 target_arch: "arm",
1310 binder32bit: true,
1311 vendor_available: true,
1312 vndk: {
1313 enabled: true,
1314 },
1315 arch: {
1316 arm: {
1317 srcs: ["liba.so"],
1318 },
1319 },
1320 }
1321 cc_library {
1322 name: "libllndk",
1323 }
1324 llndk_library {
1325 name: "libllndk",
1326 symbol_file: "",
1327 }
1328 cc_library {
1329 name: "libllndkprivate",
1330 }
1331 llndk_library {
1332 name: "libllndkprivate",
1333 vendor_available: false,
1334 symbol_file: "",
1335 }`, config)
1336
1337 assertArrayString(t, *vndkCoreLibraries(config),
1338 []string{"libvndk", "libvndkprivate"})
1339 assertArrayString(t, *vndkSpLibraries(config),
1340 []string{"libc++", "libvndksp"})
1341 assertArrayString(t, *llndkLibraries(config),
1342 []string{"libc", "libdl", "libllndk", "libllndkprivate", "libm"})
1343 assertArrayString(t, *vndkPrivateLibraries(config),
1344 []string{"libllndkprivate", "libvndkprivate"})
1345
Inseob Kim64c43952019-08-26 16:52:35 +09001346 vendorVariant27 := "android_arm64_armv8-a_vendor.27_shared"
1347
Jooyung Han38002912019-05-16 04:01:54 +09001348 tests := []struct {
1349 variant string
1350 name string
1351 expected string
1352 }{
1353 {vendorVariant, "libvndk", "native:vndk"},
1354 {vendorVariant, "libvndksp", "native:vndk"},
1355 {vendorVariant, "libvndkprivate", "native:vndk_private"},
1356 {vendorVariant, "libvendor", "native:vendor"},
1357 {vendorVariant, "libvndkext", "native:vendor"},
Jooyung Han38002912019-05-16 04:01:54 +09001358 {vendorVariant, "libllndk.llndk", "native:vndk"},
Inseob Kim64c43952019-08-26 16:52:35 +09001359 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
Jooyung Han38002912019-05-16 04:01:54 +09001360 {coreVariant, "libvndk", "native:platform"},
1361 {coreVariant, "libvndkprivate", "native:platform"},
1362 {coreVariant, "libllndk", "native:platform"},
1363 }
1364 for _, test := range tests {
1365 t.Run(test.name, func(t *testing.T) {
1366 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
1367 assertString(t, module.makeLinkType, test.expected)
1368 })
1369 }
1370}
1371
Colin Cross0af4b842015-04-30 16:36:18 -07001372var (
1373 str11 = "01234567891"
1374 str10 = str11[:10]
1375 str9 = str11[:9]
1376 str5 = str11[:5]
1377 str4 = str11[:4]
1378)
1379
1380var splitListForSizeTestCases = []struct {
1381 in []string
1382 out [][]string
1383 size int
1384}{
1385 {
1386 in: []string{str10},
1387 out: [][]string{{str10}},
1388 size: 10,
1389 },
1390 {
1391 in: []string{str9},
1392 out: [][]string{{str9}},
1393 size: 10,
1394 },
1395 {
1396 in: []string{str5},
1397 out: [][]string{{str5}},
1398 size: 10,
1399 },
1400 {
1401 in: []string{str11},
1402 out: nil,
1403 size: 10,
1404 },
1405 {
1406 in: []string{str10, str10},
1407 out: [][]string{{str10}, {str10}},
1408 size: 10,
1409 },
1410 {
1411 in: []string{str9, str10},
1412 out: [][]string{{str9}, {str10}},
1413 size: 10,
1414 },
1415 {
1416 in: []string{str10, str9},
1417 out: [][]string{{str10}, {str9}},
1418 size: 10,
1419 },
1420 {
1421 in: []string{str5, str4},
1422 out: [][]string{{str5, str4}},
1423 size: 10,
1424 },
1425 {
1426 in: []string{str5, str4, str5},
1427 out: [][]string{{str5, str4}, {str5}},
1428 size: 10,
1429 },
1430 {
1431 in: []string{str5, str4, str5, str4},
1432 out: [][]string{{str5, str4}, {str5, str4}},
1433 size: 10,
1434 },
1435 {
1436 in: []string{str5, str4, str5, str5},
1437 out: [][]string{{str5, str4}, {str5}, {str5}},
1438 size: 10,
1439 },
1440 {
1441 in: []string{str5, str5, str5, str4},
1442 out: [][]string{{str5}, {str5}, {str5, str4}},
1443 size: 10,
1444 },
1445 {
1446 in: []string{str9, str11},
1447 out: nil,
1448 size: 10,
1449 },
1450 {
1451 in: []string{str11, str9},
1452 out: nil,
1453 size: 10,
1454 },
1455}
1456
1457func TestSplitListForSize(t *testing.T) {
1458 for _, testCase := range splitListForSizeTestCases {
Colin Cross40e33732019-02-15 11:08:35 -08001459 out, _ := splitListForSize(android.PathsForTesting(testCase.in...), testCase.size)
Colin Cross5b529592017-05-09 13:34:34 -07001460
1461 var outStrings [][]string
1462
1463 if len(out) > 0 {
1464 outStrings = make([][]string, len(out))
1465 for i, o := range out {
1466 outStrings[i] = o.Strings()
1467 }
1468 }
1469
1470 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001471 t.Errorf("incorrect output:")
1472 t.Errorf(" input: %#v", testCase.in)
1473 t.Errorf(" size: %d", testCase.size)
1474 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001475 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001476 }
1477 }
1478}
Jeff Gaston294356f2017-09-27 17:05:30 -07001479
1480var staticLinkDepOrderTestCases = []struct {
1481 // This is a string representation of a map[moduleName][]moduleDependency .
1482 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001483 inStatic string
1484
1485 // This is a string representation of a map[moduleName][]moduleDependency .
1486 // It models the dependencies declared in an Android.bp file.
1487 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001488
1489 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1490 // The keys of allOrdered specify which modules we would like to check.
1491 // The values of allOrdered specify the expected result (of the transitive closure of all
1492 // dependencies) for each module to test
1493 allOrdered string
1494
1495 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1496 // The keys of outOrdered specify which modules we would like to check.
1497 // The values of outOrdered specify the expected result (of the ordered linker command line)
1498 // for each module to test.
1499 outOrdered string
1500}{
1501 // Simple tests
1502 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001503 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001504 outOrdered: "",
1505 },
1506 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001507 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001508 outOrdered: "a:",
1509 },
1510 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001511 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001512 outOrdered: "a:b; b:",
1513 },
1514 // Tests of reordering
1515 {
1516 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001517 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001518 outOrdered: "a:b,c,d; b:d; c:d; d:",
1519 },
1520 {
1521 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001522 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001523 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1524 },
1525 {
1526 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001527 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001528 outOrdered: "a:d,b,e,c; d:b; e:c",
1529 },
1530 {
1531 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001532 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001533 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1534 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1535 },
1536 {
1537 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001538 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 -07001539 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1540 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1541 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001542 // shared dependencies
1543 {
1544 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1545 // So, we don't actually have to check that a shared dependency of c will change the order
1546 // of a library that depends statically on b and on c. We only need to check that if c has
1547 // a shared dependency on b, that that shows up in allOrdered.
1548 inShared: "c:b",
1549 allOrdered: "c:b",
1550 outOrdered: "c:",
1551 },
1552 {
1553 // This test doesn't actually include any shared dependencies but it's a reminder of what
1554 // the second phase of the above test would look like
1555 inStatic: "a:b,c; c:b",
1556 allOrdered: "a:c,b; c:b",
1557 outOrdered: "a:c,b; c:b",
1558 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001559 // tiebreakers for when two modules specifying different orderings and there is no dependency
1560 // to dictate an order
1561 {
1562 // 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 -08001563 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001564 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1565 },
1566 {
1567 // 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 -08001568 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 -07001569 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1570 },
1571 // Tests involving duplicate dependencies
1572 {
1573 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001574 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001575 outOrdered: "a:c,b",
1576 },
1577 {
1578 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001579 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001580 outOrdered: "a:d,c,b",
1581 },
1582 // Tests to confirm the nonexistence of infinite loops.
1583 // These cases should never happen, so as long as the test terminates and the
1584 // result is deterministic then that should be fine.
1585 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001586 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001587 outOrdered: "a:a",
1588 },
1589 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001590 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001591 allOrdered: "a:b,c; b:c,a; c:a,b",
1592 outOrdered: "a:b; b:c; c:a",
1593 },
1594 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001595 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001596 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1597 outOrdered: "a:c,b; b:a,c; c:b,a",
1598 },
1599}
1600
1601// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1602func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1603 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1604 strippedText := strings.Replace(text, " ", "", -1)
1605 if len(strippedText) < 1 {
1606 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1607 }
1608 allDeps = make(map[android.Path][]android.Path, 0)
1609
1610 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1611 moduleTexts := strings.Split(strippedText, ";")
1612
1613 outputForModuleName := func(moduleName string) android.Path {
1614 return android.PathForTesting(moduleName)
1615 }
1616
1617 for _, moduleText := range moduleTexts {
1618 // convert from "a:b,c" to ["a", "b,c"]
1619 components := strings.Split(moduleText, ":")
1620 if len(components) != 2 {
1621 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1622 }
1623 moduleName := components[0]
1624 moduleOutput := outputForModuleName(moduleName)
1625 modulesInOrder = append(modulesInOrder, moduleOutput)
1626
1627 depString := components[1]
1628 // convert from "b,c" to ["b", "c"]
1629 depNames := strings.Split(depString, ",")
1630 if len(depString) < 1 {
1631 depNames = []string{}
1632 }
1633 var deps []android.Path
1634 for _, depName := range depNames {
1635 deps = append(deps, outputForModuleName(depName))
1636 }
1637 allDeps[moduleOutput] = deps
1638 }
1639 return modulesInOrder, allDeps
1640}
1641
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001642func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001643 for _, testCase := range staticLinkDepOrderTestCases {
1644 errs := []string{}
1645
1646 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001647 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001648 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1649 if testCase.allOrdered == "" {
1650 // allow the test case to skip specifying allOrdered
1651 testCase.allOrdered = testCase.outOrdered
1652 }
1653 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001654 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001655
1656 // For each module whose post-reordered dependencies were specified, validate that
1657 // reordering the inputs produces the expected outputs.
1658 for _, moduleName := range expectedModuleNames {
1659 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001660 givenSharedDeps := givenAllSharedDeps[moduleName]
1661 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001662
1663 correctAllOrdered := expectedAllDeps[moduleName]
1664 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1665 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001666 "\nin static:%q"+
1667 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001668 "\nmodule: %v"+
1669 "\nexpected: %s"+
1670 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001671 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001672 }
1673
1674 correctOutputDeps := expectedTransitiveDeps[moduleName]
1675 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1676 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001677 "\nin static:%q"+
1678 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001679 "\nmodule: %v"+
1680 "\nexpected: %s"+
1681 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001682 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001683 }
1684 }
1685
1686 if len(errs) > 0 {
1687 sort.Strings(errs)
1688 for _, err := range errs {
1689 t.Error(err)
1690 }
1691 }
1692 }
1693}
Logan Chienf3511742017-10-31 18:04:35 +08001694
Jeff Gaston294356f2017-09-27 17:05:30 -07001695func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1696 for _, moduleName := range moduleNames {
1697 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1698 output := module.outputFile.Path()
1699 paths = append(paths, output)
1700 }
1701 return paths
1702}
1703
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001704func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001705 ctx := testCc(t, `
1706 cc_library {
1707 name: "a",
1708 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001709 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001710 }
1711 cc_library {
1712 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001713 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001714 }
1715 cc_library {
1716 name: "c",
1717 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001718 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001719 }
1720 cc_library {
1721 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001722 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001723 }
1724
1725 `)
1726
1727 variant := "android_arm64_armv8-a_core_static"
1728 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001729 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001730 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1731
1732 if !reflect.DeepEqual(actual, expected) {
1733 t.Errorf("staticDeps orderings were not propagated correctly"+
1734 "\nactual: %v"+
1735 "\nexpected: %v",
1736 actual,
1737 expected,
1738 )
1739 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001740}
Jeff Gaston294356f2017-09-27 17:05:30 -07001741
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001742func TestStaticLibDepReorderingWithShared(t *testing.T) {
1743 ctx := testCc(t, `
1744 cc_library {
1745 name: "a",
1746 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001747 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001748 }
1749 cc_library {
1750 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001751 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001752 }
1753 cc_library {
1754 name: "c",
1755 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001756 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001757 }
1758
1759 `)
1760
1761 variant := "android_arm64_armv8-a_core_static"
1762 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1763 actual := moduleA.depsInLinkOrder
1764 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1765
1766 if !reflect.DeepEqual(actual, expected) {
1767 t.Errorf("staticDeps orderings did not account for shared libs"+
1768 "\nactual: %v"+
1769 "\nexpected: %v",
1770 actual,
1771 expected,
1772 )
1773 }
1774}
1775
Jiyong Parka46a4d52017-12-14 19:54:34 +09001776func TestLlndkHeaders(t *testing.T) {
1777 ctx := testCc(t, `
1778 llndk_headers {
1779 name: "libllndk_headers",
1780 export_include_dirs: ["my_include"],
1781 }
1782 llndk_library {
1783 name: "libllndk",
1784 export_llndk_headers: ["libllndk_headers"],
1785 }
1786 cc_library {
1787 name: "libvendor",
1788 shared_libs: ["libllndk"],
1789 vendor: true,
1790 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001791 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001792 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001793 }
1794 `)
1795
1796 // _static variant is used since _shared reuses *.o from the static variant
Inseob Kim64c43952019-08-26 16:52:35 +09001797 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor.VER_static").Rule("cc")
Jiyong Parka46a4d52017-12-14 19:54:34 +09001798 cflags := cc.Args["cFlags"]
1799 if !strings.Contains(cflags, "-Imy_include") {
1800 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1801 }
1802}
1803
Logan Chien43d34c32017-12-20 01:17:32 +08001804func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1805 actual := module.Properties.AndroidMkRuntimeLibs
1806 if !reflect.DeepEqual(actual, expected) {
1807 t.Errorf("incorrect runtime_libs for shared libs"+
1808 "\nactual: %v"+
1809 "\nexpected: %v",
1810 actual,
1811 expected,
1812 )
1813 }
1814}
1815
1816const runtimeLibAndroidBp = `
1817 cc_library {
1818 name: "libvendor_available1",
1819 vendor_available: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001820 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001821 nocrt : true,
1822 system_shared_libs : [],
1823 }
1824 cc_library {
1825 name: "libvendor_available2",
1826 vendor_available: true,
1827 runtime_libs: ["libvendor_available1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001828 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001829 nocrt : true,
1830 system_shared_libs : [],
1831 }
1832 cc_library {
1833 name: "libvendor_available3",
1834 vendor_available: true,
1835 runtime_libs: ["libvendor_available1"],
1836 target: {
1837 vendor: {
1838 exclude_runtime_libs: ["libvendor_available1"],
1839 }
1840 },
Yi Konge7fe9912019-06-02 00:53:50 -07001841 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001842 nocrt : true,
1843 system_shared_libs : [],
1844 }
1845 cc_library {
1846 name: "libcore",
1847 runtime_libs: ["libvendor_available1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001848 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001849 nocrt : true,
1850 system_shared_libs : [],
1851 }
1852 cc_library {
1853 name: "libvendor1",
1854 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001855 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001856 nocrt : true,
1857 system_shared_libs : [],
1858 }
1859 cc_library {
1860 name: "libvendor2",
1861 vendor: true,
1862 runtime_libs: ["libvendor_available1", "libvendor1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001863 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001864 nocrt : true,
1865 system_shared_libs : [],
1866 }
1867`
1868
1869func TestRuntimeLibs(t *testing.T) {
1870 ctx := testCc(t, runtimeLibAndroidBp)
1871
1872 // runtime_libs for core variants use the module names without suffixes.
1873 variant := "android_arm64_armv8-a_core_shared"
1874
1875 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1876 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1877
1878 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1879 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1880
1881 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1882 // and vendor variants.
Inseob Kim64c43952019-08-26 16:52:35 +09001883 variant = "android_arm64_armv8-a_vendor.VER_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001884
1885 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1886 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1887
1888 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1889 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1890}
1891
1892func TestExcludeRuntimeLibs(t *testing.T) {
1893 ctx := testCc(t, runtimeLibAndroidBp)
1894
1895 variant := "android_arm64_armv8-a_core_shared"
1896 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1897 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1898
Inseob Kim64c43952019-08-26 16:52:35 +09001899 variant = "android_arm64_armv8-a_vendor.VER_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001900 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1901 checkRuntimeLibs(t, nil, module)
1902}
1903
1904func TestRuntimeLibsNoVndk(t *testing.T) {
1905 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1906
1907 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1908
1909 variant := "android_arm64_armv8-a_core_shared"
1910
1911 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1912 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1913
1914 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1915 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1916}
1917
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001918func checkStaticLibs(t *testing.T, expected []string, module *Module) {
1919 actual := module.Properties.AndroidMkStaticLibs
1920 if !reflect.DeepEqual(actual, expected) {
1921 t.Errorf("incorrect static_libs"+
1922 "\nactual: %v"+
1923 "\nexpected: %v",
1924 actual,
1925 expected,
1926 )
1927 }
1928}
1929
1930const staticLibAndroidBp = `
1931 cc_library {
1932 name: "lib1",
1933 }
1934 cc_library {
1935 name: "lib2",
1936 static_libs: ["lib1"],
1937 }
1938`
1939
1940func TestStaticLibDepExport(t *testing.T) {
1941 ctx := testCc(t, staticLibAndroidBp)
1942
1943 // Check the shared version of lib2.
1944 variant := "android_arm64_armv8-a_core_shared"
1945 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Dan Albert2da19cb2019-07-24 12:17:40 -07001946 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001947
1948 // Check the static version of lib2.
1949 variant = "android_arm64_armv8-a_core_static"
1950 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1951 // libc++_static is linked additionally.
Dan Albert2da19cb2019-07-24 12:17:40 -07001952 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001953}
1954
Jiyong Parkd08b6972017-09-26 10:50:54 +09001955var compilerFlagsTestCases = []struct {
1956 in string
1957 out bool
1958}{
1959 {
1960 in: "a",
1961 out: false,
1962 },
1963 {
1964 in: "-a",
1965 out: true,
1966 },
1967 {
1968 in: "-Ipath/to/something",
1969 out: false,
1970 },
1971 {
1972 in: "-isystempath/to/something",
1973 out: false,
1974 },
1975 {
1976 in: "--coverage",
1977 out: false,
1978 },
1979 {
1980 in: "-include a/b",
1981 out: true,
1982 },
1983 {
1984 in: "-include a/b c/d",
1985 out: false,
1986 },
1987 {
1988 in: "-DMACRO",
1989 out: true,
1990 },
1991 {
1992 in: "-DMAC RO",
1993 out: false,
1994 },
1995 {
1996 in: "-a -b",
1997 out: false,
1998 },
1999 {
2000 in: "-DMACRO=definition",
2001 out: true,
2002 },
2003 {
2004 in: "-DMACRO=defi nition",
2005 out: true, // TODO(jiyong): this should be false
2006 },
2007 {
2008 in: "-DMACRO(x)=x + 1",
2009 out: true,
2010 },
2011 {
2012 in: "-DMACRO=\"defi nition\"",
2013 out: true,
2014 },
2015}
2016
2017type mockContext struct {
2018 BaseModuleContext
2019 result bool
2020}
2021
2022func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
2023 // CheckBadCompilerFlags calls this function when the flag should be rejected
2024 ctx.result = false
2025}
2026
2027func TestCompilerFlags(t *testing.T) {
2028 for _, testCase := range compilerFlagsTestCases {
2029 ctx := &mockContext{result: true}
2030 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
2031 if ctx.result != testCase.out {
2032 t.Errorf("incorrect output:")
2033 t.Errorf(" input: %#v", testCase.in)
2034 t.Errorf(" expected: %#v", testCase.out)
2035 t.Errorf(" got: %#v", ctx.result)
2036 }
2037 }
Jeff Gaston294356f2017-09-27 17:05:30 -07002038}
Jiyong Park374510b2018-03-19 18:23:01 +09002039
2040func TestVendorPublicLibraries(t *testing.T) {
2041 ctx := testCc(t, `
2042 cc_library_headers {
2043 name: "libvendorpublic_headers",
2044 export_include_dirs: ["my_include"],
2045 }
2046 vendor_public_library {
2047 name: "libvendorpublic",
2048 symbol_file: "",
2049 export_public_headers: ["libvendorpublic_headers"],
2050 }
2051 cc_library {
2052 name: "libvendorpublic",
2053 srcs: ["foo.c"],
2054 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07002055 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002056 nocrt: true,
2057 }
2058
2059 cc_library {
2060 name: "libsystem",
2061 shared_libs: ["libvendorpublic"],
2062 vendor: false,
2063 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07002064 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002065 nocrt: true,
2066 }
2067 cc_library {
2068 name: "libvendor",
2069 shared_libs: ["libvendorpublic"],
2070 vendor: true,
2071 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07002072 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002073 nocrt: true,
2074 }
2075 `)
2076
2077 variant := "android_arm64_armv8-a_core_shared"
2078
2079 // test if header search paths are correctly added
2080 // _static variant is used since _shared reuses *.o from the static variant
2081 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
2082 cflags := cc.Args["cFlags"]
2083 if !strings.Contains(cflags, "-Imy_include") {
2084 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
2085 }
2086
2087 // test if libsystem is linked to the stub
2088 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
2089 libflags := ld.Args["libFlags"]
2090 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
2091 if !strings.Contains(libflags, stubPaths[0].String()) {
2092 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
2093 }
2094
2095 // test if libvendor is linked to the real shared lib
Inseob Kim64c43952019-08-26 16:52:35 +09002096 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor.VER", 1)).Rule("ld")
Jiyong Park374510b2018-03-19 18:23:01 +09002097 libflags = ld.Args["libFlags"]
Inseob Kim64c43952019-08-26 16:52:35 +09002098 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor.VER", 1), []string{"libvendorpublic"})
Jiyong Park374510b2018-03-19 18:23:01 +09002099 if !strings.Contains(libflags, stubPaths[0].String()) {
2100 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
2101 }
2102
2103}
Jiyong Park37b25202018-07-11 10:49:27 +09002104
2105func TestRecovery(t *testing.T) {
2106 ctx := testCc(t, `
2107 cc_library_shared {
2108 name: "librecovery",
2109 recovery: true,
2110 }
2111 cc_library_shared {
2112 name: "librecovery32",
2113 recovery: true,
2114 compile_multilib:"32",
2115 }
Jiyong Park5baac542018-08-28 09:55:37 +09002116 cc_library_shared {
2117 name: "libHalInRecovery",
2118 recovery_available: true,
2119 vendor: true,
2120 }
Jiyong Park37b25202018-07-11 10:49:27 +09002121 `)
2122
2123 variants := ctx.ModuleVariantsForTests("librecovery")
2124 const arm64 = "android_arm64_armv8-a_recovery_shared"
2125 if len(variants) != 1 || !android.InList(arm64, variants) {
2126 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
2127 }
2128
2129 variants = ctx.ModuleVariantsForTests("librecovery32")
2130 if android.InList(arm64, variants) {
2131 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
2132 }
Jiyong Park5baac542018-08-28 09:55:37 +09002133
2134 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
2135 if !recoveryModule.Platform() {
2136 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
2137 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09002138}
Jiyong Park5baac542018-08-28 09:55:37 +09002139
Jiyong Park7ed9de32018-10-15 22:25:07 +09002140func TestVersionedStubs(t *testing.T) {
2141 ctx := testCc(t, `
2142 cc_library_shared {
2143 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002144 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002145 stubs: {
2146 symbol_file: "foo.map.txt",
2147 versions: ["1", "2", "3"],
2148 },
2149 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002150
Jiyong Park7ed9de32018-10-15 22:25:07 +09002151 cc_library_shared {
2152 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002153 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002154 shared_libs: ["libFoo#1"],
2155 }`)
2156
2157 variants := ctx.ModuleVariantsForTests("libFoo")
2158 expectedVariants := []string{
2159 "android_arm64_armv8-a_core_shared",
2160 "android_arm64_armv8-a_core_shared_1",
2161 "android_arm64_armv8-a_core_shared_2",
2162 "android_arm64_armv8-a_core_shared_3",
2163 "android_arm_armv7-a-neon_core_shared",
2164 "android_arm_armv7-a-neon_core_shared_1",
2165 "android_arm_armv7-a-neon_core_shared_2",
2166 "android_arm_armv7-a-neon_core_shared_3",
2167 }
2168 variantsMismatch := false
2169 if len(variants) != len(expectedVariants) {
2170 variantsMismatch = true
2171 } else {
2172 for _, v := range expectedVariants {
2173 if !inList(v, variants) {
2174 variantsMismatch = false
2175 }
2176 }
2177 }
2178 if variantsMismatch {
2179 t.Errorf("variants of libFoo expected:\n")
2180 for _, v := range expectedVariants {
2181 t.Errorf("%q\n", v)
2182 }
2183 t.Errorf(", but got:\n")
2184 for _, v := range variants {
2185 t.Errorf("%q\n", v)
2186 }
2187 }
2188
2189 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld")
2190 libFlags := libBarLinkRule.Args["libFlags"]
2191 libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so"
2192 if !strings.Contains(libFlags, libFoo1StubPath) {
2193 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
2194 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002195
2196 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("cc")
2197 cFlags := libBarCompileRule.Args["cFlags"]
2198 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
2199 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
2200 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
2201 }
Jiyong Park37b25202018-07-11 10:49:27 +09002202}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002203
2204func TestStaticExecutable(t *testing.T) {
2205 ctx := testCc(t, `
2206 cc_binary {
2207 name: "static_test",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +01002208 srcs: ["foo.c", "baz.o"],
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002209 static_executable: true,
2210 }`)
2211
2212 variant := "android_arm64_armv8-a_core"
2213 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
2214 libFlags := binModuleRule.Args["libFlags"]
2215 systemStaticLibs := []string{"libc.a", "libm.a", "libdl.a"}
2216 for _, lib := range systemStaticLibs {
2217 if !strings.Contains(libFlags, lib) {
2218 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
2219 }
2220 }
2221 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
2222 for _, lib := range systemSharedLibs {
2223 if strings.Contains(libFlags, lib) {
2224 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
2225 }
2226 }
2227}
Jiyong Parke4bb9862019-02-01 00:31:10 +09002228
2229func TestStaticDepsOrderWithStubs(t *testing.T) {
2230 ctx := testCc(t, `
2231 cc_binary {
2232 name: "mybin",
2233 srcs: ["foo.c"],
2234 static_libs: ["libB"],
2235 static_executable: true,
2236 stl: "none",
2237 }
2238
2239 cc_library {
2240 name: "libB",
2241 srcs: ["foo.c"],
2242 shared_libs: ["libC"],
2243 stl: "none",
2244 }
2245
2246 cc_library {
2247 name: "libC",
2248 srcs: ["foo.c"],
2249 stl: "none",
2250 stubs: {
2251 versions: ["1"],
2252 },
2253 }`)
2254
2255 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a_core").Module().(*Module)
2256 actual := mybin.depsInLinkOrder
2257 expected := getOutputPaths(ctx, "android_arm64_armv8-a_core_static", []string{"libB", "libC"})
2258
2259 if !reflect.DeepEqual(actual, expected) {
2260 t.Errorf("staticDeps orderings were not propagated correctly"+
2261 "\nactual: %v"+
2262 "\nexpected: %v",
2263 actual,
2264 expected,
2265 )
2266 }
2267}
Jooyung Han38002912019-05-16 04:01:54 +09002268
Jooyung Hand48f3c32019-08-23 11:18:57 +09002269func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
2270 testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
2271 cc_library {
2272 name: "libA",
2273 srcs: ["foo.c"],
2274 shared_libs: ["libB"],
2275 stl: "none",
2276 }
2277
2278 cc_library {
2279 name: "libB",
2280 srcs: ["foo.c"],
2281 enabled: false,
2282 stl: "none",
2283 }
2284 `)
2285}
2286
Mitch Phillipsda9a4632019-07-15 09:34:09 -07002287// Simple smoke test for the cc_fuzz target that ensures the rule compiles
2288// correctly.
2289func TestFuzzTarget(t *testing.T) {
2290 ctx := testCc(t, `
2291 cc_fuzz {
2292 name: "fuzz_smoke_test",
2293 srcs: ["foo.c"],
2294 }`)
2295
2296 variant := "android_arm64_armv8-a_core"
2297 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
2298}
2299
Jiyong Park29074592019-07-07 16:27:47 +09002300func TestAidl(t *testing.T) {
2301}
2302
Jooyung Han38002912019-05-16 04:01:54 +09002303func assertString(t *testing.T, got, expected string) {
2304 t.Helper()
2305 if got != expected {
2306 t.Errorf("expected %q got %q", expected, got)
2307 }
2308}
2309
2310func assertArrayString(t *testing.T, got, expected []string) {
2311 t.Helper()
2312 if len(got) != len(expected) {
2313 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
2314 return
2315 }
2316 for i := range got {
2317 if got[i] != expected[i] {
2318 t.Errorf("expected %d-th %q (%q) got %q (%q)",
2319 i, expected[i], expected, got[i], got)
2320 return
2321 }
2322 }
2323}