blob: 3d5dfb155982429c3c047ba5b1576425b31fd2d1 [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,
Jiyong Park5baac542018-08-28 09:55:37 +0900161 vendor_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700162 }
163
164 cc_object {
165 name: "crtend_so",
Jiyong Park37b25202018-07-11 10:49:27 +0900166 recovery_available: true,
Jiyong Park5baac542018-08-28 09:55:37 +0900167 vendor_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700168 }
169
Colin Crossad59e752017-11-16 14:29:11 -0800170 cc_library {
171 name: "libprotobuf-cpp-lite",
172 }
173
Jeff Gaston294356f2017-09-27 17:05:30 -0700174`
175
Jiyong Park6a43f042017-10-12 23:05:00 +0900176 ctx.MockFileSystem(map[string][]byte{
177 "Android.bp": []byte(bp),
178 "foo.c": nil,
179 "bar.c": nil,
Colin Crossad59e752017-11-16 14:29:11 -0800180 "a.proto": nil,
Colin Crossf18e1102017-11-16 14:33:08 -0800181 "b.aidl": nil,
Jiyong Parka46a4d52017-12-14 19:54:34 +0900182 "my_include": nil,
Jiyong Park6a43f042017-10-12 23:05:00 +0900183 })
184
Logan Chienf3511742017-10-31 18:04:35 +0800185 return ctx
186}
187
188func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800189 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800190 ctx := createTestContext(t, config, bp)
191
Jeff Gastond3e141d2017-08-08 17:46:01 -0700192 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +0800193 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900194 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800195 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900196
197 return ctx
198}
199
Logan Chienf3511742017-10-31 18:04:35 +0800200func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800201 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800202 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700203 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
204 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800205
206 return testCcWithConfig(t, bp, config)
207}
208
209func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800210 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800211 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700212 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800213
214 return testCcWithConfig(t, bp, config)
215}
216
217func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800218 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800219 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700220 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
221 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800222
223 ctx := createTestContext(t, config, bp)
224
225 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
226 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800227 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800228 return
229 }
230
231 _, errs = ctx.PrepareBuildActions(config)
232 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800233 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800234 return
235 }
236
237 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
238}
239
240const (
Jiyong Park5baac542018-08-28 09:55:37 +0900241 coreVariant = "android_arm64_armv8-a_core_shared"
242 vendorVariant = "android_arm64_armv8-a_vendor_shared"
243 recoveryVariant = "android_arm64_armv8-a_recovery_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800244)
245
Jiyong Park6a43f042017-10-12 23:05:00 +0900246func TestVendorSrc(t *testing.T) {
247 ctx := testCc(t, `
248 cc_library {
249 name: "libTest",
250 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800251 no_libgcc: true,
252 nocrt: true,
253 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900254 vendor_available: true,
255 target: {
256 vendor: {
257 srcs: ["bar.c"],
258 },
259 },
260 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900261 `)
262
Logan Chienf3511742017-10-31 18:04:35 +0800263 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900264 var objs []string
265 for _, o := range ld.Inputs {
266 objs = append(objs, o.Base())
267 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800268 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900269 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
270 }
271}
272
Logan Chienf3511742017-10-31 18:04:35 +0800273func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
274 isVndkSp bool, extends string) {
275
Logan Chiend3c59a22018-03-29 14:08:15 +0800276 t.Helper()
277
Logan Chienf3511742017-10-31 18:04:35 +0800278 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
279 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700280 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800281 }
282
283 // Check library properties.
284 lib, ok := mod.compiler.(*libraryDecorator)
285 if !ok {
286 t.Errorf("%q must have libraryDecorator", name)
287 } else if lib.baseInstaller.subDir != subDir {
288 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
289 lib.baseInstaller.subDir)
290 }
291
292 // Check VNDK properties.
293 if mod.vndkdep == nil {
294 t.Fatalf("%q must have `vndkdep`", name)
295 }
296 if !mod.isVndk() {
297 t.Errorf("%q isVndk() must equal to true", name)
298 }
299 if mod.isVndkSp() != isVndkSp {
300 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
301 }
302
303 // Check VNDK extension properties.
304 isVndkExt := extends != ""
305 if mod.isVndkExt() != isVndkExt {
306 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
307 }
308
309 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
310 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
311 }
312}
313
314func TestVndk(t *testing.T) {
315 ctx := testCc(t, `
316 cc_library {
317 name: "libvndk",
318 vendor_available: true,
319 vndk: {
320 enabled: true,
321 },
322 nocrt: true,
323 }
324
325 cc_library {
326 name: "libvndk_private",
327 vendor_available: false,
328 vndk: {
329 enabled: true,
330 },
331 nocrt: true,
332 }
333
334 cc_library {
335 name: "libvndk_sp",
336 vendor_available: true,
337 vndk: {
338 enabled: true,
339 support_system_process: true,
340 },
341 nocrt: true,
342 }
343
344 cc_library {
345 name: "libvndk_sp_private",
346 vendor_available: false,
347 vndk: {
348 enabled: true,
349 support_system_process: true,
350 },
351 nocrt: true,
352 }
353 `)
354
355 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
356 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
357 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
358 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
359}
360
Logan Chiend3c59a22018-03-29 14:08:15 +0800361func TestVndkDepError(t *testing.T) {
362 // Check whether an error is emitted when a VNDK lib depends on a system lib.
363 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
364 cc_library {
365 name: "libvndk",
366 vendor_available: true,
367 vndk: {
368 enabled: true,
369 },
370 shared_libs: ["libfwk"], // Cause error
371 nocrt: true,
372 }
373
374 cc_library {
375 name: "libfwk",
376 nocrt: true,
377 }
378 `)
379
380 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
381 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
382 cc_library {
383 name: "libvndk",
384 vendor_available: true,
385 vndk: {
386 enabled: true,
387 },
388 shared_libs: ["libvendor"], // Cause error
389 nocrt: true,
390 }
391
392 cc_library {
393 name: "libvendor",
394 vendor: true,
395 nocrt: true,
396 }
397 `)
398
399 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
400 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
401 cc_library {
402 name: "libvndk_sp",
403 vendor_available: true,
404 vndk: {
405 enabled: true,
406 support_system_process: true,
407 },
408 shared_libs: ["libfwk"], // Cause error
409 nocrt: true,
410 }
411
412 cc_library {
413 name: "libfwk",
414 nocrt: true,
415 }
416 `)
417
418 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
419 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
420 cc_library {
421 name: "libvndk_sp",
422 vendor_available: true,
423 vndk: {
424 enabled: true,
425 support_system_process: true,
426 },
427 shared_libs: ["libvendor"], // Cause error
428 nocrt: true,
429 }
430
431 cc_library {
432 name: "libvendor",
433 vendor: true,
434 nocrt: true,
435 }
436 `)
437
438 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
439 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
440 cc_library {
441 name: "libvndk_sp",
442 vendor_available: true,
443 vndk: {
444 enabled: true,
445 support_system_process: true,
446 },
447 shared_libs: ["libvndk"], // Cause error
448 nocrt: true,
449 }
450
451 cc_library {
452 name: "libvndk",
453 vendor_available: true,
454 vndk: {
455 enabled: true,
456 },
457 nocrt: true,
458 }
459 `)
460}
461
Logan Chienf3511742017-10-31 18:04:35 +0800462func TestVndkExt(t *testing.T) {
463 // This test checks the VNDK-Ext properties.
464 ctx := testCc(t, `
465 cc_library {
466 name: "libvndk",
467 vendor_available: true,
468 vndk: {
469 enabled: true,
470 },
471 nocrt: true,
472 }
473
474 cc_library {
475 name: "libvndk_ext",
476 vendor: true,
477 vndk: {
478 enabled: true,
479 extends: "libvndk",
480 },
481 nocrt: true,
482 }
483 `)
484
485 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
486}
487
Logan Chiend3c59a22018-03-29 14:08:15 +0800488func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800489 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
490 ctx := testCcNoVndk(t, `
491 cc_library {
492 name: "libvndk",
493 vendor_available: true,
494 vndk: {
495 enabled: true,
496 },
497 nocrt: true,
498 }
499
500 cc_library {
501 name: "libvndk_ext",
502 vendor: true,
503 vndk: {
504 enabled: true,
505 extends: "libvndk",
506 },
507 nocrt: true,
508 }
509 `)
510
511 // Ensures that the core variant of "libvndk_ext" can be found.
512 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
513 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
514 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
515 }
516}
517
518func TestVndkExtError(t *testing.T) {
519 // This test ensures an error is emitted in ill-formed vndk-ext definition.
520 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
521 cc_library {
522 name: "libvndk",
523 vendor_available: true,
524 vndk: {
525 enabled: true,
526 },
527 nocrt: true,
528 }
529
530 cc_library {
531 name: "libvndk_ext",
532 vndk: {
533 enabled: true,
534 extends: "libvndk",
535 },
536 nocrt: true,
537 }
538 `)
539
540 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
541 cc_library {
542 name: "libvndk",
543 vendor_available: true,
544 vndk: {
545 enabled: true,
546 },
547 nocrt: true,
548 }
549
550 cc_library {
551 name: "libvndk_ext",
552 vendor: true,
553 vndk: {
554 enabled: true,
555 },
556 nocrt: true,
557 }
558 `)
559}
560
561func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
562 // This test ensures an error is emitted for inconsistent support_system_process.
563 testCcError(t, "module \".*\" with mismatched support_system_process", `
564 cc_library {
565 name: "libvndk",
566 vendor_available: true,
567 vndk: {
568 enabled: true,
569 },
570 nocrt: true,
571 }
572
573 cc_library {
574 name: "libvndk_sp_ext",
575 vendor: true,
576 vndk: {
577 enabled: true,
578 extends: "libvndk",
579 support_system_process: true,
580 },
581 nocrt: true,
582 }
583 `)
584
585 testCcError(t, "module \".*\" with mismatched support_system_process", `
586 cc_library {
587 name: "libvndk_sp",
588 vendor_available: true,
589 vndk: {
590 enabled: true,
591 support_system_process: true,
592 },
593 nocrt: true,
594 }
595
596 cc_library {
597 name: "libvndk_ext",
598 vendor: true,
599 vndk: {
600 enabled: true,
601 extends: "libvndk_sp",
602 },
603 nocrt: true,
604 }
605 `)
606}
607
608func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800609 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800610 // with `vendor_available: false`.
611 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
612 cc_library {
613 name: "libvndk",
614 vendor_available: false,
615 vndk: {
616 enabled: true,
617 },
618 nocrt: true,
619 }
620
621 cc_library {
622 name: "libvndk_ext",
623 vendor: true,
624 vndk: {
625 enabled: true,
626 extends: "libvndk",
627 },
628 nocrt: true,
629 }
630 `)
631}
632
Logan Chiend3c59a22018-03-29 14:08:15 +0800633func TestVendorModuleUseVndkExt(t *testing.T) {
634 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800635 testCc(t, `
636 cc_library {
637 name: "libvndk",
638 vendor_available: true,
639 vndk: {
640 enabled: true,
641 },
642 nocrt: true,
643 }
644
645 cc_library {
646 name: "libvndk_ext",
647 vendor: true,
648 vndk: {
649 enabled: true,
650 extends: "libvndk",
651 },
652 nocrt: true,
653 }
654
655 cc_library {
656
657 name: "libvndk_sp",
658 vendor_available: true,
659 vndk: {
660 enabled: true,
661 support_system_process: true,
662 },
663 nocrt: true,
664 }
665
666 cc_library {
667 name: "libvndk_sp_ext",
668 vendor: true,
669 vndk: {
670 enabled: true,
671 extends: "libvndk_sp",
672 support_system_process: true,
673 },
674 nocrt: true,
675 }
676
677 cc_library {
678 name: "libvendor",
679 vendor: true,
680 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
681 nocrt: true,
682 }
683 `)
684}
685
Logan Chiend3c59a22018-03-29 14:08:15 +0800686func TestVndkExtUseVendorLib(t *testing.T) {
687 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800688 testCc(t, `
689 cc_library {
690 name: "libvndk",
691 vendor_available: true,
692 vndk: {
693 enabled: true,
694 },
695 nocrt: true,
696 }
697
698 cc_library {
699 name: "libvndk_ext",
700 vendor: true,
701 vndk: {
702 enabled: true,
703 extends: "libvndk",
704 },
705 shared_libs: ["libvendor"],
706 nocrt: true,
707 }
708
709 cc_library {
710 name: "libvendor",
711 vendor: true,
712 nocrt: true,
713 }
714 `)
Logan Chienf3511742017-10-31 18:04:35 +0800715
Logan Chiend3c59a22018-03-29 14:08:15 +0800716 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
717 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800718 cc_library {
719 name: "libvndk_sp",
720 vendor_available: true,
721 vndk: {
722 enabled: true,
723 support_system_process: true,
724 },
725 nocrt: true,
726 }
727
728 cc_library {
729 name: "libvndk_sp_ext",
730 vendor: true,
731 vndk: {
732 enabled: true,
733 extends: "libvndk_sp",
734 support_system_process: true,
735 },
736 shared_libs: ["libvendor"], // Cause an error
737 nocrt: true,
738 }
739
740 cc_library {
741 name: "libvendor",
742 vendor: true,
743 nocrt: true,
744 }
745 `)
746}
747
Logan Chiend3c59a22018-03-29 14:08:15 +0800748func TestVndkSpExtUseVndkError(t *testing.T) {
749 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
750 // library.
751 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
752 cc_library {
753 name: "libvndk",
754 vendor_available: true,
755 vndk: {
756 enabled: true,
757 },
758 nocrt: true,
759 }
760
761 cc_library {
762 name: "libvndk_sp",
763 vendor_available: true,
764 vndk: {
765 enabled: true,
766 support_system_process: true,
767 },
768 nocrt: true,
769 }
770
771 cc_library {
772 name: "libvndk_sp_ext",
773 vendor: true,
774 vndk: {
775 enabled: true,
776 extends: "libvndk_sp",
777 support_system_process: true,
778 },
779 shared_libs: ["libvndk"], // Cause an error
780 nocrt: true,
781 }
782 `)
783
784 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
785 // library.
786 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
787 cc_library {
788 name: "libvndk",
789 vendor_available: true,
790 vndk: {
791 enabled: true,
792 },
793 nocrt: true,
794 }
795
796 cc_library {
797 name: "libvndk_ext",
798 vendor: true,
799 vndk: {
800 enabled: true,
801 extends: "libvndk",
802 },
803 nocrt: true,
804 }
805
806 cc_library {
807 name: "libvndk_sp",
808 vendor_available: true,
809 vndk: {
810 enabled: true,
811 support_system_process: true,
812 },
813 nocrt: true,
814 }
815
816 cc_library {
817 name: "libvndk_sp_ext",
818 vendor: true,
819 vndk: {
820 enabled: true,
821 extends: "libvndk_sp",
822 support_system_process: true,
823 },
824 shared_libs: ["libvndk_ext"], // Cause an error
825 nocrt: true,
826 }
827 `)
828}
829
830func TestVndkUseVndkExtError(t *testing.T) {
831 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
832 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800833 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
834 cc_library {
835 name: "libvndk",
836 vendor_available: true,
837 vndk: {
838 enabled: true,
839 },
840 nocrt: true,
841 }
842
843 cc_library {
844 name: "libvndk_ext",
845 vendor: true,
846 vndk: {
847 enabled: true,
848 extends: "libvndk",
849 },
850 nocrt: true,
851 }
852
853 cc_library {
854 name: "libvndk2",
855 vendor_available: true,
856 vndk: {
857 enabled: true,
858 },
859 shared_libs: ["libvndk_ext"],
860 nocrt: true,
861 }
862 `)
863
864 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
865 // but target.vendor.shared_libs has not been supported yet.
866 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
867 cc_library {
868 name: "libvndk",
869 vendor_available: true,
870 vndk: {
871 enabled: true,
872 },
873 nocrt: true,
874 }
875
876 cc_library {
877 name: "libvndk_ext",
878 vendor: true,
879 vndk: {
880 enabled: true,
881 extends: "libvndk",
882 },
883 nocrt: true,
884 }
885
886 cc_library {
887 name: "libvndk2",
888 vendor_available: true,
889 vndk: {
890 enabled: true,
891 },
892 target: {
893 vendor: {
894 shared_libs: ["libvndk_ext"],
895 },
896 },
897 nocrt: true,
898 }
899 `)
900
901 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
902 cc_library {
903 name: "libvndk_sp",
904 vendor_available: true,
905 vndk: {
906 enabled: true,
907 support_system_process: true,
908 },
909 nocrt: true,
910 }
911
912 cc_library {
913 name: "libvndk_sp_ext",
914 vendor: true,
915 vndk: {
916 enabled: true,
917 extends: "libvndk_sp",
918 support_system_process: true,
919 },
920 nocrt: true,
921 }
922
923 cc_library {
924 name: "libvndk_sp_2",
925 vendor_available: true,
926 vndk: {
927 enabled: true,
928 support_system_process: true,
929 },
930 shared_libs: ["libvndk_sp_ext"],
931 nocrt: true,
932 }
933 `)
934
935 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
936 // but target.vendor.shared_libs has not been supported yet.
937 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
938 cc_library {
939 name: "libvndk_sp",
940 vendor_available: true,
941 vndk: {
942 enabled: true,
943 },
944 nocrt: true,
945 }
946
947 cc_library {
948 name: "libvndk_sp_ext",
949 vendor: true,
950 vndk: {
951 enabled: true,
952 extends: "libvndk_sp",
953 },
954 nocrt: true,
955 }
956
957 cc_library {
958 name: "libvndk_sp2",
959 vendor_available: true,
960 vndk: {
961 enabled: true,
962 },
963 target: {
964 vendor: {
965 shared_libs: ["libvndk_sp_ext"],
966 },
967 },
968 nocrt: true,
969 }
970 `)
971}
972
Colin Cross0af4b842015-04-30 16:36:18 -0700973var (
974 str11 = "01234567891"
975 str10 = str11[:10]
976 str9 = str11[:9]
977 str5 = str11[:5]
978 str4 = str11[:4]
979)
980
981var splitListForSizeTestCases = []struct {
982 in []string
983 out [][]string
984 size int
985}{
986 {
987 in: []string{str10},
988 out: [][]string{{str10}},
989 size: 10,
990 },
991 {
992 in: []string{str9},
993 out: [][]string{{str9}},
994 size: 10,
995 },
996 {
997 in: []string{str5},
998 out: [][]string{{str5}},
999 size: 10,
1000 },
1001 {
1002 in: []string{str11},
1003 out: nil,
1004 size: 10,
1005 },
1006 {
1007 in: []string{str10, str10},
1008 out: [][]string{{str10}, {str10}},
1009 size: 10,
1010 },
1011 {
1012 in: []string{str9, str10},
1013 out: [][]string{{str9}, {str10}},
1014 size: 10,
1015 },
1016 {
1017 in: []string{str10, str9},
1018 out: [][]string{{str10}, {str9}},
1019 size: 10,
1020 },
1021 {
1022 in: []string{str5, str4},
1023 out: [][]string{{str5, str4}},
1024 size: 10,
1025 },
1026 {
1027 in: []string{str5, str4, str5},
1028 out: [][]string{{str5, str4}, {str5}},
1029 size: 10,
1030 },
1031 {
1032 in: []string{str5, str4, str5, str4},
1033 out: [][]string{{str5, str4}, {str5, str4}},
1034 size: 10,
1035 },
1036 {
1037 in: []string{str5, str4, str5, str5},
1038 out: [][]string{{str5, str4}, {str5}, {str5}},
1039 size: 10,
1040 },
1041 {
1042 in: []string{str5, str5, str5, str4},
1043 out: [][]string{{str5}, {str5}, {str5, str4}},
1044 size: 10,
1045 },
1046 {
1047 in: []string{str9, str11},
1048 out: nil,
1049 size: 10,
1050 },
1051 {
1052 in: []string{str11, str9},
1053 out: nil,
1054 size: 10,
1055 },
1056}
1057
1058func TestSplitListForSize(t *testing.T) {
1059 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -07001060 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
1061
1062 var outStrings [][]string
1063
1064 if len(out) > 0 {
1065 outStrings = make([][]string, len(out))
1066 for i, o := range out {
1067 outStrings[i] = o.Strings()
1068 }
1069 }
1070
1071 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001072 t.Errorf("incorrect output:")
1073 t.Errorf(" input: %#v", testCase.in)
1074 t.Errorf(" size: %d", testCase.size)
1075 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001076 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001077 }
1078 }
1079}
Jeff Gaston294356f2017-09-27 17:05:30 -07001080
1081var staticLinkDepOrderTestCases = []struct {
1082 // This is a string representation of a map[moduleName][]moduleDependency .
1083 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001084 inStatic string
1085
1086 // This is a string representation of a map[moduleName][]moduleDependency .
1087 // It models the dependencies declared in an Android.bp file.
1088 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001089
1090 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1091 // The keys of allOrdered specify which modules we would like to check.
1092 // The values of allOrdered specify the expected result (of the transitive closure of all
1093 // dependencies) for each module to test
1094 allOrdered string
1095
1096 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1097 // The keys of outOrdered specify which modules we would like to check.
1098 // The values of outOrdered specify the expected result (of the ordered linker command line)
1099 // for each module to test.
1100 outOrdered string
1101}{
1102 // Simple tests
1103 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001104 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001105 outOrdered: "",
1106 },
1107 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001108 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001109 outOrdered: "a:",
1110 },
1111 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001112 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001113 outOrdered: "a:b; b:",
1114 },
1115 // Tests of reordering
1116 {
1117 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001118 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001119 outOrdered: "a:b,c,d; b:d; c:d; d:",
1120 },
1121 {
1122 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001123 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001124 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1125 },
1126 {
1127 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001128 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001129 outOrdered: "a:d,b,e,c; d:b; e:c",
1130 },
1131 {
1132 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001133 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001134 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1135 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1136 },
1137 {
1138 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001139 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 -07001140 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1141 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1142 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001143 // shared dependencies
1144 {
1145 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1146 // So, we don't actually have to check that a shared dependency of c will change the order
1147 // of a library that depends statically on b and on c. We only need to check that if c has
1148 // a shared dependency on b, that that shows up in allOrdered.
1149 inShared: "c:b",
1150 allOrdered: "c:b",
1151 outOrdered: "c:",
1152 },
1153 {
1154 // This test doesn't actually include any shared dependencies but it's a reminder of what
1155 // the second phase of the above test would look like
1156 inStatic: "a:b,c; c:b",
1157 allOrdered: "a:c,b; c:b",
1158 outOrdered: "a:c,b; c:b",
1159 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001160 // tiebreakers for when two modules specifying different orderings and there is no dependency
1161 // to dictate an order
1162 {
1163 // 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 -08001164 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001165 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1166 },
1167 {
1168 // 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 -08001169 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 -07001170 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1171 },
1172 // Tests involving duplicate dependencies
1173 {
1174 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001175 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001176 outOrdered: "a:c,b",
1177 },
1178 {
1179 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001180 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001181 outOrdered: "a:d,c,b",
1182 },
1183 // Tests to confirm the nonexistence of infinite loops.
1184 // These cases should never happen, so as long as the test terminates and the
1185 // result is deterministic then that should be fine.
1186 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001187 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001188 outOrdered: "a:a",
1189 },
1190 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001191 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001192 allOrdered: "a:b,c; b:c,a; c:a,b",
1193 outOrdered: "a:b; b:c; c:a",
1194 },
1195 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001196 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001197 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1198 outOrdered: "a:c,b; b:a,c; c:b,a",
1199 },
1200}
1201
1202// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1203func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1204 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1205 strippedText := strings.Replace(text, " ", "", -1)
1206 if len(strippedText) < 1 {
1207 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1208 }
1209 allDeps = make(map[android.Path][]android.Path, 0)
1210
1211 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1212 moduleTexts := strings.Split(strippedText, ";")
1213
1214 outputForModuleName := func(moduleName string) android.Path {
1215 return android.PathForTesting(moduleName)
1216 }
1217
1218 for _, moduleText := range moduleTexts {
1219 // convert from "a:b,c" to ["a", "b,c"]
1220 components := strings.Split(moduleText, ":")
1221 if len(components) != 2 {
1222 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1223 }
1224 moduleName := components[0]
1225 moduleOutput := outputForModuleName(moduleName)
1226 modulesInOrder = append(modulesInOrder, moduleOutput)
1227
1228 depString := components[1]
1229 // convert from "b,c" to ["b", "c"]
1230 depNames := strings.Split(depString, ",")
1231 if len(depString) < 1 {
1232 depNames = []string{}
1233 }
1234 var deps []android.Path
1235 for _, depName := range depNames {
1236 deps = append(deps, outputForModuleName(depName))
1237 }
1238 allDeps[moduleOutput] = deps
1239 }
1240 return modulesInOrder, allDeps
1241}
1242
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001243func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001244 for _, testCase := range staticLinkDepOrderTestCases {
1245 errs := []string{}
1246
1247 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001248 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001249 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1250 if testCase.allOrdered == "" {
1251 // allow the test case to skip specifying allOrdered
1252 testCase.allOrdered = testCase.outOrdered
1253 }
1254 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001255 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001256
1257 // For each module whose post-reordered dependencies were specified, validate that
1258 // reordering the inputs produces the expected outputs.
1259 for _, moduleName := range expectedModuleNames {
1260 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001261 givenSharedDeps := givenAllSharedDeps[moduleName]
1262 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001263
1264 correctAllOrdered := expectedAllDeps[moduleName]
1265 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1266 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001267 "\nin static:%q"+
1268 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001269 "\nmodule: %v"+
1270 "\nexpected: %s"+
1271 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001272 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001273 }
1274
1275 correctOutputDeps := expectedTransitiveDeps[moduleName]
1276 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1277 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001278 "\nin static:%q"+
1279 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001280 "\nmodule: %v"+
1281 "\nexpected: %s"+
1282 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001283 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001284 }
1285 }
1286
1287 if len(errs) > 0 {
1288 sort.Strings(errs)
1289 for _, err := range errs {
1290 t.Error(err)
1291 }
1292 }
1293 }
1294}
Logan Chienf3511742017-10-31 18:04:35 +08001295
Jeff Gaston294356f2017-09-27 17:05:30 -07001296func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1297 for _, moduleName := range moduleNames {
1298 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1299 output := module.outputFile.Path()
1300 paths = append(paths, output)
1301 }
1302 return paths
1303}
1304
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001305func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001306 ctx := testCc(t, `
1307 cc_library {
1308 name: "a",
1309 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001310 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001311 }
1312 cc_library {
1313 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001314 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001315 }
1316 cc_library {
1317 name: "c",
1318 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001319 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001320 }
1321 cc_library {
1322 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001323 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001324 }
1325
1326 `)
1327
1328 variant := "android_arm64_armv8-a_core_static"
1329 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001330 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001331 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1332
1333 if !reflect.DeepEqual(actual, expected) {
1334 t.Errorf("staticDeps orderings were not propagated correctly"+
1335 "\nactual: %v"+
1336 "\nexpected: %v",
1337 actual,
1338 expected,
1339 )
1340 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001341}
Jeff Gaston294356f2017-09-27 17:05:30 -07001342
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001343func TestStaticLibDepReorderingWithShared(t *testing.T) {
1344 ctx := testCc(t, `
1345 cc_library {
1346 name: "a",
1347 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001348 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001349 }
1350 cc_library {
1351 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001352 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001353 }
1354 cc_library {
1355 name: "c",
1356 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001357 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001358 }
1359
1360 `)
1361
1362 variant := "android_arm64_armv8-a_core_static"
1363 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1364 actual := moduleA.depsInLinkOrder
1365 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1366
1367 if !reflect.DeepEqual(actual, expected) {
1368 t.Errorf("staticDeps orderings did not account for shared libs"+
1369 "\nactual: %v"+
1370 "\nexpected: %v",
1371 actual,
1372 expected,
1373 )
1374 }
1375}
1376
Jiyong Parka46a4d52017-12-14 19:54:34 +09001377func TestLlndkHeaders(t *testing.T) {
1378 ctx := testCc(t, `
1379 llndk_headers {
1380 name: "libllndk_headers",
1381 export_include_dirs: ["my_include"],
1382 }
1383 llndk_library {
1384 name: "libllndk",
1385 export_llndk_headers: ["libllndk_headers"],
1386 }
1387 cc_library {
1388 name: "libvendor",
1389 shared_libs: ["libllndk"],
1390 vendor: true,
1391 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001392 no_libgcc: true,
1393 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001394 }
1395 `)
1396
1397 // _static variant is used since _shared reuses *.o from the static variant
1398 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1399 cflags := cc.Args["cFlags"]
1400 if !strings.Contains(cflags, "-Imy_include") {
1401 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1402 }
1403}
1404
Logan Chien43d34c32017-12-20 01:17:32 +08001405func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1406 actual := module.Properties.AndroidMkRuntimeLibs
1407 if !reflect.DeepEqual(actual, expected) {
1408 t.Errorf("incorrect runtime_libs for shared libs"+
1409 "\nactual: %v"+
1410 "\nexpected: %v",
1411 actual,
1412 expected,
1413 )
1414 }
1415}
1416
1417const runtimeLibAndroidBp = `
1418 cc_library {
1419 name: "libvendor_available1",
1420 vendor_available: true,
1421 no_libgcc : true,
1422 nocrt : true,
1423 system_shared_libs : [],
1424 }
1425 cc_library {
1426 name: "libvendor_available2",
1427 vendor_available: true,
1428 runtime_libs: ["libvendor_available1"],
1429 no_libgcc : true,
1430 nocrt : true,
1431 system_shared_libs : [],
1432 }
1433 cc_library {
1434 name: "libvendor_available3",
1435 vendor_available: true,
1436 runtime_libs: ["libvendor_available1"],
1437 target: {
1438 vendor: {
1439 exclude_runtime_libs: ["libvendor_available1"],
1440 }
1441 },
1442 no_libgcc : true,
1443 nocrt : true,
1444 system_shared_libs : [],
1445 }
1446 cc_library {
1447 name: "libcore",
1448 runtime_libs: ["libvendor_available1"],
1449 no_libgcc : true,
1450 nocrt : true,
1451 system_shared_libs : [],
1452 }
1453 cc_library {
1454 name: "libvendor1",
1455 vendor: true,
1456 no_libgcc : true,
1457 nocrt : true,
1458 system_shared_libs : [],
1459 }
1460 cc_library {
1461 name: "libvendor2",
1462 vendor: true,
1463 runtime_libs: ["libvendor_available1", "libvendor1"],
1464 no_libgcc : true,
1465 nocrt : true,
1466 system_shared_libs : [],
1467 }
1468`
1469
1470func TestRuntimeLibs(t *testing.T) {
1471 ctx := testCc(t, runtimeLibAndroidBp)
1472
1473 // runtime_libs for core variants use the module names without suffixes.
1474 variant := "android_arm64_armv8-a_core_shared"
1475
1476 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1477 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1478
1479 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1480 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1481
1482 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1483 // and vendor variants.
1484 variant = "android_arm64_armv8-a_vendor_shared"
1485
1486 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1487 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1488
1489 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1490 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1491}
1492
1493func TestExcludeRuntimeLibs(t *testing.T) {
1494 ctx := testCc(t, runtimeLibAndroidBp)
1495
1496 variant := "android_arm64_armv8-a_core_shared"
1497 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1498 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1499
1500 variant = "android_arm64_armv8-a_vendor_shared"
1501 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1502 checkRuntimeLibs(t, nil, module)
1503}
1504
1505func TestRuntimeLibsNoVndk(t *testing.T) {
1506 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1507
1508 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1509
1510 variant := "android_arm64_armv8-a_core_shared"
1511
1512 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1513 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1514
1515 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1516 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1517}
1518
Jiyong Parkd08b6972017-09-26 10:50:54 +09001519var compilerFlagsTestCases = []struct {
1520 in string
1521 out bool
1522}{
1523 {
1524 in: "a",
1525 out: false,
1526 },
1527 {
1528 in: "-a",
1529 out: true,
1530 },
1531 {
1532 in: "-Ipath/to/something",
1533 out: false,
1534 },
1535 {
1536 in: "-isystempath/to/something",
1537 out: false,
1538 },
1539 {
1540 in: "--coverage",
1541 out: false,
1542 },
1543 {
1544 in: "-include a/b",
1545 out: true,
1546 },
1547 {
1548 in: "-include a/b c/d",
1549 out: false,
1550 },
1551 {
1552 in: "-DMACRO",
1553 out: true,
1554 },
1555 {
1556 in: "-DMAC RO",
1557 out: false,
1558 },
1559 {
1560 in: "-a -b",
1561 out: false,
1562 },
1563 {
1564 in: "-DMACRO=definition",
1565 out: true,
1566 },
1567 {
1568 in: "-DMACRO=defi nition",
1569 out: true, // TODO(jiyong): this should be false
1570 },
1571 {
1572 in: "-DMACRO(x)=x + 1",
1573 out: true,
1574 },
1575 {
1576 in: "-DMACRO=\"defi nition\"",
1577 out: true,
1578 },
1579}
1580
1581type mockContext struct {
1582 BaseModuleContext
1583 result bool
1584}
1585
1586func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1587 // CheckBadCompilerFlags calls this function when the flag should be rejected
1588 ctx.result = false
1589}
1590
1591func TestCompilerFlags(t *testing.T) {
1592 for _, testCase := range compilerFlagsTestCases {
1593 ctx := &mockContext{result: true}
1594 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1595 if ctx.result != testCase.out {
1596 t.Errorf("incorrect output:")
1597 t.Errorf(" input: %#v", testCase.in)
1598 t.Errorf(" expected: %#v", testCase.out)
1599 t.Errorf(" got: %#v", ctx.result)
1600 }
1601 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001602}
Jiyong Park374510b2018-03-19 18:23:01 +09001603
1604func TestVendorPublicLibraries(t *testing.T) {
1605 ctx := testCc(t, `
1606 cc_library_headers {
1607 name: "libvendorpublic_headers",
1608 export_include_dirs: ["my_include"],
1609 }
1610 vendor_public_library {
1611 name: "libvendorpublic",
1612 symbol_file: "",
1613 export_public_headers: ["libvendorpublic_headers"],
1614 }
1615 cc_library {
1616 name: "libvendorpublic",
1617 srcs: ["foo.c"],
1618 vendor: true,
1619 no_libgcc: true,
1620 nocrt: true,
1621 }
1622
1623 cc_library {
1624 name: "libsystem",
1625 shared_libs: ["libvendorpublic"],
1626 vendor: false,
1627 srcs: ["foo.c"],
1628 no_libgcc: true,
1629 nocrt: true,
1630 }
1631 cc_library {
1632 name: "libvendor",
1633 shared_libs: ["libvendorpublic"],
1634 vendor: true,
1635 srcs: ["foo.c"],
1636 no_libgcc: true,
1637 nocrt: true,
1638 }
1639 `)
1640
1641 variant := "android_arm64_armv8-a_core_shared"
1642
1643 // test if header search paths are correctly added
1644 // _static variant is used since _shared reuses *.o from the static variant
1645 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
1646 cflags := cc.Args["cFlags"]
1647 if !strings.Contains(cflags, "-Imy_include") {
1648 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
1649 }
1650
1651 // test if libsystem is linked to the stub
1652 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
1653 libflags := ld.Args["libFlags"]
1654 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
1655 if !strings.Contains(libflags, stubPaths[0].String()) {
1656 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
1657 }
1658
1659 // test if libvendor is linked to the real shared lib
1660 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
1661 libflags = ld.Args["libFlags"]
1662 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
1663 if !strings.Contains(libflags, stubPaths[0].String()) {
1664 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
1665 }
1666
1667}
Jiyong Park37b25202018-07-11 10:49:27 +09001668
1669func TestRecovery(t *testing.T) {
1670 ctx := testCc(t, `
1671 cc_library_shared {
1672 name: "librecovery",
1673 recovery: true,
1674 }
1675 cc_library_shared {
1676 name: "librecovery32",
1677 recovery: true,
1678 compile_multilib:"32",
1679 }
Jiyong Park5baac542018-08-28 09:55:37 +09001680 cc_library_shared {
1681 name: "libHalInRecovery",
1682 recovery_available: true,
1683 vendor: true,
1684 }
Jiyong Park37b25202018-07-11 10:49:27 +09001685 `)
1686
1687 variants := ctx.ModuleVariantsForTests("librecovery")
1688 const arm64 = "android_arm64_armv8-a_recovery_shared"
1689 if len(variants) != 1 || !android.InList(arm64, variants) {
1690 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1691 }
1692
1693 variants = ctx.ModuleVariantsForTests("librecovery32")
1694 if android.InList(arm64, variants) {
1695 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1696 }
Jiyong Park5baac542018-08-28 09:55:37 +09001697
1698 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1699 if !recoveryModule.Platform() {
1700 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1701 }
1702
Jiyong Park37b25202018-07-11 10:49:27 +09001703}