blob: e368fb34977bdd5c31d9ca79b7c560af70d8584c [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 Park25fc6a92018-11-18 18:02:45 +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
Justin Yun9357f4a2018-11-28 15:14:47 +0900495func TestVndkMustNotBeProductSpecific(t *testing.T) {
496 // Check whether an error is emitted when a vndk lib has 'product_specific: true'.
497 testCcError(t, "product_specific must not be true when `vndk: {enabled: true}`", `
498 cc_library {
499 name: "libvndk",
500 product_specific: true, // Cause error
501 vendor_available: true,
502 vndk: {
503 enabled: true,
504 },
505 nocrt: true,
506 }
507 `)
508}
509
Logan Chienf3511742017-10-31 18:04:35 +0800510func TestVndkExt(t *testing.T) {
511 // This test checks the VNDK-Ext properties.
512 ctx := testCc(t, `
513 cc_library {
514 name: "libvndk",
515 vendor_available: true,
516 vndk: {
517 enabled: true,
518 },
519 nocrt: true,
520 }
521
522 cc_library {
523 name: "libvndk_ext",
524 vendor: true,
525 vndk: {
526 enabled: true,
527 extends: "libvndk",
528 },
529 nocrt: true,
530 }
531 `)
532
533 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
534}
535
Logan Chiend3c59a22018-03-29 14:08:15 +0800536func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800537 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
538 ctx := testCcNoVndk(t, `
539 cc_library {
540 name: "libvndk",
541 vendor_available: true,
542 vndk: {
543 enabled: true,
544 },
545 nocrt: true,
546 }
547
548 cc_library {
549 name: "libvndk_ext",
550 vendor: true,
551 vndk: {
552 enabled: true,
553 extends: "libvndk",
554 },
555 nocrt: true,
556 }
557 `)
558
559 // Ensures that the core variant of "libvndk_ext" can be found.
560 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
561 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
562 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
563 }
564}
565
566func TestVndkExtError(t *testing.T) {
567 // This test ensures an error is emitted in ill-formed vndk-ext definition.
568 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
569 cc_library {
570 name: "libvndk",
571 vendor_available: true,
572 vndk: {
573 enabled: true,
574 },
575 nocrt: true,
576 }
577
578 cc_library {
579 name: "libvndk_ext",
580 vndk: {
581 enabled: true,
582 extends: "libvndk",
583 },
584 nocrt: true,
585 }
586 `)
587
588 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
589 cc_library {
590 name: "libvndk",
591 vendor_available: true,
592 vndk: {
593 enabled: true,
594 },
595 nocrt: true,
596 }
597
598 cc_library {
599 name: "libvndk_ext",
600 vendor: true,
601 vndk: {
602 enabled: true,
603 },
604 nocrt: true,
605 }
606 `)
607}
608
609func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
610 // This test ensures an error is emitted for inconsistent support_system_process.
611 testCcError(t, "module \".*\" with mismatched support_system_process", `
612 cc_library {
613 name: "libvndk",
614 vendor_available: true,
615 vndk: {
616 enabled: true,
617 },
618 nocrt: true,
619 }
620
621 cc_library {
622 name: "libvndk_sp_ext",
623 vendor: true,
624 vndk: {
625 enabled: true,
626 extends: "libvndk",
627 support_system_process: true,
628 },
629 nocrt: true,
630 }
631 `)
632
633 testCcError(t, "module \".*\" with mismatched support_system_process", `
634 cc_library {
635 name: "libvndk_sp",
636 vendor_available: true,
637 vndk: {
638 enabled: true,
639 support_system_process: true,
640 },
641 nocrt: true,
642 }
643
644 cc_library {
645 name: "libvndk_ext",
646 vendor: true,
647 vndk: {
648 enabled: true,
649 extends: "libvndk_sp",
650 },
651 nocrt: true,
652 }
653 `)
654}
655
656func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800657 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800658 // with `vendor_available: false`.
659 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
660 cc_library {
661 name: "libvndk",
662 vendor_available: false,
663 vndk: {
664 enabled: true,
665 },
666 nocrt: true,
667 }
668
669 cc_library {
670 name: "libvndk_ext",
671 vendor: true,
672 vndk: {
673 enabled: true,
674 extends: "libvndk",
675 },
676 nocrt: true,
677 }
678 `)
679}
680
Logan Chiend3c59a22018-03-29 14:08:15 +0800681func TestVendorModuleUseVndkExt(t *testing.T) {
682 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800683 testCc(t, `
684 cc_library {
685 name: "libvndk",
686 vendor_available: true,
687 vndk: {
688 enabled: true,
689 },
690 nocrt: true,
691 }
692
693 cc_library {
694 name: "libvndk_ext",
695 vendor: true,
696 vndk: {
697 enabled: true,
698 extends: "libvndk",
699 },
700 nocrt: true,
701 }
702
703 cc_library {
704
705 name: "libvndk_sp",
706 vendor_available: true,
707 vndk: {
708 enabled: true,
709 support_system_process: true,
710 },
711 nocrt: true,
712 }
713
714 cc_library {
715 name: "libvndk_sp_ext",
716 vendor: true,
717 vndk: {
718 enabled: true,
719 extends: "libvndk_sp",
720 support_system_process: true,
721 },
722 nocrt: true,
723 }
724
725 cc_library {
726 name: "libvendor",
727 vendor: true,
728 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
729 nocrt: true,
730 }
731 `)
732}
733
Logan Chiend3c59a22018-03-29 14:08:15 +0800734func TestVndkExtUseVendorLib(t *testing.T) {
735 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800736 testCc(t, `
737 cc_library {
738 name: "libvndk",
739 vendor_available: true,
740 vndk: {
741 enabled: true,
742 },
743 nocrt: true,
744 }
745
746 cc_library {
747 name: "libvndk_ext",
748 vendor: true,
749 vndk: {
750 enabled: true,
751 extends: "libvndk",
752 },
753 shared_libs: ["libvendor"],
754 nocrt: true,
755 }
756
757 cc_library {
758 name: "libvendor",
759 vendor: true,
760 nocrt: true,
761 }
762 `)
Logan Chienf3511742017-10-31 18:04:35 +0800763
Logan Chiend3c59a22018-03-29 14:08:15 +0800764 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
765 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800766 cc_library {
767 name: "libvndk_sp",
768 vendor_available: true,
769 vndk: {
770 enabled: true,
771 support_system_process: true,
772 },
773 nocrt: true,
774 }
775
776 cc_library {
777 name: "libvndk_sp_ext",
778 vendor: true,
779 vndk: {
780 enabled: true,
781 extends: "libvndk_sp",
782 support_system_process: true,
783 },
784 shared_libs: ["libvendor"], // Cause an error
785 nocrt: true,
786 }
787
788 cc_library {
789 name: "libvendor",
790 vendor: true,
791 nocrt: true,
792 }
793 `)
794}
795
Logan Chiend3c59a22018-03-29 14:08:15 +0800796func TestVndkSpExtUseVndkError(t *testing.T) {
797 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
798 // library.
799 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
800 cc_library {
801 name: "libvndk",
802 vendor_available: true,
803 vndk: {
804 enabled: true,
805 },
806 nocrt: true,
807 }
808
809 cc_library {
810 name: "libvndk_sp",
811 vendor_available: true,
812 vndk: {
813 enabled: true,
814 support_system_process: true,
815 },
816 nocrt: true,
817 }
818
819 cc_library {
820 name: "libvndk_sp_ext",
821 vendor: true,
822 vndk: {
823 enabled: true,
824 extends: "libvndk_sp",
825 support_system_process: true,
826 },
827 shared_libs: ["libvndk"], // Cause an error
828 nocrt: true,
829 }
830 `)
831
832 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
833 // library.
834 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
835 cc_library {
836 name: "libvndk",
837 vendor_available: true,
838 vndk: {
839 enabled: true,
840 },
841 nocrt: true,
842 }
843
844 cc_library {
845 name: "libvndk_ext",
846 vendor: true,
847 vndk: {
848 enabled: true,
849 extends: "libvndk",
850 },
851 nocrt: true,
852 }
853
854 cc_library {
855 name: "libvndk_sp",
856 vendor_available: true,
857 vndk: {
858 enabled: true,
859 support_system_process: true,
860 },
861 nocrt: true,
862 }
863
864 cc_library {
865 name: "libvndk_sp_ext",
866 vendor: true,
867 vndk: {
868 enabled: true,
869 extends: "libvndk_sp",
870 support_system_process: true,
871 },
872 shared_libs: ["libvndk_ext"], // Cause an error
873 nocrt: true,
874 }
875 `)
876}
877
878func TestVndkUseVndkExtError(t *testing.T) {
879 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
880 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800881 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
882 cc_library {
883 name: "libvndk",
884 vendor_available: true,
885 vndk: {
886 enabled: true,
887 },
888 nocrt: true,
889 }
890
891 cc_library {
892 name: "libvndk_ext",
893 vendor: true,
894 vndk: {
895 enabled: true,
896 extends: "libvndk",
897 },
898 nocrt: true,
899 }
900
901 cc_library {
902 name: "libvndk2",
903 vendor_available: true,
904 vndk: {
905 enabled: true,
906 },
907 shared_libs: ["libvndk_ext"],
908 nocrt: true,
909 }
910 `)
911
Martin Stjernholmef449fe2018-11-06 16:12:13 +0000912 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +0800913 cc_library {
914 name: "libvndk",
915 vendor_available: true,
916 vndk: {
917 enabled: true,
918 },
919 nocrt: true,
920 }
921
922 cc_library {
923 name: "libvndk_ext",
924 vendor: true,
925 vndk: {
926 enabled: true,
927 extends: "libvndk",
928 },
929 nocrt: true,
930 }
931
932 cc_library {
933 name: "libvndk2",
934 vendor_available: true,
935 vndk: {
936 enabled: true,
937 },
938 target: {
939 vendor: {
940 shared_libs: ["libvndk_ext"],
941 },
942 },
943 nocrt: true,
944 }
945 `)
946
947 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
948 cc_library {
949 name: "libvndk_sp",
950 vendor_available: true,
951 vndk: {
952 enabled: true,
953 support_system_process: true,
954 },
955 nocrt: true,
956 }
957
958 cc_library {
959 name: "libvndk_sp_ext",
960 vendor: true,
961 vndk: {
962 enabled: true,
963 extends: "libvndk_sp",
964 support_system_process: true,
965 },
966 nocrt: true,
967 }
968
969 cc_library {
970 name: "libvndk_sp_2",
971 vendor_available: true,
972 vndk: {
973 enabled: true,
974 support_system_process: true,
975 },
976 shared_libs: ["libvndk_sp_ext"],
977 nocrt: true,
978 }
979 `)
980
Martin Stjernholmef449fe2018-11-06 16:12:13 +0000981 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
Logan Chienf3511742017-10-31 18:04:35 +0800982 cc_library {
983 name: "libvndk_sp",
984 vendor_available: true,
985 vndk: {
986 enabled: true,
987 },
988 nocrt: true,
989 }
990
991 cc_library {
992 name: "libvndk_sp_ext",
993 vendor: true,
994 vndk: {
995 enabled: true,
996 extends: "libvndk_sp",
997 },
998 nocrt: true,
999 }
1000
1001 cc_library {
1002 name: "libvndk_sp2",
1003 vendor_available: true,
1004 vndk: {
1005 enabled: true,
1006 },
1007 target: {
1008 vendor: {
1009 shared_libs: ["libvndk_sp_ext"],
1010 },
1011 },
1012 nocrt: true,
1013 }
1014 `)
1015}
1016
Colin Cross0af4b842015-04-30 16:36:18 -07001017var (
1018 str11 = "01234567891"
1019 str10 = str11[:10]
1020 str9 = str11[:9]
1021 str5 = str11[:5]
1022 str4 = str11[:4]
1023)
1024
1025var splitListForSizeTestCases = []struct {
1026 in []string
1027 out [][]string
1028 size int
1029}{
1030 {
1031 in: []string{str10},
1032 out: [][]string{{str10}},
1033 size: 10,
1034 },
1035 {
1036 in: []string{str9},
1037 out: [][]string{{str9}},
1038 size: 10,
1039 },
1040 {
1041 in: []string{str5},
1042 out: [][]string{{str5}},
1043 size: 10,
1044 },
1045 {
1046 in: []string{str11},
1047 out: nil,
1048 size: 10,
1049 },
1050 {
1051 in: []string{str10, str10},
1052 out: [][]string{{str10}, {str10}},
1053 size: 10,
1054 },
1055 {
1056 in: []string{str9, str10},
1057 out: [][]string{{str9}, {str10}},
1058 size: 10,
1059 },
1060 {
1061 in: []string{str10, str9},
1062 out: [][]string{{str10}, {str9}},
1063 size: 10,
1064 },
1065 {
1066 in: []string{str5, str4},
1067 out: [][]string{{str5, str4}},
1068 size: 10,
1069 },
1070 {
1071 in: []string{str5, str4, str5},
1072 out: [][]string{{str5, str4}, {str5}},
1073 size: 10,
1074 },
1075 {
1076 in: []string{str5, str4, str5, str4},
1077 out: [][]string{{str5, str4}, {str5, str4}},
1078 size: 10,
1079 },
1080 {
1081 in: []string{str5, str4, str5, str5},
1082 out: [][]string{{str5, str4}, {str5}, {str5}},
1083 size: 10,
1084 },
1085 {
1086 in: []string{str5, str5, str5, str4},
1087 out: [][]string{{str5}, {str5}, {str5, str4}},
1088 size: 10,
1089 },
1090 {
1091 in: []string{str9, str11},
1092 out: nil,
1093 size: 10,
1094 },
1095 {
1096 in: []string{str11, str9},
1097 out: nil,
1098 size: 10,
1099 },
1100}
1101
1102func TestSplitListForSize(t *testing.T) {
1103 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -07001104 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
1105
1106 var outStrings [][]string
1107
1108 if len(out) > 0 {
1109 outStrings = make([][]string, len(out))
1110 for i, o := range out {
1111 outStrings[i] = o.Strings()
1112 }
1113 }
1114
1115 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001116 t.Errorf("incorrect output:")
1117 t.Errorf(" input: %#v", testCase.in)
1118 t.Errorf(" size: %d", testCase.size)
1119 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001120 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001121 }
1122 }
1123}
Jeff Gaston294356f2017-09-27 17:05:30 -07001124
1125var staticLinkDepOrderTestCases = []struct {
1126 // This is a string representation of a map[moduleName][]moduleDependency .
1127 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001128 inStatic string
1129
1130 // This is a string representation of a map[moduleName][]moduleDependency .
1131 // It models the dependencies declared in an Android.bp file.
1132 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001133
1134 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1135 // The keys of allOrdered specify which modules we would like to check.
1136 // The values of allOrdered specify the expected result (of the transitive closure of all
1137 // dependencies) for each module to test
1138 allOrdered string
1139
1140 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1141 // The keys of outOrdered specify which modules we would like to check.
1142 // The values of outOrdered specify the expected result (of the ordered linker command line)
1143 // for each module to test.
1144 outOrdered string
1145}{
1146 // Simple tests
1147 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001148 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001149 outOrdered: "",
1150 },
1151 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001152 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001153 outOrdered: "a:",
1154 },
1155 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001156 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001157 outOrdered: "a:b; b:",
1158 },
1159 // Tests of reordering
1160 {
1161 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001162 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001163 outOrdered: "a:b,c,d; b:d; c:d; d:",
1164 },
1165 {
1166 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001167 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001168 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1169 },
1170 {
1171 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001172 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001173 outOrdered: "a:d,b,e,c; d:b; e:c",
1174 },
1175 {
1176 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001177 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001178 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1179 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1180 },
1181 {
1182 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001183 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 -07001184 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1185 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1186 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001187 // shared dependencies
1188 {
1189 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1190 // So, we don't actually have to check that a shared dependency of c will change the order
1191 // of a library that depends statically on b and on c. We only need to check that if c has
1192 // a shared dependency on b, that that shows up in allOrdered.
1193 inShared: "c:b",
1194 allOrdered: "c:b",
1195 outOrdered: "c:",
1196 },
1197 {
1198 // This test doesn't actually include any shared dependencies but it's a reminder of what
1199 // the second phase of the above test would look like
1200 inStatic: "a:b,c; c:b",
1201 allOrdered: "a:c,b; c:b",
1202 outOrdered: "a:c,b; c:b",
1203 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001204 // tiebreakers for when two modules specifying different orderings and there is no dependency
1205 // to dictate an order
1206 {
1207 // 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 -08001208 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001209 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1210 },
1211 {
1212 // 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 -08001213 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 -07001214 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1215 },
1216 // Tests involving duplicate dependencies
1217 {
1218 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001219 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001220 outOrdered: "a:c,b",
1221 },
1222 {
1223 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001224 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001225 outOrdered: "a:d,c,b",
1226 },
1227 // Tests to confirm the nonexistence of infinite loops.
1228 // These cases should never happen, so as long as the test terminates and the
1229 // result is deterministic then that should be fine.
1230 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001231 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001232 outOrdered: "a:a",
1233 },
1234 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001235 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001236 allOrdered: "a:b,c; b:c,a; c:a,b",
1237 outOrdered: "a:b; b:c; c:a",
1238 },
1239 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001240 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001241 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1242 outOrdered: "a:c,b; b:a,c; c:b,a",
1243 },
1244}
1245
1246// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1247func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1248 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1249 strippedText := strings.Replace(text, " ", "", -1)
1250 if len(strippedText) < 1 {
1251 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1252 }
1253 allDeps = make(map[android.Path][]android.Path, 0)
1254
1255 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1256 moduleTexts := strings.Split(strippedText, ";")
1257
1258 outputForModuleName := func(moduleName string) android.Path {
1259 return android.PathForTesting(moduleName)
1260 }
1261
1262 for _, moduleText := range moduleTexts {
1263 // convert from "a:b,c" to ["a", "b,c"]
1264 components := strings.Split(moduleText, ":")
1265 if len(components) != 2 {
1266 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1267 }
1268 moduleName := components[0]
1269 moduleOutput := outputForModuleName(moduleName)
1270 modulesInOrder = append(modulesInOrder, moduleOutput)
1271
1272 depString := components[1]
1273 // convert from "b,c" to ["b", "c"]
1274 depNames := strings.Split(depString, ",")
1275 if len(depString) < 1 {
1276 depNames = []string{}
1277 }
1278 var deps []android.Path
1279 for _, depName := range depNames {
1280 deps = append(deps, outputForModuleName(depName))
1281 }
1282 allDeps[moduleOutput] = deps
1283 }
1284 return modulesInOrder, allDeps
1285}
1286
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001287func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001288 for _, testCase := range staticLinkDepOrderTestCases {
1289 errs := []string{}
1290
1291 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001292 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001293 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1294 if testCase.allOrdered == "" {
1295 // allow the test case to skip specifying allOrdered
1296 testCase.allOrdered = testCase.outOrdered
1297 }
1298 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001299 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001300
1301 // For each module whose post-reordered dependencies were specified, validate that
1302 // reordering the inputs produces the expected outputs.
1303 for _, moduleName := range expectedModuleNames {
1304 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001305 givenSharedDeps := givenAllSharedDeps[moduleName]
1306 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001307
1308 correctAllOrdered := expectedAllDeps[moduleName]
1309 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1310 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001311 "\nin static:%q"+
1312 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001313 "\nmodule: %v"+
1314 "\nexpected: %s"+
1315 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001316 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001317 }
1318
1319 correctOutputDeps := expectedTransitiveDeps[moduleName]
1320 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1321 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001322 "\nin static:%q"+
1323 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001324 "\nmodule: %v"+
1325 "\nexpected: %s"+
1326 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001327 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001328 }
1329 }
1330
1331 if len(errs) > 0 {
1332 sort.Strings(errs)
1333 for _, err := range errs {
1334 t.Error(err)
1335 }
1336 }
1337 }
1338}
Logan Chienf3511742017-10-31 18:04:35 +08001339
Jeff Gaston294356f2017-09-27 17:05:30 -07001340func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1341 for _, moduleName := range moduleNames {
1342 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1343 output := module.outputFile.Path()
1344 paths = append(paths, output)
1345 }
1346 return paths
1347}
1348
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001349func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001350 ctx := testCc(t, `
1351 cc_library {
1352 name: "a",
1353 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001354 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001355 }
1356 cc_library {
1357 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001358 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001359 }
1360 cc_library {
1361 name: "c",
1362 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001363 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001364 }
1365 cc_library {
1366 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001367 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001368 }
1369
1370 `)
1371
1372 variant := "android_arm64_armv8-a_core_static"
1373 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001374 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001375 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1376
1377 if !reflect.DeepEqual(actual, expected) {
1378 t.Errorf("staticDeps orderings were not propagated correctly"+
1379 "\nactual: %v"+
1380 "\nexpected: %v",
1381 actual,
1382 expected,
1383 )
1384 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001385}
Jeff Gaston294356f2017-09-27 17:05:30 -07001386
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001387func TestStaticLibDepReorderingWithShared(t *testing.T) {
1388 ctx := testCc(t, `
1389 cc_library {
1390 name: "a",
1391 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001392 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001393 }
1394 cc_library {
1395 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001396 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001397 }
1398 cc_library {
1399 name: "c",
1400 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001401 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001402 }
1403
1404 `)
1405
1406 variant := "android_arm64_armv8-a_core_static"
1407 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1408 actual := moduleA.depsInLinkOrder
1409 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1410
1411 if !reflect.DeepEqual(actual, expected) {
1412 t.Errorf("staticDeps orderings did not account for shared libs"+
1413 "\nactual: %v"+
1414 "\nexpected: %v",
1415 actual,
1416 expected,
1417 )
1418 }
1419}
1420
Jiyong Parka46a4d52017-12-14 19:54:34 +09001421func TestLlndkHeaders(t *testing.T) {
1422 ctx := testCc(t, `
1423 llndk_headers {
1424 name: "libllndk_headers",
1425 export_include_dirs: ["my_include"],
1426 }
1427 llndk_library {
1428 name: "libllndk",
1429 export_llndk_headers: ["libllndk_headers"],
1430 }
1431 cc_library {
1432 name: "libvendor",
1433 shared_libs: ["libllndk"],
1434 vendor: true,
1435 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001436 no_libgcc: true,
1437 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001438 }
1439 `)
1440
1441 // _static variant is used since _shared reuses *.o from the static variant
1442 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1443 cflags := cc.Args["cFlags"]
1444 if !strings.Contains(cflags, "-Imy_include") {
1445 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1446 }
1447}
1448
Logan Chien43d34c32017-12-20 01:17:32 +08001449func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1450 actual := module.Properties.AndroidMkRuntimeLibs
1451 if !reflect.DeepEqual(actual, expected) {
1452 t.Errorf("incorrect runtime_libs for shared libs"+
1453 "\nactual: %v"+
1454 "\nexpected: %v",
1455 actual,
1456 expected,
1457 )
1458 }
1459}
1460
1461const runtimeLibAndroidBp = `
1462 cc_library {
1463 name: "libvendor_available1",
1464 vendor_available: true,
1465 no_libgcc : true,
1466 nocrt : true,
1467 system_shared_libs : [],
1468 }
1469 cc_library {
1470 name: "libvendor_available2",
1471 vendor_available: true,
1472 runtime_libs: ["libvendor_available1"],
1473 no_libgcc : true,
1474 nocrt : true,
1475 system_shared_libs : [],
1476 }
1477 cc_library {
1478 name: "libvendor_available3",
1479 vendor_available: true,
1480 runtime_libs: ["libvendor_available1"],
1481 target: {
1482 vendor: {
1483 exclude_runtime_libs: ["libvendor_available1"],
1484 }
1485 },
1486 no_libgcc : true,
1487 nocrt : true,
1488 system_shared_libs : [],
1489 }
1490 cc_library {
1491 name: "libcore",
1492 runtime_libs: ["libvendor_available1"],
1493 no_libgcc : true,
1494 nocrt : true,
1495 system_shared_libs : [],
1496 }
1497 cc_library {
1498 name: "libvendor1",
1499 vendor: true,
1500 no_libgcc : true,
1501 nocrt : true,
1502 system_shared_libs : [],
1503 }
1504 cc_library {
1505 name: "libvendor2",
1506 vendor: true,
1507 runtime_libs: ["libvendor_available1", "libvendor1"],
1508 no_libgcc : true,
1509 nocrt : true,
1510 system_shared_libs : [],
1511 }
1512`
1513
1514func TestRuntimeLibs(t *testing.T) {
1515 ctx := testCc(t, runtimeLibAndroidBp)
1516
1517 // runtime_libs for core variants use the module names without suffixes.
1518 variant := "android_arm64_armv8-a_core_shared"
1519
1520 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1521 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1522
1523 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1524 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1525
1526 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1527 // and vendor variants.
1528 variant = "android_arm64_armv8-a_vendor_shared"
1529
1530 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1531 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1532
1533 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1534 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1535}
1536
1537func TestExcludeRuntimeLibs(t *testing.T) {
1538 ctx := testCc(t, runtimeLibAndroidBp)
1539
1540 variant := "android_arm64_armv8-a_core_shared"
1541 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1542 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1543
1544 variant = "android_arm64_armv8-a_vendor_shared"
1545 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1546 checkRuntimeLibs(t, nil, module)
1547}
1548
1549func TestRuntimeLibsNoVndk(t *testing.T) {
1550 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1551
1552 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1553
1554 variant := "android_arm64_armv8-a_core_shared"
1555
1556 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1557 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1558
1559 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1560 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1561}
1562
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001563func checkStaticLibs(t *testing.T, expected []string, module *Module) {
1564 actual := module.Properties.AndroidMkStaticLibs
1565 if !reflect.DeepEqual(actual, expected) {
1566 t.Errorf("incorrect static_libs"+
1567 "\nactual: %v"+
1568 "\nexpected: %v",
1569 actual,
1570 expected,
1571 )
1572 }
1573}
1574
1575const staticLibAndroidBp = `
1576 cc_library {
1577 name: "lib1",
1578 }
1579 cc_library {
1580 name: "lib2",
1581 static_libs: ["lib1"],
1582 }
1583`
1584
1585func TestStaticLibDepExport(t *testing.T) {
1586 ctx := testCc(t, staticLibAndroidBp)
1587
1588 // Check the shared version of lib2.
1589 variant := "android_arm64_armv8-a_core_shared"
1590 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
1591 checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
1592
1593 // Check the static version of lib2.
1594 variant = "android_arm64_armv8-a_core_static"
1595 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1596 // libc++_static is linked additionally.
1597 checkStaticLibs(t, []string{"lib1", "libc++_static", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
1598}
1599
Jiyong Parkd08b6972017-09-26 10:50:54 +09001600var compilerFlagsTestCases = []struct {
1601 in string
1602 out bool
1603}{
1604 {
1605 in: "a",
1606 out: false,
1607 },
1608 {
1609 in: "-a",
1610 out: true,
1611 },
1612 {
1613 in: "-Ipath/to/something",
1614 out: false,
1615 },
1616 {
1617 in: "-isystempath/to/something",
1618 out: false,
1619 },
1620 {
1621 in: "--coverage",
1622 out: false,
1623 },
1624 {
1625 in: "-include a/b",
1626 out: true,
1627 },
1628 {
1629 in: "-include a/b c/d",
1630 out: false,
1631 },
1632 {
1633 in: "-DMACRO",
1634 out: true,
1635 },
1636 {
1637 in: "-DMAC RO",
1638 out: false,
1639 },
1640 {
1641 in: "-a -b",
1642 out: false,
1643 },
1644 {
1645 in: "-DMACRO=definition",
1646 out: true,
1647 },
1648 {
1649 in: "-DMACRO=defi nition",
1650 out: true, // TODO(jiyong): this should be false
1651 },
1652 {
1653 in: "-DMACRO(x)=x + 1",
1654 out: true,
1655 },
1656 {
1657 in: "-DMACRO=\"defi nition\"",
1658 out: true,
1659 },
1660}
1661
1662type mockContext struct {
1663 BaseModuleContext
1664 result bool
1665}
1666
1667func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1668 // CheckBadCompilerFlags calls this function when the flag should be rejected
1669 ctx.result = false
1670}
1671
1672func TestCompilerFlags(t *testing.T) {
1673 for _, testCase := range compilerFlagsTestCases {
1674 ctx := &mockContext{result: true}
1675 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1676 if ctx.result != testCase.out {
1677 t.Errorf("incorrect output:")
1678 t.Errorf(" input: %#v", testCase.in)
1679 t.Errorf(" expected: %#v", testCase.out)
1680 t.Errorf(" got: %#v", ctx.result)
1681 }
1682 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001683}
Jiyong Park374510b2018-03-19 18:23:01 +09001684
1685func TestVendorPublicLibraries(t *testing.T) {
1686 ctx := testCc(t, `
1687 cc_library_headers {
1688 name: "libvendorpublic_headers",
1689 export_include_dirs: ["my_include"],
1690 }
1691 vendor_public_library {
1692 name: "libvendorpublic",
1693 symbol_file: "",
1694 export_public_headers: ["libvendorpublic_headers"],
1695 }
1696 cc_library {
1697 name: "libvendorpublic",
1698 srcs: ["foo.c"],
1699 vendor: true,
1700 no_libgcc: true,
1701 nocrt: true,
1702 }
1703
1704 cc_library {
1705 name: "libsystem",
1706 shared_libs: ["libvendorpublic"],
1707 vendor: false,
1708 srcs: ["foo.c"],
1709 no_libgcc: true,
1710 nocrt: true,
1711 }
1712 cc_library {
1713 name: "libvendor",
1714 shared_libs: ["libvendorpublic"],
1715 vendor: true,
1716 srcs: ["foo.c"],
1717 no_libgcc: true,
1718 nocrt: true,
1719 }
1720 `)
1721
1722 variant := "android_arm64_armv8-a_core_shared"
1723
1724 // test if header search paths are correctly added
1725 // _static variant is used since _shared reuses *.o from the static variant
1726 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
1727 cflags := cc.Args["cFlags"]
1728 if !strings.Contains(cflags, "-Imy_include") {
1729 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
1730 }
1731
1732 // test if libsystem is linked to the stub
1733 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
1734 libflags := ld.Args["libFlags"]
1735 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
1736 if !strings.Contains(libflags, stubPaths[0].String()) {
1737 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
1738 }
1739
1740 // test if libvendor is linked to the real shared lib
1741 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
1742 libflags = ld.Args["libFlags"]
1743 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
1744 if !strings.Contains(libflags, stubPaths[0].String()) {
1745 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
1746 }
1747
1748}
Jiyong Park37b25202018-07-11 10:49:27 +09001749
1750func TestRecovery(t *testing.T) {
1751 ctx := testCc(t, `
1752 cc_library_shared {
1753 name: "librecovery",
1754 recovery: true,
1755 }
1756 cc_library_shared {
1757 name: "librecovery32",
1758 recovery: true,
1759 compile_multilib:"32",
1760 }
Jiyong Park5baac542018-08-28 09:55:37 +09001761 cc_library_shared {
1762 name: "libHalInRecovery",
1763 recovery_available: true,
1764 vendor: true,
1765 }
Jiyong Park37b25202018-07-11 10:49:27 +09001766 `)
1767
1768 variants := ctx.ModuleVariantsForTests("librecovery")
1769 const arm64 = "android_arm64_armv8-a_recovery_shared"
1770 if len(variants) != 1 || !android.InList(arm64, variants) {
1771 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1772 }
1773
1774 variants = ctx.ModuleVariantsForTests("librecovery32")
1775 if android.InList(arm64, variants) {
1776 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1777 }
Jiyong Park5baac542018-08-28 09:55:37 +09001778
1779 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1780 if !recoveryModule.Platform() {
1781 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1782 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09001783}
Jiyong Park5baac542018-08-28 09:55:37 +09001784
Jiyong Park7ed9de32018-10-15 22:25:07 +09001785func TestVersionedStubs(t *testing.T) {
1786 ctx := testCc(t, `
1787 cc_library_shared {
1788 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001789 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001790 stubs: {
1791 symbol_file: "foo.map.txt",
1792 versions: ["1", "2", "3"],
1793 },
1794 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001795
Jiyong Park7ed9de32018-10-15 22:25:07 +09001796 cc_library_shared {
1797 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001798 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001799 shared_libs: ["libFoo#1"],
1800 }`)
1801
1802 variants := ctx.ModuleVariantsForTests("libFoo")
1803 expectedVariants := []string{
1804 "android_arm64_armv8-a_core_shared",
1805 "android_arm64_armv8-a_core_shared_1",
1806 "android_arm64_armv8-a_core_shared_2",
1807 "android_arm64_armv8-a_core_shared_3",
1808 "android_arm_armv7-a-neon_core_shared",
1809 "android_arm_armv7-a-neon_core_shared_1",
1810 "android_arm_armv7-a-neon_core_shared_2",
1811 "android_arm_armv7-a-neon_core_shared_3",
1812 }
1813 variantsMismatch := false
1814 if len(variants) != len(expectedVariants) {
1815 variantsMismatch = true
1816 } else {
1817 for _, v := range expectedVariants {
1818 if !inList(v, variants) {
1819 variantsMismatch = false
1820 }
1821 }
1822 }
1823 if variantsMismatch {
1824 t.Errorf("variants of libFoo expected:\n")
1825 for _, v := range expectedVariants {
1826 t.Errorf("%q\n", v)
1827 }
1828 t.Errorf(", but got:\n")
1829 for _, v := range variants {
1830 t.Errorf("%q\n", v)
1831 }
1832 }
1833
1834 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld")
1835 libFlags := libBarLinkRule.Args["libFlags"]
1836 libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so"
1837 if !strings.Contains(libFlags, libFoo1StubPath) {
1838 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
1839 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001840
1841 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("cc")
1842 cFlags := libBarCompileRule.Args["cFlags"]
1843 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
1844 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
1845 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
1846 }
Jiyong Park37b25202018-07-11 10:49:27 +09001847}