blob: bca26ea2452ff3d3f63daf7fbf1442f638e75e3f [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))
Colin Crosse40b4ea2018-10-02 22:25:58 -070059 ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(ToolchainLibraryFactory))
Jiyong Park6a43f042017-10-12 23:05:00 +090060 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))
Colin Crosse40b4ea2018-10-02 22:25:58 -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()
Colin Crosse40b4ea2018-10-02 22:25:58 -070067 ctx.BottomUp("link", LinkageMutator).Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +090068 ctx.BottomUp("vndk", vndkMutator).Parallel()
Colin Crosse40b4ea2018-10-02 22:25:58 -070069 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,
Dan Willemsenfeea4df2018-10-07 18:16:48 -070079 src: "",
Jeff Gaston294356f2017-09-27 17:05:30 -070080 }
81
82 toolchain_library {
83 name: "libcompiler_rt-extras",
84 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +090085 recovery_available: true,
Dan Willemsenfeea4df2018-10-07 18:16:48 -070086 src: "",
Jeff Gaston294356f2017-09-27 17:05:30 -070087 }
88
89 toolchain_library {
90 name: "libgcc",
91 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +090092 recovery_available: true,
Dan Willemsenfeea4df2018-10-07 18:16:48 -070093 src: "",
Jeff Gaston294356f2017-09-27 17:05:30 -070094 }
95
96 cc_library {
97 name: "libc",
Logan Chienf3511742017-10-31 18:04:35 +080098 no_libgcc: true,
99 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700100 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900101 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700102 }
103 llndk_library {
104 name: "libc",
105 symbol_file: "",
106 }
107 cc_library {
108 name: "libm",
Logan Chienf3511742017-10-31 18:04:35 +0800109 no_libgcc: true,
110 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700111 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900112 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700113 }
114 llndk_library {
115 name: "libm",
116 symbol_file: "",
117 }
118 cc_library {
119 name: "libdl",
Logan Chienf3511742017-10-31 18:04:35 +0800120 no_libgcc: true,
121 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700122 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900123 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700124 }
125 llndk_library {
126 name: "libdl",
127 symbol_file: "",
128 }
Jiyong Park374510b2018-03-19 18:23:01 +0900129 cc_library {
130 name: "libc++_static",
131 no_libgcc: true,
132 nocrt: true,
133 system_shared_libs: [],
134 stl: "none",
135 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900136 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900137 }
138 cc_library {
139 name: "libc++",
140 no_libgcc: true,
141 nocrt: true,
142 system_shared_libs: [],
143 stl: "none",
144 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900145 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900146 vndk: {
147 enabled: true,
148 support_system_process: true,
149 },
150 }
151 cc_library {
152 name: "libunwind_llvm",
153 no_libgcc: true,
154 nocrt: true,
155 system_shared_libs: [],
156 stl: "none",
157 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900158 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900159 }
Jeff Gaston294356f2017-09-27 17:05:30 -0700160
161 cc_object {
162 name: "crtbegin_so",
Jiyong Park37b25202018-07-11 10:49:27 +0900163 recovery_available: true,
Jiyong Park5baac542018-08-28 09:55:37 +0900164 vendor_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700165 }
166
167 cc_object {
168 name: "crtend_so",
Jiyong Park37b25202018-07-11 10:49:27 +0900169 recovery_available: true,
Jiyong Park5baac542018-08-28 09:55:37 +0900170 vendor_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700171 }
172
Colin Crossad59e752017-11-16 14:29:11 -0800173 cc_library {
174 name: "libprotobuf-cpp-lite",
175 }
176
Jeff Gaston294356f2017-09-27 17:05:30 -0700177`
178
Jiyong Park6a43f042017-10-12 23:05:00 +0900179 ctx.MockFileSystem(map[string][]byte{
180 "Android.bp": []byte(bp),
181 "foo.c": nil,
182 "bar.c": nil,
Colin Crossad59e752017-11-16 14:29:11 -0800183 "a.proto": nil,
Colin Crossf18e1102017-11-16 14:33:08 -0800184 "b.aidl": nil,
Jiyong Parka46a4d52017-12-14 19:54:34 +0900185 "my_include": nil,
Jiyong Park6a43f042017-10-12 23:05:00 +0900186 })
187
Logan Chienf3511742017-10-31 18:04:35 +0800188 return ctx
189}
190
191func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800192 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800193 ctx := createTestContext(t, config, bp)
194
Jeff Gastond3e141d2017-08-08 17:46:01 -0700195 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +0800196 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900197 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800198 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900199
200 return ctx
201}
202
Logan Chienf3511742017-10-31 18:04:35 +0800203func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800204 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800205 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700206 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
207 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800208
209 return testCcWithConfig(t, bp, config)
210}
211
212func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800213 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800214 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700215 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800216
217 return testCcWithConfig(t, bp, config)
218}
219
220func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800221 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800222 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700223 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
224 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800225
226 ctx := createTestContext(t, config, bp)
227
228 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
229 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800230 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800231 return
232 }
233
234 _, errs = ctx.PrepareBuildActions(config)
235 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800236 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800237 return
238 }
239
240 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
241}
242
243const (
Jiyong Park5baac542018-08-28 09:55:37 +0900244 coreVariant = "android_arm64_armv8-a_core_shared"
245 vendorVariant = "android_arm64_armv8-a_vendor_shared"
246 recoveryVariant = "android_arm64_armv8-a_recovery_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800247)
248
Jiyong Park6a43f042017-10-12 23:05:00 +0900249func TestVendorSrc(t *testing.T) {
250 ctx := testCc(t, `
251 cc_library {
252 name: "libTest",
253 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800254 no_libgcc: true,
255 nocrt: true,
256 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900257 vendor_available: true,
258 target: {
259 vendor: {
260 srcs: ["bar.c"],
261 },
262 },
263 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900264 `)
265
Logan Chienf3511742017-10-31 18:04:35 +0800266 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900267 var objs []string
268 for _, o := range ld.Inputs {
269 objs = append(objs, o.Base())
270 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800271 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900272 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
273 }
274}
275
Logan Chienf3511742017-10-31 18:04:35 +0800276func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
277 isVndkSp bool, extends string) {
278
Logan Chiend3c59a22018-03-29 14:08:15 +0800279 t.Helper()
280
Logan Chienf3511742017-10-31 18:04:35 +0800281 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
282 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700283 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800284 }
285
286 // Check library properties.
287 lib, ok := mod.compiler.(*libraryDecorator)
288 if !ok {
289 t.Errorf("%q must have libraryDecorator", name)
290 } else if lib.baseInstaller.subDir != subDir {
291 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
292 lib.baseInstaller.subDir)
293 }
294
295 // Check VNDK properties.
296 if mod.vndkdep == nil {
297 t.Fatalf("%q must have `vndkdep`", name)
298 }
299 if !mod.isVndk() {
300 t.Errorf("%q isVndk() must equal to true", name)
301 }
302 if mod.isVndkSp() != isVndkSp {
303 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
304 }
305
306 // Check VNDK extension properties.
307 isVndkExt := extends != ""
308 if mod.isVndkExt() != isVndkExt {
309 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
310 }
311
312 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
313 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
314 }
315}
316
317func TestVndk(t *testing.T) {
318 ctx := testCc(t, `
319 cc_library {
320 name: "libvndk",
321 vendor_available: true,
322 vndk: {
323 enabled: true,
324 },
325 nocrt: true,
326 }
327
328 cc_library {
329 name: "libvndk_private",
330 vendor_available: false,
331 vndk: {
332 enabled: true,
333 },
334 nocrt: true,
335 }
336
337 cc_library {
338 name: "libvndk_sp",
339 vendor_available: true,
340 vndk: {
341 enabled: true,
342 support_system_process: true,
343 },
344 nocrt: true,
345 }
346
347 cc_library {
348 name: "libvndk_sp_private",
349 vendor_available: false,
350 vndk: {
351 enabled: true,
352 support_system_process: true,
353 },
354 nocrt: true,
355 }
356 `)
357
358 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
359 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
360 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
361 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
362}
363
Logan Chiend3c59a22018-03-29 14:08:15 +0800364func TestVndkDepError(t *testing.T) {
365 // Check whether an error is emitted when a VNDK lib depends on a system lib.
366 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
367 cc_library {
368 name: "libvndk",
369 vendor_available: true,
370 vndk: {
371 enabled: true,
372 },
373 shared_libs: ["libfwk"], // Cause error
374 nocrt: true,
375 }
376
377 cc_library {
378 name: "libfwk",
379 nocrt: true,
380 }
381 `)
382
383 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
384 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
385 cc_library {
386 name: "libvndk",
387 vendor_available: true,
388 vndk: {
389 enabled: true,
390 },
391 shared_libs: ["libvendor"], // Cause error
392 nocrt: true,
393 }
394
395 cc_library {
396 name: "libvendor",
397 vendor: true,
398 nocrt: true,
399 }
400 `)
401
402 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
403 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
404 cc_library {
405 name: "libvndk_sp",
406 vendor_available: true,
407 vndk: {
408 enabled: true,
409 support_system_process: true,
410 },
411 shared_libs: ["libfwk"], // Cause error
412 nocrt: true,
413 }
414
415 cc_library {
416 name: "libfwk",
417 nocrt: true,
418 }
419 `)
420
421 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
422 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
423 cc_library {
424 name: "libvndk_sp",
425 vendor_available: true,
426 vndk: {
427 enabled: true,
428 support_system_process: true,
429 },
430 shared_libs: ["libvendor"], // Cause error
431 nocrt: true,
432 }
433
434 cc_library {
435 name: "libvendor",
436 vendor: true,
437 nocrt: true,
438 }
439 `)
440
441 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
442 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
443 cc_library {
444 name: "libvndk_sp",
445 vendor_available: true,
446 vndk: {
447 enabled: true,
448 support_system_process: true,
449 },
450 shared_libs: ["libvndk"], // Cause error
451 nocrt: true,
452 }
453
454 cc_library {
455 name: "libvndk",
456 vendor_available: true,
457 vndk: {
458 enabled: true,
459 },
460 nocrt: true,
461 }
462 `)
463}
464
Logan Chienf3511742017-10-31 18:04:35 +0800465func TestVndkExt(t *testing.T) {
466 // This test checks the VNDK-Ext properties.
467 ctx := testCc(t, `
468 cc_library {
469 name: "libvndk",
470 vendor_available: true,
471 vndk: {
472 enabled: true,
473 },
474 nocrt: true,
475 }
476
477 cc_library {
478 name: "libvndk_ext",
479 vendor: true,
480 vndk: {
481 enabled: true,
482 extends: "libvndk",
483 },
484 nocrt: true,
485 }
486 `)
487
488 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
489}
490
Logan Chiend3c59a22018-03-29 14:08:15 +0800491func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800492 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
493 ctx := testCcNoVndk(t, `
494 cc_library {
495 name: "libvndk",
496 vendor_available: true,
497 vndk: {
498 enabled: true,
499 },
500 nocrt: true,
501 }
502
503 cc_library {
504 name: "libvndk_ext",
505 vendor: true,
506 vndk: {
507 enabled: true,
508 extends: "libvndk",
509 },
510 nocrt: true,
511 }
512 `)
513
514 // Ensures that the core variant of "libvndk_ext" can be found.
515 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
516 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
517 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
518 }
519}
520
521func TestVndkExtError(t *testing.T) {
522 // This test ensures an error is emitted in ill-formed vndk-ext definition.
523 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
524 cc_library {
525 name: "libvndk",
526 vendor_available: true,
527 vndk: {
528 enabled: true,
529 },
530 nocrt: true,
531 }
532
533 cc_library {
534 name: "libvndk_ext",
535 vndk: {
536 enabled: true,
537 extends: "libvndk",
538 },
539 nocrt: true,
540 }
541 `)
542
543 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
544 cc_library {
545 name: "libvndk",
546 vendor_available: true,
547 vndk: {
548 enabled: true,
549 },
550 nocrt: true,
551 }
552
553 cc_library {
554 name: "libvndk_ext",
555 vendor: true,
556 vndk: {
557 enabled: true,
558 },
559 nocrt: true,
560 }
561 `)
562}
563
564func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
565 // This test ensures an error is emitted for inconsistent support_system_process.
566 testCcError(t, "module \".*\" with mismatched support_system_process", `
567 cc_library {
568 name: "libvndk",
569 vendor_available: true,
570 vndk: {
571 enabled: true,
572 },
573 nocrt: true,
574 }
575
576 cc_library {
577 name: "libvndk_sp_ext",
578 vendor: true,
579 vndk: {
580 enabled: true,
581 extends: "libvndk",
582 support_system_process: true,
583 },
584 nocrt: true,
585 }
586 `)
587
588 testCcError(t, "module \".*\" with mismatched support_system_process", `
589 cc_library {
590 name: "libvndk_sp",
591 vendor_available: true,
592 vndk: {
593 enabled: true,
594 support_system_process: true,
595 },
596 nocrt: true,
597 }
598
599 cc_library {
600 name: "libvndk_ext",
601 vendor: true,
602 vndk: {
603 enabled: true,
604 extends: "libvndk_sp",
605 },
606 nocrt: true,
607 }
608 `)
609}
610
611func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800612 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800613 // with `vendor_available: false`.
614 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
615 cc_library {
616 name: "libvndk",
617 vendor_available: false,
618 vndk: {
619 enabled: true,
620 },
621 nocrt: true,
622 }
623
624 cc_library {
625 name: "libvndk_ext",
626 vendor: true,
627 vndk: {
628 enabled: true,
629 extends: "libvndk",
630 },
631 nocrt: true,
632 }
633 `)
634}
635
Logan Chiend3c59a22018-03-29 14:08:15 +0800636func TestVendorModuleUseVndkExt(t *testing.T) {
637 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800638 testCc(t, `
639 cc_library {
640 name: "libvndk",
641 vendor_available: true,
642 vndk: {
643 enabled: true,
644 },
645 nocrt: true,
646 }
647
648 cc_library {
649 name: "libvndk_ext",
650 vendor: true,
651 vndk: {
652 enabled: true,
653 extends: "libvndk",
654 },
655 nocrt: true,
656 }
657
658 cc_library {
659
660 name: "libvndk_sp",
661 vendor_available: true,
662 vndk: {
663 enabled: true,
664 support_system_process: true,
665 },
666 nocrt: true,
667 }
668
669 cc_library {
670 name: "libvndk_sp_ext",
671 vendor: true,
672 vndk: {
673 enabled: true,
674 extends: "libvndk_sp",
675 support_system_process: true,
676 },
677 nocrt: true,
678 }
679
680 cc_library {
681 name: "libvendor",
682 vendor: true,
683 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
684 nocrt: true,
685 }
686 `)
687}
688
Logan Chiend3c59a22018-03-29 14:08:15 +0800689func TestVndkExtUseVendorLib(t *testing.T) {
690 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800691 testCc(t, `
692 cc_library {
693 name: "libvndk",
694 vendor_available: true,
695 vndk: {
696 enabled: true,
697 },
698 nocrt: true,
699 }
700
701 cc_library {
702 name: "libvndk_ext",
703 vendor: true,
704 vndk: {
705 enabled: true,
706 extends: "libvndk",
707 },
708 shared_libs: ["libvendor"],
709 nocrt: true,
710 }
711
712 cc_library {
713 name: "libvendor",
714 vendor: true,
715 nocrt: true,
716 }
717 `)
Logan Chienf3511742017-10-31 18:04:35 +0800718
Logan Chiend3c59a22018-03-29 14:08:15 +0800719 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
720 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800721 cc_library {
722 name: "libvndk_sp",
723 vendor_available: true,
724 vndk: {
725 enabled: true,
726 support_system_process: true,
727 },
728 nocrt: true,
729 }
730
731 cc_library {
732 name: "libvndk_sp_ext",
733 vendor: true,
734 vndk: {
735 enabled: true,
736 extends: "libvndk_sp",
737 support_system_process: true,
738 },
739 shared_libs: ["libvendor"], // Cause an error
740 nocrt: true,
741 }
742
743 cc_library {
744 name: "libvendor",
745 vendor: true,
746 nocrt: true,
747 }
748 `)
749}
750
Logan Chiend3c59a22018-03-29 14:08:15 +0800751func TestVndkSpExtUseVndkError(t *testing.T) {
752 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
753 // library.
754 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
755 cc_library {
756 name: "libvndk",
757 vendor_available: true,
758 vndk: {
759 enabled: true,
760 },
761 nocrt: true,
762 }
763
764 cc_library {
765 name: "libvndk_sp",
766 vendor_available: true,
767 vndk: {
768 enabled: true,
769 support_system_process: true,
770 },
771 nocrt: true,
772 }
773
774 cc_library {
775 name: "libvndk_sp_ext",
776 vendor: true,
777 vndk: {
778 enabled: true,
779 extends: "libvndk_sp",
780 support_system_process: true,
781 },
782 shared_libs: ["libvndk"], // Cause an error
783 nocrt: true,
784 }
785 `)
786
787 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
788 // library.
789 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
790 cc_library {
791 name: "libvndk",
792 vendor_available: true,
793 vndk: {
794 enabled: true,
795 },
796 nocrt: true,
797 }
798
799 cc_library {
800 name: "libvndk_ext",
801 vendor: true,
802 vndk: {
803 enabled: true,
804 extends: "libvndk",
805 },
806 nocrt: true,
807 }
808
809 cc_library {
810 name: "libvndk_sp",
811 vendor_available: true,
812 vndk: {
813 enabled: true,
814 support_system_process: true,
815 },
816 nocrt: true,
817 }
818
819 cc_library {
820 name: "libvndk_sp_ext",
821 vendor: true,
822 vndk: {
823 enabled: true,
824 extends: "libvndk_sp",
825 support_system_process: true,
826 },
827 shared_libs: ["libvndk_ext"], // Cause an error
828 nocrt: true,
829 }
830 `)
831}
832
833func TestVndkUseVndkExtError(t *testing.T) {
834 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
835 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800836 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
837 cc_library {
838 name: "libvndk",
839 vendor_available: true,
840 vndk: {
841 enabled: true,
842 },
843 nocrt: true,
844 }
845
846 cc_library {
847 name: "libvndk_ext",
848 vendor: true,
849 vndk: {
850 enabled: true,
851 extends: "libvndk",
852 },
853 nocrt: true,
854 }
855
856 cc_library {
857 name: "libvndk2",
858 vendor_available: true,
859 vndk: {
860 enabled: true,
861 },
862 shared_libs: ["libvndk_ext"],
863 nocrt: true,
864 }
865 `)
866
867 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
868 // but target.vendor.shared_libs has not been supported yet.
869 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
870 cc_library {
871 name: "libvndk",
872 vendor_available: true,
873 vndk: {
874 enabled: true,
875 },
876 nocrt: true,
877 }
878
879 cc_library {
880 name: "libvndk_ext",
881 vendor: true,
882 vndk: {
883 enabled: true,
884 extends: "libvndk",
885 },
886 nocrt: true,
887 }
888
889 cc_library {
890 name: "libvndk2",
891 vendor_available: true,
892 vndk: {
893 enabled: true,
894 },
895 target: {
896 vendor: {
897 shared_libs: ["libvndk_ext"],
898 },
899 },
900 nocrt: true,
901 }
902 `)
903
904 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
905 cc_library {
906 name: "libvndk_sp",
907 vendor_available: true,
908 vndk: {
909 enabled: true,
910 support_system_process: true,
911 },
912 nocrt: true,
913 }
914
915 cc_library {
916 name: "libvndk_sp_ext",
917 vendor: true,
918 vndk: {
919 enabled: true,
920 extends: "libvndk_sp",
921 support_system_process: true,
922 },
923 nocrt: true,
924 }
925
926 cc_library {
927 name: "libvndk_sp_2",
928 vendor_available: true,
929 vndk: {
930 enabled: true,
931 support_system_process: true,
932 },
933 shared_libs: ["libvndk_sp_ext"],
934 nocrt: true,
935 }
936 `)
937
938 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
939 // but target.vendor.shared_libs has not been supported yet.
940 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
941 cc_library {
942 name: "libvndk_sp",
943 vendor_available: true,
944 vndk: {
945 enabled: true,
946 },
947 nocrt: true,
948 }
949
950 cc_library {
951 name: "libvndk_sp_ext",
952 vendor: true,
953 vndk: {
954 enabled: true,
955 extends: "libvndk_sp",
956 },
957 nocrt: true,
958 }
959
960 cc_library {
961 name: "libvndk_sp2",
962 vendor_available: true,
963 vndk: {
964 enabled: true,
965 },
966 target: {
967 vendor: {
968 shared_libs: ["libvndk_sp_ext"],
969 },
970 },
971 nocrt: true,
972 }
973 `)
974}
975
Colin Cross0af4b842015-04-30 16:36:18 -0700976var (
977 str11 = "01234567891"
978 str10 = str11[:10]
979 str9 = str11[:9]
980 str5 = str11[:5]
981 str4 = str11[:4]
982)
983
984var splitListForSizeTestCases = []struct {
985 in []string
986 out [][]string
987 size int
988}{
989 {
990 in: []string{str10},
991 out: [][]string{{str10}},
992 size: 10,
993 },
994 {
995 in: []string{str9},
996 out: [][]string{{str9}},
997 size: 10,
998 },
999 {
1000 in: []string{str5},
1001 out: [][]string{{str5}},
1002 size: 10,
1003 },
1004 {
1005 in: []string{str11},
1006 out: nil,
1007 size: 10,
1008 },
1009 {
1010 in: []string{str10, str10},
1011 out: [][]string{{str10}, {str10}},
1012 size: 10,
1013 },
1014 {
1015 in: []string{str9, str10},
1016 out: [][]string{{str9}, {str10}},
1017 size: 10,
1018 },
1019 {
1020 in: []string{str10, str9},
1021 out: [][]string{{str10}, {str9}},
1022 size: 10,
1023 },
1024 {
1025 in: []string{str5, str4},
1026 out: [][]string{{str5, str4}},
1027 size: 10,
1028 },
1029 {
1030 in: []string{str5, str4, str5},
1031 out: [][]string{{str5, str4}, {str5}},
1032 size: 10,
1033 },
1034 {
1035 in: []string{str5, str4, str5, str4},
1036 out: [][]string{{str5, str4}, {str5, str4}},
1037 size: 10,
1038 },
1039 {
1040 in: []string{str5, str4, str5, str5},
1041 out: [][]string{{str5, str4}, {str5}, {str5}},
1042 size: 10,
1043 },
1044 {
1045 in: []string{str5, str5, str5, str4},
1046 out: [][]string{{str5}, {str5}, {str5, str4}},
1047 size: 10,
1048 },
1049 {
1050 in: []string{str9, str11},
1051 out: nil,
1052 size: 10,
1053 },
1054 {
1055 in: []string{str11, str9},
1056 out: nil,
1057 size: 10,
1058 },
1059}
1060
1061func TestSplitListForSize(t *testing.T) {
1062 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -07001063 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
1064
1065 var outStrings [][]string
1066
1067 if len(out) > 0 {
1068 outStrings = make([][]string, len(out))
1069 for i, o := range out {
1070 outStrings[i] = o.Strings()
1071 }
1072 }
1073
1074 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001075 t.Errorf("incorrect output:")
1076 t.Errorf(" input: %#v", testCase.in)
1077 t.Errorf(" size: %d", testCase.size)
1078 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001079 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001080 }
1081 }
1082}
Jeff Gaston294356f2017-09-27 17:05:30 -07001083
1084var staticLinkDepOrderTestCases = []struct {
1085 // This is a string representation of a map[moduleName][]moduleDependency .
1086 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001087 inStatic string
1088
1089 // This is a string representation of a map[moduleName][]moduleDependency .
1090 // It models the dependencies declared in an Android.bp file.
1091 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001092
1093 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1094 // The keys of allOrdered specify which modules we would like to check.
1095 // The values of allOrdered specify the expected result (of the transitive closure of all
1096 // dependencies) for each module to test
1097 allOrdered string
1098
1099 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1100 // The keys of outOrdered specify which modules we would like to check.
1101 // The values of outOrdered specify the expected result (of the ordered linker command line)
1102 // for each module to test.
1103 outOrdered string
1104}{
1105 // Simple tests
1106 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001107 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001108 outOrdered: "",
1109 },
1110 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001111 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001112 outOrdered: "a:",
1113 },
1114 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001115 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001116 outOrdered: "a:b; b:",
1117 },
1118 // Tests of reordering
1119 {
1120 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001121 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001122 outOrdered: "a:b,c,d; b:d; c:d; d:",
1123 },
1124 {
1125 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001126 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001127 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1128 },
1129 {
1130 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001131 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001132 outOrdered: "a:d,b,e,c; d:b; e:c",
1133 },
1134 {
1135 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001136 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001137 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1138 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1139 },
1140 {
1141 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001142 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 -07001143 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1144 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1145 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001146 // shared dependencies
1147 {
1148 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1149 // So, we don't actually have to check that a shared dependency of c will change the order
1150 // of a library that depends statically on b and on c. We only need to check that if c has
1151 // a shared dependency on b, that that shows up in allOrdered.
1152 inShared: "c:b",
1153 allOrdered: "c:b",
1154 outOrdered: "c:",
1155 },
1156 {
1157 // This test doesn't actually include any shared dependencies but it's a reminder of what
1158 // the second phase of the above test would look like
1159 inStatic: "a:b,c; c:b",
1160 allOrdered: "a:c,b; c:b",
1161 outOrdered: "a:c,b; c:b",
1162 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001163 // tiebreakers for when two modules specifying different orderings and there is no dependency
1164 // to dictate an order
1165 {
1166 // 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 -08001167 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001168 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1169 },
1170 {
1171 // 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 -08001172 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 -07001173 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1174 },
1175 // Tests involving duplicate dependencies
1176 {
1177 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001178 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001179 outOrdered: "a:c,b",
1180 },
1181 {
1182 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001183 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001184 outOrdered: "a:d,c,b",
1185 },
1186 // Tests to confirm the nonexistence of infinite loops.
1187 // These cases should never happen, so as long as the test terminates and the
1188 // result is deterministic then that should be fine.
1189 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001190 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001191 outOrdered: "a:a",
1192 },
1193 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001194 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001195 allOrdered: "a:b,c; b:c,a; c:a,b",
1196 outOrdered: "a:b; b:c; c:a",
1197 },
1198 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001199 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001200 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1201 outOrdered: "a:c,b; b:a,c; c:b,a",
1202 },
1203}
1204
1205// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1206func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1207 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1208 strippedText := strings.Replace(text, " ", "", -1)
1209 if len(strippedText) < 1 {
1210 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1211 }
1212 allDeps = make(map[android.Path][]android.Path, 0)
1213
1214 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1215 moduleTexts := strings.Split(strippedText, ";")
1216
1217 outputForModuleName := func(moduleName string) android.Path {
1218 return android.PathForTesting(moduleName)
1219 }
1220
1221 for _, moduleText := range moduleTexts {
1222 // convert from "a:b,c" to ["a", "b,c"]
1223 components := strings.Split(moduleText, ":")
1224 if len(components) != 2 {
1225 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1226 }
1227 moduleName := components[0]
1228 moduleOutput := outputForModuleName(moduleName)
1229 modulesInOrder = append(modulesInOrder, moduleOutput)
1230
1231 depString := components[1]
1232 // convert from "b,c" to ["b", "c"]
1233 depNames := strings.Split(depString, ",")
1234 if len(depString) < 1 {
1235 depNames = []string{}
1236 }
1237 var deps []android.Path
1238 for _, depName := range depNames {
1239 deps = append(deps, outputForModuleName(depName))
1240 }
1241 allDeps[moduleOutput] = deps
1242 }
1243 return modulesInOrder, allDeps
1244}
1245
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001246func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001247 for _, testCase := range staticLinkDepOrderTestCases {
1248 errs := []string{}
1249
1250 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001251 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001252 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1253 if testCase.allOrdered == "" {
1254 // allow the test case to skip specifying allOrdered
1255 testCase.allOrdered = testCase.outOrdered
1256 }
1257 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001258 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001259
1260 // For each module whose post-reordered dependencies were specified, validate that
1261 // reordering the inputs produces the expected outputs.
1262 for _, moduleName := range expectedModuleNames {
1263 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001264 givenSharedDeps := givenAllSharedDeps[moduleName]
1265 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001266
1267 correctAllOrdered := expectedAllDeps[moduleName]
1268 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1269 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001270 "\nin static:%q"+
1271 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001272 "\nmodule: %v"+
1273 "\nexpected: %s"+
1274 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001275 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001276 }
1277
1278 correctOutputDeps := expectedTransitiveDeps[moduleName]
1279 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1280 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001281 "\nin static:%q"+
1282 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001283 "\nmodule: %v"+
1284 "\nexpected: %s"+
1285 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001286 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001287 }
1288 }
1289
1290 if len(errs) > 0 {
1291 sort.Strings(errs)
1292 for _, err := range errs {
1293 t.Error(err)
1294 }
1295 }
1296 }
1297}
Logan Chienf3511742017-10-31 18:04:35 +08001298
Jeff Gaston294356f2017-09-27 17:05:30 -07001299func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1300 for _, moduleName := range moduleNames {
1301 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1302 output := module.outputFile.Path()
1303 paths = append(paths, output)
1304 }
1305 return paths
1306}
1307
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001308func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001309 ctx := testCc(t, `
1310 cc_library {
1311 name: "a",
1312 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001313 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001314 }
1315 cc_library {
1316 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001317 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001318 }
1319 cc_library {
1320 name: "c",
1321 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001322 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001323 }
1324 cc_library {
1325 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001326 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001327 }
1328
1329 `)
1330
1331 variant := "android_arm64_armv8-a_core_static"
1332 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001333 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001334 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1335
1336 if !reflect.DeepEqual(actual, expected) {
1337 t.Errorf("staticDeps orderings were not propagated correctly"+
1338 "\nactual: %v"+
1339 "\nexpected: %v",
1340 actual,
1341 expected,
1342 )
1343 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001344}
Jeff Gaston294356f2017-09-27 17:05:30 -07001345
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001346func TestStaticLibDepReorderingWithShared(t *testing.T) {
1347 ctx := testCc(t, `
1348 cc_library {
1349 name: "a",
1350 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001351 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001352 }
1353 cc_library {
1354 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001355 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001356 }
1357 cc_library {
1358 name: "c",
1359 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001360 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001361 }
1362
1363 `)
1364
1365 variant := "android_arm64_armv8-a_core_static"
1366 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1367 actual := moduleA.depsInLinkOrder
1368 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1369
1370 if !reflect.DeepEqual(actual, expected) {
1371 t.Errorf("staticDeps orderings did not account for shared libs"+
1372 "\nactual: %v"+
1373 "\nexpected: %v",
1374 actual,
1375 expected,
1376 )
1377 }
1378}
1379
Jiyong Parka46a4d52017-12-14 19:54:34 +09001380func TestLlndkHeaders(t *testing.T) {
1381 ctx := testCc(t, `
1382 llndk_headers {
1383 name: "libllndk_headers",
1384 export_include_dirs: ["my_include"],
1385 }
1386 llndk_library {
1387 name: "libllndk",
1388 export_llndk_headers: ["libllndk_headers"],
1389 }
1390 cc_library {
1391 name: "libvendor",
1392 shared_libs: ["libllndk"],
1393 vendor: true,
1394 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001395 no_libgcc: true,
1396 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001397 }
1398 `)
1399
1400 // _static variant is used since _shared reuses *.o from the static variant
1401 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1402 cflags := cc.Args["cFlags"]
1403 if !strings.Contains(cflags, "-Imy_include") {
1404 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1405 }
1406}
1407
Logan Chien43d34c32017-12-20 01:17:32 +08001408func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1409 actual := module.Properties.AndroidMkRuntimeLibs
1410 if !reflect.DeepEqual(actual, expected) {
1411 t.Errorf("incorrect runtime_libs for shared libs"+
1412 "\nactual: %v"+
1413 "\nexpected: %v",
1414 actual,
1415 expected,
1416 )
1417 }
1418}
1419
1420const runtimeLibAndroidBp = `
1421 cc_library {
1422 name: "libvendor_available1",
1423 vendor_available: true,
1424 no_libgcc : true,
1425 nocrt : true,
1426 system_shared_libs : [],
1427 }
1428 cc_library {
1429 name: "libvendor_available2",
1430 vendor_available: true,
1431 runtime_libs: ["libvendor_available1"],
1432 no_libgcc : true,
1433 nocrt : true,
1434 system_shared_libs : [],
1435 }
1436 cc_library {
1437 name: "libvendor_available3",
1438 vendor_available: true,
1439 runtime_libs: ["libvendor_available1"],
1440 target: {
1441 vendor: {
1442 exclude_runtime_libs: ["libvendor_available1"],
1443 }
1444 },
1445 no_libgcc : true,
1446 nocrt : true,
1447 system_shared_libs : [],
1448 }
1449 cc_library {
1450 name: "libcore",
1451 runtime_libs: ["libvendor_available1"],
1452 no_libgcc : true,
1453 nocrt : true,
1454 system_shared_libs : [],
1455 }
1456 cc_library {
1457 name: "libvendor1",
1458 vendor: true,
1459 no_libgcc : true,
1460 nocrt : true,
1461 system_shared_libs : [],
1462 }
1463 cc_library {
1464 name: "libvendor2",
1465 vendor: true,
1466 runtime_libs: ["libvendor_available1", "libvendor1"],
1467 no_libgcc : true,
1468 nocrt : true,
1469 system_shared_libs : [],
1470 }
1471`
1472
1473func TestRuntimeLibs(t *testing.T) {
1474 ctx := testCc(t, runtimeLibAndroidBp)
1475
1476 // runtime_libs for core variants use the module names without suffixes.
1477 variant := "android_arm64_armv8-a_core_shared"
1478
1479 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1480 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1481
1482 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1483 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1484
1485 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1486 // and vendor variants.
1487 variant = "android_arm64_armv8-a_vendor_shared"
1488
1489 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1490 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1491
1492 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1493 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1494}
1495
1496func TestExcludeRuntimeLibs(t *testing.T) {
1497 ctx := testCc(t, runtimeLibAndroidBp)
1498
1499 variant := "android_arm64_armv8-a_core_shared"
1500 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1501 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1502
1503 variant = "android_arm64_armv8-a_vendor_shared"
1504 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1505 checkRuntimeLibs(t, nil, module)
1506}
1507
1508func TestRuntimeLibsNoVndk(t *testing.T) {
1509 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1510
1511 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1512
1513 variant := "android_arm64_armv8-a_core_shared"
1514
1515 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1516 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1517
1518 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1519 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1520}
1521
Jiyong Parkd08b6972017-09-26 10:50:54 +09001522var compilerFlagsTestCases = []struct {
1523 in string
1524 out bool
1525}{
1526 {
1527 in: "a",
1528 out: false,
1529 },
1530 {
1531 in: "-a",
1532 out: true,
1533 },
1534 {
1535 in: "-Ipath/to/something",
1536 out: false,
1537 },
1538 {
1539 in: "-isystempath/to/something",
1540 out: false,
1541 },
1542 {
1543 in: "--coverage",
1544 out: false,
1545 },
1546 {
1547 in: "-include a/b",
1548 out: true,
1549 },
1550 {
1551 in: "-include a/b c/d",
1552 out: false,
1553 },
1554 {
1555 in: "-DMACRO",
1556 out: true,
1557 },
1558 {
1559 in: "-DMAC RO",
1560 out: false,
1561 },
1562 {
1563 in: "-a -b",
1564 out: false,
1565 },
1566 {
1567 in: "-DMACRO=definition",
1568 out: true,
1569 },
1570 {
1571 in: "-DMACRO=defi nition",
1572 out: true, // TODO(jiyong): this should be false
1573 },
1574 {
1575 in: "-DMACRO(x)=x + 1",
1576 out: true,
1577 },
1578 {
1579 in: "-DMACRO=\"defi nition\"",
1580 out: true,
1581 },
1582}
1583
1584type mockContext struct {
1585 BaseModuleContext
1586 result bool
1587}
1588
1589func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1590 // CheckBadCompilerFlags calls this function when the flag should be rejected
1591 ctx.result = false
1592}
1593
1594func TestCompilerFlags(t *testing.T) {
1595 for _, testCase := range compilerFlagsTestCases {
1596 ctx := &mockContext{result: true}
1597 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1598 if ctx.result != testCase.out {
1599 t.Errorf("incorrect output:")
1600 t.Errorf(" input: %#v", testCase.in)
1601 t.Errorf(" expected: %#v", testCase.out)
1602 t.Errorf(" got: %#v", ctx.result)
1603 }
1604 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001605}
Jiyong Park374510b2018-03-19 18:23:01 +09001606
1607func TestVendorPublicLibraries(t *testing.T) {
1608 ctx := testCc(t, `
1609 cc_library_headers {
1610 name: "libvendorpublic_headers",
1611 export_include_dirs: ["my_include"],
1612 }
1613 vendor_public_library {
1614 name: "libvendorpublic",
1615 symbol_file: "",
1616 export_public_headers: ["libvendorpublic_headers"],
1617 }
1618 cc_library {
1619 name: "libvendorpublic",
1620 srcs: ["foo.c"],
1621 vendor: true,
1622 no_libgcc: true,
1623 nocrt: true,
1624 }
1625
1626 cc_library {
1627 name: "libsystem",
1628 shared_libs: ["libvendorpublic"],
1629 vendor: false,
1630 srcs: ["foo.c"],
1631 no_libgcc: true,
1632 nocrt: true,
1633 }
1634 cc_library {
1635 name: "libvendor",
1636 shared_libs: ["libvendorpublic"],
1637 vendor: true,
1638 srcs: ["foo.c"],
1639 no_libgcc: true,
1640 nocrt: true,
1641 }
1642 `)
1643
1644 variant := "android_arm64_armv8-a_core_shared"
1645
1646 // test if header search paths are correctly added
1647 // _static variant is used since _shared reuses *.o from the static variant
1648 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
1649 cflags := cc.Args["cFlags"]
1650 if !strings.Contains(cflags, "-Imy_include") {
1651 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
1652 }
1653
1654 // test if libsystem is linked to the stub
1655 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
1656 libflags := ld.Args["libFlags"]
1657 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
1658 if !strings.Contains(libflags, stubPaths[0].String()) {
1659 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
1660 }
1661
1662 // test if libvendor is linked to the real shared lib
1663 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
1664 libflags = ld.Args["libFlags"]
1665 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
1666 if !strings.Contains(libflags, stubPaths[0].String()) {
1667 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
1668 }
1669
1670}
Jiyong Park37b25202018-07-11 10:49:27 +09001671
1672func TestRecovery(t *testing.T) {
1673 ctx := testCc(t, `
1674 cc_library_shared {
1675 name: "librecovery",
1676 recovery: true,
1677 }
1678 cc_library_shared {
1679 name: "librecovery32",
1680 recovery: true,
1681 compile_multilib:"32",
1682 }
Jiyong Park5baac542018-08-28 09:55:37 +09001683 cc_library_shared {
1684 name: "libHalInRecovery",
1685 recovery_available: true,
1686 vendor: true,
1687 }
Jiyong Park37b25202018-07-11 10:49:27 +09001688 `)
1689
1690 variants := ctx.ModuleVariantsForTests("librecovery")
1691 const arm64 = "android_arm64_armv8-a_recovery_shared"
1692 if len(variants) != 1 || !android.InList(arm64, variants) {
1693 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1694 }
1695
1696 variants = ctx.ModuleVariantsForTests("librecovery32")
1697 if android.InList(arm64, variants) {
1698 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1699 }
Jiyong Park5baac542018-08-28 09:55:37 +09001700
1701 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1702 if !recoveryModule.Platform() {
1703 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1704 }
1705
Jiyong Park37b25202018-07-11 10:49:27 +09001706}