blob: c619b5aa841bbb0f087db2881a96abe5e12339f9 [file] [log] [blame]
Colin Crossd00350c2017-11-17 10:55:38 -08001// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Colin Cross74d1ec02015-04-28 13:30:13 -070015package cc
16
17import (
Colin Cross5b529592017-05-09 13:34:34 -070018 "android/soong/android"
Colin Crossf18e1102017-11-16 14:33:08 -080019
Jeff Gaston294356f2017-09-27 17:05:30 -070020 "fmt"
Jiyong Park6a43f042017-10-12 23:05:00 +090021 "io/ioutil"
22 "os"
Inseob Kim1f086e22019-05-09 13:29:15 +090023 "path/filepath"
Colin Cross74d1ec02015-04-28 13:30:13 -070024 "reflect"
Jeff Gaston294356f2017-09-27 17:05:30 -070025 "sort"
26 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070027 "testing"
28)
29
Jiyong Park6a43f042017-10-12 23:05:00 +090030var buildDir string
31
32func setUp() {
33 var err error
34 buildDir, err = ioutil.TempDir("", "soong_cc_test")
35 if err != nil {
36 panic(err)
37 }
38}
39
40func tearDown() {
41 os.RemoveAll(buildDir)
42}
43
44func TestMain(m *testing.M) {
45 run := func() int {
46 setUp()
47 defer tearDown()
48
49 return m.Run()
50 }
51
52 os.Exit(run())
53}
54
Logan Chienf3511742017-10-31 18:04:35 +080055func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Doug Hornc32c6b02019-01-17 14:44:05 -080056 return testCcWithConfigForOs(t, bp, config, android.Android)
57}
58
59func testCcWithConfigForOs(t *testing.T, bp string, config android.Config, os android.OsType) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080060 t.Helper()
Colin Cross9a942872019-05-14 15:44:26 -070061 ctx := CreateTestContext(bp, nil, os)
Colin Cross33b2fb72019-05-14 14:07:01 -070062 ctx.Register()
Logan Chienf3511742017-10-31 18:04:35 +080063
Jeff Gastond3e141d2017-08-08 17:46:01 -070064 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +080065 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +090066 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +080067 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +090068
69 return ctx
70}
71
Logan Chienf3511742017-10-31 18:04:35 +080072func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080073 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080074 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070075 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
76 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080077
78 return testCcWithConfig(t, bp, config)
79}
80
81func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080082 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080083 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070084 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080085
86 return testCcWithConfig(t, bp, config)
87}
88
89func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +080090 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080091 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070092 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
93 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080094
Colin Cross9a942872019-05-14 15:44:26 -070095 ctx := CreateTestContext(bp, nil, android.Android)
Colin Cross33b2fb72019-05-14 14:07:01 -070096 ctx.Register()
Logan Chienf3511742017-10-31 18:04:35 +080097
98 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
99 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800100 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800101 return
102 }
103
104 _, errs = ctx.PrepareBuildActions(config)
105 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800106 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800107 return
108 }
109
110 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
111}
112
113const (
Jiyong Park5baac542018-08-28 09:55:37 +0900114 coreVariant = "android_arm64_armv8-a_core_shared"
115 vendorVariant = "android_arm64_armv8-a_vendor_shared"
116 recoveryVariant = "android_arm64_armv8-a_recovery_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800117)
118
Doug Hornc32c6b02019-01-17 14:44:05 -0800119func TestFuchsiaDeps(t *testing.T) {
120 t.Helper()
121
122 bp := `
123 cc_library {
124 name: "libTest",
125 srcs: ["foo.c"],
126 target: {
127 fuchsia: {
128 srcs: ["bar.c"],
129 },
130 },
131 }`
132
133 config := android.TestArchConfigFuchsia(buildDir, nil)
134 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
135
136 rt := false
137 fb := false
138
139 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
140 implicits := ld.Implicits
141 for _, lib := range implicits {
142 if strings.Contains(lib.Rel(), "libcompiler_rt") {
143 rt = true
144 }
145
146 if strings.Contains(lib.Rel(), "libbioniccompat") {
147 fb = true
148 }
149 }
150
151 if !rt || !fb {
152 t.Errorf("fuchsia libs must link libcompiler_rt and libbioniccompat")
153 }
154}
155
156func TestFuchsiaTargetDecl(t *testing.T) {
157 t.Helper()
158
159 bp := `
160 cc_library {
161 name: "libTest",
162 srcs: ["foo.c"],
163 target: {
164 fuchsia: {
165 srcs: ["bar.c"],
166 },
167 },
168 }`
169
170 config := android.TestArchConfigFuchsia(buildDir, nil)
171 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
172 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
173 var objs []string
174 for _, o := range ld.Inputs {
175 objs = append(objs, o.Base())
176 }
177 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
178 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
179 }
180}
181
Jiyong Park6a43f042017-10-12 23:05:00 +0900182func TestVendorSrc(t *testing.T) {
183 ctx := testCc(t, `
184 cc_library {
185 name: "libTest",
186 srcs: ["foo.c"],
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
331 variant := "android_arm64_armv8-a_vendor_shared"
332 variant2nd := "android_arm_armv7-a-neon_vendor_shared"
333
334 checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLibPath, variant)
335 checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLib2ndPath, variant2nd)
336 checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLibPath, variant)
337 checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLib2ndPath, variant2nd)
Logan Chienf3511742017-10-31 18:04:35 +0800338}
339
Logan Chiend3c59a22018-03-29 14:08:15 +0800340func TestVndkDepError(t *testing.T) {
341 // Check whether an error is emitted when a VNDK lib depends on a system lib.
342 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
343 cc_library {
344 name: "libvndk",
345 vendor_available: true,
346 vndk: {
347 enabled: true,
348 },
349 shared_libs: ["libfwk"], // Cause error
350 nocrt: true,
351 }
352
353 cc_library {
354 name: "libfwk",
355 nocrt: true,
356 }
357 `)
358
359 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
360 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
361 cc_library {
362 name: "libvndk",
363 vendor_available: true,
364 vndk: {
365 enabled: true,
366 },
367 shared_libs: ["libvendor"], // Cause error
368 nocrt: true,
369 }
370
371 cc_library {
372 name: "libvendor",
373 vendor: true,
374 nocrt: true,
375 }
376 `)
377
378 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
379 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
380 cc_library {
381 name: "libvndk_sp",
382 vendor_available: true,
383 vndk: {
384 enabled: true,
385 support_system_process: true,
386 },
387 shared_libs: ["libfwk"], // Cause error
388 nocrt: true,
389 }
390
391 cc_library {
392 name: "libfwk",
393 nocrt: true,
394 }
395 `)
396
397 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
398 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
399 cc_library {
400 name: "libvndk_sp",
401 vendor_available: true,
402 vndk: {
403 enabled: true,
404 support_system_process: true,
405 },
406 shared_libs: ["libvendor"], // Cause error
407 nocrt: true,
408 }
409
410 cc_library {
411 name: "libvendor",
412 vendor: true,
413 nocrt: true,
414 }
415 `)
416
417 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
418 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
419 cc_library {
420 name: "libvndk_sp",
421 vendor_available: true,
422 vndk: {
423 enabled: true,
424 support_system_process: true,
425 },
426 shared_libs: ["libvndk"], // Cause error
427 nocrt: true,
428 }
429
430 cc_library {
431 name: "libvndk",
432 vendor_available: true,
433 vndk: {
434 enabled: true,
435 },
436 nocrt: true,
437 }
438 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900439
440 // Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib.
441 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
442 cc_library {
443 name: "libvndk",
444 vendor_available: true,
445 vndk: {
446 enabled: true,
447 },
448 shared_libs: ["libnonvndk"],
449 nocrt: true,
450 }
451
452 cc_library {
453 name: "libnonvndk",
454 vendor_available: true,
455 nocrt: true,
456 }
457 `)
458
459 // Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib.
460 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
461 cc_library {
462 name: "libvndkprivate",
463 vendor_available: false,
464 vndk: {
465 enabled: true,
466 },
467 shared_libs: ["libnonvndk"],
468 nocrt: true,
469 }
470
471 cc_library {
472 name: "libnonvndk",
473 vendor_available: true,
474 nocrt: true,
475 }
476 `)
477
478 // Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib.
479 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
480 cc_library {
481 name: "libvndksp",
482 vendor_available: true,
483 vndk: {
484 enabled: true,
485 support_system_process: true,
486 },
487 shared_libs: ["libnonvndk"],
488 nocrt: true,
489 }
490
491 cc_library {
492 name: "libnonvndk",
493 vendor_available: true,
494 nocrt: true,
495 }
496 `)
497
498 // Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib.
499 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
500 cc_library {
501 name: "libvndkspprivate",
502 vendor_available: false,
503 vndk: {
504 enabled: true,
505 support_system_process: true,
506 },
507 shared_libs: ["libnonvndk"],
508 nocrt: true,
509 }
510
511 cc_library {
512 name: "libnonvndk",
513 vendor_available: true,
514 nocrt: true,
515 }
516 `)
517}
518
519func TestDoubleLoadbleDep(t *testing.T) {
520 // okay to link : LLNDK -> double_loadable VNDK
521 testCc(t, `
522 cc_library {
523 name: "libllndk",
524 shared_libs: ["libdoubleloadable"],
525 }
526
527 llndk_library {
528 name: "libllndk",
529 symbol_file: "",
530 }
531
532 cc_library {
533 name: "libdoubleloadable",
534 vendor_available: true,
535 vndk: {
536 enabled: true,
537 },
538 double_loadable: true,
539 }
540 `)
541 // okay to link : LLNDK -> VNDK-SP
542 testCc(t, `
543 cc_library {
544 name: "libllndk",
545 shared_libs: ["libvndksp"],
546 }
547
548 llndk_library {
549 name: "libllndk",
550 symbol_file: "",
551 }
552
553 cc_library {
554 name: "libvndksp",
555 vendor_available: true,
556 vndk: {
557 enabled: true,
558 support_system_process: true,
559 },
560 }
561 `)
562 // okay to link : double_loadable -> double_loadable
563 testCc(t, `
564 cc_library {
565 name: "libdoubleloadable1",
566 shared_libs: ["libdoubleloadable2"],
567 vendor_available: true,
568 double_loadable: true,
569 }
570
571 cc_library {
572 name: "libdoubleloadable2",
573 vendor_available: true,
574 double_loadable: true,
575 }
576 `)
577 // okay to link : double_loadable VNDK -> double_loadable VNDK private
578 testCc(t, `
579 cc_library {
580 name: "libdoubleloadable",
581 vendor_available: true,
582 vndk: {
583 enabled: true,
584 },
585 double_loadable: true,
586 shared_libs: ["libnondoubleloadable"],
587 }
588
589 cc_library {
590 name: "libnondoubleloadable",
591 vendor_available: false,
592 vndk: {
593 enabled: true,
594 },
595 double_loadable: true,
596 }
597 `)
598 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
599 testCc(t, `
600 cc_library {
601 name: "libllndk",
602 shared_libs: ["libcoreonly"],
603 }
604
605 llndk_library {
606 name: "libllndk",
607 symbol_file: "",
608 }
609
610 cc_library {
611 name: "libcoreonly",
612 shared_libs: ["libvendoravailable"],
613 }
614
615 // indirect dependency of LLNDK
616 cc_library {
617 name: "libvendoravailable",
618 vendor_available: true,
619 double_loadable: true,
620 }
621 `)
622}
623
624func TestDoubleLoadableDepError(t *testing.T) {
625 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
626 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
627 cc_library {
628 name: "libllndk",
629 shared_libs: ["libnondoubleloadable"],
630 }
631
632 llndk_library {
633 name: "libllndk",
634 symbol_file: "",
635 }
636
637 cc_library {
638 name: "libnondoubleloadable",
639 vendor_available: true,
640 vndk: {
641 enabled: true,
642 },
643 }
644 `)
645
646 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
647 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
648 cc_library {
649 name: "libllndk",
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
1346 tests := []struct {
1347 variant string
1348 name string
1349 expected string
1350 }{
1351 {vendorVariant, "libvndk", "native:vndk"},
1352 {vendorVariant, "libvndksp", "native:vndk"},
1353 {vendorVariant, "libvndkprivate", "native:vndk_private"},
1354 {vendorVariant, "libvendor", "native:vendor"},
1355 {vendorVariant, "libvndkext", "native:vendor"},
1356 {vendorVariant, "prevndk.vndk.27.arm.binder32", "native:vndk"},
1357 {vendorVariant, "libllndk.llndk", "native:vndk"},
1358 {coreVariant, "libvndk", "native:platform"},
1359 {coreVariant, "libvndkprivate", "native:platform"},
1360 {coreVariant, "libllndk", "native:platform"},
1361 }
1362 for _, test := range tests {
1363 t.Run(test.name, func(t *testing.T) {
1364 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
1365 assertString(t, module.makeLinkType, test.expected)
1366 })
1367 }
1368}
1369
Colin Cross0af4b842015-04-30 16:36:18 -07001370var (
1371 str11 = "01234567891"
1372 str10 = str11[:10]
1373 str9 = str11[:9]
1374 str5 = str11[:5]
1375 str4 = str11[:4]
1376)
1377
1378var splitListForSizeTestCases = []struct {
1379 in []string
1380 out [][]string
1381 size int
1382}{
1383 {
1384 in: []string{str10},
1385 out: [][]string{{str10}},
1386 size: 10,
1387 },
1388 {
1389 in: []string{str9},
1390 out: [][]string{{str9}},
1391 size: 10,
1392 },
1393 {
1394 in: []string{str5},
1395 out: [][]string{{str5}},
1396 size: 10,
1397 },
1398 {
1399 in: []string{str11},
1400 out: nil,
1401 size: 10,
1402 },
1403 {
1404 in: []string{str10, str10},
1405 out: [][]string{{str10}, {str10}},
1406 size: 10,
1407 },
1408 {
1409 in: []string{str9, str10},
1410 out: [][]string{{str9}, {str10}},
1411 size: 10,
1412 },
1413 {
1414 in: []string{str10, str9},
1415 out: [][]string{{str10}, {str9}},
1416 size: 10,
1417 },
1418 {
1419 in: []string{str5, str4},
1420 out: [][]string{{str5, str4}},
1421 size: 10,
1422 },
1423 {
1424 in: []string{str5, str4, str5},
1425 out: [][]string{{str5, str4}, {str5}},
1426 size: 10,
1427 },
1428 {
1429 in: []string{str5, str4, str5, str4},
1430 out: [][]string{{str5, str4}, {str5, str4}},
1431 size: 10,
1432 },
1433 {
1434 in: []string{str5, str4, str5, str5},
1435 out: [][]string{{str5, str4}, {str5}, {str5}},
1436 size: 10,
1437 },
1438 {
1439 in: []string{str5, str5, str5, str4},
1440 out: [][]string{{str5}, {str5}, {str5, str4}},
1441 size: 10,
1442 },
1443 {
1444 in: []string{str9, str11},
1445 out: nil,
1446 size: 10,
1447 },
1448 {
1449 in: []string{str11, str9},
1450 out: nil,
1451 size: 10,
1452 },
1453}
1454
1455func TestSplitListForSize(t *testing.T) {
1456 for _, testCase := range splitListForSizeTestCases {
Colin Cross40e33732019-02-15 11:08:35 -08001457 out, _ := splitListForSize(android.PathsForTesting(testCase.in...), testCase.size)
Colin Cross5b529592017-05-09 13:34:34 -07001458
1459 var outStrings [][]string
1460
1461 if len(out) > 0 {
1462 outStrings = make([][]string, len(out))
1463 for i, o := range out {
1464 outStrings[i] = o.Strings()
1465 }
1466 }
1467
1468 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001469 t.Errorf("incorrect output:")
1470 t.Errorf(" input: %#v", testCase.in)
1471 t.Errorf(" size: %d", testCase.size)
1472 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001473 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001474 }
1475 }
1476}
Jeff Gaston294356f2017-09-27 17:05:30 -07001477
1478var staticLinkDepOrderTestCases = []struct {
1479 // This is a string representation of a map[moduleName][]moduleDependency .
1480 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001481 inStatic string
1482
1483 // This is a string representation of a map[moduleName][]moduleDependency .
1484 // It models the dependencies declared in an Android.bp file.
1485 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001486
1487 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1488 // The keys of allOrdered specify which modules we would like to check.
1489 // The values of allOrdered specify the expected result (of the transitive closure of all
1490 // dependencies) for each module to test
1491 allOrdered string
1492
1493 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1494 // The keys of outOrdered specify which modules we would like to check.
1495 // The values of outOrdered specify the expected result (of the ordered linker command line)
1496 // for each module to test.
1497 outOrdered string
1498}{
1499 // Simple tests
1500 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001501 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001502 outOrdered: "",
1503 },
1504 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001505 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001506 outOrdered: "a:",
1507 },
1508 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001509 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001510 outOrdered: "a:b; b:",
1511 },
1512 // Tests of reordering
1513 {
1514 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001515 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001516 outOrdered: "a:b,c,d; b:d; c:d; d:",
1517 },
1518 {
1519 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001520 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001521 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1522 },
1523 {
1524 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001525 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001526 outOrdered: "a:d,b,e,c; d:b; e:c",
1527 },
1528 {
1529 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001530 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001531 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1532 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1533 },
1534 {
1535 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001536 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 -07001537 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1538 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1539 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001540 // shared dependencies
1541 {
1542 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1543 // So, we don't actually have to check that a shared dependency of c will change the order
1544 // of a library that depends statically on b and on c. We only need to check that if c has
1545 // a shared dependency on b, that that shows up in allOrdered.
1546 inShared: "c:b",
1547 allOrdered: "c:b",
1548 outOrdered: "c:",
1549 },
1550 {
1551 // This test doesn't actually include any shared dependencies but it's a reminder of what
1552 // the second phase of the above test would look like
1553 inStatic: "a:b,c; c:b",
1554 allOrdered: "a:c,b; c:b",
1555 outOrdered: "a:c,b; c:b",
1556 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001557 // tiebreakers for when two modules specifying different orderings and there is no dependency
1558 // to dictate an order
1559 {
1560 // 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 -08001561 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001562 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1563 },
1564 {
1565 // 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 -08001566 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 -07001567 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1568 },
1569 // Tests involving duplicate dependencies
1570 {
1571 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001572 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001573 outOrdered: "a:c,b",
1574 },
1575 {
1576 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001577 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001578 outOrdered: "a:d,c,b",
1579 },
1580 // Tests to confirm the nonexistence of infinite loops.
1581 // These cases should never happen, so as long as the test terminates and the
1582 // result is deterministic then that should be fine.
1583 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001584 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001585 outOrdered: "a:a",
1586 },
1587 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001588 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001589 allOrdered: "a:b,c; b:c,a; c:a,b",
1590 outOrdered: "a:b; b:c; c:a",
1591 },
1592 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001593 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001594 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1595 outOrdered: "a:c,b; b:a,c; c:b,a",
1596 },
1597}
1598
1599// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1600func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1601 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1602 strippedText := strings.Replace(text, " ", "", -1)
1603 if len(strippedText) < 1 {
1604 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1605 }
1606 allDeps = make(map[android.Path][]android.Path, 0)
1607
1608 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1609 moduleTexts := strings.Split(strippedText, ";")
1610
1611 outputForModuleName := func(moduleName string) android.Path {
1612 return android.PathForTesting(moduleName)
1613 }
1614
1615 for _, moduleText := range moduleTexts {
1616 // convert from "a:b,c" to ["a", "b,c"]
1617 components := strings.Split(moduleText, ":")
1618 if len(components) != 2 {
1619 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1620 }
1621 moduleName := components[0]
1622 moduleOutput := outputForModuleName(moduleName)
1623 modulesInOrder = append(modulesInOrder, moduleOutput)
1624
1625 depString := components[1]
1626 // convert from "b,c" to ["b", "c"]
1627 depNames := strings.Split(depString, ",")
1628 if len(depString) < 1 {
1629 depNames = []string{}
1630 }
1631 var deps []android.Path
1632 for _, depName := range depNames {
1633 deps = append(deps, outputForModuleName(depName))
1634 }
1635 allDeps[moduleOutput] = deps
1636 }
1637 return modulesInOrder, allDeps
1638}
1639
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001640func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001641 for _, testCase := range staticLinkDepOrderTestCases {
1642 errs := []string{}
1643
1644 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001645 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001646 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1647 if testCase.allOrdered == "" {
1648 // allow the test case to skip specifying allOrdered
1649 testCase.allOrdered = testCase.outOrdered
1650 }
1651 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001652 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001653
1654 // For each module whose post-reordered dependencies were specified, validate that
1655 // reordering the inputs produces the expected outputs.
1656 for _, moduleName := range expectedModuleNames {
1657 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001658 givenSharedDeps := givenAllSharedDeps[moduleName]
1659 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001660
1661 correctAllOrdered := expectedAllDeps[moduleName]
1662 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1663 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001664 "\nin static:%q"+
1665 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001666 "\nmodule: %v"+
1667 "\nexpected: %s"+
1668 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001669 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001670 }
1671
1672 correctOutputDeps := expectedTransitiveDeps[moduleName]
1673 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1674 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001675 "\nin static:%q"+
1676 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001677 "\nmodule: %v"+
1678 "\nexpected: %s"+
1679 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001680 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001681 }
1682 }
1683
1684 if len(errs) > 0 {
1685 sort.Strings(errs)
1686 for _, err := range errs {
1687 t.Error(err)
1688 }
1689 }
1690 }
1691}
Logan Chienf3511742017-10-31 18:04:35 +08001692
Jeff Gaston294356f2017-09-27 17:05:30 -07001693func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1694 for _, moduleName := range moduleNames {
1695 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1696 output := module.outputFile.Path()
1697 paths = append(paths, output)
1698 }
1699 return paths
1700}
1701
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001702func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001703 ctx := testCc(t, `
1704 cc_library {
1705 name: "a",
1706 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001707 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001708 }
1709 cc_library {
1710 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001711 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001712 }
1713 cc_library {
1714 name: "c",
1715 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001716 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001717 }
1718 cc_library {
1719 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001720 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001721 }
1722
1723 `)
1724
1725 variant := "android_arm64_armv8-a_core_static"
1726 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001727 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001728 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1729
1730 if !reflect.DeepEqual(actual, expected) {
1731 t.Errorf("staticDeps orderings were not propagated correctly"+
1732 "\nactual: %v"+
1733 "\nexpected: %v",
1734 actual,
1735 expected,
1736 )
1737 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001738}
Jeff Gaston294356f2017-09-27 17:05:30 -07001739
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001740func TestStaticLibDepReorderingWithShared(t *testing.T) {
1741 ctx := testCc(t, `
1742 cc_library {
1743 name: "a",
1744 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001745 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001746 }
1747 cc_library {
1748 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001749 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001750 }
1751 cc_library {
1752 name: "c",
1753 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001754 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001755 }
1756
1757 `)
1758
1759 variant := "android_arm64_armv8-a_core_static"
1760 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1761 actual := moduleA.depsInLinkOrder
1762 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1763
1764 if !reflect.DeepEqual(actual, expected) {
1765 t.Errorf("staticDeps orderings did not account for shared libs"+
1766 "\nactual: %v"+
1767 "\nexpected: %v",
1768 actual,
1769 expected,
1770 )
1771 }
1772}
1773
Jiyong Parka46a4d52017-12-14 19:54:34 +09001774func TestLlndkHeaders(t *testing.T) {
1775 ctx := testCc(t, `
1776 llndk_headers {
1777 name: "libllndk_headers",
1778 export_include_dirs: ["my_include"],
1779 }
1780 llndk_library {
1781 name: "libllndk",
1782 export_llndk_headers: ["libllndk_headers"],
1783 }
1784 cc_library {
1785 name: "libvendor",
1786 shared_libs: ["libllndk"],
1787 vendor: true,
1788 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001789 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001790 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001791 }
1792 `)
1793
1794 // _static variant is used since _shared reuses *.o from the static variant
1795 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1796 cflags := cc.Args["cFlags"]
1797 if !strings.Contains(cflags, "-Imy_include") {
1798 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1799 }
1800}
1801
Logan Chien43d34c32017-12-20 01:17:32 +08001802func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1803 actual := module.Properties.AndroidMkRuntimeLibs
1804 if !reflect.DeepEqual(actual, expected) {
1805 t.Errorf("incorrect runtime_libs for shared libs"+
1806 "\nactual: %v"+
1807 "\nexpected: %v",
1808 actual,
1809 expected,
1810 )
1811 }
1812}
1813
1814const runtimeLibAndroidBp = `
1815 cc_library {
1816 name: "libvendor_available1",
1817 vendor_available: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001818 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001819 nocrt : true,
1820 system_shared_libs : [],
1821 }
1822 cc_library {
1823 name: "libvendor_available2",
1824 vendor_available: true,
1825 runtime_libs: ["libvendor_available1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001826 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001827 nocrt : true,
1828 system_shared_libs : [],
1829 }
1830 cc_library {
1831 name: "libvendor_available3",
1832 vendor_available: true,
1833 runtime_libs: ["libvendor_available1"],
1834 target: {
1835 vendor: {
1836 exclude_runtime_libs: ["libvendor_available1"],
1837 }
1838 },
Yi Konge7fe9912019-06-02 00:53:50 -07001839 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001840 nocrt : true,
1841 system_shared_libs : [],
1842 }
1843 cc_library {
1844 name: "libcore",
1845 runtime_libs: ["libvendor_available1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001846 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001847 nocrt : true,
1848 system_shared_libs : [],
1849 }
1850 cc_library {
1851 name: "libvendor1",
1852 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001853 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001854 nocrt : true,
1855 system_shared_libs : [],
1856 }
1857 cc_library {
1858 name: "libvendor2",
1859 vendor: true,
1860 runtime_libs: ["libvendor_available1", "libvendor1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001861 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001862 nocrt : true,
1863 system_shared_libs : [],
1864 }
1865`
1866
1867func TestRuntimeLibs(t *testing.T) {
1868 ctx := testCc(t, runtimeLibAndroidBp)
1869
1870 // runtime_libs for core variants use the module names without suffixes.
1871 variant := "android_arm64_armv8-a_core_shared"
1872
1873 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1874 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1875
1876 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1877 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1878
1879 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1880 // and vendor variants.
1881 variant = "android_arm64_armv8-a_vendor_shared"
1882
1883 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1884 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1885
1886 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1887 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1888}
1889
1890func TestExcludeRuntimeLibs(t *testing.T) {
1891 ctx := testCc(t, runtimeLibAndroidBp)
1892
1893 variant := "android_arm64_armv8-a_core_shared"
1894 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1895 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1896
1897 variant = "android_arm64_armv8-a_vendor_shared"
1898 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1899 checkRuntimeLibs(t, nil, module)
1900}
1901
1902func TestRuntimeLibsNoVndk(t *testing.T) {
1903 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1904
1905 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1906
1907 variant := "android_arm64_armv8-a_core_shared"
1908
1909 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1910 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1911
1912 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1913 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1914}
1915
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001916func checkStaticLibs(t *testing.T, expected []string, module *Module) {
1917 actual := module.Properties.AndroidMkStaticLibs
1918 if !reflect.DeepEqual(actual, expected) {
1919 t.Errorf("incorrect static_libs"+
1920 "\nactual: %v"+
1921 "\nexpected: %v",
1922 actual,
1923 expected,
1924 )
1925 }
1926}
1927
1928const staticLibAndroidBp = `
1929 cc_library {
1930 name: "lib1",
1931 }
1932 cc_library {
1933 name: "lib2",
1934 static_libs: ["lib1"],
1935 }
1936`
1937
1938func TestStaticLibDepExport(t *testing.T) {
1939 ctx := testCc(t, staticLibAndroidBp)
1940
1941 // Check the shared version of lib2.
1942 variant := "android_arm64_armv8-a_core_shared"
1943 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Yi Kongacee27c2019-03-29 20:05:14 -07001944 checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001945
1946 // Check the static version of lib2.
1947 variant = "android_arm64_armv8-a_core_static"
1948 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1949 // libc++_static is linked additionally.
Yi Kongacee27c2019-03-29 20:05:14 -07001950 checkStaticLibs(t, []string{"lib1", "libc++_static", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001951}
1952
Jiyong Parkd08b6972017-09-26 10:50:54 +09001953var compilerFlagsTestCases = []struct {
1954 in string
1955 out bool
1956}{
1957 {
1958 in: "a",
1959 out: false,
1960 },
1961 {
1962 in: "-a",
1963 out: true,
1964 },
1965 {
1966 in: "-Ipath/to/something",
1967 out: false,
1968 },
1969 {
1970 in: "-isystempath/to/something",
1971 out: false,
1972 },
1973 {
1974 in: "--coverage",
1975 out: false,
1976 },
1977 {
1978 in: "-include a/b",
1979 out: true,
1980 },
1981 {
1982 in: "-include a/b c/d",
1983 out: false,
1984 },
1985 {
1986 in: "-DMACRO",
1987 out: true,
1988 },
1989 {
1990 in: "-DMAC RO",
1991 out: false,
1992 },
1993 {
1994 in: "-a -b",
1995 out: false,
1996 },
1997 {
1998 in: "-DMACRO=definition",
1999 out: true,
2000 },
2001 {
2002 in: "-DMACRO=defi nition",
2003 out: true, // TODO(jiyong): this should be false
2004 },
2005 {
2006 in: "-DMACRO(x)=x + 1",
2007 out: true,
2008 },
2009 {
2010 in: "-DMACRO=\"defi nition\"",
2011 out: true,
2012 },
2013}
2014
2015type mockContext struct {
2016 BaseModuleContext
2017 result bool
2018}
2019
2020func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
2021 // CheckBadCompilerFlags calls this function when the flag should be rejected
2022 ctx.result = false
2023}
2024
2025func TestCompilerFlags(t *testing.T) {
2026 for _, testCase := range compilerFlagsTestCases {
2027 ctx := &mockContext{result: true}
2028 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
2029 if ctx.result != testCase.out {
2030 t.Errorf("incorrect output:")
2031 t.Errorf(" input: %#v", testCase.in)
2032 t.Errorf(" expected: %#v", testCase.out)
2033 t.Errorf(" got: %#v", ctx.result)
2034 }
2035 }
Jeff Gaston294356f2017-09-27 17:05:30 -07002036}
Jiyong Park374510b2018-03-19 18:23:01 +09002037
2038func TestVendorPublicLibraries(t *testing.T) {
2039 ctx := testCc(t, `
2040 cc_library_headers {
2041 name: "libvendorpublic_headers",
2042 export_include_dirs: ["my_include"],
2043 }
2044 vendor_public_library {
2045 name: "libvendorpublic",
2046 symbol_file: "",
2047 export_public_headers: ["libvendorpublic_headers"],
2048 }
2049 cc_library {
2050 name: "libvendorpublic",
2051 srcs: ["foo.c"],
2052 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07002053 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002054 nocrt: true,
2055 }
2056
2057 cc_library {
2058 name: "libsystem",
2059 shared_libs: ["libvendorpublic"],
2060 vendor: false,
2061 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07002062 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002063 nocrt: true,
2064 }
2065 cc_library {
2066 name: "libvendor",
2067 shared_libs: ["libvendorpublic"],
2068 vendor: true,
2069 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07002070 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002071 nocrt: true,
2072 }
2073 `)
2074
2075 variant := "android_arm64_armv8-a_core_shared"
2076
2077 // test if header search paths are correctly added
2078 // _static variant is used since _shared reuses *.o from the static variant
2079 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
2080 cflags := cc.Args["cFlags"]
2081 if !strings.Contains(cflags, "-Imy_include") {
2082 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
2083 }
2084
2085 // test if libsystem is linked to the stub
2086 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
2087 libflags := ld.Args["libFlags"]
2088 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
2089 if !strings.Contains(libflags, stubPaths[0].String()) {
2090 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
2091 }
2092
2093 // test if libvendor is linked to the real shared lib
2094 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
2095 libflags = ld.Args["libFlags"]
2096 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
2097 if !strings.Contains(libflags, stubPaths[0].String()) {
2098 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
2099 }
2100
2101}
Jiyong Park37b25202018-07-11 10:49:27 +09002102
2103func TestRecovery(t *testing.T) {
2104 ctx := testCc(t, `
2105 cc_library_shared {
2106 name: "librecovery",
2107 recovery: true,
2108 }
2109 cc_library_shared {
2110 name: "librecovery32",
2111 recovery: true,
2112 compile_multilib:"32",
2113 }
Jiyong Park5baac542018-08-28 09:55:37 +09002114 cc_library_shared {
2115 name: "libHalInRecovery",
2116 recovery_available: true,
2117 vendor: true,
2118 }
Jiyong Park37b25202018-07-11 10:49:27 +09002119 `)
2120
2121 variants := ctx.ModuleVariantsForTests("librecovery")
2122 const arm64 = "android_arm64_armv8-a_recovery_shared"
2123 if len(variants) != 1 || !android.InList(arm64, variants) {
2124 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
2125 }
2126
2127 variants = ctx.ModuleVariantsForTests("librecovery32")
2128 if android.InList(arm64, variants) {
2129 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
2130 }
Jiyong Park5baac542018-08-28 09:55:37 +09002131
2132 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
2133 if !recoveryModule.Platform() {
2134 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
2135 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09002136}
Jiyong Park5baac542018-08-28 09:55:37 +09002137
Jiyong Park7ed9de32018-10-15 22:25:07 +09002138func TestVersionedStubs(t *testing.T) {
2139 ctx := testCc(t, `
2140 cc_library_shared {
2141 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002142 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002143 stubs: {
2144 symbol_file: "foo.map.txt",
2145 versions: ["1", "2", "3"],
2146 },
2147 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002148
Jiyong Park7ed9de32018-10-15 22:25:07 +09002149 cc_library_shared {
2150 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002151 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002152 shared_libs: ["libFoo#1"],
2153 }`)
2154
2155 variants := ctx.ModuleVariantsForTests("libFoo")
2156 expectedVariants := []string{
2157 "android_arm64_armv8-a_core_shared",
2158 "android_arm64_armv8-a_core_shared_1",
2159 "android_arm64_armv8-a_core_shared_2",
2160 "android_arm64_armv8-a_core_shared_3",
2161 "android_arm_armv7-a-neon_core_shared",
2162 "android_arm_armv7-a-neon_core_shared_1",
2163 "android_arm_armv7-a-neon_core_shared_2",
2164 "android_arm_armv7-a-neon_core_shared_3",
2165 }
2166 variantsMismatch := false
2167 if len(variants) != len(expectedVariants) {
2168 variantsMismatch = true
2169 } else {
2170 for _, v := range expectedVariants {
2171 if !inList(v, variants) {
2172 variantsMismatch = false
2173 }
2174 }
2175 }
2176 if variantsMismatch {
2177 t.Errorf("variants of libFoo expected:\n")
2178 for _, v := range expectedVariants {
2179 t.Errorf("%q\n", v)
2180 }
2181 t.Errorf(", but got:\n")
2182 for _, v := range variants {
2183 t.Errorf("%q\n", v)
2184 }
2185 }
2186
2187 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld")
2188 libFlags := libBarLinkRule.Args["libFlags"]
2189 libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so"
2190 if !strings.Contains(libFlags, libFoo1StubPath) {
2191 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
2192 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002193
2194 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("cc")
2195 cFlags := libBarCompileRule.Args["cFlags"]
2196 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
2197 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
2198 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
2199 }
Jiyong Park37b25202018-07-11 10:49:27 +09002200}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002201
2202func TestStaticExecutable(t *testing.T) {
2203 ctx := testCc(t, `
2204 cc_binary {
2205 name: "static_test",
2206 srcs: ["foo.c"],
2207 static_executable: true,
2208 }`)
2209
2210 variant := "android_arm64_armv8-a_core"
2211 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
2212 libFlags := binModuleRule.Args["libFlags"]
2213 systemStaticLibs := []string{"libc.a", "libm.a", "libdl.a"}
2214 for _, lib := range systemStaticLibs {
2215 if !strings.Contains(libFlags, lib) {
2216 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
2217 }
2218 }
2219 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
2220 for _, lib := range systemSharedLibs {
2221 if strings.Contains(libFlags, lib) {
2222 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
2223 }
2224 }
2225}
Jiyong Parke4bb9862019-02-01 00:31:10 +09002226
2227func TestStaticDepsOrderWithStubs(t *testing.T) {
2228 ctx := testCc(t, `
2229 cc_binary {
2230 name: "mybin",
2231 srcs: ["foo.c"],
2232 static_libs: ["libB"],
2233 static_executable: true,
2234 stl: "none",
2235 }
2236
2237 cc_library {
2238 name: "libB",
2239 srcs: ["foo.c"],
2240 shared_libs: ["libC"],
2241 stl: "none",
2242 }
2243
2244 cc_library {
2245 name: "libC",
2246 srcs: ["foo.c"],
2247 stl: "none",
2248 stubs: {
2249 versions: ["1"],
2250 },
2251 }`)
2252
2253 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a_core").Module().(*Module)
2254 actual := mybin.depsInLinkOrder
2255 expected := getOutputPaths(ctx, "android_arm64_armv8-a_core_static", []string{"libB", "libC"})
2256
2257 if !reflect.DeepEqual(actual, expected) {
2258 t.Errorf("staticDeps orderings were not propagated correctly"+
2259 "\nactual: %v"+
2260 "\nexpected: %v",
2261 actual,
2262 expected,
2263 )
2264 }
2265}
Jooyung Han38002912019-05-16 04:01:54 +09002266
Mitch Phillipsda9a4632019-07-15 09:34:09 -07002267// Simple smoke test for the cc_fuzz target that ensures the rule compiles
2268// correctly.
2269func TestFuzzTarget(t *testing.T) {
2270 ctx := testCc(t, `
2271 cc_fuzz {
2272 name: "fuzz_smoke_test",
2273 srcs: ["foo.c"],
2274 }`)
2275
2276 variant := "android_arm64_armv8-a_core"
2277 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
2278}
2279
Jiyong Park29074592019-07-07 16:27:47 +09002280func TestAidl(t *testing.T) {
2281}
2282
Jooyung Han38002912019-05-16 04:01:54 +09002283func assertString(t *testing.T, got, expected string) {
2284 t.Helper()
2285 if got != expected {
2286 t.Errorf("expected %q got %q", expected, got)
2287 }
2288}
2289
2290func assertArrayString(t *testing.T, got, expected []string) {
2291 t.Helper()
2292 if len(got) != len(expected) {
2293 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
2294 return
2295 }
2296 for i := range got {
2297 if got[i] != expected[i] {
2298 t.Errorf("expected %d-th %q (%q) got %q (%q)",
2299 i, expected[i], expected, got[i], got)
2300 return
2301 }
2302 }
2303}