blob: 3d162e7e87e9a571c1d01e7e04b9444786ab8900 [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"
Colin Cross74d1ec02015-04-28 13:30:13 -070023 "reflect"
Jeff Gaston294356f2017-09-27 17:05:30 -070024 "sort"
25 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070026 "testing"
27)
28
Jiyong Park6a43f042017-10-12 23:05:00 +090029var buildDir string
30
31func setUp() {
32 var err error
33 buildDir, err = ioutil.TempDir("", "soong_cc_test")
34 if err != nil {
35 panic(err)
36 }
37}
38
39func tearDown() {
40 os.RemoveAll(buildDir)
41}
42
43func TestMain(m *testing.M) {
44 run := func() int {
45 setUp()
46 defer tearDown()
47
48 return m.Run()
49 }
50
51 os.Exit(run())
52}
53
Logan Chienf3511742017-10-31 18:04:35 +080054func createTestContext(t *testing.T, config android.Config, bp string) *android.TestContext {
Jiyong Park6a43f042017-10-12 23:05:00 +090055 ctx := android.NewTestArchContext()
Steven Morelandf9e62162017-11-02 17:00:50 -070056 ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory))
Colin Crossf18e1102017-11-16 14:33:08 -080057 ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory))
Jiyong Park374510b2018-03-19 18:23:01 +090058 ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory))
Jiyong Park6a43f042017-10-12 23:05:00 +090059 ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(toolchainLibraryFactory))
60 ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(llndkLibraryFactory))
Jiyong Parka46a4d52017-12-14 19:54:34 +090061 ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory))
Jiyong Park374510b2018-03-19 18:23:01 +090062 ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
Jeff Gaston294356f2017-09-27 17:05:30 -070063 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(objectFactory))
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -070064 ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
Jiyong Park6a43f042017-10-12 23:05:00 +090065 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
Jiyong Parkf9332f12018-02-01 00:54:12 +090066 ctx.BottomUp("image", imageMutator).Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +090067 ctx.BottomUp("link", linkageMutator).Parallel()
68 ctx.BottomUp("vndk", vndkMutator).Parallel()
Jiyong Park374510b2018-03-19 18:23:01 +090069 ctx.BottomUp("begin", beginMutator).Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +090070 })
71 ctx.Register()
72
Jeff Gaston294356f2017-09-27 17:05:30 -070073 // add some modules that are required by the compiler and/or linker
74 bp = bp + `
75 toolchain_library {
76 name: "libatomic",
77 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +090078 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -070079 }
80
81 toolchain_library {
82 name: "libcompiler_rt-extras",
83 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +090084 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -070085 }
86
87 toolchain_library {
88 name: "libgcc",
89 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +090090 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -070091 }
92
93 cc_library {
94 name: "libc",
Logan Chienf3511742017-10-31 18:04:35 +080095 no_libgcc: true,
96 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -070097 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +090098 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -070099 }
100 llndk_library {
101 name: "libc",
102 symbol_file: "",
103 }
104 cc_library {
105 name: "libm",
Logan Chienf3511742017-10-31 18:04:35 +0800106 no_libgcc: true,
107 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700108 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900109 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700110 }
111 llndk_library {
112 name: "libm",
113 symbol_file: "",
114 }
115 cc_library {
116 name: "libdl",
Logan Chienf3511742017-10-31 18:04:35 +0800117 no_libgcc: true,
118 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700119 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900120 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700121 }
122 llndk_library {
123 name: "libdl",
124 symbol_file: "",
125 }
Jiyong Park374510b2018-03-19 18:23:01 +0900126 cc_library {
127 name: "libc++_static",
128 no_libgcc: true,
129 nocrt: true,
130 system_shared_libs: [],
131 stl: "none",
132 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900133 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900134 }
135 cc_library {
136 name: "libc++",
137 no_libgcc: true,
138 nocrt: true,
139 system_shared_libs: [],
140 stl: "none",
141 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900142 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900143 vndk: {
144 enabled: true,
145 support_system_process: true,
146 },
147 }
148 cc_library {
149 name: "libunwind_llvm",
150 no_libgcc: true,
151 nocrt: true,
152 system_shared_libs: [],
153 stl: "none",
154 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900155 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900156 }
Jeff Gaston294356f2017-09-27 17:05:30 -0700157
158 cc_object {
159 name: "crtbegin_so",
Jiyong Park37b25202018-07-11 10:49:27 +0900160 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700161 }
162
163 cc_object {
164 name: "crtend_so",
Jiyong Park37b25202018-07-11 10:49:27 +0900165 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700166 }
167
Colin Crossad59e752017-11-16 14:29:11 -0800168 cc_library {
169 name: "libprotobuf-cpp-lite",
170 }
171
Jeff Gaston294356f2017-09-27 17:05:30 -0700172`
173
Jiyong Park6a43f042017-10-12 23:05:00 +0900174 ctx.MockFileSystem(map[string][]byte{
175 "Android.bp": []byte(bp),
176 "foo.c": nil,
177 "bar.c": nil,
Colin Crossad59e752017-11-16 14:29:11 -0800178 "a.proto": nil,
Colin Crossf18e1102017-11-16 14:33:08 -0800179 "b.aidl": nil,
Jiyong Parka46a4d52017-12-14 19:54:34 +0900180 "my_include": nil,
Jiyong Park6a43f042017-10-12 23:05:00 +0900181 })
182
Logan Chienf3511742017-10-31 18:04:35 +0800183 return ctx
184}
185
186func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800187 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800188 ctx := createTestContext(t, config, bp)
189
Jeff Gastond3e141d2017-08-08 17:46:01 -0700190 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +0800191 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900192 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800193 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900194
195 return ctx
196}
197
Logan Chienf3511742017-10-31 18:04:35 +0800198func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800199 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800200 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700201 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
202 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800203
204 return testCcWithConfig(t, bp, config)
205}
206
207func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800208 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800209 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700210 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800211
212 return testCcWithConfig(t, bp, config)
213}
214
215func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800216 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800217 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700218 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
219 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800220
221 ctx := createTestContext(t, config, bp)
222
223 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
224 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800225 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800226 return
227 }
228
229 _, errs = ctx.PrepareBuildActions(config)
230 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800231 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800232 return
233 }
234
235 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
236}
237
238const (
239 coreVariant = "android_arm64_armv8-a_core_shared"
240 vendorVariant = "android_arm64_armv8-a_vendor_shared"
241)
242
Jiyong Park6a43f042017-10-12 23:05:00 +0900243func TestVendorSrc(t *testing.T) {
244 ctx := testCc(t, `
245 cc_library {
246 name: "libTest",
247 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800248 no_libgcc: true,
249 nocrt: true,
250 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900251 vendor_available: true,
252 target: {
253 vendor: {
254 srcs: ["bar.c"],
255 },
256 },
257 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900258 `)
259
Logan Chienf3511742017-10-31 18:04:35 +0800260 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900261 var objs []string
262 for _, o := range ld.Inputs {
263 objs = append(objs, o.Base())
264 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800265 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900266 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
267 }
268}
269
Logan Chienf3511742017-10-31 18:04:35 +0800270func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
271 isVndkSp bool, extends string) {
272
Logan Chiend3c59a22018-03-29 14:08:15 +0800273 t.Helper()
274
Logan Chienf3511742017-10-31 18:04:35 +0800275 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
276 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700277 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800278 }
279
280 // Check library properties.
281 lib, ok := mod.compiler.(*libraryDecorator)
282 if !ok {
283 t.Errorf("%q must have libraryDecorator", name)
284 } else if lib.baseInstaller.subDir != subDir {
285 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
286 lib.baseInstaller.subDir)
287 }
288
289 // Check VNDK properties.
290 if mod.vndkdep == nil {
291 t.Fatalf("%q must have `vndkdep`", name)
292 }
293 if !mod.isVndk() {
294 t.Errorf("%q isVndk() must equal to true", name)
295 }
296 if mod.isVndkSp() != isVndkSp {
297 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
298 }
299
300 // Check VNDK extension properties.
301 isVndkExt := extends != ""
302 if mod.isVndkExt() != isVndkExt {
303 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
304 }
305
306 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
307 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
308 }
309}
310
311func TestVndk(t *testing.T) {
312 ctx := testCc(t, `
313 cc_library {
314 name: "libvndk",
315 vendor_available: true,
316 vndk: {
317 enabled: true,
318 },
319 nocrt: true,
320 }
321
322 cc_library {
323 name: "libvndk_private",
324 vendor_available: false,
325 vndk: {
326 enabled: true,
327 },
328 nocrt: true,
329 }
330
331 cc_library {
332 name: "libvndk_sp",
333 vendor_available: true,
334 vndk: {
335 enabled: true,
336 support_system_process: true,
337 },
338 nocrt: true,
339 }
340
341 cc_library {
342 name: "libvndk_sp_private",
343 vendor_available: false,
344 vndk: {
345 enabled: true,
346 support_system_process: true,
347 },
348 nocrt: true,
349 }
350 `)
351
352 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
353 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
354 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
355 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
356}
357
Logan Chiend3c59a22018-03-29 14:08:15 +0800358func TestVndkDepError(t *testing.T) {
359 // Check whether an error is emitted when a VNDK lib depends on a system 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: ["libfwk"], // Cause error
368 nocrt: true,
369 }
370
371 cc_library {
372 name: "libfwk",
373 nocrt: true,
374 }
375 `)
376
377 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
378 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
379 cc_library {
380 name: "libvndk",
381 vendor_available: true,
382 vndk: {
383 enabled: true,
384 },
385 shared_libs: ["libvendor"], // Cause error
386 nocrt: true,
387 }
388
389 cc_library {
390 name: "libvendor",
391 vendor: true,
392 nocrt: true,
393 }
394 `)
395
396 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
397 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
398 cc_library {
399 name: "libvndk_sp",
400 vendor_available: true,
401 vndk: {
402 enabled: true,
403 support_system_process: true,
404 },
405 shared_libs: ["libfwk"], // Cause error
406 nocrt: true,
407 }
408
409 cc_library {
410 name: "libfwk",
411 nocrt: true,
412 }
413 `)
414
415 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
416 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
417 cc_library {
418 name: "libvndk_sp",
419 vendor_available: true,
420 vndk: {
421 enabled: true,
422 support_system_process: true,
423 },
424 shared_libs: ["libvendor"], // Cause error
425 nocrt: true,
426 }
427
428 cc_library {
429 name: "libvendor",
430 vendor: true,
431 nocrt: true,
432 }
433 `)
434
435 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
436 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
437 cc_library {
438 name: "libvndk_sp",
439 vendor_available: true,
440 vndk: {
441 enabled: true,
442 support_system_process: true,
443 },
444 shared_libs: ["libvndk"], // Cause error
445 nocrt: true,
446 }
447
448 cc_library {
449 name: "libvndk",
450 vendor_available: true,
451 vndk: {
452 enabled: true,
453 },
454 nocrt: true,
455 }
456 `)
457}
458
Logan Chienf3511742017-10-31 18:04:35 +0800459func TestVndkExt(t *testing.T) {
460 // This test checks the VNDK-Ext properties.
461 ctx := testCc(t, `
462 cc_library {
463 name: "libvndk",
464 vendor_available: true,
465 vndk: {
466 enabled: true,
467 },
468 nocrt: true,
469 }
470
471 cc_library {
472 name: "libvndk_ext",
473 vendor: true,
474 vndk: {
475 enabled: true,
476 extends: "libvndk",
477 },
478 nocrt: true,
479 }
480 `)
481
482 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
483}
484
Logan Chiend3c59a22018-03-29 14:08:15 +0800485func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800486 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
487 ctx := testCcNoVndk(t, `
488 cc_library {
489 name: "libvndk",
490 vendor_available: true,
491 vndk: {
492 enabled: true,
493 },
494 nocrt: true,
495 }
496
497 cc_library {
498 name: "libvndk_ext",
499 vendor: true,
500 vndk: {
501 enabled: true,
502 extends: "libvndk",
503 },
504 nocrt: true,
505 }
506 `)
507
508 // Ensures that the core variant of "libvndk_ext" can be found.
509 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
510 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
511 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
512 }
513}
514
515func TestVndkExtError(t *testing.T) {
516 // This test ensures an error is emitted in ill-formed vndk-ext definition.
517 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
518 cc_library {
519 name: "libvndk",
520 vendor_available: true,
521 vndk: {
522 enabled: true,
523 },
524 nocrt: true,
525 }
526
527 cc_library {
528 name: "libvndk_ext",
529 vndk: {
530 enabled: true,
531 extends: "libvndk",
532 },
533 nocrt: true,
534 }
535 `)
536
537 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
538 cc_library {
539 name: "libvndk",
540 vendor_available: true,
541 vndk: {
542 enabled: true,
543 },
544 nocrt: true,
545 }
546
547 cc_library {
548 name: "libvndk_ext",
549 vendor: true,
550 vndk: {
551 enabled: true,
552 },
553 nocrt: true,
554 }
555 `)
556}
557
558func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
559 // This test ensures an error is emitted for inconsistent support_system_process.
560 testCcError(t, "module \".*\" with mismatched support_system_process", `
561 cc_library {
562 name: "libvndk",
563 vendor_available: true,
564 vndk: {
565 enabled: true,
566 },
567 nocrt: true,
568 }
569
570 cc_library {
571 name: "libvndk_sp_ext",
572 vendor: true,
573 vndk: {
574 enabled: true,
575 extends: "libvndk",
576 support_system_process: true,
577 },
578 nocrt: true,
579 }
580 `)
581
582 testCcError(t, "module \".*\" with mismatched support_system_process", `
583 cc_library {
584 name: "libvndk_sp",
585 vendor_available: true,
586 vndk: {
587 enabled: true,
588 support_system_process: true,
589 },
590 nocrt: true,
591 }
592
593 cc_library {
594 name: "libvndk_ext",
595 vendor: true,
596 vndk: {
597 enabled: true,
598 extends: "libvndk_sp",
599 },
600 nocrt: true,
601 }
602 `)
603}
604
605func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800606 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800607 // with `vendor_available: false`.
608 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
609 cc_library {
610 name: "libvndk",
611 vendor_available: false,
612 vndk: {
613 enabled: true,
614 },
615 nocrt: true,
616 }
617
618 cc_library {
619 name: "libvndk_ext",
620 vendor: true,
621 vndk: {
622 enabled: true,
623 extends: "libvndk",
624 },
625 nocrt: true,
626 }
627 `)
628}
629
Logan Chiend3c59a22018-03-29 14:08:15 +0800630func TestVendorModuleUseVndkExt(t *testing.T) {
631 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800632 testCc(t, `
633 cc_library {
634 name: "libvndk",
635 vendor_available: true,
636 vndk: {
637 enabled: true,
638 },
639 nocrt: true,
640 }
641
642 cc_library {
643 name: "libvndk_ext",
644 vendor: true,
645 vndk: {
646 enabled: true,
647 extends: "libvndk",
648 },
649 nocrt: true,
650 }
651
652 cc_library {
653
654 name: "libvndk_sp",
655 vendor_available: true,
656 vndk: {
657 enabled: true,
658 support_system_process: true,
659 },
660 nocrt: true,
661 }
662
663 cc_library {
664 name: "libvndk_sp_ext",
665 vendor: true,
666 vndk: {
667 enabled: true,
668 extends: "libvndk_sp",
669 support_system_process: true,
670 },
671 nocrt: true,
672 }
673
674 cc_library {
675 name: "libvendor",
676 vendor: true,
677 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
678 nocrt: true,
679 }
680 `)
681}
682
Logan Chiend3c59a22018-03-29 14:08:15 +0800683func TestVndkExtUseVendorLib(t *testing.T) {
684 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800685 testCc(t, `
686 cc_library {
687 name: "libvndk",
688 vendor_available: true,
689 vndk: {
690 enabled: true,
691 },
692 nocrt: true,
693 }
694
695 cc_library {
696 name: "libvndk_ext",
697 vendor: true,
698 vndk: {
699 enabled: true,
700 extends: "libvndk",
701 },
702 shared_libs: ["libvendor"],
703 nocrt: true,
704 }
705
706 cc_library {
707 name: "libvendor",
708 vendor: true,
709 nocrt: true,
710 }
711 `)
Logan Chienf3511742017-10-31 18:04:35 +0800712
Logan Chiend3c59a22018-03-29 14:08:15 +0800713 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
714 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800715 cc_library {
716 name: "libvndk_sp",
717 vendor_available: true,
718 vndk: {
719 enabled: true,
720 support_system_process: true,
721 },
722 nocrt: true,
723 }
724
725 cc_library {
726 name: "libvndk_sp_ext",
727 vendor: true,
728 vndk: {
729 enabled: true,
730 extends: "libvndk_sp",
731 support_system_process: true,
732 },
733 shared_libs: ["libvendor"], // Cause an error
734 nocrt: true,
735 }
736
737 cc_library {
738 name: "libvendor",
739 vendor: true,
740 nocrt: true,
741 }
742 `)
743}
744
Logan Chiend3c59a22018-03-29 14:08:15 +0800745func TestVndkSpExtUseVndkError(t *testing.T) {
746 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
747 // library.
748 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
749 cc_library {
750 name: "libvndk",
751 vendor_available: true,
752 vndk: {
753 enabled: true,
754 },
755 nocrt: true,
756 }
757
758 cc_library {
759 name: "libvndk_sp",
760 vendor_available: true,
761 vndk: {
762 enabled: true,
763 support_system_process: true,
764 },
765 nocrt: true,
766 }
767
768 cc_library {
769 name: "libvndk_sp_ext",
770 vendor: true,
771 vndk: {
772 enabled: true,
773 extends: "libvndk_sp",
774 support_system_process: true,
775 },
776 shared_libs: ["libvndk"], // Cause an error
777 nocrt: true,
778 }
779 `)
780
781 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
782 // library.
783 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
784 cc_library {
785 name: "libvndk",
786 vendor_available: true,
787 vndk: {
788 enabled: true,
789 },
790 nocrt: true,
791 }
792
793 cc_library {
794 name: "libvndk_ext",
795 vendor: true,
796 vndk: {
797 enabled: true,
798 extends: "libvndk",
799 },
800 nocrt: true,
801 }
802
803 cc_library {
804 name: "libvndk_sp",
805 vendor_available: true,
806 vndk: {
807 enabled: true,
808 support_system_process: true,
809 },
810 nocrt: true,
811 }
812
813 cc_library {
814 name: "libvndk_sp_ext",
815 vendor: true,
816 vndk: {
817 enabled: true,
818 extends: "libvndk_sp",
819 support_system_process: true,
820 },
821 shared_libs: ["libvndk_ext"], // Cause an error
822 nocrt: true,
823 }
824 `)
825}
826
827func TestVndkUseVndkExtError(t *testing.T) {
828 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
829 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800830 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
831 cc_library {
832 name: "libvndk",
833 vendor_available: true,
834 vndk: {
835 enabled: true,
836 },
837 nocrt: true,
838 }
839
840 cc_library {
841 name: "libvndk_ext",
842 vendor: true,
843 vndk: {
844 enabled: true,
845 extends: "libvndk",
846 },
847 nocrt: true,
848 }
849
850 cc_library {
851 name: "libvndk2",
852 vendor_available: true,
853 vndk: {
854 enabled: true,
855 },
856 shared_libs: ["libvndk_ext"],
857 nocrt: true,
858 }
859 `)
860
861 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
862 // but target.vendor.shared_libs has not been supported yet.
863 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
864 cc_library {
865 name: "libvndk",
866 vendor_available: true,
867 vndk: {
868 enabled: true,
869 },
870 nocrt: true,
871 }
872
873 cc_library {
874 name: "libvndk_ext",
875 vendor: true,
876 vndk: {
877 enabled: true,
878 extends: "libvndk",
879 },
880 nocrt: true,
881 }
882
883 cc_library {
884 name: "libvndk2",
885 vendor_available: true,
886 vndk: {
887 enabled: true,
888 },
889 target: {
890 vendor: {
891 shared_libs: ["libvndk_ext"],
892 },
893 },
894 nocrt: true,
895 }
896 `)
897
898 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
899 cc_library {
900 name: "libvndk_sp",
901 vendor_available: true,
902 vndk: {
903 enabled: true,
904 support_system_process: true,
905 },
906 nocrt: true,
907 }
908
909 cc_library {
910 name: "libvndk_sp_ext",
911 vendor: true,
912 vndk: {
913 enabled: true,
914 extends: "libvndk_sp",
915 support_system_process: true,
916 },
917 nocrt: true,
918 }
919
920 cc_library {
921 name: "libvndk_sp_2",
922 vendor_available: true,
923 vndk: {
924 enabled: true,
925 support_system_process: true,
926 },
927 shared_libs: ["libvndk_sp_ext"],
928 nocrt: true,
929 }
930 `)
931
932 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
933 // but target.vendor.shared_libs has not been supported yet.
934 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
935 cc_library {
936 name: "libvndk_sp",
937 vendor_available: true,
938 vndk: {
939 enabled: true,
940 },
941 nocrt: true,
942 }
943
944 cc_library {
945 name: "libvndk_sp_ext",
946 vendor: true,
947 vndk: {
948 enabled: true,
949 extends: "libvndk_sp",
950 },
951 nocrt: true,
952 }
953
954 cc_library {
955 name: "libvndk_sp2",
956 vendor_available: true,
957 vndk: {
958 enabled: true,
959 },
960 target: {
961 vendor: {
962 shared_libs: ["libvndk_sp_ext"],
963 },
964 },
965 nocrt: true,
966 }
967 `)
968}
969
Colin Cross0af4b842015-04-30 16:36:18 -0700970var (
971 str11 = "01234567891"
972 str10 = str11[:10]
973 str9 = str11[:9]
974 str5 = str11[:5]
975 str4 = str11[:4]
976)
977
978var splitListForSizeTestCases = []struct {
979 in []string
980 out [][]string
981 size int
982}{
983 {
984 in: []string{str10},
985 out: [][]string{{str10}},
986 size: 10,
987 },
988 {
989 in: []string{str9},
990 out: [][]string{{str9}},
991 size: 10,
992 },
993 {
994 in: []string{str5},
995 out: [][]string{{str5}},
996 size: 10,
997 },
998 {
999 in: []string{str11},
1000 out: nil,
1001 size: 10,
1002 },
1003 {
1004 in: []string{str10, str10},
1005 out: [][]string{{str10}, {str10}},
1006 size: 10,
1007 },
1008 {
1009 in: []string{str9, str10},
1010 out: [][]string{{str9}, {str10}},
1011 size: 10,
1012 },
1013 {
1014 in: []string{str10, str9},
1015 out: [][]string{{str10}, {str9}},
1016 size: 10,
1017 },
1018 {
1019 in: []string{str5, str4},
1020 out: [][]string{{str5, str4}},
1021 size: 10,
1022 },
1023 {
1024 in: []string{str5, str4, str5},
1025 out: [][]string{{str5, str4}, {str5}},
1026 size: 10,
1027 },
1028 {
1029 in: []string{str5, str4, str5, str4},
1030 out: [][]string{{str5, str4}, {str5, str4}},
1031 size: 10,
1032 },
1033 {
1034 in: []string{str5, str4, str5, str5},
1035 out: [][]string{{str5, str4}, {str5}, {str5}},
1036 size: 10,
1037 },
1038 {
1039 in: []string{str5, str5, str5, str4},
1040 out: [][]string{{str5}, {str5}, {str5, str4}},
1041 size: 10,
1042 },
1043 {
1044 in: []string{str9, str11},
1045 out: nil,
1046 size: 10,
1047 },
1048 {
1049 in: []string{str11, str9},
1050 out: nil,
1051 size: 10,
1052 },
1053}
1054
1055func TestSplitListForSize(t *testing.T) {
1056 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -07001057 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
1058
1059 var outStrings [][]string
1060
1061 if len(out) > 0 {
1062 outStrings = make([][]string, len(out))
1063 for i, o := range out {
1064 outStrings[i] = o.Strings()
1065 }
1066 }
1067
1068 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001069 t.Errorf("incorrect output:")
1070 t.Errorf(" input: %#v", testCase.in)
1071 t.Errorf(" size: %d", testCase.size)
1072 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001073 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001074 }
1075 }
1076}
Jeff Gaston294356f2017-09-27 17:05:30 -07001077
1078var staticLinkDepOrderTestCases = []struct {
1079 // This is a string representation of a map[moduleName][]moduleDependency .
1080 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001081 inStatic string
1082
1083 // This is a string representation of a map[moduleName][]moduleDependency .
1084 // It models the dependencies declared in an Android.bp file.
1085 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001086
1087 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1088 // The keys of allOrdered specify which modules we would like to check.
1089 // The values of allOrdered specify the expected result (of the transitive closure of all
1090 // dependencies) for each module to test
1091 allOrdered string
1092
1093 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1094 // The keys of outOrdered specify which modules we would like to check.
1095 // The values of outOrdered specify the expected result (of the ordered linker command line)
1096 // for each module to test.
1097 outOrdered string
1098}{
1099 // Simple tests
1100 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001101 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001102 outOrdered: "",
1103 },
1104 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001105 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001106 outOrdered: "a:",
1107 },
1108 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001109 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001110 outOrdered: "a:b; b:",
1111 },
1112 // Tests of reordering
1113 {
1114 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001115 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001116 outOrdered: "a:b,c,d; b:d; c:d; d:",
1117 },
1118 {
1119 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001120 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001121 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1122 },
1123 {
1124 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001125 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001126 outOrdered: "a:d,b,e,c; d:b; e:c",
1127 },
1128 {
1129 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001130 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001131 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1132 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1133 },
1134 {
1135 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001136 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 -07001137 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1138 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1139 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001140 // shared dependencies
1141 {
1142 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1143 // So, we don't actually have to check that a shared dependency of c will change the order
1144 // of a library that depends statically on b and on c. We only need to check that if c has
1145 // a shared dependency on b, that that shows up in allOrdered.
1146 inShared: "c:b",
1147 allOrdered: "c:b",
1148 outOrdered: "c:",
1149 },
1150 {
1151 // This test doesn't actually include any shared dependencies but it's a reminder of what
1152 // the second phase of the above test would look like
1153 inStatic: "a:b,c; c:b",
1154 allOrdered: "a:c,b; c:b",
1155 outOrdered: "a:c,b; c:b",
1156 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001157 // tiebreakers for when two modules specifying different orderings and there is no dependency
1158 // to dictate an order
1159 {
1160 // 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 -08001161 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001162 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1163 },
1164 {
1165 // 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 -08001166 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 -07001167 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1168 },
1169 // Tests involving duplicate dependencies
1170 {
1171 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001172 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001173 outOrdered: "a:c,b",
1174 },
1175 {
1176 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001177 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001178 outOrdered: "a:d,c,b",
1179 },
1180 // Tests to confirm the nonexistence of infinite loops.
1181 // These cases should never happen, so as long as the test terminates and the
1182 // result is deterministic then that should be fine.
1183 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001184 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001185 outOrdered: "a:a",
1186 },
1187 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001188 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001189 allOrdered: "a:b,c; b:c,a; c:a,b",
1190 outOrdered: "a:b; b:c; c:a",
1191 },
1192 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001193 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001194 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1195 outOrdered: "a:c,b; b:a,c; c:b,a",
1196 },
1197}
1198
1199// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1200func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1201 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1202 strippedText := strings.Replace(text, " ", "", -1)
1203 if len(strippedText) < 1 {
1204 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1205 }
1206 allDeps = make(map[android.Path][]android.Path, 0)
1207
1208 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1209 moduleTexts := strings.Split(strippedText, ";")
1210
1211 outputForModuleName := func(moduleName string) android.Path {
1212 return android.PathForTesting(moduleName)
1213 }
1214
1215 for _, moduleText := range moduleTexts {
1216 // convert from "a:b,c" to ["a", "b,c"]
1217 components := strings.Split(moduleText, ":")
1218 if len(components) != 2 {
1219 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1220 }
1221 moduleName := components[0]
1222 moduleOutput := outputForModuleName(moduleName)
1223 modulesInOrder = append(modulesInOrder, moduleOutput)
1224
1225 depString := components[1]
1226 // convert from "b,c" to ["b", "c"]
1227 depNames := strings.Split(depString, ",")
1228 if len(depString) < 1 {
1229 depNames = []string{}
1230 }
1231 var deps []android.Path
1232 for _, depName := range depNames {
1233 deps = append(deps, outputForModuleName(depName))
1234 }
1235 allDeps[moduleOutput] = deps
1236 }
1237 return modulesInOrder, allDeps
1238}
1239
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001240func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001241 for _, testCase := range staticLinkDepOrderTestCases {
1242 errs := []string{}
1243
1244 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001245 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001246 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1247 if testCase.allOrdered == "" {
1248 // allow the test case to skip specifying allOrdered
1249 testCase.allOrdered = testCase.outOrdered
1250 }
1251 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001252 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001253
1254 // For each module whose post-reordered dependencies were specified, validate that
1255 // reordering the inputs produces the expected outputs.
1256 for _, moduleName := range expectedModuleNames {
1257 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001258 givenSharedDeps := givenAllSharedDeps[moduleName]
1259 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001260
1261 correctAllOrdered := expectedAllDeps[moduleName]
1262 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1263 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001264 "\nin static:%q"+
1265 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001266 "\nmodule: %v"+
1267 "\nexpected: %s"+
1268 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001269 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001270 }
1271
1272 correctOutputDeps := expectedTransitiveDeps[moduleName]
1273 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1274 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001275 "\nin static:%q"+
1276 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001277 "\nmodule: %v"+
1278 "\nexpected: %s"+
1279 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001280 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001281 }
1282 }
1283
1284 if len(errs) > 0 {
1285 sort.Strings(errs)
1286 for _, err := range errs {
1287 t.Error(err)
1288 }
1289 }
1290 }
1291}
Logan Chienf3511742017-10-31 18:04:35 +08001292
Jeff Gaston294356f2017-09-27 17:05:30 -07001293func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1294 for _, moduleName := range moduleNames {
1295 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1296 output := module.outputFile.Path()
1297 paths = append(paths, output)
1298 }
1299 return paths
1300}
1301
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001302func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001303 ctx := testCc(t, `
1304 cc_library {
1305 name: "a",
1306 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001307 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001308 }
1309 cc_library {
1310 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001311 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001312 }
1313 cc_library {
1314 name: "c",
1315 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001316 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001317 }
1318 cc_library {
1319 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001320 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001321 }
1322
1323 `)
1324
1325 variant := "android_arm64_armv8-a_core_static"
1326 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001327 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001328 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1329
1330 if !reflect.DeepEqual(actual, expected) {
1331 t.Errorf("staticDeps orderings were not propagated correctly"+
1332 "\nactual: %v"+
1333 "\nexpected: %v",
1334 actual,
1335 expected,
1336 )
1337 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001338}
Jeff Gaston294356f2017-09-27 17:05:30 -07001339
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001340func TestStaticLibDepReorderingWithShared(t *testing.T) {
1341 ctx := testCc(t, `
1342 cc_library {
1343 name: "a",
1344 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001345 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001346 }
1347 cc_library {
1348 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001349 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001350 }
1351 cc_library {
1352 name: "c",
1353 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001354 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001355 }
1356
1357 `)
1358
1359 variant := "android_arm64_armv8-a_core_static"
1360 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1361 actual := moduleA.depsInLinkOrder
1362 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1363
1364 if !reflect.DeepEqual(actual, expected) {
1365 t.Errorf("staticDeps orderings did not account for shared libs"+
1366 "\nactual: %v"+
1367 "\nexpected: %v",
1368 actual,
1369 expected,
1370 )
1371 }
1372}
1373
Jiyong Parka46a4d52017-12-14 19:54:34 +09001374func TestLlndkHeaders(t *testing.T) {
1375 ctx := testCc(t, `
1376 llndk_headers {
1377 name: "libllndk_headers",
1378 export_include_dirs: ["my_include"],
1379 }
1380 llndk_library {
1381 name: "libllndk",
1382 export_llndk_headers: ["libllndk_headers"],
1383 }
1384 cc_library {
1385 name: "libvendor",
1386 shared_libs: ["libllndk"],
1387 vendor: true,
1388 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001389 no_libgcc: true,
1390 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001391 }
1392 `)
1393
1394 // _static variant is used since _shared reuses *.o from the static variant
1395 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1396 cflags := cc.Args["cFlags"]
1397 if !strings.Contains(cflags, "-Imy_include") {
1398 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1399 }
1400}
1401
Logan Chien43d34c32017-12-20 01:17:32 +08001402func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1403 actual := module.Properties.AndroidMkRuntimeLibs
1404 if !reflect.DeepEqual(actual, expected) {
1405 t.Errorf("incorrect runtime_libs for shared libs"+
1406 "\nactual: %v"+
1407 "\nexpected: %v",
1408 actual,
1409 expected,
1410 )
1411 }
1412}
1413
1414const runtimeLibAndroidBp = `
1415 cc_library {
1416 name: "libvendor_available1",
1417 vendor_available: true,
1418 no_libgcc : true,
1419 nocrt : true,
1420 system_shared_libs : [],
1421 }
1422 cc_library {
1423 name: "libvendor_available2",
1424 vendor_available: true,
1425 runtime_libs: ["libvendor_available1"],
1426 no_libgcc : true,
1427 nocrt : true,
1428 system_shared_libs : [],
1429 }
1430 cc_library {
1431 name: "libvendor_available3",
1432 vendor_available: true,
1433 runtime_libs: ["libvendor_available1"],
1434 target: {
1435 vendor: {
1436 exclude_runtime_libs: ["libvendor_available1"],
1437 }
1438 },
1439 no_libgcc : true,
1440 nocrt : true,
1441 system_shared_libs : [],
1442 }
1443 cc_library {
1444 name: "libcore",
1445 runtime_libs: ["libvendor_available1"],
1446 no_libgcc : true,
1447 nocrt : true,
1448 system_shared_libs : [],
1449 }
1450 cc_library {
1451 name: "libvendor1",
1452 vendor: true,
1453 no_libgcc : true,
1454 nocrt : true,
1455 system_shared_libs : [],
1456 }
1457 cc_library {
1458 name: "libvendor2",
1459 vendor: true,
1460 runtime_libs: ["libvendor_available1", "libvendor1"],
1461 no_libgcc : true,
1462 nocrt : true,
1463 system_shared_libs : [],
1464 }
1465`
1466
1467func TestRuntimeLibs(t *testing.T) {
1468 ctx := testCc(t, runtimeLibAndroidBp)
1469
1470 // runtime_libs for core variants use the module names without suffixes.
1471 variant := "android_arm64_armv8-a_core_shared"
1472
1473 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1474 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1475
1476 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1477 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1478
1479 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1480 // and vendor variants.
1481 variant = "android_arm64_armv8-a_vendor_shared"
1482
1483 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1484 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1485
1486 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1487 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1488}
1489
1490func TestExcludeRuntimeLibs(t *testing.T) {
1491 ctx := testCc(t, runtimeLibAndroidBp)
1492
1493 variant := "android_arm64_armv8-a_core_shared"
1494 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1495 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1496
1497 variant = "android_arm64_armv8-a_vendor_shared"
1498 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1499 checkRuntimeLibs(t, nil, module)
1500}
1501
1502func TestRuntimeLibsNoVndk(t *testing.T) {
1503 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1504
1505 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1506
1507 variant := "android_arm64_armv8-a_core_shared"
1508
1509 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1510 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1511
1512 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1513 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1514}
1515
Jiyong Parkd08b6972017-09-26 10:50:54 +09001516var compilerFlagsTestCases = []struct {
1517 in string
1518 out bool
1519}{
1520 {
1521 in: "a",
1522 out: false,
1523 },
1524 {
1525 in: "-a",
1526 out: true,
1527 },
1528 {
1529 in: "-Ipath/to/something",
1530 out: false,
1531 },
1532 {
1533 in: "-isystempath/to/something",
1534 out: false,
1535 },
1536 {
1537 in: "--coverage",
1538 out: false,
1539 },
1540 {
1541 in: "-include a/b",
1542 out: true,
1543 },
1544 {
1545 in: "-include a/b c/d",
1546 out: false,
1547 },
1548 {
1549 in: "-DMACRO",
1550 out: true,
1551 },
1552 {
1553 in: "-DMAC RO",
1554 out: false,
1555 },
1556 {
1557 in: "-a -b",
1558 out: false,
1559 },
1560 {
1561 in: "-DMACRO=definition",
1562 out: true,
1563 },
1564 {
1565 in: "-DMACRO=defi nition",
1566 out: true, // TODO(jiyong): this should be false
1567 },
1568 {
1569 in: "-DMACRO(x)=x + 1",
1570 out: true,
1571 },
1572 {
1573 in: "-DMACRO=\"defi nition\"",
1574 out: true,
1575 },
1576}
1577
1578type mockContext struct {
1579 BaseModuleContext
1580 result bool
1581}
1582
1583func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1584 // CheckBadCompilerFlags calls this function when the flag should be rejected
1585 ctx.result = false
1586}
1587
1588func TestCompilerFlags(t *testing.T) {
1589 for _, testCase := range compilerFlagsTestCases {
1590 ctx := &mockContext{result: true}
1591 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1592 if ctx.result != testCase.out {
1593 t.Errorf("incorrect output:")
1594 t.Errorf(" input: %#v", testCase.in)
1595 t.Errorf(" expected: %#v", testCase.out)
1596 t.Errorf(" got: %#v", ctx.result)
1597 }
1598 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001599}
Jiyong Park374510b2018-03-19 18:23:01 +09001600
1601func TestVendorPublicLibraries(t *testing.T) {
1602 ctx := testCc(t, `
1603 cc_library_headers {
1604 name: "libvendorpublic_headers",
1605 export_include_dirs: ["my_include"],
1606 }
1607 vendor_public_library {
1608 name: "libvendorpublic",
1609 symbol_file: "",
1610 export_public_headers: ["libvendorpublic_headers"],
1611 }
1612 cc_library {
1613 name: "libvendorpublic",
1614 srcs: ["foo.c"],
1615 vendor: true,
1616 no_libgcc: true,
1617 nocrt: true,
1618 }
1619
1620 cc_library {
1621 name: "libsystem",
1622 shared_libs: ["libvendorpublic"],
1623 vendor: false,
1624 srcs: ["foo.c"],
1625 no_libgcc: true,
1626 nocrt: true,
1627 }
1628 cc_library {
1629 name: "libvendor",
1630 shared_libs: ["libvendorpublic"],
1631 vendor: true,
1632 srcs: ["foo.c"],
1633 no_libgcc: true,
1634 nocrt: true,
1635 }
1636 `)
1637
1638 variant := "android_arm64_armv8-a_core_shared"
1639
1640 // test if header search paths are correctly added
1641 // _static variant is used since _shared reuses *.o from the static variant
1642 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
1643 cflags := cc.Args["cFlags"]
1644 if !strings.Contains(cflags, "-Imy_include") {
1645 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
1646 }
1647
1648 // test if libsystem is linked to the stub
1649 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
1650 libflags := ld.Args["libFlags"]
1651 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
1652 if !strings.Contains(libflags, stubPaths[0].String()) {
1653 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
1654 }
1655
1656 // test if libvendor is linked to the real shared lib
1657 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
1658 libflags = ld.Args["libFlags"]
1659 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
1660 if !strings.Contains(libflags, stubPaths[0].String()) {
1661 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
1662 }
1663
1664}
Jiyong Park37b25202018-07-11 10:49:27 +09001665
1666func TestRecovery(t *testing.T) {
1667 ctx := testCc(t, `
1668 cc_library_shared {
1669 name: "librecovery",
1670 recovery: true,
1671 }
1672 cc_library_shared {
1673 name: "librecovery32",
1674 recovery: true,
1675 compile_multilib:"32",
1676 }
1677 `)
1678
1679 variants := ctx.ModuleVariantsForTests("librecovery")
1680 const arm64 = "android_arm64_armv8-a_recovery_shared"
1681 if len(variants) != 1 || !android.InList(arm64, variants) {
1682 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1683 }
1684
1685 variants = ctx.ModuleVariantsForTests("librecovery32")
1686 if android.InList(arm64, variants) {
1687 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1688 }
1689}