blob: 3e78ec7897c9a3e927a2139afd65d970c2111a3c [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()
Jiyong Park7ed9de32018-10-15 22:25:07 +090069 ctx.BottomUp("version", versionMutator).Parallel()
Colin Crosse40b4ea2018-10-02 22:25:58 -070070 ctx.BottomUp("begin", BeginMutator).Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +090071 })
72 ctx.Register()
73
Jeff Gaston294356f2017-09-27 17:05:30 -070074 // add some modules that are required by the compiler and/or linker
75 bp = bp + `
76 toolchain_library {
77 name: "libatomic",
78 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +090079 recovery_available: true,
Dan Willemsenfeea4df2018-10-07 18:16:48 -070080 src: "",
Jeff Gaston294356f2017-09-27 17:05:30 -070081 }
82
83 toolchain_library {
84 name: "libcompiler_rt-extras",
85 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +090086 recovery_available: true,
Dan Willemsenfeea4df2018-10-07 18:16:48 -070087 src: "",
Jeff Gaston294356f2017-09-27 17:05:30 -070088 }
89
90 toolchain_library {
Yi Kong7df0f302018-10-08 22:10:12 +000091 name: "libclang_rt.builtins-arm-android",
92 vendor_available: true,
93 recovery_available: true,
94 src: "",
95 }
96
97 toolchain_library {
98 name: "libclang_rt.builtins-aarch64-android",
99 vendor_available: true,
100 recovery_available: true,
101 src: "",
102 }
103
104 toolchain_library {
105 name: "libclang_rt.builtins-i686-android",
106 vendor_available: true,
107 recovery_available: true,
108 src: "",
109 }
110
111 toolchain_library {
112 name: "libclang_rt.builtins-x86_64-android",
113 vendor_available: true,
114 recovery_available: true,
115 src: "",
116 }
117
118 toolchain_library {
Jeff Gaston294356f2017-09-27 17:05:30 -0700119 name: "libgcc",
120 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900121 recovery_available: true,
Dan Willemsenfeea4df2018-10-07 18:16:48 -0700122 src: "",
Jeff Gaston294356f2017-09-27 17:05:30 -0700123 }
124
125 cc_library {
126 name: "libc",
Logan Chienf3511742017-10-31 18:04:35 +0800127 no_libgcc: true,
128 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700129 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900130 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700131 }
132 llndk_library {
133 name: "libc",
134 symbol_file: "",
135 }
136 cc_library {
137 name: "libm",
Logan Chienf3511742017-10-31 18:04:35 +0800138 no_libgcc: true,
139 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700140 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900141 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700142 }
143 llndk_library {
144 name: "libm",
145 symbol_file: "",
146 }
147 cc_library {
148 name: "libdl",
Logan Chienf3511742017-10-31 18:04:35 +0800149 no_libgcc: true,
150 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700151 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900152 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700153 }
154 llndk_library {
155 name: "libdl",
156 symbol_file: "",
157 }
Jaewoong Jung3e6b1fb2018-11-02 22:56:30 +0000158 cc_library {
Jiyong Park374510b2018-03-19 18:23:01 +0900159 name: "libc++_static",
160 no_libgcc: true,
161 nocrt: true,
162 system_shared_libs: [],
163 stl: "none",
164 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900165 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900166 }
167 cc_library {
168 name: "libc++",
169 no_libgcc: true,
170 nocrt: true,
171 system_shared_libs: [],
172 stl: "none",
173 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900174 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900175 vndk: {
176 enabled: true,
177 support_system_process: true,
178 },
179 }
180 cc_library {
181 name: "libunwind_llvm",
182 no_libgcc: true,
183 nocrt: true,
184 system_shared_libs: [],
185 stl: "none",
186 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900187 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900188 }
Jeff Gaston294356f2017-09-27 17:05:30 -0700189
190 cc_object {
191 name: "crtbegin_so",
Jiyong Park37b25202018-07-11 10:49:27 +0900192 recovery_available: true,
Jiyong Park5baac542018-08-28 09:55:37 +0900193 vendor_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700194 }
195
196 cc_object {
197 name: "crtend_so",
Jiyong Park37b25202018-07-11 10:49:27 +0900198 recovery_available: true,
Jiyong Park5baac542018-08-28 09:55:37 +0900199 vendor_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700200 }
201
Colin Crossad59e752017-11-16 14:29:11 -0800202 cc_library {
203 name: "libprotobuf-cpp-lite",
204 }
205
Jeff Gaston294356f2017-09-27 17:05:30 -0700206`
207
Jiyong Park6a43f042017-10-12 23:05:00 +0900208 ctx.MockFileSystem(map[string][]byte{
Jiyong Park7ed9de32018-10-15 22:25:07 +0900209 "Android.bp": []byte(bp),
210 "foo.c": nil,
211 "bar.c": nil,
212 "a.proto": nil,
213 "b.aidl": nil,
214 "my_include": nil,
215 "foo.map.txt": nil,
Jiyong Park6a43f042017-10-12 23:05:00 +0900216 })
217
Logan Chienf3511742017-10-31 18:04:35 +0800218 return ctx
219}
220
221func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800222 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800223 ctx := createTestContext(t, config, bp)
224
Jeff Gastond3e141d2017-08-08 17:46:01 -0700225 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +0800226 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900227 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800228 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900229
230 return ctx
231}
232
Logan Chienf3511742017-10-31 18:04:35 +0800233func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800234 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800235 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700236 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
237 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800238
239 return testCcWithConfig(t, bp, config)
240}
241
242func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800243 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800244 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700245 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800246
247 return testCcWithConfig(t, bp, config)
248}
249
250func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800251 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800252 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700253 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
254 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800255
256 ctx := createTestContext(t, config, bp)
257
258 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
259 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800260 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800261 return
262 }
263
264 _, errs = ctx.PrepareBuildActions(config)
265 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800266 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800267 return
268 }
269
270 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
271}
272
273const (
Jiyong Park5baac542018-08-28 09:55:37 +0900274 coreVariant = "android_arm64_armv8-a_core_shared"
275 vendorVariant = "android_arm64_armv8-a_vendor_shared"
276 recoveryVariant = "android_arm64_armv8-a_recovery_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800277)
278
Jiyong Park6a43f042017-10-12 23:05:00 +0900279func TestVendorSrc(t *testing.T) {
280 ctx := testCc(t, `
281 cc_library {
282 name: "libTest",
283 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800284 no_libgcc: true,
285 nocrt: true,
286 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900287 vendor_available: true,
288 target: {
289 vendor: {
290 srcs: ["bar.c"],
291 },
292 },
293 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900294 `)
295
Logan Chienf3511742017-10-31 18:04:35 +0800296 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900297 var objs []string
298 for _, o := range ld.Inputs {
299 objs = append(objs, o.Base())
300 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800301 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900302 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
303 }
304}
305
Logan Chienf3511742017-10-31 18:04:35 +0800306func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
307 isVndkSp bool, extends string) {
308
Logan Chiend3c59a22018-03-29 14:08:15 +0800309 t.Helper()
310
Logan Chienf3511742017-10-31 18:04:35 +0800311 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
312 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700313 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800314 }
315
316 // Check library properties.
317 lib, ok := mod.compiler.(*libraryDecorator)
318 if !ok {
319 t.Errorf("%q must have libraryDecorator", name)
320 } else if lib.baseInstaller.subDir != subDir {
321 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
322 lib.baseInstaller.subDir)
323 }
324
325 // Check VNDK properties.
326 if mod.vndkdep == nil {
327 t.Fatalf("%q must have `vndkdep`", name)
328 }
329 if !mod.isVndk() {
330 t.Errorf("%q isVndk() must equal to true", name)
331 }
332 if mod.isVndkSp() != isVndkSp {
333 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
334 }
335
336 // Check VNDK extension properties.
337 isVndkExt := extends != ""
338 if mod.isVndkExt() != isVndkExt {
339 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
340 }
341
342 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
343 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
344 }
345}
346
347func TestVndk(t *testing.T) {
348 ctx := testCc(t, `
349 cc_library {
350 name: "libvndk",
351 vendor_available: true,
352 vndk: {
353 enabled: true,
354 },
355 nocrt: true,
356 }
357
358 cc_library {
359 name: "libvndk_private",
360 vendor_available: false,
361 vndk: {
362 enabled: true,
363 },
364 nocrt: true,
365 }
366
367 cc_library {
368 name: "libvndk_sp",
369 vendor_available: true,
370 vndk: {
371 enabled: true,
372 support_system_process: true,
373 },
374 nocrt: true,
375 }
376
377 cc_library {
378 name: "libvndk_sp_private",
379 vendor_available: false,
380 vndk: {
381 enabled: true,
382 support_system_process: true,
383 },
384 nocrt: true,
385 }
386 `)
387
388 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
389 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
390 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
391 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
392}
393
Logan Chiend3c59a22018-03-29 14:08:15 +0800394func TestVndkDepError(t *testing.T) {
395 // Check whether an error is emitted when a VNDK lib depends on a system lib.
396 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
397 cc_library {
398 name: "libvndk",
399 vendor_available: true,
400 vndk: {
401 enabled: true,
402 },
403 shared_libs: ["libfwk"], // Cause error
404 nocrt: true,
405 }
406
407 cc_library {
408 name: "libfwk",
409 nocrt: true,
410 }
411 `)
412
413 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
414 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
415 cc_library {
416 name: "libvndk",
417 vendor_available: true,
418 vndk: {
419 enabled: true,
420 },
421 shared_libs: ["libvendor"], // Cause error
422 nocrt: true,
423 }
424
425 cc_library {
426 name: "libvendor",
427 vendor: true,
428 nocrt: true,
429 }
430 `)
431
432 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
433 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
434 cc_library {
435 name: "libvndk_sp",
436 vendor_available: true,
437 vndk: {
438 enabled: true,
439 support_system_process: true,
440 },
441 shared_libs: ["libfwk"], // Cause error
442 nocrt: true,
443 }
444
445 cc_library {
446 name: "libfwk",
447 nocrt: true,
448 }
449 `)
450
451 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
452 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
453 cc_library {
454 name: "libvndk_sp",
455 vendor_available: true,
456 vndk: {
457 enabled: true,
458 support_system_process: true,
459 },
460 shared_libs: ["libvendor"], // Cause error
461 nocrt: true,
462 }
463
464 cc_library {
465 name: "libvendor",
466 vendor: true,
467 nocrt: true,
468 }
469 `)
470
471 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
472 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
473 cc_library {
474 name: "libvndk_sp",
475 vendor_available: true,
476 vndk: {
477 enabled: true,
478 support_system_process: true,
479 },
480 shared_libs: ["libvndk"], // Cause error
481 nocrt: true,
482 }
483
484 cc_library {
485 name: "libvndk",
486 vendor_available: true,
487 vndk: {
488 enabled: true,
489 },
490 nocrt: true,
491 }
492 `)
493}
494
Logan Chienf3511742017-10-31 18:04:35 +0800495func TestVndkExt(t *testing.T) {
496 // This test checks the VNDK-Ext properties.
497 ctx := testCc(t, `
498 cc_library {
499 name: "libvndk",
500 vendor_available: true,
501 vndk: {
502 enabled: true,
503 },
504 nocrt: true,
505 }
506
507 cc_library {
508 name: "libvndk_ext",
509 vendor: true,
510 vndk: {
511 enabled: true,
512 extends: "libvndk",
513 },
514 nocrt: true,
515 }
516 `)
517
518 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
519}
520
Logan Chiend3c59a22018-03-29 14:08:15 +0800521func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800522 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
523 ctx := testCcNoVndk(t, `
524 cc_library {
525 name: "libvndk",
526 vendor_available: true,
527 vndk: {
528 enabled: true,
529 },
530 nocrt: true,
531 }
532
533 cc_library {
534 name: "libvndk_ext",
535 vendor: true,
536 vndk: {
537 enabled: true,
538 extends: "libvndk",
539 },
540 nocrt: true,
541 }
542 `)
543
544 // Ensures that the core variant of "libvndk_ext" can be found.
545 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
546 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
547 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
548 }
549}
550
551func TestVndkExtError(t *testing.T) {
552 // This test ensures an error is emitted in ill-formed vndk-ext definition.
553 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
554 cc_library {
555 name: "libvndk",
556 vendor_available: true,
557 vndk: {
558 enabled: true,
559 },
560 nocrt: true,
561 }
562
563 cc_library {
564 name: "libvndk_ext",
565 vndk: {
566 enabled: true,
567 extends: "libvndk",
568 },
569 nocrt: true,
570 }
571 `)
572
573 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
574 cc_library {
575 name: "libvndk",
576 vendor_available: true,
577 vndk: {
578 enabled: true,
579 },
580 nocrt: true,
581 }
582
583 cc_library {
584 name: "libvndk_ext",
585 vendor: true,
586 vndk: {
587 enabled: true,
588 },
589 nocrt: true,
590 }
591 `)
592}
593
594func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
595 // This test ensures an error is emitted for inconsistent support_system_process.
596 testCcError(t, "module \".*\" with mismatched support_system_process", `
597 cc_library {
598 name: "libvndk",
599 vendor_available: true,
600 vndk: {
601 enabled: true,
602 },
603 nocrt: true,
604 }
605
606 cc_library {
607 name: "libvndk_sp_ext",
608 vendor: true,
609 vndk: {
610 enabled: true,
611 extends: "libvndk",
612 support_system_process: true,
613 },
614 nocrt: true,
615 }
616 `)
617
618 testCcError(t, "module \".*\" with mismatched support_system_process", `
619 cc_library {
620 name: "libvndk_sp",
621 vendor_available: true,
622 vndk: {
623 enabled: true,
624 support_system_process: true,
625 },
626 nocrt: true,
627 }
628
629 cc_library {
630 name: "libvndk_ext",
631 vendor: true,
632 vndk: {
633 enabled: true,
634 extends: "libvndk_sp",
635 },
636 nocrt: true,
637 }
638 `)
639}
640
641func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800642 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800643 // with `vendor_available: false`.
644 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
645 cc_library {
646 name: "libvndk",
647 vendor_available: false,
648 vndk: {
649 enabled: true,
650 },
651 nocrt: true,
652 }
653
654 cc_library {
655 name: "libvndk_ext",
656 vendor: true,
657 vndk: {
658 enabled: true,
659 extends: "libvndk",
660 },
661 nocrt: true,
662 }
663 `)
664}
665
Logan Chiend3c59a22018-03-29 14:08:15 +0800666func TestVendorModuleUseVndkExt(t *testing.T) {
667 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800668 testCc(t, `
669 cc_library {
670 name: "libvndk",
671 vendor_available: true,
672 vndk: {
673 enabled: true,
674 },
675 nocrt: true,
676 }
677
678 cc_library {
679 name: "libvndk_ext",
680 vendor: true,
681 vndk: {
682 enabled: true,
683 extends: "libvndk",
684 },
685 nocrt: true,
686 }
687
688 cc_library {
689
690 name: "libvndk_sp",
691 vendor_available: true,
692 vndk: {
693 enabled: true,
694 support_system_process: true,
695 },
696 nocrt: true,
697 }
698
699 cc_library {
700 name: "libvndk_sp_ext",
701 vendor: true,
702 vndk: {
703 enabled: true,
704 extends: "libvndk_sp",
705 support_system_process: true,
706 },
707 nocrt: true,
708 }
709
710 cc_library {
711 name: "libvendor",
712 vendor: true,
713 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
714 nocrt: true,
715 }
716 `)
717}
718
Logan Chiend3c59a22018-03-29 14:08:15 +0800719func TestVndkExtUseVendorLib(t *testing.T) {
720 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800721 testCc(t, `
722 cc_library {
723 name: "libvndk",
724 vendor_available: true,
725 vndk: {
726 enabled: true,
727 },
728 nocrt: true,
729 }
730
731 cc_library {
732 name: "libvndk_ext",
733 vendor: true,
734 vndk: {
735 enabled: true,
736 extends: "libvndk",
737 },
738 shared_libs: ["libvendor"],
739 nocrt: true,
740 }
741
742 cc_library {
743 name: "libvendor",
744 vendor: true,
745 nocrt: true,
746 }
747 `)
Logan Chienf3511742017-10-31 18:04:35 +0800748
Logan Chiend3c59a22018-03-29 14:08:15 +0800749 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
750 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800751 cc_library {
752 name: "libvndk_sp",
753 vendor_available: true,
754 vndk: {
755 enabled: true,
756 support_system_process: true,
757 },
758 nocrt: true,
759 }
760
761 cc_library {
762 name: "libvndk_sp_ext",
763 vendor: true,
764 vndk: {
765 enabled: true,
766 extends: "libvndk_sp",
767 support_system_process: true,
768 },
769 shared_libs: ["libvendor"], // Cause an error
770 nocrt: true,
771 }
772
773 cc_library {
774 name: "libvendor",
775 vendor: true,
776 nocrt: true,
777 }
778 `)
779}
780
Logan Chiend3c59a22018-03-29 14:08:15 +0800781func TestVndkSpExtUseVndkError(t *testing.T) {
782 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
783 // library.
784 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
785 cc_library {
786 name: "libvndk",
787 vendor_available: true,
788 vndk: {
789 enabled: true,
790 },
791 nocrt: true,
792 }
793
794 cc_library {
795 name: "libvndk_sp",
796 vendor_available: true,
797 vndk: {
798 enabled: true,
799 support_system_process: true,
800 },
801 nocrt: true,
802 }
803
804 cc_library {
805 name: "libvndk_sp_ext",
806 vendor: true,
807 vndk: {
808 enabled: true,
809 extends: "libvndk_sp",
810 support_system_process: true,
811 },
812 shared_libs: ["libvndk"], // Cause an error
813 nocrt: true,
814 }
815 `)
816
817 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
818 // library.
819 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
820 cc_library {
821 name: "libvndk",
822 vendor_available: true,
823 vndk: {
824 enabled: true,
825 },
826 nocrt: true,
827 }
828
829 cc_library {
830 name: "libvndk_ext",
831 vendor: true,
832 vndk: {
833 enabled: true,
834 extends: "libvndk",
835 },
836 nocrt: true,
837 }
838
839 cc_library {
840 name: "libvndk_sp",
841 vendor_available: true,
842 vndk: {
843 enabled: true,
844 support_system_process: true,
845 },
846 nocrt: true,
847 }
848
849 cc_library {
850 name: "libvndk_sp_ext",
851 vendor: true,
852 vndk: {
853 enabled: true,
854 extends: "libvndk_sp",
855 support_system_process: true,
856 },
857 shared_libs: ["libvndk_ext"], // Cause an error
858 nocrt: true,
859 }
860 `)
861}
862
863func TestVndkUseVndkExtError(t *testing.T) {
864 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
865 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800866 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
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 shared_libs: ["libvndk_ext"],
893 nocrt: true,
894 }
895 `)
896
Martin Stjernholmef449fe2018-11-06 16:12:13 +0000897 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +0800898 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
Martin Stjernholmef449fe2018-11-06 16:12:13 +0000966 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +0800967 cc_library {
968 name: "libvndk_sp",
969 vendor_available: true,
970 vndk: {
971 enabled: true,
972 },
973 nocrt: true,
974 }
975
976 cc_library {
977 name: "libvndk_sp_ext",
978 vendor: true,
979 vndk: {
980 enabled: true,
981 extends: "libvndk_sp",
982 },
983 nocrt: true,
984 }
985
986 cc_library {
987 name: "libvndk_sp2",
988 vendor_available: true,
989 vndk: {
990 enabled: true,
991 },
992 target: {
993 vendor: {
994 shared_libs: ["libvndk_sp_ext"],
995 },
996 },
997 nocrt: true,
998 }
999 `)
1000}
1001
Colin Cross0af4b842015-04-30 16:36:18 -07001002var (
1003 str11 = "01234567891"
1004 str10 = str11[:10]
1005 str9 = str11[:9]
1006 str5 = str11[:5]
1007 str4 = str11[:4]
1008)
1009
1010var splitListForSizeTestCases = []struct {
1011 in []string
1012 out [][]string
1013 size int
1014}{
1015 {
1016 in: []string{str10},
1017 out: [][]string{{str10}},
1018 size: 10,
1019 },
1020 {
1021 in: []string{str9},
1022 out: [][]string{{str9}},
1023 size: 10,
1024 },
1025 {
1026 in: []string{str5},
1027 out: [][]string{{str5}},
1028 size: 10,
1029 },
1030 {
1031 in: []string{str11},
1032 out: nil,
1033 size: 10,
1034 },
1035 {
1036 in: []string{str10, str10},
1037 out: [][]string{{str10}, {str10}},
1038 size: 10,
1039 },
1040 {
1041 in: []string{str9, str10},
1042 out: [][]string{{str9}, {str10}},
1043 size: 10,
1044 },
1045 {
1046 in: []string{str10, str9},
1047 out: [][]string{{str10}, {str9}},
1048 size: 10,
1049 },
1050 {
1051 in: []string{str5, str4},
1052 out: [][]string{{str5, str4}},
1053 size: 10,
1054 },
1055 {
1056 in: []string{str5, str4, str5},
1057 out: [][]string{{str5, str4}, {str5}},
1058 size: 10,
1059 },
1060 {
1061 in: []string{str5, str4, str5, str4},
1062 out: [][]string{{str5, str4}, {str5, str4}},
1063 size: 10,
1064 },
1065 {
1066 in: []string{str5, str4, str5, str5},
1067 out: [][]string{{str5, str4}, {str5}, {str5}},
1068 size: 10,
1069 },
1070 {
1071 in: []string{str5, str5, str5, str4},
1072 out: [][]string{{str5}, {str5}, {str5, str4}},
1073 size: 10,
1074 },
1075 {
1076 in: []string{str9, str11},
1077 out: nil,
1078 size: 10,
1079 },
1080 {
1081 in: []string{str11, str9},
1082 out: nil,
1083 size: 10,
1084 },
1085}
1086
1087func TestSplitListForSize(t *testing.T) {
1088 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -07001089 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
1090
1091 var outStrings [][]string
1092
1093 if len(out) > 0 {
1094 outStrings = make([][]string, len(out))
1095 for i, o := range out {
1096 outStrings[i] = o.Strings()
1097 }
1098 }
1099
1100 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001101 t.Errorf("incorrect output:")
1102 t.Errorf(" input: %#v", testCase.in)
1103 t.Errorf(" size: %d", testCase.size)
1104 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001105 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001106 }
1107 }
1108}
Jeff Gaston294356f2017-09-27 17:05:30 -07001109
1110var staticLinkDepOrderTestCases = []struct {
1111 // This is a string representation of a map[moduleName][]moduleDependency .
1112 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001113 inStatic string
1114
1115 // This is a string representation of a map[moduleName][]moduleDependency .
1116 // It models the dependencies declared in an Android.bp file.
1117 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001118
1119 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1120 // The keys of allOrdered specify which modules we would like to check.
1121 // The values of allOrdered specify the expected result (of the transitive closure of all
1122 // dependencies) for each module to test
1123 allOrdered string
1124
1125 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1126 // The keys of outOrdered specify which modules we would like to check.
1127 // The values of outOrdered specify the expected result (of the ordered linker command line)
1128 // for each module to test.
1129 outOrdered string
1130}{
1131 // Simple tests
1132 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001133 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001134 outOrdered: "",
1135 },
1136 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001137 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001138 outOrdered: "a:",
1139 },
1140 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001141 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001142 outOrdered: "a:b; b:",
1143 },
1144 // Tests of reordering
1145 {
1146 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001147 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001148 outOrdered: "a:b,c,d; b:d; c:d; d:",
1149 },
1150 {
1151 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001152 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001153 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1154 },
1155 {
1156 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001157 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001158 outOrdered: "a:d,b,e,c; d:b; e:c",
1159 },
1160 {
1161 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001162 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001163 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1164 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1165 },
1166 {
1167 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001168 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 -07001169 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1170 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1171 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001172 // shared dependencies
1173 {
1174 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1175 // So, we don't actually have to check that a shared dependency of c will change the order
1176 // of a library that depends statically on b and on c. We only need to check that if c has
1177 // a shared dependency on b, that that shows up in allOrdered.
1178 inShared: "c:b",
1179 allOrdered: "c:b",
1180 outOrdered: "c:",
1181 },
1182 {
1183 // This test doesn't actually include any shared dependencies but it's a reminder of what
1184 // the second phase of the above test would look like
1185 inStatic: "a:b,c; c:b",
1186 allOrdered: "a:c,b; c:b",
1187 outOrdered: "a:c,b; c:b",
1188 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001189 // tiebreakers for when two modules specifying different orderings and there is no dependency
1190 // to dictate an order
1191 {
1192 // 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 -08001193 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001194 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1195 },
1196 {
1197 // 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 -08001198 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 -07001199 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1200 },
1201 // Tests involving duplicate dependencies
1202 {
1203 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001204 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001205 outOrdered: "a:c,b",
1206 },
1207 {
1208 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001209 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001210 outOrdered: "a:d,c,b",
1211 },
1212 // Tests to confirm the nonexistence of infinite loops.
1213 // These cases should never happen, so as long as the test terminates and the
1214 // result is deterministic then that should be fine.
1215 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001216 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001217 outOrdered: "a:a",
1218 },
1219 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001220 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001221 allOrdered: "a:b,c; b:c,a; c:a,b",
1222 outOrdered: "a:b; b:c; c:a",
1223 },
1224 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001225 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001226 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1227 outOrdered: "a:c,b; b:a,c; c:b,a",
1228 },
1229}
1230
1231// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1232func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1233 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1234 strippedText := strings.Replace(text, " ", "", -1)
1235 if len(strippedText) < 1 {
1236 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1237 }
1238 allDeps = make(map[android.Path][]android.Path, 0)
1239
1240 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1241 moduleTexts := strings.Split(strippedText, ";")
1242
1243 outputForModuleName := func(moduleName string) android.Path {
1244 return android.PathForTesting(moduleName)
1245 }
1246
1247 for _, moduleText := range moduleTexts {
1248 // convert from "a:b,c" to ["a", "b,c"]
1249 components := strings.Split(moduleText, ":")
1250 if len(components) != 2 {
1251 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1252 }
1253 moduleName := components[0]
1254 moduleOutput := outputForModuleName(moduleName)
1255 modulesInOrder = append(modulesInOrder, moduleOutput)
1256
1257 depString := components[1]
1258 // convert from "b,c" to ["b", "c"]
1259 depNames := strings.Split(depString, ",")
1260 if len(depString) < 1 {
1261 depNames = []string{}
1262 }
1263 var deps []android.Path
1264 for _, depName := range depNames {
1265 deps = append(deps, outputForModuleName(depName))
1266 }
1267 allDeps[moduleOutput] = deps
1268 }
1269 return modulesInOrder, allDeps
1270}
1271
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001272func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001273 for _, testCase := range staticLinkDepOrderTestCases {
1274 errs := []string{}
1275
1276 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001277 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001278 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1279 if testCase.allOrdered == "" {
1280 // allow the test case to skip specifying allOrdered
1281 testCase.allOrdered = testCase.outOrdered
1282 }
1283 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001284 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001285
1286 // For each module whose post-reordered dependencies were specified, validate that
1287 // reordering the inputs produces the expected outputs.
1288 for _, moduleName := range expectedModuleNames {
1289 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001290 givenSharedDeps := givenAllSharedDeps[moduleName]
1291 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001292
1293 correctAllOrdered := expectedAllDeps[moduleName]
1294 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1295 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001296 "\nin static:%q"+
1297 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001298 "\nmodule: %v"+
1299 "\nexpected: %s"+
1300 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001301 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001302 }
1303
1304 correctOutputDeps := expectedTransitiveDeps[moduleName]
1305 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1306 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001307 "\nin static:%q"+
1308 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001309 "\nmodule: %v"+
1310 "\nexpected: %s"+
1311 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001312 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001313 }
1314 }
1315
1316 if len(errs) > 0 {
1317 sort.Strings(errs)
1318 for _, err := range errs {
1319 t.Error(err)
1320 }
1321 }
1322 }
1323}
Logan Chienf3511742017-10-31 18:04:35 +08001324
Jeff Gaston294356f2017-09-27 17:05:30 -07001325func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1326 for _, moduleName := range moduleNames {
1327 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1328 output := module.outputFile.Path()
1329 paths = append(paths, output)
1330 }
1331 return paths
1332}
1333
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001334func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001335 ctx := testCc(t, `
1336 cc_library {
1337 name: "a",
1338 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001339 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001340 }
1341 cc_library {
1342 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001343 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001344 }
1345 cc_library {
1346 name: "c",
1347 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001348 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001349 }
1350 cc_library {
1351 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001352 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001353 }
1354
1355 `)
1356
1357 variant := "android_arm64_armv8-a_core_static"
1358 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001359 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001360 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1361
1362 if !reflect.DeepEqual(actual, expected) {
1363 t.Errorf("staticDeps orderings were not propagated correctly"+
1364 "\nactual: %v"+
1365 "\nexpected: %v",
1366 actual,
1367 expected,
1368 )
1369 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001370}
Jeff Gaston294356f2017-09-27 17:05:30 -07001371
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001372func TestStaticLibDepReorderingWithShared(t *testing.T) {
1373 ctx := testCc(t, `
1374 cc_library {
1375 name: "a",
1376 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001377 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001378 }
1379 cc_library {
1380 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001381 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001382 }
1383 cc_library {
1384 name: "c",
1385 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001386 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001387 }
1388
1389 `)
1390
1391 variant := "android_arm64_armv8-a_core_static"
1392 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1393 actual := moduleA.depsInLinkOrder
1394 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1395
1396 if !reflect.DeepEqual(actual, expected) {
1397 t.Errorf("staticDeps orderings did not account for shared libs"+
1398 "\nactual: %v"+
1399 "\nexpected: %v",
1400 actual,
1401 expected,
1402 )
1403 }
1404}
1405
Jiyong Parka46a4d52017-12-14 19:54:34 +09001406func TestLlndkHeaders(t *testing.T) {
1407 ctx := testCc(t, `
1408 llndk_headers {
1409 name: "libllndk_headers",
1410 export_include_dirs: ["my_include"],
1411 }
1412 llndk_library {
1413 name: "libllndk",
1414 export_llndk_headers: ["libllndk_headers"],
1415 }
1416 cc_library {
1417 name: "libvendor",
1418 shared_libs: ["libllndk"],
1419 vendor: true,
1420 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001421 no_libgcc: true,
1422 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001423 }
1424 `)
1425
1426 // _static variant is used since _shared reuses *.o from the static variant
1427 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1428 cflags := cc.Args["cFlags"]
1429 if !strings.Contains(cflags, "-Imy_include") {
1430 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1431 }
1432}
1433
Logan Chien43d34c32017-12-20 01:17:32 +08001434func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1435 actual := module.Properties.AndroidMkRuntimeLibs
1436 if !reflect.DeepEqual(actual, expected) {
1437 t.Errorf("incorrect runtime_libs for shared libs"+
1438 "\nactual: %v"+
1439 "\nexpected: %v",
1440 actual,
1441 expected,
1442 )
1443 }
1444}
1445
1446const runtimeLibAndroidBp = `
1447 cc_library {
1448 name: "libvendor_available1",
1449 vendor_available: true,
1450 no_libgcc : true,
1451 nocrt : true,
1452 system_shared_libs : [],
1453 }
1454 cc_library {
1455 name: "libvendor_available2",
1456 vendor_available: true,
1457 runtime_libs: ["libvendor_available1"],
1458 no_libgcc : true,
1459 nocrt : true,
1460 system_shared_libs : [],
1461 }
1462 cc_library {
1463 name: "libvendor_available3",
1464 vendor_available: true,
1465 runtime_libs: ["libvendor_available1"],
1466 target: {
1467 vendor: {
1468 exclude_runtime_libs: ["libvendor_available1"],
1469 }
1470 },
1471 no_libgcc : true,
1472 nocrt : true,
1473 system_shared_libs : [],
1474 }
1475 cc_library {
1476 name: "libcore",
1477 runtime_libs: ["libvendor_available1"],
1478 no_libgcc : true,
1479 nocrt : true,
1480 system_shared_libs : [],
1481 }
1482 cc_library {
1483 name: "libvendor1",
1484 vendor: true,
1485 no_libgcc : true,
1486 nocrt : true,
1487 system_shared_libs : [],
1488 }
1489 cc_library {
1490 name: "libvendor2",
1491 vendor: true,
1492 runtime_libs: ["libvendor_available1", "libvendor1"],
1493 no_libgcc : true,
1494 nocrt : true,
1495 system_shared_libs : [],
1496 }
1497`
1498
1499func TestRuntimeLibs(t *testing.T) {
1500 ctx := testCc(t, runtimeLibAndroidBp)
1501
1502 // runtime_libs for core variants use the module names without suffixes.
1503 variant := "android_arm64_armv8-a_core_shared"
1504
1505 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1506 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1507
1508 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1509 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1510
1511 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1512 // and vendor variants.
1513 variant = "android_arm64_armv8-a_vendor_shared"
1514
1515 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1516 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1517
1518 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1519 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1520}
1521
1522func TestExcludeRuntimeLibs(t *testing.T) {
1523 ctx := testCc(t, runtimeLibAndroidBp)
1524
1525 variant := "android_arm64_armv8-a_core_shared"
1526 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1527 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1528
1529 variant = "android_arm64_armv8-a_vendor_shared"
1530 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1531 checkRuntimeLibs(t, nil, module)
1532}
1533
1534func TestRuntimeLibsNoVndk(t *testing.T) {
1535 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1536
1537 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1538
1539 variant := "android_arm64_armv8-a_core_shared"
1540
1541 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1542 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1543
1544 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1545 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1546}
1547
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001548func checkStaticLibs(t *testing.T, expected []string, module *Module) {
1549 actual := module.Properties.AndroidMkStaticLibs
1550 if !reflect.DeepEqual(actual, expected) {
1551 t.Errorf("incorrect static_libs"+
1552 "\nactual: %v"+
1553 "\nexpected: %v",
1554 actual,
1555 expected,
1556 )
1557 }
1558}
1559
1560const staticLibAndroidBp = `
1561 cc_library {
1562 name: "lib1",
1563 }
1564 cc_library {
1565 name: "lib2",
1566 static_libs: ["lib1"],
1567 }
1568`
1569
1570func TestStaticLibDepExport(t *testing.T) {
1571 ctx := testCc(t, staticLibAndroidBp)
1572
1573 // Check the shared version of lib2.
1574 variant := "android_arm64_armv8-a_core_shared"
1575 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
1576 checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
1577
1578 // Check the static version of lib2.
1579 variant = "android_arm64_armv8-a_core_static"
1580 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1581 // libc++_static is linked additionally.
1582 checkStaticLibs(t, []string{"lib1", "libc++_static", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
1583}
1584
Jiyong Parkd08b6972017-09-26 10:50:54 +09001585var compilerFlagsTestCases = []struct {
1586 in string
1587 out bool
1588}{
1589 {
1590 in: "a",
1591 out: false,
1592 },
1593 {
1594 in: "-a",
1595 out: true,
1596 },
1597 {
1598 in: "-Ipath/to/something",
1599 out: false,
1600 },
1601 {
1602 in: "-isystempath/to/something",
1603 out: false,
1604 },
1605 {
1606 in: "--coverage",
1607 out: false,
1608 },
1609 {
1610 in: "-include a/b",
1611 out: true,
1612 },
1613 {
1614 in: "-include a/b c/d",
1615 out: false,
1616 },
1617 {
1618 in: "-DMACRO",
1619 out: true,
1620 },
1621 {
1622 in: "-DMAC RO",
1623 out: false,
1624 },
1625 {
1626 in: "-a -b",
1627 out: false,
1628 },
1629 {
1630 in: "-DMACRO=definition",
1631 out: true,
1632 },
1633 {
1634 in: "-DMACRO=defi nition",
1635 out: true, // TODO(jiyong): this should be false
1636 },
1637 {
1638 in: "-DMACRO(x)=x + 1",
1639 out: true,
1640 },
1641 {
1642 in: "-DMACRO=\"defi nition\"",
1643 out: true,
1644 },
1645}
1646
1647type mockContext struct {
1648 BaseModuleContext
1649 result bool
1650}
1651
1652func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1653 // CheckBadCompilerFlags calls this function when the flag should be rejected
1654 ctx.result = false
1655}
1656
1657func TestCompilerFlags(t *testing.T) {
1658 for _, testCase := range compilerFlagsTestCases {
1659 ctx := &mockContext{result: true}
1660 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1661 if ctx.result != testCase.out {
1662 t.Errorf("incorrect output:")
1663 t.Errorf(" input: %#v", testCase.in)
1664 t.Errorf(" expected: %#v", testCase.out)
1665 t.Errorf(" got: %#v", ctx.result)
1666 }
1667 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001668}
Jiyong Park374510b2018-03-19 18:23:01 +09001669
1670func TestVendorPublicLibraries(t *testing.T) {
1671 ctx := testCc(t, `
1672 cc_library_headers {
1673 name: "libvendorpublic_headers",
1674 export_include_dirs: ["my_include"],
1675 }
1676 vendor_public_library {
1677 name: "libvendorpublic",
1678 symbol_file: "",
1679 export_public_headers: ["libvendorpublic_headers"],
1680 }
1681 cc_library {
1682 name: "libvendorpublic",
1683 srcs: ["foo.c"],
1684 vendor: true,
1685 no_libgcc: true,
1686 nocrt: true,
1687 }
1688
1689 cc_library {
1690 name: "libsystem",
1691 shared_libs: ["libvendorpublic"],
1692 vendor: false,
1693 srcs: ["foo.c"],
1694 no_libgcc: true,
1695 nocrt: true,
1696 }
1697 cc_library {
1698 name: "libvendor",
1699 shared_libs: ["libvendorpublic"],
1700 vendor: true,
1701 srcs: ["foo.c"],
1702 no_libgcc: true,
1703 nocrt: true,
1704 }
1705 `)
1706
1707 variant := "android_arm64_armv8-a_core_shared"
1708
1709 // test if header search paths are correctly added
1710 // _static variant is used since _shared reuses *.o from the static variant
1711 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
1712 cflags := cc.Args["cFlags"]
1713 if !strings.Contains(cflags, "-Imy_include") {
1714 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
1715 }
1716
1717 // test if libsystem is linked to the stub
1718 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
1719 libflags := ld.Args["libFlags"]
1720 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
1721 if !strings.Contains(libflags, stubPaths[0].String()) {
1722 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
1723 }
1724
1725 // test if libvendor is linked to the real shared lib
1726 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
1727 libflags = ld.Args["libFlags"]
1728 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
1729 if !strings.Contains(libflags, stubPaths[0].String()) {
1730 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
1731 }
1732
1733}
Jiyong Park37b25202018-07-11 10:49:27 +09001734
1735func TestRecovery(t *testing.T) {
1736 ctx := testCc(t, `
1737 cc_library_shared {
1738 name: "librecovery",
1739 recovery: true,
1740 }
1741 cc_library_shared {
1742 name: "librecovery32",
1743 recovery: true,
1744 compile_multilib:"32",
1745 }
Jiyong Park5baac542018-08-28 09:55:37 +09001746 cc_library_shared {
1747 name: "libHalInRecovery",
1748 recovery_available: true,
1749 vendor: true,
1750 }
Jiyong Park37b25202018-07-11 10:49:27 +09001751 `)
1752
1753 variants := ctx.ModuleVariantsForTests("librecovery")
1754 const arm64 = "android_arm64_armv8-a_recovery_shared"
1755 if len(variants) != 1 || !android.InList(arm64, variants) {
1756 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1757 }
1758
1759 variants = ctx.ModuleVariantsForTests("librecovery32")
1760 if android.InList(arm64, variants) {
1761 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1762 }
Jiyong Park5baac542018-08-28 09:55:37 +09001763
1764 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1765 if !recoveryModule.Platform() {
1766 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1767 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09001768}
Jiyong Park5baac542018-08-28 09:55:37 +09001769
Jiyong Park7ed9de32018-10-15 22:25:07 +09001770func TestVersionedStubs(t *testing.T) {
1771 ctx := testCc(t, `
1772 cc_library_shared {
1773 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001774 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001775 stubs: {
1776 symbol_file: "foo.map.txt",
1777 versions: ["1", "2", "3"],
1778 },
1779 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001780
Jiyong Park7ed9de32018-10-15 22:25:07 +09001781 cc_library_shared {
1782 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001783 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001784 shared_libs: ["libFoo#1"],
1785 }`)
1786
1787 variants := ctx.ModuleVariantsForTests("libFoo")
1788 expectedVariants := []string{
1789 "android_arm64_armv8-a_core_shared",
1790 "android_arm64_armv8-a_core_shared_1",
1791 "android_arm64_armv8-a_core_shared_2",
1792 "android_arm64_armv8-a_core_shared_3",
1793 "android_arm_armv7-a-neon_core_shared",
1794 "android_arm_armv7-a-neon_core_shared_1",
1795 "android_arm_armv7-a-neon_core_shared_2",
1796 "android_arm_armv7-a-neon_core_shared_3",
1797 }
1798 variantsMismatch := false
1799 if len(variants) != len(expectedVariants) {
1800 variantsMismatch = true
1801 } else {
1802 for _, v := range expectedVariants {
1803 if !inList(v, variants) {
1804 variantsMismatch = false
1805 }
1806 }
1807 }
1808 if variantsMismatch {
1809 t.Errorf("variants of libFoo expected:\n")
1810 for _, v := range expectedVariants {
1811 t.Errorf("%q\n", v)
1812 }
1813 t.Errorf(", but got:\n")
1814 for _, v := range variants {
1815 t.Errorf("%q\n", v)
1816 }
1817 }
1818
1819 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld")
1820 libFlags := libBarLinkRule.Args["libFlags"]
1821 libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so"
1822 if !strings.Contains(libFlags, libFoo1StubPath) {
1823 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
1824 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001825
1826 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("cc")
1827 cFlags := libBarCompileRule.Args["cFlags"]
1828 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
1829 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
1830 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
1831 }
Jiyong Park37b25202018-07-11 10:49:27 +09001832}