blob: f13bee5ff0683f4e28ee837c6f52f75ff0ca2a91 [file] [log] [blame]
Colin Crossd00350c2017-11-17 10:55:38 -08001// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Colin Cross74d1ec02015-04-28 13:30:13 -070015package cc
16
17import (
Jeff Gaston294356f2017-09-27 17:05:30 -070018 "fmt"
Jiyong Park6a43f042017-10-12 23:05:00 +090019 "io/ioutil"
20 "os"
Inseob Kim1f086e22019-05-09 13:29:15 +090021 "path/filepath"
Colin Cross74d1ec02015-04-28 13:30:13 -070022 "reflect"
Jeff Gaston294356f2017-09-27 17:05:30 -070023 "sort"
24 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070025 "testing"
Colin Crosse1bb5d02019-09-24 14:55:04 -070026
27 "android/soong/android"
Colin Cross74d1ec02015-04-28 13:30:13 -070028)
29
Jiyong Park6a43f042017-10-12 23:05:00 +090030var buildDir string
31
32func setUp() {
33 var err error
34 buildDir, err = ioutil.TempDir("", "soong_cc_test")
35 if err != nil {
36 panic(err)
37 }
38}
39
40func tearDown() {
41 os.RemoveAll(buildDir)
42}
43
44func TestMain(m *testing.M) {
45 run := func() int {
46 setUp()
47 defer tearDown()
48
49 return m.Run()
50 }
51
52 os.Exit(run())
53}
54
Logan Chienf3511742017-10-31 18:04:35 +080055func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Colin Crosse1bb5d02019-09-24 14:55:04 -070056 t.Helper()
Doug Hornc32c6b02019-01-17 14:44:05 -080057 return testCcWithConfigForOs(t, bp, config, android.Android)
58}
59
60func testCcWithConfigForOs(t *testing.T, bp string, config android.Config, os android.OsType) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080061 t.Helper()
Colin Cross9a942872019-05-14 15:44:26 -070062 ctx := CreateTestContext(bp, nil, os)
Colin Cross33b2fb72019-05-14 14:07:01 -070063 ctx.Register()
Logan Chienf3511742017-10-31 18:04:35 +080064
Jeff Gastond3e141d2017-08-08 17:46:01 -070065 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +080066 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +090067 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +080068 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +090069
70 return ctx
71}
72
Logan Chienf3511742017-10-31 18:04:35 +080073func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080074 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080075 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070076 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
77 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080078
79 return testCcWithConfig(t, bp, config)
80}
81
82func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080083 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080084 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070085 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080086
87 return testCcWithConfig(t, bp, config)
88}
89
90func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +080091 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +080092 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -070093 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
94 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +080095
Colin Cross9a942872019-05-14 15:44:26 -070096 ctx := CreateTestContext(bp, nil, android.Android)
Colin Cross33b2fb72019-05-14 14:07:01 -070097 ctx.Register()
Logan Chienf3511742017-10-31 18:04:35 +080098
99 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
100 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800101 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800102 return
103 }
104
105 _, errs = ctx.PrepareBuildActions(config)
106 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800107 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800108 return
109 }
110
111 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
112}
113
114const (
Jiyong Park5baac542018-08-28 09:55:37 +0900115 coreVariant = "android_arm64_armv8-a_core_shared"
Inseob Kim64c43952019-08-26 16:52:35 +0900116 vendorVariant = "android_arm64_armv8-a_vendor.VER_shared"
Jiyong Park5baac542018-08-28 09:55:37 +0900117 recoveryVariant = "android_arm64_armv8-a_recovery_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800118)
119
Doug Hornc32c6b02019-01-17 14:44:05 -0800120func TestFuchsiaDeps(t *testing.T) {
121 t.Helper()
122
123 bp := `
124 cc_library {
125 name: "libTest",
126 srcs: ["foo.c"],
127 target: {
128 fuchsia: {
129 srcs: ["bar.c"],
130 },
131 },
132 }`
133
134 config := android.TestArchConfigFuchsia(buildDir, nil)
135 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
136
137 rt := false
138 fb := false
139
140 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
141 implicits := ld.Implicits
142 for _, lib := range implicits {
143 if strings.Contains(lib.Rel(), "libcompiler_rt") {
144 rt = true
145 }
146
147 if strings.Contains(lib.Rel(), "libbioniccompat") {
148 fb = true
149 }
150 }
151
152 if !rt || !fb {
153 t.Errorf("fuchsia libs must link libcompiler_rt and libbioniccompat")
154 }
155}
156
157func TestFuchsiaTargetDecl(t *testing.T) {
158 t.Helper()
159
160 bp := `
161 cc_library {
162 name: "libTest",
163 srcs: ["foo.c"],
164 target: {
165 fuchsia: {
166 srcs: ["bar.c"],
167 },
168 },
169 }`
170
171 config := android.TestArchConfigFuchsia(buildDir, nil)
172 ctx := testCcWithConfigForOs(t, bp, config, android.Fuchsia)
173 ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
174 var objs []string
175 for _, o := range ld.Inputs {
176 objs = append(objs, o.Base())
177 }
178 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
179 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
180 }
181}
182
Jiyong Park6a43f042017-10-12 23:05:00 +0900183func TestVendorSrc(t *testing.T) {
184 ctx := testCc(t, `
185 cc_library {
186 name: "libTest",
187 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -0700188 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +0800189 nocrt: true,
190 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900191 vendor_available: true,
192 target: {
193 vendor: {
194 srcs: ["bar.c"],
195 },
196 },
197 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900198 `)
199
Logan Chienf3511742017-10-31 18:04:35 +0800200 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900201 var objs []string
202 for _, o := range ld.Inputs {
203 objs = append(objs, o.Base())
204 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800205 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900206 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
207 }
208}
209
Logan Chienf3511742017-10-31 18:04:35 +0800210func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
211 isVndkSp bool, extends string) {
212
Logan Chiend3c59a22018-03-29 14:08:15 +0800213 t.Helper()
214
Logan Chienf3511742017-10-31 18:04:35 +0800215 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
216 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700217 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800218 }
219
220 // Check library properties.
221 lib, ok := mod.compiler.(*libraryDecorator)
222 if !ok {
223 t.Errorf("%q must have libraryDecorator", name)
224 } else if lib.baseInstaller.subDir != subDir {
225 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
226 lib.baseInstaller.subDir)
227 }
228
229 // Check VNDK properties.
230 if mod.vndkdep == nil {
231 t.Fatalf("%q must have `vndkdep`", name)
232 }
233 if !mod.isVndk() {
234 t.Errorf("%q isVndk() must equal to true", name)
235 }
236 if mod.isVndkSp() != isVndkSp {
237 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
238 }
239
240 // Check VNDK extension properties.
241 isVndkExt := extends != ""
242 if mod.isVndkExt() != isVndkExt {
243 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
244 }
245
246 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
247 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
248 }
249}
250
Inseob Kim1f086e22019-05-09 13:29:15 +0900251func checkVndkSnapshot(t *testing.T, ctx *android.TestContext, name, subDir, variant string) {
252 vndkSnapshot := ctx.SingletonForTests("vndk-snapshot")
253
254 snapshotPath := filepath.Join(subDir, name+".so")
255 mod := ctx.ModuleForTests(name, variant).Module().(*Module)
256 if !mod.outputFile.Valid() {
257 t.Errorf("%q must have output\n", name)
258 return
259 }
260
261 out := vndkSnapshot.Output(snapshotPath)
262 if out.Input != mod.outputFile.Path() {
263 t.Errorf("The input of VNDK snapshot must be %q, but %q", out.Input.String(), mod.outputFile.String())
264 }
265}
266
Jooyung Han097087b2019-10-22 19:32:18 +0900267func checkVndkOutput(t *testing.T, ctx *android.TestContext, output string, expected []string) {
268 t.Helper()
269 vndkSnapshot := ctx.SingletonForTests("vndk-snapshot")
270 actual := strings.FieldsFunc(strings.ReplaceAll(vndkSnapshot.Output(output).Args["content"], "\\n", "\n"), func(r rune) bool { return r == '\n' })
271 assertArrayString(t, actual, expected)
272}
273
Logan Chienf3511742017-10-31 18:04:35 +0800274func TestVndk(t *testing.T) {
Inseob Kim1f086e22019-05-09 13:29:15 +0900275 config := android.TestArchConfig(buildDir, nil)
276 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
277 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
278
279 ctx := testCcWithConfig(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800280 cc_library {
281 name: "libvndk",
282 vendor_available: true,
283 vndk: {
284 enabled: true,
285 },
286 nocrt: true,
287 }
288
289 cc_library {
290 name: "libvndk_private",
291 vendor_available: false,
292 vndk: {
293 enabled: true,
294 },
295 nocrt: true,
296 }
297
298 cc_library {
299 name: "libvndk_sp",
300 vendor_available: true,
301 vndk: {
302 enabled: true,
303 support_system_process: true,
304 },
305 nocrt: true,
306 }
307
308 cc_library {
309 name: "libvndk_sp_private",
310 vendor_available: false,
311 vndk: {
312 enabled: true,
313 support_system_process: true,
314 },
315 nocrt: true,
316 }
Inseob Kim1f086e22019-05-09 13:29:15 +0900317 `, config)
Logan Chienf3511742017-10-31 18:04:35 +0800318
319 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
320 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
321 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
322 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
Inseob Kim1f086e22019-05-09 13:29:15 +0900323
324 // Check VNDK snapshot output.
325
326 snapshotDir := "vndk-snapshot"
327 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
328
329 vndkLibPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
330 "arm64", "armv8-a"))
331 vndkLib2ndPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
332 "arm", "armv7-a-neon"))
333
334 vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core")
335 vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp")
336 vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
337 vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
338
Inseob Kim64c43952019-08-26 16:52:35 +0900339 variant := "android_arm64_armv8-a_vendor.VER_shared"
340 variant2nd := "android_arm_armv7-a-neon_vendor.VER_shared"
Inseob Kim1f086e22019-05-09 13:29:15 +0900341
342 checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLibPath, variant)
343 checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLib2ndPath, variant2nd)
344 checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLibPath, variant)
345 checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLib2ndPath, variant2nd)
Jooyung Han097087b2019-10-22 19:32:18 +0900346
347 checkVndkOutput(t, ctx, "vndk/llndk.libraries.txt", []string{"libc.so", "libdl.so", "libft2.so", "libm.so"})
348 checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{"libvndk.so", "libvndk_private.so"})
349 checkVndkOutput(t, ctx, "vndk/vndkprivate.libraries.txt", []string{"libft2.so", "libvndk_private.so", "libvndk_sp_private.so"})
350 checkVndkOutput(t, ctx, "vndk/vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp.so", "libvndk_sp_private.so"})
351 checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", nil)
352 // merged & tagged & filtered-out(libclang_rt)
353 checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
354 "LLNDK: libc.so",
355 "LLNDK: libdl.so",
356 "LLNDK: libft2.so",
357 "LLNDK: libm.so",
358 "VNDK-SP: libc++.so",
359 "VNDK-SP: libvndk_sp.so",
360 "VNDK-SP: libvndk_sp_private.so",
361 "VNDK-core: libvndk.so",
362 "VNDK-core: libvndk_private.so",
363 "VNDK-private: libft2.so",
364 "VNDK-private: libvndk_private.so",
365 "VNDK-private: libvndk_sp_private.so",
366 })
367}
368
369func TestVndkUsingCoreVariant(t *testing.T) {
370 config := android.TestArchConfig(buildDir, nil)
371 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
372 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
373 config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
374
375 setVndkMustUseVendorVariantListForTest(config, []string{"libvndk"})
376
377 ctx := testCcWithConfig(t, `
378 cc_library {
379 name: "libvndk",
380 vendor_available: true,
381 vndk: {
382 enabled: true,
383 },
384 nocrt: true,
385 }
386
387 cc_library {
388 name: "libvndk_sp",
389 vendor_available: true,
390 vndk: {
391 enabled: true,
392 support_system_process: true,
393 },
394 nocrt: true,
395 }
396
397 cc_library {
398 name: "libvndk2",
399 vendor_available: false,
400 vndk: {
401 enabled: true,
402 },
403 nocrt: true,
404 }
405 `, config)
406
407 checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{"libvndk.so", "libvndk2.so"})
408 checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", []string{"libvndk2.so"})
Logan Chienf3511742017-10-31 18:04:35 +0800409}
410
Logan Chiend3c59a22018-03-29 14:08:15 +0800411func TestVndkDepError(t *testing.T) {
412 // Check whether an error is emitted when a VNDK lib depends on a system lib.
413 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
414 cc_library {
415 name: "libvndk",
416 vendor_available: true,
417 vndk: {
418 enabled: true,
419 },
420 shared_libs: ["libfwk"], // Cause error
421 nocrt: true,
422 }
423
424 cc_library {
425 name: "libfwk",
426 nocrt: true,
427 }
428 `)
429
430 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
431 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
432 cc_library {
433 name: "libvndk",
434 vendor_available: true,
435 vndk: {
436 enabled: true,
437 },
438 shared_libs: ["libvendor"], // Cause error
439 nocrt: true,
440 }
441
442 cc_library {
443 name: "libvendor",
444 vendor: true,
445 nocrt: true,
446 }
447 `)
448
449 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
450 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
451 cc_library {
452 name: "libvndk_sp",
453 vendor_available: true,
454 vndk: {
455 enabled: true,
456 support_system_process: true,
457 },
458 shared_libs: ["libfwk"], // Cause error
459 nocrt: true,
460 }
461
462 cc_library {
463 name: "libfwk",
464 nocrt: true,
465 }
466 `)
467
468 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
469 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
470 cc_library {
471 name: "libvndk_sp",
472 vendor_available: true,
473 vndk: {
474 enabled: true,
475 support_system_process: true,
476 },
477 shared_libs: ["libvendor"], // Cause error
478 nocrt: true,
479 }
480
481 cc_library {
482 name: "libvendor",
483 vendor: true,
484 nocrt: true,
485 }
486 `)
487
488 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
489 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
490 cc_library {
491 name: "libvndk_sp",
492 vendor_available: true,
493 vndk: {
494 enabled: true,
495 support_system_process: true,
496 },
497 shared_libs: ["libvndk"], // Cause error
498 nocrt: true,
499 }
500
501 cc_library {
502 name: "libvndk",
503 vendor_available: true,
504 vndk: {
505 enabled: true,
506 },
507 nocrt: true,
508 }
509 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900510
511 // Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib.
512 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
513 cc_library {
514 name: "libvndk",
515 vendor_available: true,
516 vndk: {
517 enabled: true,
518 },
519 shared_libs: ["libnonvndk"],
520 nocrt: true,
521 }
522
523 cc_library {
524 name: "libnonvndk",
525 vendor_available: true,
526 nocrt: true,
527 }
528 `)
529
530 // Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib.
531 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
532 cc_library {
533 name: "libvndkprivate",
534 vendor_available: false,
535 vndk: {
536 enabled: true,
537 },
538 shared_libs: ["libnonvndk"],
539 nocrt: true,
540 }
541
542 cc_library {
543 name: "libnonvndk",
544 vendor_available: true,
545 nocrt: true,
546 }
547 `)
548
549 // Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib.
550 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
551 cc_library {
552 name: "libvndksp",
553 vendor_available: true,
554 vndk: {
555 enabled: true,
556 support_system_process: true,
557 },
558 shared_libs: ["libnonvndk"],
559 nocrt: true,
560 }
561
562 cc_library {
563 name: "libnonvndk",
564 vendor_available: true,
565 nocrt: true,
566 }
567 `)
568
569 // Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib.
570 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
571 cc_library {
572 name: "libvndkspprivate",
573 vendor_available: false,
574 vndk: {
575 enabled: true,
576 support_system_process: true,
577 },
578 shared_libs: ["libnonvndk"],
579 nocrt: true,
580 }
581
582 cc_library {
583 name: "libnonvndk",
584 vendor_available: true,
585 nocrt: true,
586 }
587 `)
588}
589
590func TestDoubleLoadbleDep(t *testing.T) {
591 // okay to link : LLNDK -> double_loadable VNDK
592 testCc(t, `
593 cc_library {
594 name: "libllndk",
595 shared_libs: ["libdoubleloadable"],
596 }
597
598 llndk_library {
599 name: "libllndk",
600 symbol_file: "",
601 }
602
603 cc_library {
604 name: "libdoubleloadable",
605 vendor_available: true,
606 vndk: {
607 enabled: true,
608 },
609 double_loadable: true,
610 }
611 `)
612 // okay to link : LLNDK -> VNDK-SP
613 testCc(t, `
614 cc_library {
615 name: "libllndk",
616 shared_libs: ["libvndksp"],
617 }
618
619 llndk_library {
620 name: "libllndk",
621 symbol_file: "",
622 }
623
624 cc_library {
625 name: "libvndksp",
626 vendor_available: true,
627 vndk: {
628 enabled: true,
629 support_system_process: true,
630 },
631 }
632 `)
633 // okay to link : double_loadable -> double_loadable
634 testCc(t, `
635 cc_library {
636 name: "libdoubleloadable1",
637 shared_libs: ["libdoubleloadable2"],
638 vendor_available: true,
639 double_loadable: true,
640 }
641
642 cc_library {
643 name: "libdoubleloadable2",
644 vendor_available: true,
645 double_loadable: true,
646 }
647 `)
648 // okay to link : double_loadable VNDK -> double_loadable VNDK private
649 testCc(t, `
650 cc_library {
651 name: "libdoubleloadable",
652 vendor_available: true,
653 vndk: {
654 enabled: true,
655 },
656 double_loadable: true,
657 shared_libs: ["libnondoubleloadable"],
658 }
659
660 cc_library {
661 name: "libnondoubleloadable",
662 vendor_available: false,
663 vndk: {
664 enabled: true,
665 },
666 double_loadable: true,
667 }
668 `)
669 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
670 testCc(t, `
671 cc_library {
672 name: "libllndk",
673 shared_libs: ["libcoreonly"],
674 }
675
676 llndk_library {
677 name: "libllndk",
678 symbol_file: "",
679 }
680
681 cc_library {
682 name: "libcoreonly",
683 shared_libs: ["libvendoravailable"],
684 }
685
686 // indirect dependency of LLNDK
687 cc_library {
688 name: "libvendoravailable",
689 vendor_available: true,
690 double_loadable: true,
691 }
692 `)
693}
694
695func TestDoubleLoadableDepError(t *testing.T) {
696 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
697 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
698 cc_library {
699 name: "libllndk",
700 shared_libs: ["libnondoubleloadable"],
701 }
702
703 llndk_library {
704 name: "libllndk",
705 symbol_file: "",
706 }
707
708 cc_library {
709 name: "libnondoubleloadable",
710 vendor_available: true,
711 vndk: {
712 enabled: true,
713 },
714 }
715 `)
716
717 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
718 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
719 cc_library {
720 name: "libllndk",
Yi Konge7fe9912019-06-02 00:53:50 -0700721 no_libcrt: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900722 shared_libs: ["libnondoubleloadable"],
723 }
724
725 llndk_library {
726 name: "libllndk",
727 symbol_file: "",
728 }
729
730 cc_library {
731 name: "libnondoubleloadable",
732 vendor_available: true,
733 }
734 `)
735
736 // Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable vendor_available lib.
737 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
738 cc_library {
739 name: "libdoubleloadable",
740 vendor_available: true,
741 double_loadable: true,
742 shared_libs: ["libnondoubleloadable"],
743 }
744
745 cc_library {
746 name: "libnondoubleloadable",
747 vendor_available: true,
748 }
749 `)
750
751 // Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable VNDK lib.
752 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
753 cc_library {
754 name: "libdoubleloadable",
755 vendor_available: true,
756 double_loadable: true,
757 shared_libs: ["libnondoubleloadable"],
758 }
759
760 cc_library {
761 name: "libnondoubleloadable",
762 vendor_available: true,
763 vndk: {
764 enabled: true,
765 },
766 }
767 `)
768
769 // Check whether an error is emitted when a double_loadable VNDK depends on a non-double_loadable VNDK private lib.
770 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
771 cc_library {
772 name: "libdoubleloadable",
773 vendor_available: true,
774 vndk: {
775 enabled: true,
776 },
777 double_loadable: true,
778 shared_libs: ["libnondoubleloadable"],
779 }
780
781 cc_library {
782 name: "libnondoubleloadable",
783 vendor_available: false,
784 vndk: {
785 enabled: true,
786 },
787 }
788 `)
789
790 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
791 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
792 cc_library {
793 name: "libllndk",
794 shared_libs: ["libcoreonly"],
795 }
796
797 llndk_library {
798 name: "libllndk",
799 symbol_file: "",
800 }
801
802 cc_library {
803 name: "libcoreonly",
804 shared_libs: ["libvendoravailable"],
805 }
806
807 // indirect dependency of LLNDK
808 cc_library {
809 name: "libvendoravailable",
810 vendor_available: true,
811 }
812 `)
Logan Chiend3c59a22018-03-29 14:08:15 +0800813}
814
Justin Yun9357f4a2018-11-28 15:14:47 +0900815func TestVndkMustNotBeProductSpecific(t *testing.T) {
816 // Check whether an error is emitted when a vndk lib has 'product_specific: true'.
817 testCcError(t, "product_specific must not be true when `vndk: {enabled: true}`", `
818 cc_library {
819 name: "libvndk",
820 product_specific: true, // Cause error
821 vendor_available: true,
822 vndk: {
823 enabled: true,
824 },
825 nocrt: true,
826 }
827 `)
828}
829
Logan Chienf3511742017-10-31 18:04:35 +0800830func TestVndkExt(t *testing.T) {
831 // This test checks the VNDK-Ext properties.
832 ctx := testCc(t, `
833 cc_library {
834 name: "libvndk",
835 vendor_available: true,
836 vndk: {
837 enabled: true,
838 },
839 nocrt: true,
840 }
841
842 cc_library {
843 name: "libvndk_ext",
844 vendor: true,
845 vndk: {
846 enabled: true,
847 extends: "libvndk",
848 },
849 nocrt: true,
850 }
851 `)
852
853 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
854}
855
Logan Chiend3c59a22018-03-29 14:08:15 +0800856func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800857 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
858 ctx := testCcNoVndk(t, `
859 cc_library {
860 name: "libvndk",
861 vendor_available: true,
862 vndk: {
863 enabled: true,
864 },
865 nocrt: true,
866 }
867
868 cc_library {
869 name: "libvndk_ext",
870 vendor: true,
871 vndk: {
872 enabled: true,
873 extends: "libvndk",
874 },
875 nocrt: true,
876 }
877 `)
878
879 // Ensures that the core variant of "libvndk_ext" can be found.
880 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
881 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
882 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
883 }
884}
885
886func TestVndkExtError(t *testing.T) {
887 // This test ensures an error is emitted in ill-formed vndk-ext definition.
888 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
889 cc_library {
890 name: "libvndk",
891 vendor_available: true,
892 vndk: {
893 enabled: true,
894 },
895 nocrt: true,
896 }
897
898 cc_library {
899 name: "libvndk_ext",
900 vndk: {
901 enabled: true,
902 extends: "libvndk",
903 },
904 nocrt: true,
905 }
906 `)
907
908 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
909 cc_library {
910 name: "libvndk",
911 vendor_available: true,
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 },
924 nocrt: true,
925 }
926 `)
927}
928
929func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
930 // This test ensures an error is emitted for inconsistent support_system_process.
931 testCcError(t, "module \".*\" with mismatched support_system_process", `
932 cc_library {
933 name: "libvndk",
934 vendor_available: true,
935 vndk: {
936 enabled: true,
937 },
938 nocrt: true,
939 }
940
941 cc_library {
942 name: "libvndk_sp_ext",
943 vendor: true,
944 vndk: {
945 enabled: true,
946 extends: "libvndk",
947 support_system_process: true,
948 },
949 nocrt: true,
950 }
951 `)
952
953 testCcError(t, "module \".*\" with mismatched support_system_process", `
954 cc_library {
955 name: "libvndk_sp",
956 vendor_available: true,
957 vndk: {
958 enabled: true,
959 support_system_process: true,
960 },
961 nocrt: true,
962 }
963
964 cc_library {
965 name: "libvndk_ext",
966 vendor: true,
967 vndk: {
968 enabled: true,
969 extends: "libvndk_sp",
970 },
971 nocrt: true,
972 }
973 `)
974}
975
976func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800977 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800978 // with `vendor_available: false`.
979 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
980 cc_library {
981 name: "libvndk",
982 vendor_available: false,
983 vndk: {
984 enabled: true,
985 },
986 nocrt: true,
987 }
988
989 cc_library {
990 name: "libvndk_ext",
991 vendor: true,
992 vndk: {
993 enabled: true,
994 extends: "libvndk",
995 },
996 nocrt: true,
997 }
998 `)
999}
1000
Logan Chiend3c59a22018-03-29 14:08:15 +08001001func TestVendorModuleUseVndkExt(t *testing.T) {
1002 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +08001003 testCc(t, `
1004 cc_library {
1005 name: "libvndk",
1006 vendor_available: true,
1007 vndk: {
1008 enabled: true,
1009 },
1010 nocrt: true,
1011 }
1012
1013 cc_library {
1014 name: "libvndk_ext",
1015 vendor: true,
1016 vndk: {
1017 enabled: true,
1018 extends: "libvndk",
1019 },
1020 nocrt: true,
1021 }
1022
1023 cc_library {
1024
1025 name: "libvndk_sp",
1026 vendor_available: true,
1027 vndk: {
1028 enabled: true,
1029 support_system_process: true,
1030 },
1031 nocrt: true,
1032 }
1033
1034 cc_library {
1035 name: "libvndk_sp_ext",
1036 vendor: true,
1037 vndk: {
1038 enabled: true,
1039 extends: "libvndk_sp",
1040 support_system_process: true,
1041 },
1042 nocrt: true,
1043 }
1044
1045 cc_library {
1046 name: "libvendor",
1047 vendor: true,
1048 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
1049 nocrt: true,
1050 }
1051 `)
1052}
1053
Logan Chiend3c59a22018-03-29 14:08:15 +08001054func TestVndkExtUseVendorLib(t *testing.T) {
1055 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +08001056 testCc(t, `
1057 cc_library {
1058 name: "libvndk",
1059 vendor_available: true,
1060 vndk: {
1061 enabled: true,
1062 },
1063 nocrt: true,
1064 }
1065
1066 cc_library {
1067 name: "libvndk_ext",
1068 vendor: true,
1069 vndk: {
1070 enabled: true,
1071 extends: "libvndk",
1072 },
1073 shared_libs: ["libvendor"],
1074 nocrt: true,
1075 }
1076
1077 cc_library {
1078 name: "libvendor",
1079 vendor: true,
1080 nocrt: true,
1081 }
1082 `)
Logan Chienf3511742017-10-31 18:04:35 +08001083
Logan Chiend3c59a22018-03-29 14:08:15 +08001084 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
1085 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +08001086 cc_library {
1087 name: "libvndk_sp",
1088 vendor_available: true,
1089 vndk: {
1090 enabled: true,
1091 support_system_process: true,
1092 },
1093 nocrt: true,
1094 }
1095
1096 cc_library {
1097 name: "libvndk_sp_ext",
1098 vendor: true,
1099 vndk: {
1100 enabled: true,
1101 extends: "libvndk_sp",
1102 support_system_process: true,
1103 },
1104 shared_libs: ["libvendor"], // Cause an error
1105 nocrt: true,
1106 }
1107
1108 cc_library {
1109 name: "libvendor",
1110 vendor: true,
1111 nocrt: true,
1112 }
1113 `)
1114}
1115
Logan Chiend3c59a22018-03-29 14:08:15 +08001116func TestVndkSpExtUseVndkError(t *testing.T) {
1117 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
1118 // library.
1119 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1120 cc_library {
1121 name: "libvndk",
1122 vendor_available: true,
1123 vndk: {
1124 enabled: true,
1125 },
1126 nocrt: true,
1127 }
1128
1129 cc_library {
1130 name: "libvndk_sp",
1131 vendor_available: true,
1132 vndk: {
1133 enabled: true,
1134 support_system_process: true,
1135 },
1136 nocrt: true,
1137 }
1138
1139 cc_library {
1140 name: "libvndk_sp_ext",
1141 vendor: true,
1142 vndk: {
1143 enabled: true,
1144 extends: "libvndk_sp",
1145 support_system_process: true,
1146 },
1147 shared_libs: ["libvndk"], // Cause an error
1148 nocrt: true,
1149 }
1150 `)
1151
1152 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
1153 // library.
1154 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1155 cc_library {
1156 name: "libvndk",
1157 vendor_available: true,
1158 vndk: {
1159 enabled: true,
1160 },
1161 nocrt: true,
1162 }
1163
1164 cc_library {
1165 name: "libvndk_ext",
1166 vendor: true,
1167 vndk: {
1168 enabled: true,
1169 extends: "libvndk",
1170 },
1171 nocrt: true,
1172 }
1173
1174 cc_library {
1175 name: "libvndk_sp",
1176 vendor_available: true,
1177 vndk: {
1178 enabled: true,
1179 support_system_process: true,
1180 },
1181 nocrt: true,
1182 }
1183
1184 cc_library {
1185 name: "libvndk_sp_ext",
1186 vendor: true,
1187 vndk: {
1188 enabled: true,
1189 extends: "libvndk_sp",
1190 support_system_process: true,
1191 },
1192 shared_libs: ["libvndk_ext"], // Cause an error
1193 nocrt: true,
1194 }
1195 `)
1196}
1197
1198func TestVndkUseVndkExtError(t *testing.T) {
1199 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
1200 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +08001201 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1202 cc_library {
1203 name: "libvndk",
1204 vendor_available: true,
1205 vndk: {
1206 enabled: true,
1207 },
1208 nocrt: true,
1209 }
1210
1211 cc_library {
1212 name: "libvndk_ext",
1213 vendor: true,
1214 vndk: {
1215 enabled: true,
1216 extends: "libvndk",
1217 },
1218 nocrt: true,
1219 }
1220
1221 cc_library {
1222 name: "libvndk2",
1223 vendor_available: true,
1224 vndk: {
1225 enabled: true,
1226 },
1227 shared_libs: ["libvndk_ext"],
1228 nocrt: true,
1229 }
1230 `)
1231
Martin Stjernholmef449fe2018-11-06 16:12:13 +00001232 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +08001233 cc_library {
1234 name: "libvndk",
1235 vendor_available: true,
1236 vndk: {
1237 enabled: true,
1238 },
1239 nocrt: true,
1240 }
1241
1242 cc_library {
1243 name: "libvndk_ext",
1244 vendor: true,
1245 vndk: {
1246 enabled: true,
1247 extends: "libvndk",
1248 },
1249 nocrt: true,
1250 }
1251
1252 cc_library {
1253 name: "libvndk2",
1254 vendor_available: true,
1255 vndk: {
1256 enabled: true,
1257 },
1258 target: {
1259 vendor: {
1260 shared_libs: ["libvndk_ext"],
1261 },
1262 },
1263 nocrt: true,
1264 }
1265 `)
1266
1267 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1268 cc_library {
1269 name: "libvndk_sp",
1270 vendor_available: true,
1271 vndk: {
1272 enabled: true,
1273 support_system_process: true,
1274 },
1275 nocrt: true,
1276 }
1277
1278 cc_library {
1279 name: "libvndk_sp_ext",
1280 vendor: true,
1281 vndk: {
1282 enabled: true,
1283 extends: "libvndk_sp",
1284 support_system_process: true,
1285 },
1286 nocrt: true,
1287 }
1288
1289 cc_library {
1290 name: "libvndk_sp_2",
1291 vendor_available: true,
1292 vndk: {
1293 enabled: true,
1294 support_system_process: true,
1295 },
1296 shared_libs: ["libvndk_sp_ext"],
1297 nocrt: true,
1298 }
1299 `)
1300
Martin Stjernholmef449fe2018-11-06 16:12:13 +00001301 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +08001302 cc_library {
1303 name: "libvndk_sp",
1304 vendor_available: true,
1305 vndk: {
1306 enabled: true,
1307 },
1308 nocrt: true,
1309 }
1310
1311 cc_library {
1312 name: "libvndk_sp_ext",
1313 vendor: true,
1314 vndk: {
1315 enabled: true,
1316 extends: "libvndk_sp",
1317 },
1318 nocrt: true,
1319 }
1320
1321 cc_library {
1322 name: "libvndk_sp2",
1323 vendor_available: true,
1324 vndk: {
1325 enabled: true,
1326 },
1327 target: {
1328 vendor: {
1329 shared_libs: ["libvndk_sp_ext"],
1330 },
1331 },
1332 nocrt: true,
1333 }
1334 `)
1335}
1336
Jooyung Han38002912019-05-16 04:01:54 +09001337func TestMakeLinkType(t *testing.T) {
1338 config := android.TestArchConfig(buildDir, nil)
1339 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1340 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
1341 // native:vndk
1342 ctx := testCcWithConfig(t, `
1343 cc_library {
1344 name: "libvndk",
1345 vendor_available: true,
1346 vndk: {
1347 enabled: true,
1348 },
1349 }
1350 cc_library {
1351 name: "libvndksp",
1352 vendor_available: true,
1353 vndk: {
1354 enabled: true,
1355 support_system_process: true,
1356 },
1357 }
1358 cc_library {
1359 name: "libvndkprivate",
1360 vendor_available: false,
1361 vndk: {
1362 enabled: true,
1363 },
1364 }
1365 cc_library {
1366 name: "libvendor",
1367 vendor: true,
1368 }
1369 cc_library {
1370 name: "libvndkext",
1371 vendor: true,
1372 vndk: {
1373 enabled: true,
1374 extends: "libvndk",
1375 },
1376 }
1377 vndk_prebuilt_shared {
1378 name: "prevndk",
1379 version: "27",
1380 target_arch: "arm",
1381 binder32bit: true,
1382 vendor_available: true,
1383 vndk: {
1384 enabled: true,
1385 },
1386 arch: {
1387 arm: {
1388 srcs: ["liba.so"],
1389 },
1390 },
1391 }
1392 cc_library {
1393 name: "libllndk",
1394 }
1395 llndk_library {
1396 name: "libllndk",
1397 symbol_file: "",
1398 }
1399 cc_library {
1400 name: "libllndkprivate",
1401 }
1402 llndk_library {
1403 name: "libllndkprivate",
1404 vendor_available: false,
1405 symbol_file: "",
1406 }`, config)
1407
1408 assertArrayString(t, *vndkCoreLibraries(config),
1409 []string{"libvndk", "libvndkprivate"})
1410 assertArrayString(t, *vndkSpLibraries(config),
1411 []string{"libc++", "libvndksp"})
1412 assertArrayString(t, *llndkLibraries(config),
Jooyung Han097087b2019-10-22 19:32:18 +09001413 []string{"libc", "libdl", "libft2", "libllndk", "libllndkprivate", "libm"})
Jooyung Han38002912019-05-16 04:01:54 +09001414 assertArrayString(t, *vndkPrivateLibraries(config),
Jooyung Han097087b2019-10-22 19:32:18 +09001415 []string{"libft2", "libllndkprivate", "libvndkprivate"})
Jooyung Han38002912019-05-16 04:01:54 +09001416
Inseob Kim64c43952019-08-26 16:52:35 +09001417 vendorVariant27 := "android_arm64_armv8-a_vendor.27_shared"
1418
Jooyung Han38002912019-05-16 04:01:54 +09001419 tests := []struct {
1420 variant string
1421 name string
1422 expected string
1423 }{
1424 {vendorVariant, "libvndk", "native:vndk"},
1425 {vendorVariant, "libvndksp", "native:vndk"},
1426 {vendorVariant, "libvndkprivate", "native:vndk_private"},
1427 {vendorVariant, "libvendor", "native:vendor"},
1428 {vendorVariant, "libvndkext", "native:vendor"},
Jooyung Han38002912019-05-16 04:01:54 +09001429 {vendorVariant, "libllndk.llndk", "native:vndk"},
Inseob Kim64c43952019-08-26 16:52:35 +09001430 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
Jooyung Han38002912019-05-16 04:01:54 +09001431 {coreVariant, "libvndk", "native:platform"},
1432 {coreVariant, "libvndkprivate", "native:platform"},
1433 {coreVariant, "libllndk", "native:platform"},
1434 }
1435 for _, test := range tests {
1436 t.Run(test.name, func(t *testing.T) {
1437 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
1438 assertString(t, module.makeLinkType, test.expected)
1439 })
1440 }
1441}
1442
Colin Cross0af4b842015-04-30 16:36:18 -07001443var (
1444 str11 = "01234567891"
1445 str10 = str11[:10]
1446 str9 = str11[:9]
1447 str5 = str11[:5]
1448 str4 = str11[:4]
1449)
1450
1451var splitListForSizeTestCases = []struct {
1452 in []string
1453 out [][]string
1454 size int
1455}{
1456 {
1457 in: []string{str10},
1458 out: [][]string{{str10}},
1459 size: 10,
1460 },
1461 {
1462 in: []string{str9},
1463 out: [][]string{{str9}},
1464 size: 10,
1465 },
1466 {
1467 in: []string{str5},
1468 out: [][]string{{str5}},
1469 size: 10,
1470 },
1471 {
1472 in: []string{str11},
1473 out: nil,
1474 size: 10,
1475 },
1476 {
1477 in: []string{str10, str10},
1478 out: [][]string{{str10}, {str10}},
1479 size: 10,
1480 },
1481 {
1482 in: []string{str9, str10},
1483 out: [][]string{{str9}, {str10}},
1484 size: 10,
1485 },
1486 {
1487 in: []string{str10, str9},
1488 out: [][]string{{str10}, {str9}},
1489 size: 10,
1490 },
1491 {
1492 in: []string{str5, str4},
1493 out: [][]string{{str5, str4}},
1494 size: 10,
1495 },
1496 {
1497 in: []string{str5, str4, str5},
1498 out: [][]string{{str5, str4}, {str5}},
1499 size: 10,
1500 },
1501 {
1502 in: []string{str5, str4, str5, str4},
1503 out: [][]string{{str5, str4}, {str5, str4}},
1504 size: 10,
1505 },
1506 {
1507 in: []string{str5, str4, str5, str5},
1508 out: [][]string{{str5, str4}, {str5}, {str5}},
1509 size: 10,
1510 },
1511 {
1512 in: []string{str5, str5, str5, str4},
1513 out: [][]string{{str5}, {str5}, {str5, str4}},
1514 size: 10,
1515 },
1516 {
1517 in: []string{str9, str11},
1518 out: nil,
1519 size: 10,
1520 },
1521 {
1522 in: []string{str11, str9},
1523 out: nil,
1524 size: 10,
1525 },
1526}
1527
1528func TestSplitListForSize(t *testing.T) {
1529 for _, testCase := range splitListForSizeTestCases {
Colin Cross40e33732019-02-15 11:08:35 -08001530 out, _ := splitListForSize(android.PathsForTesting(testCase.in...), testCase.size)
Colin Cross5b529592017-05-09 13:34:34 -07001531
1532 var outStrings [][]string
1533
1534 if len(out) > 0 {
1535 outStrings = make([][]string, len(out))
1536 for i, o := range out {
1537 outStrings[i] = o.Strings()
1538 }
1539 }
1540
1541 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001542 t.Errorf("incorrect output:")
1543 t.Errorf(" input: %#v", testCase.in)
1544 t.Errorf(" size: %d", testCase.size)
1545 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001546 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001547 }
1548 }
1549}
Jeff Gaston294356f2017-09-27 17:05:30 -07001550
1551var staticLinkDepOrderTestCases = []struct {
1552 // This is a string representation of a map[moduleName][]moduleDependency .
1553 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001554 inStatic string
1555
1556 // This is a string representation of a map[moduleName][]moduleDependency .
1557 // It models the dependencies declared in an Android.bp file.
1558 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001559
1560 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1561 // The keys of allOrdered specify which modules we would like to check.
1562 // The values of allOrdered specify the expected result (of the transitive closure of all
1563 // dependencies) for each module to test
1564 allOrdered string
1565
1566 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1567 // The keys of outOrdered specify which modules we would like to check.
1568 // The values of outOrdered specify the expected result (of the ordered linker command line)
1569 // for each module to test.
1570 outOrdered string
1571}{
1572 // Simple tests
1573 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001574 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001575 outOrdered: "",
1576 },
1577 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001578 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001579 outOrdered: "a:",
1580 },
1581 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001582 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001583 outOrdered: "a:b; b:",
1584 },
1585 // Tests of reordering
1586 {
1587 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001588 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001589 outOrdered: "a:b,c,d; b:d; c:d; d:",
1590 },
1591 {
1592 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001593 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001594 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1595 },
1596 {
1597 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001598 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001599 outOrdered: "a:d,b,e,c; d:b; e:c",
1600 },
1601 {
1602 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001603 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001604 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1605 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1606 },
1607 {
1608 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001609 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 -07001610 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1611 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1612 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001613 // shared dependencies
1614 {
1615 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1616 // So, we don't actually have to check that a shared dependency of c will change the order
1617 // of a library that depends statically on b and on c. We only need to check that if c has
1618 // a shared dependency on b, that that shows up in allOrdered.
1619 inShared: "c:b",
1620 allOrdered: "c:b",
1621 outOrdered: "c:",
1622 },
1623 {
1624 // This test doesn't actually include any shared dependencies but it's a reminder of what
1625 // the second phase of the above test would look like
1626 inStatic: "a:b,c; c:b",
1627 allOrdered: "a:c,b; c:b",
1628 outOrdered: "a:c,b; c:b",
1629 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001630 // tiebreakers for when two modules specifying different orderings and there is no dependency
1631 // to dictate an order
1632 {
1633 // 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 -08001634 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001635 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1636 },
1637 {
1638 // 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 -08001639 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 -07001640 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1641 },
1642 // Tests involving duplicate dependencies
1643 {
1644 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001645 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001646 outOrdered: "a:c,b",
1647 },
1648 {
1649 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001650 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001651 outOrdered: "a:d,c,b",
1652 },
1653 // Tests to confirm the nonexistence of infinite loops.
1654 // These cases should never happen, so as long as the test terminates and the
1655 // result is deterministic then that should be fine.
1656 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001657 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001658 outOrdered: "a:a",
1659 },
1660 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001661 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001662 allOrdered: "a:b,c; b:c,a; c:a,b",
1663 outOrdered: "a:b; b:c; c:a",
1664 },
1665 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001666 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001667 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1668 outOrdered: "a:c,b; b:a,c; c:b,a",
1669 },
1670}
1671
1672// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1673func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1674 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1675 strippedText := strings.Replace(text, " ", "", -1)
1676 if len(strippedText) < 1 {
1677 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1678 }
1679 allDeps = make(map[android.Path][]android.Path, 0)
1680
1681 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1682 moduleTexts := strings.Split(strippedText, ";")
1683
1684 outputForModuleName := func(moduleName string) android.Path {
1685 return android.PathForTesting(moduleName)
1686 }
1687
1688 for _, moduleText := range moduleTexts {
1689 // convert from "a:b,c" to ["a", "b,c"]
1690 components := strings.Split(moduleText, ":")
1691 if len(components) != 2 {
1692 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1693 }
1694 moduleName := components[0]
1695 moduleOutput := outputForModuleName(moduleName)
1696 modulesInOrder = append(modulesInOrder, moduleOutput)
1697
1698 depString := components[1]
1699 // convert from "b,c" to ["b", "c"]
1700 depNames := strings.Split(depString, ",")
1701 if len(depString) < 1 {
1702 depNames = []string{}
1703 }
1704 var deps []android.Path
1705 for _, depName := range depNames {
1706 deps = append(deps, outputForModuleName(depName))
1707 }
1708 allDeps[moduleOutput] = deps
1709 }
1710 return modulesInOrder, allDeps
1711}
1712
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001713func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001714 for _, testCase := range staticLinkDepOrderTestCases {
1715 errs := []string{}
1716
1717 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001718 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001719 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1720 if testCase.allOrdered == "" {
1721 // allow the test case to skip specifying allOrdered
1722 testCase.allOrdered = testCase.outOrdered
1723 }
1724 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001725 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001726
1727 // For each module whose post-reordered dependencies were specified, validate that
1728 // reordering the inputs produces the expected outputs.
1729 for _, moduleName := range expectedModuleNames {
1730 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001731 givenSharedDeps := givenAllSharedDeps[moduleName]
1732 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001733
1734 correctAllOrdered := expectedAllDeps[moduleName]
1735 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1736 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001737 "\nin static:%q"+
1738 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001739 "\nmodule: %v"+
1740 "\nexpected: %s"+
1741 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001742 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001743 }
1744
1745 correctOutputDeps := expectedTransitiveDeps[moduleName]
1746 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1747 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001748 "\nin static:%q"+
1749 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001750 "\nmodule: %v"+
1751 "\nexpected: %s"+
1752 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001753 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001754 }
1755 }
1756
1757 if len(errs) > 0 {
1758 sort.Strings(errs)
1759 for _, err := range errs {
1760 t.Error(err)
1761 }
1762 }
1763 }
1764}
Logan Chienf3511742017-10-31 18:04:35 +08001765
Jeff Gaston294356f2017-09-27 17:05:30 -07001766func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1767 for _, moduleName := range moduleNames {
1768 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1769 output := module.outputFile.Path()
1770 paths = append(paths, output)
1771 }
1772 return paths
1773}
1774
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001775func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001776 ctx := testCc(t, `
1777 cc_library {
1778 name: "a",
1779 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001780 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001781 }
1782 cc_library {
1783 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001784 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001785 }
1786 cc_library {
1787 name: "c",
1788 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001789 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001790 }
1791 cc_library {
1792 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001793 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001794 }
1795
1796 `)
1797
1798 variant := "android_arm64_armv8-a_core_static"
1799 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001800 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001801 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1802
1803 if !reflect.DeepEqual(actual, expected) {
1804 t.Errorf("staticDeps orderings were not propagated correctly"+
1805 "\nactual: %v"+
1806 "\nexpected: %v",
1807 actual,
1808 expected,
1809 )
1810 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001811}
Jeff Gaston294356f2017-09-27 17:05:30 -07001812
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001813func TestStaticLibDepReorderingWithShared(t *testing.T) {
1814 ctx := testCc(t, `
1815 cc_library {
1816 name: "a",
1817 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001818 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001819 }
1820 cc_library {
1821 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001822 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001823 }
1824 cc_library {
1825 name: "c",
1826 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001827 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001828 }
1829
1830 `)
1831
1832 variant := "android_arm64_armv8-a_core_static"
1833 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1834 actual := moduleA.depsInLinkOrder
1835 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1836
1837 if !reflect.DeepEqual(actual, expected) {
1838 t.Errorf("staticDeps orderings did not account for shared libs"+
1839 "\nactual: %v"+
1840 "\nexpected: %v",
1841 actual,
1842 expected,
1843 )
1844 }
1845}
1846
Jiyong Parka46a4d52017-12-14 19:54:34 +09001847func TestLlndkHeaders(t *testing.T) {
1848 ctx := testCc(t, `
1849 llndk_headers {
1850 name: "libllndk_headers",
1851 export_include_dirs: ["my_include"],
1852 }
1853 llndk_library {
1854 name: "libllndk",
1855 export_llndk_headers: ["libllndk_headers"],
1856 }
1857 cc_library {
1858 name: "libvendor",
1859 shared_libs: ["libllndk"],
1860 vendor: true,
1861 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001862 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001863 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001864 }
1865 `)
1866
1867 // _static variant is used since _shared reuses *.o from the static variant
Inseob Kim64c43952019-08-26 16:52:35 +09001868 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor.VER_static").Rule("cc")
Jiyong Parka46a4d52017-12-14 19:54:34 +09001869 cflags := cc.Args["cFlags"]
1870 if !strings.Contains(cflags, "-Imy_include") {
1871 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1872 }
1873}
1874
Logan Chien43d34c32017-12-20 01:17:32 +08001875func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1876 actual := module.Properties.AndroidMkRuntimeLibs
1877 if !reflect.DeepEqual(actual, expected) {
1878 t.Errorf("incorrect runtime_libs for shared libs"+
1879 "\nactual: %v"+
1880 "\nexpected: %v",
1881 actual,
1882 expected,
1883 )
1884 }
1885}
1886
1887const runtimeLibAndroidBp = `
1888 cc_library {
1889 name: "libvendor_available1",
1890 vendor_available: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001891 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001892 nocrt : true,
1893 system_shared_libs : [],
1894 }
1895 cc_library {
1896 name: "libvendor_available2",
1897 vendor_available: true,
1898 runtime_libs: ["libvendor_available1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001899 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001900 nocrt : true,
1901 system_shared_libs : [],
1902 }
1903 cc_library {
1904 name: "libvendor_available3",
1905 vendor_available: true,
1906 runtime_libs: ["libvendor_available1"],
1907 target: {
1908 vendor: {
1909 exclude_runtime_libs: ["libvendor_available1"],
1910 }
1911 },
Yi Konge7fe9912019-06-02 00:53:50 -07001912 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001913 nocrt : true,
1914 system_shared_libs : [],
1915 }
1916 cc_library {
1917 name: "libcore",
1918 runtime_libs: ["libvendor_available1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001919 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001920 nocrt : true,
1921 system_shared_libs : [],
1922 }
1923 cc_library {
1924 name: "libvendor1",
1925 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001926 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001927 nocrt : true,
1928 system_shared_libs : [],
1929 }
1930 cc_library {
1931 name: "libvendor2",
1932 vendor: true,
1933 runtime_libs: ["libvendor_available1", "libvendor1"],
Yi Konge7fe9912019-06-02 00:53:50 -07001934 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001935 nocrt : true,
1936 system_shared_libs : [],
1937 }
1938`
1939
1940func TestRuntimeLibs(t *testing.T) {
1941 ctx := testCc(t, runtimeLibAndroidBp)
1942
1943 // runtime_libs for core variants use the module names without suffixes.
1944 variant := "android_arm64_armv8-a_core_shared"
1945
1946 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1947 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1948
1949 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1950 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1951
1952 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1953 // and vendor variants.
Inseob Kim64c43952019-08-26 16:52:35 +09001954 variant = "android_arm64_armv8-a_vendor.VER_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001955
1956 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1957 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1958
1959 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1960 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1961}
1962
1963func TestExcludeRuntimeLibs(t *testing.T) {
1964 ctx := testCc(t, runtimeLibAndroidBp)
1965
1966 variant := "android_arm64_armv8-a_core_shared"
1967 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1968 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1969
Inseob Kim64c43952019-08-26 16:52:35 +09001970 variant = "android_arm64_armv8-a_vendor.VER_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001971 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1972 checkRuntimeLibs(t, nil, module)
1973}
1974
1975func TestRuntimeLibsNoVndk(t *testing.T) {
1976 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1977
1978 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1979
1980 variant := "android_arm64_armv8-a_core_shared"
1981
1982 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1983 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1984
1985 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1986 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1987}
1988
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001989func checkStaticLibs(t *testing.T, expected []string, module *Module) {
1990 actual := module.Properties.AndroidMkStaticLibs
1991 if !reflect.DeepEqual(actual, expected) {
1992 t.Errorf("incorrect static_libs"+
1993 "\nactual: %v"+
1994 "\nexpected: %v",
1995 actual,
1996 expected,
1997 )
1998 }
1999}
2000
2001const staticLibAndroidBp = `
2002 cc_library {
2003 name: "lib1",
2004 }
2005 cc_library {
2006 name: "lib2",
2007 static_libs: ["lib1"],
2008 }
2009`
2010
2011func TestStaticLibDepExport(t *testing.T) {
2012 ctx := testCc(t, staticLibAndroidBp)
2013
2014 // Check the shared version of lib2.
2015 variant := "android_arm64_armv8-a_core_shared"
2016 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Dan Albert2da19cb2019-07-24 12:17:40 -07002017 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00002018
2019 // Check the static version of lib2.
2020 variant = "android_arm64_armv8-a_core_static"
2021 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
2022 // libc++_static is linked additionally.
Dan Albert2da19cb2019-07-24 12:17:40 -07002023 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00002024}
2025
Jiyong Parkd08b6972017-09-26 10:50:54 +09002026var compilerFlagsTestCases = []struct {
2027 in string
2028 out bool
2029}{
2030 {
2031 in: "a",
2032 out: false,
2033 },
2034 {
2035 in: "-a",
2036 out: true,
2037 },
2038 {
2039 in: "-Ipath/to/something",
2040 out: false,
2041 },
2042 {
2043 in: "-isystempath/to/something",
2044 out: false,
2045 },
2046 {
2047 in: "--coverage",
2048 out: false,
2049 },
2050 {
2051 in: "-include a/b",
2052 out: true,
2053 },
2054 {
2055 in: "-include a/b c/d",
2056 out: false,
2057 },
2058 {
2059 in: "-DMACRO",
2060 out: true,
2061 },
2062 {
2063 in: "-DMAC RO",
2064 out: false,
2065 },
2066 {
2067 in: "-a -b",
2068 out: false,
2069 },
2070 {
2071 in: "-DMACRO=definition",
2072 out: true,
2073 },
2074 {
2075 in: "-DMACRO=defi nition",
2076 out: true, // TODO(jiyong): this should be false
2077 },
2078 {
2079 in: "-DMACRO(x)=x + 1",
2080 out: true,
2081 },
2082 {
2083 in: "-DMACRO=\"defi nition\"",
2084 out: true,
2085 },
2086}
2087
2088type mockContext struct {
2089 BaseModuleContext
2090 result bool
2091}
2092
2093func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
2094 // CheckBadCompilerFlags calls this function when the flag should be rejected
2095 ctx.result = false
2096}
2097
2098func TestCompilerFlags(t *testing.T) {
2099 for _, testCase := range compilerFlagsTestCases {
2100 ctx := &mockContext{result: true}
2101 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
2102 if ctx.result != testCase.out {
2103 t.Errorf("incorrect output:")
2104 t.Errorf(" input: %#v", testCase.in)
2105 t.Errorf(" expected: %#v", testCase.out)
2106 t.Errorf(" got: %#v", ctx.result)
2107 }
2108 }
Jeff Gaston294356f2017-09-27 17:05:30 -07002109}
Jiyong Park374510b2018-03-19 18:23:01 +09002110
2111func TestVendorPublicLibraries(t *testing.T) {
2112 ctx := testCc(t, `
2113 cc_library_headers {
2114 name: "libvendorpublic_headers",
2115 export_include_dirs: ["my_include"],
2116 }
2117 vendor_public_library {
2118 name: "libvendorpublic",
2119 symbol_file: "",
2120 export_public_headers: ["libvendorpublic_headers"],
2121 }
2122 cc_library {
2123 name: "libvendorpublic",
2124 srcs: ["foo.c"],
2125 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07002126 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002127 nocrt: true,
2128 }
2129
2130 cc_library {
2131 name: "libsystem",
2132 shared_libs: ["libvendorpublic"],
2133 vendor: false,
2134 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07002135 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002136 nocrt: true,
2137 }
2138 cc_library {
2139 name: "libvendor",
2140 shared_libs: ["libvendorpublic"],
2141 vendor: true,
2142 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07002143 no_libcrt: true,
Jiyong Park374510b2018-03-19 18:23:01 +09002144 nocrt: true,
2145 }
2146 `)
2147
2148 variant := "android_arm64_armv8-a_core_shared"
2149
2150 // test if header search paths are correctly added
2151 // _static variant is used since _shared reuses *.o from the static variant
2152 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
2153 cflags := cc.Args["cFlags"]
2154 if !strings.Contains(cflags, "-Imy_include") {
2155 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
2156 }
2157
2158 // test if libsystem is linked to the stub
2159 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
2160 libflags := ld.Args["libFlags"]
2161 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
2162 if !strings.Contains(libflags, stubPaths[0].String()) {
2163 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
2164 }
2165
2166 // test if libvendor is linked to the real shared lib
Inseob Kim64c43952019-08-26 16:52:35 +09002167 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor.VER", 1)).Rule("ld")
Jiyong Park374510b2018-03-19 18:23:01 +09002168 libflags = ld.Args["libFlags"]
Inseob Kim64c43952019-08-26 16:52:35 +09002169 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor.VER", 1), []string{"libvendorpublic"})
Jiyong Park374510b2018-03-19 18:23:01 +09002170 if !strings.Contains(libflags, stubPaths[0].String()) {
2171 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
2172 }
2173
2174}
Jiyong Park37b25202018-07-11 10:49:27 +09002175
2176func TestRecovery(t *testing.T) {
2177 ctx := testCc(t, `
2178 cc_library_shared {
2179 name: "librecovery",
2180 recovery: true,
2181 }
2182 cc_library_shared {
2183 name: "librecovery32",
2184 recovery: true,
2185 compile_multilib:"32",
2186 }
Jiyong Park5baac542018-08-28 09:55:37 +09002187 cc_library_shared {
2188 name: "libHalInRecovery",
2189 recovery_available: true,
2190 vendor: true,
2191 }
Jiyong Park37b25202018-07-11 10:49:27 +09002192 `)
2193
2194 variants := ctx.ModuleVariantsForTests("librecovery")
2195 const arm64 = "android_arm64_armv8-a_recovery_shared"
2196 if len(variants) != 1 || !android.InList(arm64, variants) {
2197 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
2198 }
2199
2200 variants = ctx.ModuleVariantsForTests("librecovery32")
2201 if android.InList(arm64, variants) {
2202 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
2203 }
Jiyong Park5baac542018-08-28 09:55:37 +09002204
2205 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
2206 if !recoveryModule.Platform() {
2207 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
2208 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09002209}
Jiyong Park5baac542018-08-28 09:55:37 +09002210
Jiyong Park7ed9de32018-10-15 22:25:07 +09002211func TestVersionedStubs(t *testing.T) {
2212 ctx := testCc(t, `
2213 cc_library_shared {
2214 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002215 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002216 stubs: {
2217 symbol_file: "foo.map.txt",
2218 versions: ["1", "2", "3"],
2219 },
2220 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002221
Jiyong Park7ed9de32018-10-15 22:25:07 +09002222 cc_library_shared {
2223 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09002224 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09002225 shared_libs: ["libFoo#1"],
2226 }`)
2227
2228 variants := ctx.ModuleVariantsForTests("libFoo")
2229 expectedVariants := []string{
2230 "android_arm64_armv8-a_core_shared",
2231 "android_arm64_armv8-a_core_shared_1",
2232 "android_arm64_armv8-a_core_shared_2",
2233 "android_arm64_armv8-a_core_shared_3",
2234 "android_arm_armv7-a-neon_core_shared",
2235 "android_arm_armv7-a-neon_core_shared_1",
2236 "android_arm_armv7-a-neon_core_shared_2",
2237 "android_arm_armv7-a-neon_core_shared_3",
2238 }
2239 variantsMismatch := false
2240 if len(variants) != len(expectedVariants) {
2241 variantsMismatch = true
2242 } else {
2243 for _, v := range expectedVariants {
2244 if !inList(v, variants) {
2245 variantsMismatch = false
2246 }
2247 }
2248 }
2249 if variantsMismatch {
2250 t.Errorf("variants of libFoo expected:\n")
2251 for _, v := range expectedVariants {
2252 t.Errorf("%q\n", v)
2253 }
2254 t.Errorf(", but got:\n")
2255 for _, v := range variants {
2256 t.Errorf("%q\n", v)
2257 }
2258 }
2259
2260 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld")
2261 libFlags := libBarLinkRule.Args["libFlags"]
2262 libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so"
2263 if !strings.Contains(libFlags, libFoo1StubPath) {
2264 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
2265 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09002266
2267 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("cc")
2268 cFlags := libBarCompileRule.Args["cFlags"]
2269 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
2270 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
2271 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
2272 }
Jiyong Park37b25202018-07-11 10:49:27 +09002273}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002274
2275func TestStaticExecutable(t *testing.T) {
2276 ctx := testCc(t, `
2277 cc_binary {
2278 name: "static_test",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +01002279 srcs: ["foo.c", "baz.o"],
Jaewoong Jung232c07c2018-12-18 11:08:25 -08002280 static_executable: true,
2281 }`)
2282
2283 variant := "android_arm64_armv8-a_core"
2284 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
2285 libFlags := binModuleRule.Args["libFlags"]
2286 systemStaticLibs := []string{"libc.a", "libm.a", "libdl.a"}
2287 for _, lib := range systemStaticLibs {
2288 if !strings.Contains(libFlags, lib) {
2289 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
2290 }
2291 }
2292 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
2293 for _, lib := range systemSharedLibs {
2294 if strings.Contains(libFlags, lib) {
2295 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
2296 }
2297 }
2298}
Jiyong Parke4bb9862019-02-01 00:31:10 +09002299
2300func TestStaticDepsOrderWithStubs(t *testing.T) {
2301 ctx := testCc(t, `
2302 cc_binary {
2303 name: "mybin",
2304 srcs: ["foo.c"],
2305 static_libs: ["libB"],
2306 static_executable: true,
2307 stl: "none",
2308 }
2309
2310 cc_library {
2311 name: "libB",
2312 srcs: ["foo.c"],
2313 shared_libs: ["libC"],
2314 stl: "none",
2315 }
2316
2317 cc_library {
2318 name: "libC",
2319 srcs: ["foo.c"],
2320 stl: "none",
2321 stubs: {
2322 versions: ["1"],
2323 },
2324 }`)
2325
2326 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a_core").Module().(*Module)
2327 actual := mybin.depsInLinkOrder
2328 expected := getOutputPaths(ctx, "android_arm64_armv8-a_core_static", []string{"libB", "libC"})
2329
2330 if !reflect.DeepEqual(actual, expected) {
2331 t.Errorf("staticDeps orderings were not propagated correctly"+
2332 "\nactual: %v"+
2333 "\nexpected: %v",
2334 actual,
2335 expected,
2336 )
2337 }
2338}
Jooyung Han38002912019-05-16 04:01:54 +09002339
Jooyung Hand48f3c32019-08-23 11:18:57 +09002340func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
2341 testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
2342 cc_library {
2343 name: "libA",
2344 srcs: ["foo.c"],
2345 shared_libs: ["libB"],
2346 stl: "none",
2347 }
2348
2349 cc_library {
2350 name: "libB",
2351 srcs: ["foo.c"],
2352 enabled: false,
2353 stl: "none",
2354 }
2355 `)
2356}
2357
Mitch Phillipsda9a4632019-07-15 09:34:09 -07002358// Simple smoke test for the cc_fuzz target that ensures the rule compiles
2359// correctly.
2360func TestFuzzTarget(t *testing.T) {
2361 ctx := testCc(t, `
2362 cc_fuzz {
2363 name: "fuzz_smoke_test",
2364 srcs: ["foo.c"],
2365 }`)
2366
2367 variant := "android_arm64_armv8-a_core"
2368 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
2369}
2370
Jiyong Park29074592019-07-07 16:27:47 +09002371func TestAidl(t *testing.T) {
2372}
2373
Jooyung Han38002912019-05-16 04:01:54 +09002374func assertString(t *testing.T, got, expected string) {
2375 t.Helper()
2376 if got != expected {
2377 t.Errorf("expected %q got %q", expected, got)
2378 }
2379}
2380
2381func assertArrayString(t *testing.T, got, expected []string) {
2382 t.Helper()
2383 if len(got) != len(expected) {
2384 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
2385 return
2386 }
2387 for i := range got {
2388 if got[i] != expected[i] {
2389 t.Errorf("expected %d-th %q (%q) got %q (%q)",
2390 i, expected[i], expected, got[i], got)
2391 return
2392 }
2393 }
2394}
Colin Crosse1bb5d02019-09-24 14:55:04 -07002395
2396func TestDefaults(t *testing.T) {
2397 ctx := testCc(t, `
2398 cc_defaults {
2399 name: "defaults",
2400 srcs: ["foo.c"],
2401 static: {
2402 srcs: ["bar.c"],
2403 },
2404 shared: {
2405 srcs: ["baz.c"],
2406 },
2407 }
2408
2409 cc_library_static {
2410 name: "libstatic",
2411 defaults: ["defaults"],
2412 }
2413
2414 cc_library_shared {
2415 name: "libshared",
2416 defaults: ["defaults"],
2417 }
2418
2419 cc_library {
2420 name: "libboth",
2421 defaults: ["defaults"],
2422 }
2423
2424 cc_binary {
2425 name: "binary",
2426 defaults: ["defaults"],
2427 }`)
2428
2429 pathsToBase := func(paths android.Paths) []string {
2430 var ret []string
2431 for _, p := range paths {
2432 ret = append(ret, p.Base())
2433 }
2434 return ret
2435 }
2436
2437 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_core_shared").Rule("ld")
2438 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2439 t.Errorf("libshared ld rule wanted %q, got %q", w, g)
2440 }
2441 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_core_shared").Rule("ld")
2442 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2443 t.Errorf("libboth ld rule wanted %q, got %q", w, g)
2444 }
2445 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a_core").Rule("ld")
2446 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
2447 t.Errorf("binary ld rule wanted %q, got %q", w, g)
2448 }
2449
2450 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_core_static").Rule("ar")
2451 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2452 t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
2453 }
2454 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_core_static").Rule("ar")
2455 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2456 t.Errorf("libboth ar rule wanted %q, got %q", w, g)
2457 }
2458}