blob: ead89f6e363dfcad188b2742b9d31e9a9da0151e [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 {
Yi Kong7df0f302018-10-08 22:10:12 +000090 name: "libclang_rt.builtins-arm-android",
91 vendor_available: true,
92 recovery_available: true,
93 src: "",
94 }
95
96 toolchain_library {
97 name: "libclang_rt.builtins-aarch64-android",
98 vendor_available: true,
99 recovery_available: true,
100 src: "",
101 }
102
103 toolchain_library {
104 name: "libclang_rt.builtins-i686-android",
105 vendor_available: true,
106 recovery_available: true,
107 src: "",
108 }
109
110 toolchain_library {
111 name: "libclang_rt.builtins-x86_64-android",
112 vendor_available: true,
113 recovery_available: true,
114 src: "",
115 }
116
117 toolchain_library {
Jeff Gaston294356f2017-09-27 17:05:30 -0700118 name: "libgcc",
119 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900120 recovery_available: true,
Dan Willemsenfeea4df2018-10-07 18:16:48 -0700121 src: "",
Jeff Gaston294356f2017-09-27 17:05:30 -0700122 }
123
124 cc_library {
125 name: "libc",
Logan Chienf3511742017-10-31 18:04:35 +0800126 no_libgcc: true,
127 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700128 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900129 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700130 }
131 llndk_library {
132 name: "libc",
133 symbol_file: "",
134 }
135 cc_library {
136 name: "libm",
Logan Chienf3511742017-10-31 18:04:35 +0800137 no_libgcc: true,
138 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700139 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900140 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700141 }
142 llndk_library {
143 name: "libm",
144 symbol_file: "",
145 }
146 cc_library {
147 name: "libdl",
Logan Chienf3511742017-10-31 18:04:35 +0800148 no_libgcc: true,
149 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700150 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900151 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700152 }
153 llndk_library {
154 name: "libdl",
155 symbol_file: "",
156 }
Jiyong Park374510b2018-03-19 18:23:01 +0900157 cc_library {
158 name: "libc++_static",
159 no_libgcc: true,
160 nocrt: true,
161 system_shared_libs: [],
162 stl: "none",
163 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900164 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900165 }
166 cc_library {
167 name: "libc++",
168 no_libgcc: true,
169 nocrt: true,
170 system_shared_libs: [],
171 stl: "none",
172 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900173 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900174 vndk: {
175 enabled: true,
176 support_system_process: true,
177 },
178 }
179 cc_library {
180 name: "libunwind_llvm",
181 no_libgcc: true,
182 nocrt: true,
183 system_shared_libs: [],
184 stl: "none",
185 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900186 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900187 }
Jeff Gaston294356f2017-09-27 17:05:30 -0700188
189 cc_object {
190 name: "crtbegin_so",
Jiyong Park37b25202018-07-11 10:49:27 +0900191 recovery_available: true,
Jiyong Park5baac542018-08-28 09:55:37 +0900192 vendor_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700193 }
194
195 cc_object {
196 name: "crtend_so",
Jiyong Park37b25202018-07-11 10:49:27 +0900197 recovery_available: true,
Jiyong Park5baac542018-08-28 09:55:37 +0900198 vendor_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700199 }
200
Colin Crossad59e752017-11-16 14:29:11 -0800201 cc_library {
202 name: "libprotobuf-cpp-lite",
203 }
204
Jeff Gaston294356f2017-09-27 17:05:30 -0700205`
206
Jiyong Park6a43f042017-10-12 23:05:00 +0900207 ctx.MockFileSystem(map[string][]byte{
208 "Android.bp": []byte(bp),
209 "foo.c": nil,
210 "bar.c": nil,
Colin Crossad59e752017-11-16 14:29:11 -0800211 "a.proto": nil,
Colin Crossf18e1102017-11-16 14:33:08 -0800212 "b.aidl": nil,
Jiyong Parka46a4d52017-12-14 19:54:34 +0900213 "my_include": nil,
Jiyong Park6a43f042017-10-12 23:05:00 +0900214 })
215
Logan Chienf3511742017-10-31 18:04:35 +0800216 return ctx
217}
218
219func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800220 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800221 ctx := createTestContext(t, config, bp)
222
Jeff Gastond3e141d2017-08-08 17:46:01 -0700223 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +0800224 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900225 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800226 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900227
228 return ctx
229}
230
Logan Chienf3511742017-10-31 18:04:35 +0800231func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800232 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800233 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700234 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
235 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800236
237 return testCcWithConfig(t, bp, config)
238}
239
240func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800241 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800242 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700243 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800244
245 return testCcWithConfig(t, bp, config)
246}
247
248func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800249 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800250 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700251 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
252 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800253
254 ctx := createTestContext(t, config, bp)
255
256 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
257 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800258 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800259 return
260 }
261
262 _, errs = ctx.PrepareBuildActions(config)
263 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800264 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800265 return
266 }
267
268 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
269}
270
271const (
Jiyong Park5baac542018-08-28 09:55:37 +0900272 coreVariant = "android_arm64_armv8-a_core_shared"
273 vendorVariant = "android_arm64_armv8-a_vendor_shared"
274 recoveryVariant = "android_arm64_armv8-a_recovery_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800275)
276
Jiyong Park6a43f042017-10-12 23:05:00 +0900277func TestVendorSrc(t *testing.T) {
278 ctx := testCc(t, `
279 cc_library {
280 name: "libTest",
281 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800282 no_libgcc: true,
283 nocrt: true,
284 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900285 vendor_available: true,
286 target: {
287 vendor: {
288 srcs: ["bar.c"],
289 },
290 },
291 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900292 `)
293
Logan Chienf3511742017-10-31 18:04:35 +0800294 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900295 var objs []string
296 for _, o := range ld.Inputs {
297 objs = append(objs, o.Base())
298 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800299 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900300 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
301 }
302}
303
Logan Chienf3511742017-10-31 18:04:35 +0800304func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
305 isVndkSp bool, extends string) {
306
Logan Chiend3c59a22018-03-29 14:08:15 +0800307 t.Helper()
308
Logan Chienf3511742017-10-31 18:04:35 +0800309 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
310 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700311 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800312 }
313
314 // Check library properties.
315 lib, ok := mod.compiler.(*libraryDecorator)
316 if !ok {
317 t.Errorf("%q must have libraryDecorator", name)
318 } else if lib.baseInstaller.subDir != subDir {
319 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
320 lib.baseInstaller.subDir)
321 }
322
323 // Check VNDK properties.
324 if mod.vndkdep == nil {
325 t.Fatalf("%q must have `vndkdep`", name)
326 }
327 if !mod.isVndk() {
328 t.Errorf("%q isVndk() must equal to true", name)
329 }
330 if mod.isVndkSp() != isVndkSp {
331 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
332 }
333
334 // Check VNDK extension properties.
335 isVndkExt := extends != ""
336 if mod.isVndkExt() != isVndkExt {
337 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
338 }
339
340 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
341 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
342 }
343}
344
345func TestVndk(t *testing.T) {
346 ctx := testCc(t, `
347 cc_library {
348 name: "libvndk",
349 vendor_available: true,
350 vndk: {
351 enabled: true,
352 },
353 nocrt: true,
354 }
355
356 cc_library {
357 name: "libvndk_private",
358 vendor_available: false,
359 vndk: {
360 enabled: true,
361 },
362 nocrt: true,
363 }
364
365 cc_library {
366 name: "libvndk_sp",
367 vendor_available: true,
368 vndk: {
369 enabled: true,
370 support_system_process: true,
371 },
372 nocrt: true,
373 }
374
375 cc_library {
376 name: "libvndk_sp_private",
377 vendor_available: false,
378 vndk: {
379 enabled: true,
380 support_system_process: true,
381 },
382 nocrt: true,
383 }
384 `)
385
386 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
387 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
388 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
389 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
390}
391
Logan Chiend3c59a22018-03-29 14:08:15 +0800392func TestVndkDepError(t *testing.T) {
393 // Check whether an error is emitted when a VNDK lib depends on a system lib.
394 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
395 cc_library {
396 name: "libvndk",
397 vendor_available: true,
398 vndk: {
399 enabled: true,
400 },
401 shared_libs: ["libfwk"], // Cause error
402 nocrt: true,
403 }
404
405 cc_library {
406 name: "libfwk",
407 nocrt: true,
408 }
409 `)
410
411 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
412 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
413 cc_library {
414 name: "libvndk",
415 vendor_available: true,
416 vndk: {
417 enabled: true,
418 },
419 shared_libs: ["libvendor"], // Cause error
420 nocrt: true,
421 }
422
423 cc_library {
424 name: "libvendor",
425 vendor: true,
426 nocrt: true,
427 }
428 `)
429
430 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
431 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
432 cc_library {
433 name: "libvndk_sp",
434 vendor_available: true,
435 vndk: {
436 enabled: true,
437 support_system_process: true,
438 },
439 shared_libs: ["libfwk"], // Cause error
440 nocrt: true,
441 }
442
443 cc_library {
444 name: "libfwk",
445 nocrt: true,
446 }
447 `)
448
449 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
450 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
451 cc_library {
452 name: "libvndk_sp",
453 vendor_available: true,
454 vndk: {
455 enabled: true,
456 support_system_process: true,
457 },
458 shared_libs: ["libvendor"], // Cause error
459 nocrt: true,
460 }
461
462 cc_library {
463 name: "libvendor",
464 vendor: true,
465 nocrt: true,
466 }
467 `)
468
469 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
470 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
471 cc_library {
472 name: "libvndk_sp",
473 vendor_available: true,
474 vndk: {
475 enabled: true,
476 support_system_process: true,
477 },
478 shared_libs: ["libvndk"], // Cause error
479 nocrt: true,
480 }
481
482 cc_library {
483 name: "libvndk",
484 vendor_available: true,
485 vndk: {
486 enabled: true,
487 },
488 nocrt: true,
489 }
490 `)
491}
492
Logan Chienf3511742017-10-31 18:04:35 +0800493func TestVndkExt(t *testing.T) {
494 // This test checks the VNDK-Ext properties.
495 ctx := testCc(t, `
496 cc_library {
497 name: "libvndk",
498 vendor_available: true,
499 vndk: {
500 enabled: true,
501 },
502 nocrt: true,
503 }
504
505 cc_library {
506 name: "libvndk_ext",
507 vendor: true,
508 vndk: {
509 enabled: true,
510 extends: "libvndk",
511 },
512 nocrt: true,
513 }
514 `)
515
516 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
517}
518
Logan Chiend3c59a22018-03-29 14:08:15 +0800519func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800520 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
521 ctx := testCcNoVndk(t, `
522 cc_library {
523 name: "libvndk",
524 vendor_available: true,
525 vndk: {
526 enabled: true,
527 },
528 nocrt: true,
529 }
530
531 cc_library {
532 name: "libvndk_ext",
533 vendor: true,
534 vndk: {
535 enabled: true,
536 extends: "libvndk",
537 },
538 nocrt: true,
539 }
540 `)
541
542 // Ensures that the core variant of "libvndk_ext" can be found.
543 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
544 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
545 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
546 }
547}
548
549func TestVndkExtError(t *testing.T) {
550 // This test ensures an error is emitted in ill-formed vndk-ext definition.
551 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
552 cc_library {
553 name: "libvndk",
554 vendor_available: true,
555 vndk: {
556 enabled: true,
557 },
558 nocrt: true,
559 }
560
561 cc_library {
562 name: "libvndk_ext",
563 vndk: {
564 enabled: true,
565 extends: "libvndk",
566 },
567 nocrt: true,
568 }
569 `)
570
571 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
572 cc_library {
573 name: "libvndk",
574 vendor_available: true,
575 vndk: {
576 enabled: true,
577 },
578 nocrt: true,
579 }
580
581 cc_library {
582 name: "libvndk_ext",
583 vendor: true,
584 vndk: {
585 enabled: true,
586 },
587 nocrt: true,
588 }
589 `)
590}
591
592func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
593 // This test ensures an error is emitted for inconsistent support_system_process.
594 testCcError(t, "module \".*\" with mismatched support_system_process", `
595 cc_library {
596 name: "libvndk",
597 vendor_available: true,
598 vndk: {
599 enabled: true,
600 },
601 nocrt: true,
602 }
603
604 cc_library {
605 name: "libvndk_sp_ext",
606 vendor: true,
607 vndk: {
608 enabled: true,
609 extends: "libvndk",
610 support_system_process: true,
611 },
612 nocrt: true,
613 }
614 `)
615
616 testCcError(t, "module \".*\" with mismatched support_system_process", `
617 cc_library {
618 name: "libvndk_sp",
619 vendor_available: true,
620 vndk: {
621 enabled: true,
622 support_system_process: true,
623 },
624 nocrt: true,
625 }
626
627 cc_library {
628 name: "libvndk_ext",
629 vendor: true,
630 vndk: {
631 enabled: true,
632 extends: "libvndk_sp",
633 },
634 nocrt: true,
635 }
636 `)
637}
638
639func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800640 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800641 // with `vendor_available: false`.
642 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
643 cc_library {
644 name: "libvndk",
645 vendor_available: false,
646 vndk: {
647 enabled: true,
648 },
649 nocrt: true,
650 }
651
652 cc_library {
653 name: "libvndk_ext",
654 vendor: true,
655 vndk: {
656 enabled: true,
657 extends: "libvndk",
658 },
659 nocrt: true,
660 }
661 `)
662}
663
Logan Chiend3c59a22018-03-29 14:08:15 +0800664func TestVendorModuleUseVndkExt(t *testing.T) {
665 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800666 testCc(t, `
667 cc_library {
668 name: "libvndk",
669 vendor_available: true,
670 vndk: {
671 enabled: true,
672 },
673 nocrt: true,
674 }
675
676 cc_library {
677 name: "libvndk_ext",
678 vendor: true,
679 vndk: {
680 enabled: true,
681 extends: "libvndk",
682 },
683 nocrt: true,
684 }
685
686 cc_library {
687
688 name: "libvndk_sp",
689 vendor_available: true,
690 vndk: {
691 enabled: true,
692 support_system_process: true,
693 },
694 nocrt: true,
695 }
696
697 cc_library {
698 name: "libvndk_sp_ext",
699 vendor: true,
700 vndk: {
701 enabled: true,
702 extends: "libvndk_sp",
703 support_system_process: true,
704 },
705 nocrt: true,
706 }
707
708 cc_library {
709 name: "libvendor",
710 vendor: true,
711 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
712 nocrt: true,
713 }
714 `)
715}
716
Logan Chiend3c59a22018-03-29 14:08:15 +0800717func TestVndkExtUseVendorLib(t *testing.T) {
718 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800719 testCc(t, `
720 cc_library {
721 name: "libvndk",
722 vendor_available: true,
723 vndk: {
724 enabled: true,
725 },
726 nocrt: true,
727 }
728
729 cc_library {
730 name: "libvndk_ext",
731 vendor: true,
732 vndk: {
733 enabled: true,
734 extends: "libvndk",
735 },
736 shared_libs: ["libvendor"],
737 nocrt: true,
738 }
739
740 cc_library {
741 name: "libvendor",
742 vendor: true,
743 nocrt: true,
744 }
745 `)
Logan Chienf3511742017-10-31 18:04:35 +0800746
Logan Chiend3c59a22018-03-29 14:08:15 +0800747 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
748 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800749 cc_library {
750 name: "libvndk_sp",
751 vendor_available: true,
752 vndk: {
753 enabled: true,
754 support_system_process: true,
755 },
756 nocrt: true,
757 }
758
759 cc_library {
760 name: "libvndk_sp_ext",
761 vendor: true,
762 vndk: {
763 enabled: true,
764 extends: "libvndk_sp",
765 support_system_process: true,
766 },
767 shared_libs: ["libvendor"], // Cause an error
768 nocrt: true,
769 }
770
771 cc_library {
772 name: "libvendor",
773 vendor: true,
774 nocrt: true,
775 }
776 `)
777}
778
Logan Chiend3c59a22018-03-29 14:08:15 +0800779func TestVndkSpExtUseVndkError(t *testing.T) {
780 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
781 // library.
782 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
783 cc_library {
784 name: "libvndk",
785 vendor_available: true,
786 vndk: {
787 enabled: true,
788 },
789 nocrt: true,
790 }
791
792 cc_library {
793 name: "libvndk_sp",
794 vendor_available: true,
795 vndk: {
796 enabled: true,
797 support_system_process: true,
798 },
799 nocrt: true,
800 }
801
802 cc_library {
803 name: "libvndk_sp_ext",
804 vendor: true,
805 vndk: {
806 enabled: true,
807 extends: "libvndk_sp",
808 support_system_process: true,
809 },
810 shared_libs: ["libvndk"], // Cause an error
811 nocrt: true,
812 }
813 `)
814
815 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
816 // library.
817 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
818 cc_library {
819 name: "libvndk",
820 vendor_available: true,
821 vndk: {
822 enabled: true,
823 },
824 nocrt: true,
825 }
826
827 cc_library {
828 name: "libvndk_ext",
829 vendor: true,
830 vndk: {
831 enabled: true,
832 extends: "libvndk",
833 },
834 nocrt: true,
835 }
836
837 cc_library {
838 name: "libvndk_sp",
839 vendor_available: true,
840 vndk: {
841 enabled: true,
842 support_system_process: true,
843 },
844 nocrt: true,
845 }
846
847 cc_library {
848 name: "libvndk_sp_ext",
849 vendor: true,
850 vndk: {
851 enabled: true,
852 extends: "libvndk_sp",
853 support_system_process: true,
854 },
855 shared_libs: ["libvndk_ext"], // Cause an error
856 nocrt: true,
857 }
858 `)
859}
860
861func TestVndkUseVndkExtError(t *testing.T) {
862 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
863 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800864 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
865 cc_library {
866 name: "libvndk",
867 vendor_available: true,
868 vndk: {
869 enabled: true,
870 },
871 nocrt: true,
872 }
873
874 cc_library {
875 name: "libvndk_ext",
876 vendor: true,
877 vndk: {
878 enabled: true,
879 extends: "libvndk",
880 },
881 nocrt: true,
882 }
883
884 cc_library {
885 name: "libvndk2",
886 vendor_available: true,
887 vndk: {
888 enabled: true,
889 },
890 shared_libs: ["libvndk_ext"],
891 nocrt: true,
892 }
893 `)
894
895 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
896 // but target.vendor.shared_libs has not been supported yet.
897 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
898 cc_library {
899 name: "libvndk",
900 vendor_available: true,
901 vndk: {
902 enabled: true,
903 },
904 nocrt: true,
905 }
906
907 cc_library {
908 name: "libvndk_ext",
909 vendor: true,
910 vndk: {
911 enabled: true,
912 extends: "libvndk",
913 },
914 nocrt: true,
915 }
916
917 cc_library {
918 name: "libvndk2",
919 vendor_available: true,
920 vndk: {
921 enabled: true,
922 },
923 target: {
924 vendor: {
925 shared_libs: ["libvndk_ext"],
926 },
927 },
928 nocrt: true,
929 }
930 `)
931
932 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
933 cc_library {
934 name: "libvndk_sp",
935 vendor_available: true,
936 vndk: {
937 enabled: true,
938 support_system_process: true,
939 },
940 nocrt: true,
941 }
942
943 cc_library {
944 name: "libvndk_sp_ext",
945 vendor: true,
946 vndk: {
947 enabled: true,
948 extends: "libvndk_sp",
949 support_system_process: true,
950 },
951 nocrt: true,
952 }
953
954 cc_library {
955 name: "libvndk_sp_2",
956 vendor_available: true,
957 vndk: {
958 enabled: true,
959 support_system_process: true,
960 },
961 shared_libs: ["libvndk_sp_ext"],
962 nocrt: true,
963 }
964 `)
965
966 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
967 // but target.vendor.shared_libs has not been supported yet.
968 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
969 cc_library {
970 name: "libvndk_sp",
971 vendor_available: true,
972 vndk: {
973 enabled: true,
974 },
975 nocrt: true,
976 }
977
978 cc_library {
979 name: "libvndk_sp_ext",
980 vendor: true,
981 vndk: {
982 enabled: true,
983 extends: "libvndk_sp",
984 },
985 nocrt: true,
986 }
987
988 cc_library {
989 name: "libvndk_sp2",
990 vendor_available: true,
991 vndk: {
992 enabled: true,
993 },
994 target: {
995 vendor: {
996 shared_libs: ["libvndk_sp_ext"],
997 },
998 },
999 nocrt: true,
1000 }
1001 `)
1002}
1003
Colin Cross0af4b842015-04-30 16:36:18 -07001004var (
1005 str11 = "01234567891"
1006 str10 = str11[:10]
1007 str9 = str11[:9]
1008 str5 = str11[:5]
1009 str4 = str11[:4]
1010)
1011
1012var splitListForSizeTestCases = []struct {
1013 in []string
1014 out [][]string
1015 size int
1016}{
1017 {
1018 in: []string{str10},
1019 out: [][]string{{str10}},
1020 size: 10,
1021 },
1022 {
1023 in: []string{str9},
1024 out: [][]string{{str9}},
1025 size: 10,
1026 },
1027 {
1028 in: []string{str5},
1029 out: [][]string{{str5}},
1030 size: 10,
1031 },
1032 {
1033 in: []string{str11},
1034 out: nil,
1035 size: 10,
1036 },
1037 {
1038 in: []string{str10, str10},
1039 out: [][]string{{str10}, {str10}},
1040 size: 10,
1041 },
1042 {
1043 in: []string{str9, str10},
1044 out: [][]string{{str9}, {str10}},
1045 size: 10,
1046 },
1047 {
1048 in: []string{str10, str9},
1049 out: [][]string{{str10}, {str9}},
1050 size: 10,
1051 },
1052 {
1053 in: []string{str5, str4},
1054 out: [][]string{{str5, str4}},
1055 size: 10,
1056 },
1057 {
1058 in: []string{str5, str4, str5},
1059 out: [][]string{{str5, str4}, {str5}},
1060 size: 10,
1061 },
1062 {
1063 in: []string{str5, str4, str5, str4},
1064 out: [][]string{{str5, str4}, {str5, str4}},
1065 size: 10,
1066 },
1067 {
1068 in: []string{str5, str4, str5, str5},
1069 out: [][]string{{str5, str4}, {str5}, {str5}},
1070 size: 10,
1071 },
1072 {
1073 in: []string{str5, str5, str5, str4},
1074 out: [][]string{{str5}, {str5}, {str5, str4}},
1075 size: 10,
1076 },
1077 {
1078 in: []string{str9, str11},
1079 out: nil,
1080 size: 10,
1081 },
1082 {
1083 in: []string{str11, str9},
1084 out: nil,
1085 size: 10,
1086 },
1087}
1088
1089func TestSplitListForSize(t *testing.T) {
1090 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -07001091 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
1092
1093 var outStrings [][]string
1094
1095 if len(out) > 0 {
1096 outStrings = make([][]string, len(out))
1097 for i, o := range out {
1098 outStrings[i] = o.Strings()
1099 }
1100 }
1101
1102 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001103 t.Errorf("incorrect output:")
1104 t.Errorf(" input: %#v", testCase.in)
1105 t.Errorf(" size: %d", testCase.size)
1106 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001107 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001108 }
1109 }
1110}
Jeff Gaston294356f2017-09-27 17:05:30 -07001111
1112var staticLinkDepOrderTestCases = []struct {
1113 // This is a string representation of a map[moduleName][]moduleDependency .
1114 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001115 inStatic string
1116
1117 // This is a string representation of a map[moduleName][]moduleDependency .
1118 // It models the dependencies declared in an Android.bp file.
1119 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001120
1121 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1122 // The keys of allOrdered specify which modules we would like to check.
1123 // The values of allOrdered specify the expected result (of the transitive closure of all
1124 // dependencies) for each module to test
1125 allOrdered string
1126
1127 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1128 // The keys of outOrdered specify which modules we would like to check.
1129 // The values of outOrdered specify the expected result (of the ordered linker command line)
1130 // for each module to test.
1131 outOrdered string
1132}{
1133 // Simple tests
1134 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001135 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001136 outOrdered: "",
1137 },
1138 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001139 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001140 outOrdered: "a:",
1141 },
1142 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001143 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001144 outOrdered: "a:b; b:",
1145 },
1146 // Tests of reordering
1147 {
1148 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001149 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001150 outOrdered: "a:b,c,d; b:d; c:d; d:",
1151 },
1152 {
1153 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001154 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001155 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1156 },
1157 {
1158 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001159 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001160 outOrdered: "a:d,b,e,c; d:b; e:c",
1161 },
1162 {
1163 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001164 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001165 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1166 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1167 },
1168 {
1169 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001170 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 -07001171 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1172 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1173 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001174 // shared dependencies
1175 {
1176 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1177 // So, we don't actually have to check that a shared dependency of c will change the order
1178 // of a library that depends statically on b and on c. We only need to check that if c has
1179 // a shared dependency on b, that that shows up in allOrdered.
1180 inShared: "c:b",
1181 allOrdered: "c:b",
1182 outOrdered: "c:",
1183 },
1184 {
1185 // This test doesn't actually include any shared dependencies but it's a reminder of what
1186 // the second phase of the above test would look like
1187 inStatic: "a:b,c; c:b",
1188 allOrdered: "a:c,b; c:b",
1189 outOrdered: "a:c,b; c:b",
1190 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001191 // tiebreakers for when two modules specifying different orderings and there is no dependency
1192 // to dictate an order
1193 {
1194 // 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 -08001195 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001196 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1197 },
1198 {
1199 // 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 -08001200 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 -07001201 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1202 },
1203 // Tests involving duplicate dependencies
1204 {
1205 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001206 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001207 outOrdered: "a:c,b",
1208 },
1209 {
1210 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001211 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001212 outOrdered: "a:d,c,b",
1213 },
1214 // Tests to confirm the nonexistence of infinite loops.
1215 // These cases should never happen, so as long as the test terminates and the
1216 // result is deterministic then that should be fine.
1217 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001218 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001219 outOrdered: "a:a",
1220 },
1221 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001222 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001223 allOrdered: "a:b,c; b:c,a; c:a,b",
1224 outOrdered: "a:b; b:c; c:a",
1225 },
1226 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001227 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001228 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1229 outOrdered: "a:c,b; b:a,c; c:b,a",
1230 },
1231}
1232
1233// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1234func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1235 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1236 strippedText := strings.Replace(text, " ", "", -1)
1237 if len(strippedText) < 1 {
1238 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1239 }
1240 allDeps = make(map[android.Path][]android.Path, 0)
1241
1242 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1243 moduleTexts := strings.Split(strippedText, ";")
1244
1245 outputForModuleName := func(moduleName string) android.Path {
1246 return android.PathForTesting(moduleName)
1247 }
1248
1249 for _, moduleText := range moduleTexts {
1250 // convert from "a:b,c" to ["a", "b,c"]
1251 components := strings.Split(moduleText, ":")
1252 if len(components) != 2 {
1253 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1254 }
1255 moduleName := components[0]
1256 moduleOutput := outputForModuleName(moduleName)
1257 modulesInOrder = append(modulesInOrder, moduleOutput)
1258
1259 depString := components[1]
1260 // convert from "b,c" to ["b", "c"]
1261 depNames := strings.Split(depString, ",")
1262 if len(depString) < 1 {
1263 depNames = []string{}
1264 }
1265 var deps []android.Path
1266 for _, depName := range depNames {
1267 deps = append(deps, outputForModuleName(depName))
1268 }
1269 allDeps[moduleOutput] = deps
1270 }
1271 return modulesInOrder, allDeps
1272}
1273
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001274func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001275 for _, testCase := range staticLinkDepOrderTestCases {
1276 errs := []string{}
1277
1278 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001279 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001280 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1281 if testCase.allOrdered == "" {
1282 // allow the test case to skip specifying allOrdered
1283 testCase.allOrdered = testCase.outOrdered
1284 }
1285 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001286 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001287
1288 // For each module whose post-reordered dependencies were specified, validate that
1289 // reordering the inputs produces the expected outputs.
1290 for _, moduleName := range expectedModuleNames {
1291 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001292 givenSharedDeps := givenAllSharedDeps[moduleName]
1293 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001294
1295 correctAllOrdered := expectedAllDeps[moduleName]
1296 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1297 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001298 "\nin static:%q"+
1299 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001300 "\nmodule: %v"+
1301 "\nexpected: %s"+
1302 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001303 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001304 }
1305
1306 correctOutputDeps := expectedTransitiveDeps[moduleName]
1307 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1308 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001309 "\nin static:%q"+
1310 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001311 "\nmodule: %v"+
1312 "\nexpected: %s"+
1313 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001314 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001315 }
1316 }
1317
1318 if len(errs) > 0 {
1319 sort.Strings(errs)
1320 for _, err := range errs {
1321 t.Error(err)
1322 }
1323 }
1324 }
1325}
Logan Chienf3511742017-10-31 18:04:35 +08001326
Jeff Gaston294356f2017-09-27 17:05:30 -07001327func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1328 for _, moduleName := range moduleNames {
1329 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1330 output := module.outputFile.Path()
1331 paths = append(paths, output)
1332 }
1333 return paths
1334}
1335
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001336func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001337 ctx := testCc(t, `
1338 cc_library {
1339 name: "a",
1340 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001341 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001342 }
1343 cc_library {
1344 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001345 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001346 }
1347 cc_library {
1348 name: "c",
1349 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001350 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001351 }
1352 cc_library {
1353 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001354 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001355 }
1356
1357 `)
1358
1359 variant := "android_arm64_armv8-a_core_static"
1360 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001361 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001362 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1363
1364 if !reflect.DeepEqual(actual, expected) {
1365 t.Errorf("staticDeps orderings were not propagated correctly"+
1366 "\nactual: %v"+
1367 "\nexpected: %v",
1368 actual,
1369 expected,
1370 )
1371 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001372}
Jeff Gaston294356f2017-09-27 17:05:30 -07001373
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001374func TestStaticLibDepReorderingWithShared(t *testing.T) {
1375 ctx := testCc(t, `
1376 cc_library {
1377 name: "a",
1378 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001379 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001380 }
1381 cc_library {
1382 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001383 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001384 }
1385 cc_library {
1386 name: "c",
1387 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001388 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001389 }
1390
1391 `)
1392
1393 variant := "android_arm64_armv8-a_core_static"
1394 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1395 actual := moduleA.depsInLinkOrder
1396 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1397
1398 if !reflect.DeepEqual(actual, expected) {
1399 t.Errorf("staticDeps orderings did not account for shared libs"+
1400 "\nactual: %v"+
1401 "\nexpected: %v",
1402 actual,
1403 expected,
1404 )
1405 }
1406}
1407
Jiyong Parka46a4d52017-12-14 19:54:34 +09001408func TestLlndkHeaders(t *testing.T) {
1409 ctx := testCc(t, `
1410 llndk_headers {
1411 name: "libllndk_headers",
1412 export_include_dirs: ["my_include"],
1413 }
1414 llndk_library {
1415 name: "libllndk",
1416 export_llndk_headers: ["libllndk_headers"],
1417 }
1418 cc_library {
1419 name: "libvendor",
1420 shared_libs: ["libllndk"],
1421 vendor: true,
1422 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001423 no_libgcc: true,
1424 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001425 }
1426 `)
1427
1428 // _static variant is used since _shared reuses *.o from the static variant
1429 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1430 cflags := cc.Args["cFlags"]
1431 if !strings.Contains(cflags, "-Imy_include") {
1432 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1433 }
1434}
1435
Logan Chien43d34c32017-12-20 01:17:32 +08001436func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1437 actual := module.Properties.AndroidMkRuntimeLibs
1438 if !reflect.DeepEqual(actual, expected) {
1439 t.Errorf("incorrect runtime_libs for shared libs"+
1440 "\nactual: %v"+
1441 "\nexpected: %v",
1442 actual,
1443 expected,
1444 )
1445 }
1446}
1447
1448const runtimeLibAndroidBp = `
1449 cc_library {
1450 name: "libvendor_available1",
1451 vendor_available: true,
1452 no_libgcc : true,
1453 nocrt : true,
1454 system_shared_libs : [],
1455 }
1456 cc_library {
1457 name: "libvendor_available2",
1458 vendor_available: true,
1459 runtime_libs: ["libvendor_available1"],
1460 no_libgcc : true,
1461 nocrt : true,
1462 system_shared_libs : [],
1463 }
1464 cc_library {
1465 name: "libvendor_available3",
1466 vendor_available: true,
1467 runtime_libs: ["libvendor_available1"],
1468 target: {
1469 vendor: {
1470 exclude_runtime_libs: ["libvendor_available1"],
1471 }
1472 },
1473 no_libgcc : true,
1474 nocrt : true,
1475 system_shared_libs : [],
1476 }
1477 cc_library {
1478 name: "libcore",
1479 runtime_libs: ["libvendor_available1"],
1480 no_libgcc : true,
1481 nocrt : true,
1482 system_shared_libs : [],
1483 }
1484 cc_library {
1485 name: "libvendor1",
1486 vendor: true,
1487 no_libgcc : true,
1488 nocrt : true,
1489 system_shared_libs : [],
1490 }
1491 cc_library {
1492 name: "libvendor2",
1493 vendor: true,
1494 runtime_libs: ["libvendor_available1", "libvendor1"],
1495 no_libgcc : true,
1496 nocrt : true,
1497 system_shared_libs : [],
1498 }
1499`
1500
1501func TestRuntimeLibs(t *testing.T) {
1502 ctx := testCc(t, runtimeLibAndroidBp)
1503
1504 // runtime_libs for core variants use the module names without suffixes.
1505 variant := "android_arm64_armv8-a_core_shared"
1506
1507 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1508 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1509
1510 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1511 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1512
1513 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1514 // and vendor variants.
1515 variant = "android_arm64_armv8-a_vendor_shared"
1516
1517 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1518 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1519
1520 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1521 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1522}
1523
1524func TestExcludeRuntimeLibs(t *testing.T) {
1525 ctx := testCc(t, runtimeLibAndroidBp)
1526
1527 variant := "android_arm64_armv8-a_core_shared"
1528 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1529 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1530
1531 variant = "android_arm64_armv8-a_vendor_shared"
1532 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1533 checkRuntimeLibs(t, nil, module)
1534}
1535
1536func TestRuntimeLibsNoVndk(t *testing.T) {
1537 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1538
1539 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1540
1541 variant := "android_arm64_armv8-a_core_shared"
1542
1543 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1544 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1545
1546 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1547 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1548}
1549
Jiyong Parkd08b6972017-09-26 10:50:54 +09001550var compilerFlagsTestCases = []struct {
1551 in string
1552 out bool
1553}{
1554 {
1555 in: "a",
1556 out: false,
1557 },
1558 {
1559 in: "-a",
1560 out: true,
1561 },
1562 {
1563 in: "-Ipath/to/something",
1564 out: false,
1565 },
1566 {
1567 in: "-isystempath/to/something",
1568 out: false,
1569 },
1570 {
1571 in: "--coverage",
1572 out: false,
1573 },
1574 {
1575 in: "-include a/b",
1576 out: true,
1577 },
1578 {
1579 in: "-include a/b c/d",
1580 out: false,
1581 },
1582 {
1583 in: "-DMACRO",
1584 out: true,
1585 },
1586 {
1587 in: "-DMAC RO",
1588 out: false,
1589 },
1590 {
1591 in: "-a -b",
1592 out: false,
1593 },
1594 {
1595 in: "-DMACRO=definition",
1596 out: true,
1597 },
1598 {
1599 in: "-DMACRO=defi nition",
1600 out: true, // TODO(jiyong): this should be false
1601 },
1602 {
1603 in: "-DMACRO(x)=x + 1",
1604 out: true,
1605 },
1606 {
1607 in: "-DMACRO=\"defi nition\"",
1608 out: true,
1609 },
1610}
1611
1612type mockContext struct {
1613 BaseModuleContext
1614 result bool
1615}
1616
1617func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1618 // CheckBadCompilerFlags calls this function when the flag should be rejected
1619 ctx.result = false
1620}
1621
1622func TestCompilerFlags(t *testing.T) {
1623 for _, testCase := range compilerFlagsTestCases {
1624 ctx := &mockContext{result: true}
1625 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1626 if ctx.result != testCase.out {
1627 t.Errorf("incorrect output:")
1628 t.Errorf(" input: %#v", testCase.in)
1629 t.Errorf(" expected: %#v", testCase.out)
1630 t.Errorf(" got: %#v", ctx.result)
1631 }
1632 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001633}
Jiyong Park374510b2018-03-19 18:23:01 +09001634
1635func TestVendorPublicLibraries(t *testing.T) {
1636 ctx := testCc(t, `
1637 cc_library_headers {
1638 name: "libvendorpublic_headers",
1639 export_include_dirs: ["my_include"],
1640 }
1641 vendor_public_library {
1642 name: "libvendorpublic",
1643 symbol_file: "",
1644 export_public_headers: ["libvendorpublic_headers"],
1645 }
1646 cc_library {
1647 name: "libvendorpublic",
1648 srcs: ["foo.c"],
1649 vendor: true,
1650 no_libgcc: true,
1651 nocrt: true,
1652 }
1653
1654 cc_library {
1655 name: "libsystem",
1656 shared_libs: ["libvendorpublic"],
1657 vendor: false,
1658 srcs: ["foo.c"],
1659 no_libgcc: true,
1660 nocrt: true,
1661 }
1662 cc_library {
1663 name: "libvendor",
1664 shared_libs: ["libvendorpublic"],
1665 vendor: true,
1666 srcs: ["foo.c"],
1667 no_libgcc: true,
1668 nocrt: true,
1669 }
1670 `)
1671
1672 variant := "android_arm64_armv8-a_core_shared"
1673
1674 // test if header search paths are correctly added
1675 // _static variant is used since _shared reuses *.o from the static variant
1676 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
1677 cflags := cc.Args["cFlags"]
1678 if !strings.Contains(cflags, "-Imy_include") {
1679 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
1680 }
1681
1682 // test if libsystem is linked to the stub
1683 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
1684 libflags := ld.Args["libFlags"]
1685 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
1686 if !strings.Contains(libflags, stubPaths[0].String()) {
1687 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
1688 }
1689
1690 // test if libvendor is linked to the real shared lib
1691 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
1692 libflags = ld.Args["libFlags"]
1693 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
1694 if !strings.Contains(libflags, stubPaths[0].String()) {
1695 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
1696 }
1697
1698}
Jiyong Park37b25202018-07-11 10:49:27 +09001699
1700func TestRecovery(t *testing.T) {
1701 ctx := testCc(t, `
1702 cc_library_shared {
1703 name: "librecovery",
1704 recovery: true,
1705 }
1706 cc_library_shared {
1707 name: "librecovery32",
1708 recovery: true,
1709 compile_multilib:"32",
1710 }
Jiyong Park5baac542018-08-28 09:55:37 +09001711 cc_library_shared {
1712 name: "libHalInRecovery",
1713 recovery_available: true,
1714 vendor: true,
1715 }
Jiyong Park37b25202018-07-11 10:49:27 +09001716 `)
1717
1718 variants := ctx.ModuleVariantsForTests("librecovery")
1719 const arm64 = "android_arm64_armv8-a_recovery_shared"
1720 if len(variants) != 1 || !android.InList(arm64, variants) {
1721 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1722 }
1723
1724 variants = ctx.ModuleVariantsForTests("librecovery32")
1725 if android.InList(arm64, variants) {
1726 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1727 }
Jiyong Park5baac542018-08-28 09:55:37 +09001728
1729 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1730 if !recoveryModule.Platform() {
1731 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1732 }
1733
Jiyong Park37b25202018-07-11 10:49:27 +09001734}