blob: 8e257d39c392717530e46848fd7ff5b00159ba47 [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))
Jaewoong Jung5d19e1d2018-11-01 15:40:37 -070058 ctx.RegisterModuleType("cc_library_static", android.ModuleFactoryAdaptor(LibraryStaticFactory))
Jiyong Park374510b2018-03-19 18:23:01 +090059 ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory))
Jaewoong Jung5d19e1d2018-11-01 15:40:37 -070060 ctx.RegisterModuleType("cc_library_host_static", android.ModuleFactoryAdaptor(LibraryHostStaticFactory))
Colin Crosse40b4ea2018-10-02 22:25:58 -070061 ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(ToolchainLibraryFactory))
Jiyong Park6a43f042017-10-12 23:05:00 +090062 ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(llndkLibraryFactory))
Jiyong Parka46a4d52017-12-14 19:54:34 +090063 ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory))
Jiyong Park374510b2018-03-19 18:23:01 +090064 ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
Colin Crosse40b4ea2018-10-02 22:25:58 -070065 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory))
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -070066 ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
Jaewoong Jung5d19e1d2018-11-01 15:40:37 -070067 ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(binaryFactory))
68 ctx.RegisterModuleType("cc_binary_host", android.ModuleFactoryAdaptor(binaryHostFactory))
Jiyong Park6a43f042017-10-12 23:05:00 +090069 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
Jiyong Parkf9332f12018-02-01 00:54:12 +090070 ctx.BottomUp("image", imageMutator).Parallel()
Colin Crosse40b4ea2018-10-02 22:25:58 -070071 ctx.BottomUp("link", LinkageMutator).Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +090072 ctx.BottomUp("vndk", vndkMutator).Parallel()
Jiyong Park7ed9de32018-10-15 22:25:07 +090073 ctx.BottomUp("version", versionMutator).Parallel()
Colin Crosse40b4ea2018-10-02 22:25:58 -070074 ctx.BottomUp("begin", BeginMutator).Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +090075 })
76 ctx.Register()
77
Jeff Gaston294356f2017-09-27 17:05:30 -070078 // add some modules that are required by the compiler and/or linker
79 bp = bp + `
80 toolchain_library {
81 name: "libatomic",
82 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +090083 recovery_available: true,
Dan Willemsenfeea4df2018-10-07 18:16:48 -070084 src: "",
Jeff Gaston294356f2017-09-27 17:05:30 -070085 }
86
87 toolchain_library {
88 name: "libcompiler_rt-extras",
89 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +090090 recovery_available: true,
Dan Willemsenfeea4df2018-10-07 18:16:48 -070091 src: "",
Jeff Gaston294356f2017-09-27 17:05:30 -070092 }
93
94 toolchain_library {
Yi Kong7df0f302018-10-08 22:10:12 +000095 name: "libclang_rt.builtins-arm-android",
96 vendor_available: true,
97 recovery_available: true,
98 src: "",
99 }
100
101 toolchain_library {
102 name: "libclang_rt.builtins-aarch64-android",
103 vendor_available: true,
104 recovery_available: true,
105 src: "",
106 }
107
108 toolchain_library {
109 name: "libclang_rt.builtins-i686-android",
110 vendor_available: true,
111 recovery_available: true,
112 src: "",
113 }
114
115 toolchain_library {
116 name: "libclang_rt.builtins-x86_64-android",
117 vendor_available: true,
118 recovery_available: true,
119 src: "",
120 }
121
122 toolchain_library {
Jeff Gaston294356f2017-09-27 17:05:30 -0700123 name: "libgcc",
124 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900125 recovery_available: true,
Dan Willemsenfeea4df2018-10-07 18:16:48 -0700126 src: "",
Jeff Gaston294356f2017-09-27 17:05:30 -0700127 }
128
Jaewoong Jung5d19e1d2018-11-01 15:40:37 -0700129 toolchain_library {
130 name: "libwinpthread",
131 vendor_available: true,
132 recovery_available: true,
133 host_supported: true,
134 src: "",
135 target: {
136 windows: {
137 enabled: true,
138 },
139 },
140 }
141
Jeff Gaston294356f2017-09-27 17:05:30 -0700142 cc_library {
143 name: "libc",
Logan Chienf3511742017-10-31 18:04:35 +0800144 no_libgcc: true,
145 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700146 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900147 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700148 }
149 llndk_library {
150 name: "libc",
151 symbol_file: "",
152 }
153 cc_library {
154 name: "libm",
Logan Chienf3511742017-10-31 18:04:35 +0800155 no_libgcc: true,
156 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700157 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900158 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700159 }
160 llndk_library {
161 name: "libm",
162 symbol_file: "",
163 }
164 cc_library {
165 name: "libdl",
Logan Chienf3511742017-10-31 18:04:35 +0800166 no_libgcc: true,
167 nocrt: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700168 system_shared_libs: [],
Jiyong Park37b25202018-07-11 10:49:27 +0900169 recovery_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700170 }
171 llndk_library {
172 name: "libdl",
173 symbol_file: "",
174 }
Jaewoong Jung5d19e1d2018-11-01 15:40:37 -0700175 cc_library_static {
Jiyong Park374510b2018-03-19 18:23:01 +0900176 name: "libc++_static",
177 no_libgcc: true,
178 nocrt: true,
179 system_shared_libs: [],
180 stl: "none",
Jaewoong Jung5d19e1d2018-11-01 15:40:37 -0700181 host_supported: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900182 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900183 recovery_available: true,
Jaewoong Jung5d19e1d2018-11-01 15:40:37 -0700184 target: {
185 windows: {
186 enabled: true,
187 },
188 },
Jiyong Park374510b2018-03-19 18:23:01 +0900189 }
190 cc_library {
191 name: "libc++",
192 no_libgcc: true,
193 nocrt: true,
194 system_shared_libs: [],
195 stl: "none",
196 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900197 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900198 vndk: {
199 enabled: true,
200 support_system_process: true,
201 },
202 }
203 cc_library {
204 name: "libunwind_llvm",
205 no_libgcc: true,
206 nocrt: true,
207 system_shared_libs: [],
208 stl: "none",
209 vendor_available: true,
Jiyong Park37b25202018-07-11 10:49:27 +0900210 recovery_available: true,
Jiyong Park374510b2018-03-19 18:23:01 +0900211 }
Jeff Gaston294356f2017-09-27 17:05:30 -0700212
213 cc_object {
214 name: "crtbegin_so",
Jiyong Park37b25202018-07-11 10:49:27 +0900215 recovery_available: true,
Jiyong Park5baac542018-08-28 09:55:37 +0900216 vendor_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700217 }
218
219 cc_object {
Jaewoong Jung5d19e1d2018-11-01 15:40:37 -0700220 name: "crtbegin_dynamic",
221 }
222
223 cc_object {
224 name: "crtend_android",
225 }
226
227 cc_object {
Jeff Gaston294356f2017-09-27 17:05:30 -0700228 name: "crtend_so",
Jiyong Park37b25202018-07-11 10:49:27 +0900229 recovery_available: true,
Jiyong Park5baac542018-08-28 09:55:37 +0900230 vendor_available: true,
Jeff Gaston294356f2017-09-27 17:05:30 -0700231 }
232
Colin Crossad59e752017-11-16 14:29:11 -0800233 cc_library {
234 name: "libprotobuf-cpp-lite",
235 }
236
Jeff Gaston294356f2017-09-27 17:05:30 -0700237`
238
Jiyong Park6a43f042017-10-12 23:05:00 +0900239 ctx.MockFileSystem(map[string][]byte{
Jiyong Park7ed9de32018-10-15 22:25:07 +0900240 "Android.bp": []byte(bp),
241 "foo.c": nil,
242 "bar.c": nil,
243 "a.proto": nil,
244 "b.aidl": nil,
245 "my_include": nil,
246 "foo.map.txt": nil,
Jiyong Park6a43f042017-10-12 23:05:00 +0900247 })
248
Logan Chienf3511742017-10-31 18:04:35 +0800249 return ctx
250}
251
252func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800253 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800254 ctx := createTestContext(t, config, bp)
255
Jeff Gastond3e141d2017-08-08 17:46:01 -0700256 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
Logan Chien42039712018-03-12 16:29:17 +0800257 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900258 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800259 android.FailIfErrored(t, errs)
Jiyong Park6a43f042017-10-12 23:05:00 +0900260
261 return ctx
262}
263
Logan Chienf3511742017-10-31 18:04:35 +0800264func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800265 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800266 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700267 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
268 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800269
270 return testCcWithConfig(t, bp, config)
271}
272
273func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +0800274 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800275 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700276 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800277
278 return testCcWithConfig(t, bp, config)
279}
280
281func testCcError(t *testing.T, pattern string, bp string) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800282 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800283 config := android.TestArchConfig(buildDir, nil)
Dan Willemsen674dc7f2018-03-12 18:06:05 -0700284 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
285 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
Logan Chienf3511742017-10-31 18:04:35 +0800286
287 ctx := createTestContext(t, config, bp)
288
289 _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
290 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800291 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800292 return
293 }
294
295 _, errs = ctx.PrepareBuildActions(config)
296 if len(errs) > 0 {
Logan Chienee97c3e2018-03-12 16:34:26 +0800297 android.FailIfNoMatchingErrors(t, pattern, errs)
Logan Chienf3511742017-10-31 18:04:35 +0800298 return
299 }
300
301 t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
302}
303
304const (
Jiyong Park5baac542018-08-28 09:55:37 +0900305 coreVariant = "android_arm64_armv8-a_core_shared"
306 vendorVariant = "android_arm64_armv8-a_vendor_shared"
307 recoveryVariant = "android_arm64_armv8-a_recovery_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800308)
309
Jiyong Park6a43f042017-10-12 23:05:00 +0900310func TestVendorSrc(t *testing.T) {
311 ctx := testCc(t, `
312 cc_library {
313 name: "libTest",
314 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +0800315 no_libgcc: true,
316 nocrt: true,
317 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900318 vendor_available: true,
319 target: {
320 vendor: {
321 srcs: ["bar.c"],
322 },
323 },
324 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900325 `)
326
Logan Chienf3511742017-10-31 18:04:35 +0800327 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900328 var objs []string
329 for _, o := range ld.Inputs {
330 objs = append(objs, o.Base())
331 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800332 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900333 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
334 }
335}
336
Logan Chienf3511742017-10-31 18:04:35 +0800337func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
338 isVndkSp bool, extends string) {
339
Logan Chiend3c59a22018-03-29 14:08:15 +0800340 t.Helper()
341
Logan Chienf3511742017-10-31 18:04:35 +0800342 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
343 if !mod.hasVendorVariant() {
Colin Crossf46e37f2018-03-21 16:25:58 -0700344 t.Errorf("%q must have vendor variant", name)
Logan Chienf3511742017-10-31 18:04:35 +0800345 }
346
347 // Check library properties.
348 lib, ok := mod.compiler.(*libraryDecorator)
349 if !ok {
350 t.Errorf("%q must have libraryDecorator", name)
351 } else if lib.baseInstaller.subDir != subDir {
352 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
353 lib.baseInstaller.subDir)
354 }
355
356 // Check VNDK properties.
357 if mod.vndkdep == nil {
358 t.Fatalf("%q must have `vndkdep`", name)
359 }
360 if !mod.isVndk() {
361 t.Errorf("%q isVndk() must equal to true", name)
362 }
363 if mod.isVndkSp() != isVndkSp {
364 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
365 }
366
367 // Check VNDK extension properties.
368 isVndkExt := extends != ""
369 if mod.isVndkExt() != isVndkExt {
370 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
371 }
372
373 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
374 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
375 }
376}
377
378func TestVndk(t *testing.T) {
379 ctx := testCc(t, `
380 cc_library {
381 name: "libvndk",
382 vendor_available: true,
383 vndk: {
384 enabled: true,
385 },
386 nocrt: true,
387 }
388
389 cc_library {
390 name: "libvndk_private",
391 vendor_available: false,
392 vndk: {
393 enabled: true,
394 },
395 nocrt: true,
396 }
397
398 cc_library {
399 name: "libvndk_sp",
400 vendor_available: true,
401 vndk: {
402 enabled: true,
403 support_system_process: true,
404 },
405 nocrt: true,
406 }
407
408 cc_library {
409 name: "libvndk_sp_private",
410 vendor_available: false,
411 vndk: {
412 enabled: true,
413 support_system_process: true,
414 },
415 nocrt: true,
416 }
417 `)
418
419 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
420 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
421 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
422 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
423}
424
Logan Chiend3c59a22018-03-29 14:08:15 +0800425func TestVndkDepError(t *testing.T) {
426 // Check whether an error is emitted when a VNDK lib depends on a system lib.
427 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
428 cc_library {
429 name: "libvndk",
430 vendor_available: true,
431 vndk: {
432 enabled: true,
433 },
434 shared_libs: ["libfwk"], // Cause error
435 nocrt: true,
436 }
437
438 cc_library {
439 name: "libfwk",
440 nocrt: true,
441 }
442 `)
443
444 // Check whether an error is emitted when a VNDK lib depends on a vendor lib.
445 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
446 cc_library {
447 name: "libvndk",
448 vendor_available: true,
449 vndk: {
450 enabled: true,
451 },
452 shared_libs: ["libvendor"], // Cause error
453 nocrt: true,
454 }
455
456 cc_library {
457 name: "libvendor",
458 vendor: true,
459 nocrt: true,
460 }
461 `)
462
463 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
464 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
465 cc_library {
466 name: "libvndk_sp",
467 vendor_available: true,
468 vndk: {
469 enabled: true,
470 support_system_process: true,
471 },
472 shared_libs: ["libfwk"], // Cause error
473 nocrt: true,
474 }
475
476 cc_library {
477 name: "libfwk",
478 nocrt: true,
479 }
480 `)
481
482 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
483 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
484 cc_library {
485 name: "libvndk_sp",
486 vendor_available: true,
487 vndk: {
488 enabled: true,
489 support_system_process: true,
490 },
491 shared_libs: ["libvendor"], // Cause error
492 nocrt: true,
493 }
494
495 cc_library {
496 name: "libvendor",
497 vendor: true,
498 nocrt: true,
499 }
500 `)
501
502 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
503 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
504 cc_library {
505 name: "libvndk_sp",
506 vendor_available: true,
507 vndk: {
508 enabled: true,
509 support_system_process: true,
510 },
511 shared_libs: ["libvndk"], // Cause error
512 nocrt: true,
513 }
514
515 cc_library {
516 name: "libvndk",
517 vendor_available: true,
518 vndk: {
519 enabled: true,
520 },
521 nocrt: true,
522 }
523 `)
524}
525
Logan Chienf3511742017-10-31 18:04:35 +0800526func TestVndkExt(t *testing.T) {
527 // This test checks the VNDK-Ext properties.
528 ctx := testCc(t, `
529 cc_library {
530 name: "libvndk",
531 vendor_available: true,
532 vndk: {
533 enabled: true,
534 },
535 nocrt: true,
536 }
537
538 cc_library {
539 name: "libvndk_ext",
540 vendor: true,
541 vndk: {
542 enabled: true,
543 extends: "libvndk",
544 },
545 nocrt: true,
546 }
547 `)
548
549 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
550}
551
Logan Chiend3c59a22018-03-29 14:08:15 +0800552func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
Logan Chienf3511742017-10-31 18:04:35 +0800553 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
554 ctx := testCcNoVndk(t, `
555 cc_library {
556 name: "libvndk",
557 vendor_available: true,
558 vndk: {
559 enabled: true,
560 },
561 nocrt: true,
562 }
563
564 cc_library {
565 name: "libvndk_ext",
566 vendor: true,
567 vndk: {
568 enabled: true,
569 extends: "libvndk",
570 },
571 nocrt: true,
572 }
573 `)
574
575 // Ensures that the core variant of "libvndk_ext" can be found.
576 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
577 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
578 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
579 }
580}
581
582func TestVndkExtError(t *testing.T) {
583 // This test ensures an error is emitted in ill-formed vndk-ext definition.
584 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
585 cc_library {
586 name: "libvndk",
587 vendor_available: true,
588 vndk: {
589 enabled: true,
590 },
591 nocrt: true,
592 }
593
594 cc_library {
595 name: "libvndk_ext",
596 vndk: {
597 enabled: true,
598 extends: "libvndk",
599 },
600 nocrt: true,
601 }
602 `)
603
604 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
605 cc_library {
606 name: "libvndk",
607 vendor_available: true,
608 vndk: {
609 enabled: true,
610 },
611 nocrt: true,
612 }
613
614 cc_library {
615 name: "libvndk_ext",
616 vendor: true,
617 vndk: {
618 enabled: true,
619 },
620 nocrt: true,
621 }
622 `)
623}
624
625func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
626 // This test ensures an error is emitted for inconsistent support_system_process.
627 testCcError(t, "module \".*\" with mismatched support_system_process", `
628 cc_library {
629 name: "libvndk",
630 vendor_available: true,
631 vndk: {
632 enabled: true,
633 },
634 nocrt: true,
635 }
636
637 cc_library {
638 name: "libvndk_sp_ext",
639 vendor: true,
640 vndk: {
641 enabled: true,
642 extends: "libvndk",
643 support_system_process: true,
644 },
645 nocrt: true,
646 }
647 `)
648
649 testCcError(t, "module \".*\" with mismatched support_system_process", `
650 cc_library {
651 name: "libvndk_sp",
652 vendor_available: true,
653 vndk: {
654 enabled: true,
655 support_system_process: true,
656 },
657 nocrt: true,
658 }
659
660 cc_library {
661 name: "libvndk_ext",
662 vendor: true,
663 vndk: {
664 enabled: true,
665 extends: "libvndk_sp",
666 },
667 nocrt: true,
668 }
669 `)
670}
671
672func TestVndkExtVendorAvailableFalseError(t *testing.T) {
Logan Chiend3c59a22018-03-29 14:08:15 +0800673 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
Logan Chienf3511742017-10-31 18:04:35 +0800674 // with `vendor_available: false`.
675 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
676 cc_library {
677 name: "libvndk",
678 vendor_available: false,
679 vndk: {
680 enabled: true,
681 },
682 nocrt: true,
683 }
684
685 cc_library {
686 name: "libvndk_ext",
687 vendor: true,
688 vndk: {
689 enabled: true,
690 extends: "libvndk",
691 },
692 nocrt: true,
693 }
694 `)
695}
696
Logan Chiend3c59a22018-03-29 14:08:15 +0800697func TestVendorModuleUseVndkExt(t *testing.T) {
698 // This test ensures a vendor module can depend on a VNDK-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800699 testCc(t, `
700 cc_library {
701 name: "libvndk",
702 vendor_available: true,
703 vndk: {
704 enabled: true,
705 },
706 nocrt: true,
707 }
708
709 cc_library {
710 name: "libvndk_ext",
711 vendor: true,
712 vndk: {
713 enabled: true,
714 extends: "libvndk",
715 },
716 nocrt: true,
717 }
718
719 cc_library {
720
721 name: "libvndk_sp",
722 vendor_available: true,
723 vndk: {
724 enabled: true,
725 support_system_process: true,
726 },
727 nocrt: true,
728 }
729
730 cc_library {
731 name: "libvndk_sp_ext",
732 vendor: true,
733 vndk: {
734 enabled: true,
735 extends: "libvndk_sp",
736 support_system_process: true,
737 },
738 nocrt: true,
739 }
740
741 cc_library {
742 name: "libvendor",
743 vendor: true,
744 shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
745 nocrt: true,
746 }
747 `)
748}
749
Logan Chiend3c59a22018-03-29 14:08:15 +0800750func TestVndkExtUseVendorLib(t *testing.T) {
751 // This test ensures a VNDK-Ext library can depend on a vendor library.
Logan Chienf3511742017-10-31 18:04:35 +0800752 testCc(t, `
753 cc_library {
754 name: "libvndk",
755 vendor_available: true,
756 vndk: {
757 enabled: true,
758 },
759 nocrt: true,
760 }
761
762 cc_library {
763 name: "libvndk_ext",
764 vendor: true,
765 vndk: {
766 enabled: true,
767 extends: "libvndk",
768 },
769 shared_libs: ["libvendor"],
770 nocrt: true,
771 }
772
773 cc_library {
774 name: "libvendor",
775 vendor: true,
776 nocrt: true,
777 }
778 `)
Logan Chienf3511742017-10-31 18:04:35 +0800779
Logan Chiend3c59a22018-03-29 14:08:15 +0800780 // This test ensures a VNDK-SP-Ext library can depend on a vendor library.
781 testCc(t, `
Logan Chienf3511742017-10-31 18:04:35 +0800782 cc_library {
783 name: "libvndk_sp",
784 vendor_available: true,
785 vndk: {
786 enabled: true,
787 support_system_process: true,
788 },
789 nocrt: true,
790 }
791
792 cc_library {
793 name: "libvndk_sp_ext",
794 vendor: true,
795 vndk: {
796 enabled: true,
797 extends: "libvndk_sp",
798 support_system_process: true,
799 },
800 shared_libs: ["libvendor"], // Cause an error
801 nocrt: true,
802 }
803
804 cc_library {
805 name: "libvendor",
806 vendor: true,
807 nocrt: true,
808 }
809 `)
810}
811
Logan Chiend3c59a22018-03-29 14:08:15 +0800812func TestVndkSpExtUseVndkError(t *testing.T) {
813 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
814 // library.
815 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
816 cc_library {
817 name: "libvndk",
818 vendor_available: true,
819 vndk: {
820 enabled: true,
821 },
822 nocrt: true,
823 }
824
825 cc_library {
826 name: "libvndk_sp",
827 vendor_available: true,
828 vndk: {
829 enabled: true,
830 support_system_process: true,
831 },
832 nocrt: true,
833 }
834
835 cc_library {
836 name: "libvndk_sp_ext",
837 vendor: true,
838 vndk: {
839 enabled: true,
840 extends: "libvndk_sp",
841 support_system_process: true,
842 },
843 shared_libs: ["libvndk"], // Cause an error
844 nocrt: true,
845 }
846 `)
847
848 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
849 // library.
850 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
851 cc_library {
852 name: "libvndk",
853 vendor_available: true,
854 vndk: {
855 enabled: true,
856 },
857 nocrt: true,
858 }
859
860 cc_library {
861 name: "libvndk_ext",
862 vendor: true,
863 vndk: {
864 enabled: true,
865 extends: "libvndk",
866 },
867 nocrt: true,
868 }
869
870 cc_library {
871 name: "libvndk_sp",
872 vendor_available: true,
873 vndk: {
874 enabled: true,
875 support_system_process: true,
876 },
877 nocrt: true,
878 }
879
880 cc_library {
881 name: "libvndk_sp_ext",
882 vendor: true,
883 vndk: {
884 enabled: true,
885 extends: "libvndk_sp",
886 support_system_process: true,
887 },
888 shared_libs: ["libvndk_ext"], // Cause an error
889 nocrt: true,
890 }
891 `)
892}
893
894func TestVndkUseVndkExtError(t *testing.T) {
895 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
896 // VNDK-Ext/VNDK-SP-Ext library.
Logan Chienf3511742017-10-31 18:04:35 +0800897 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
898 cc_library {
899 name: "libvndk",
900 vendor_available: true,
901 vndk: {
902 enabled: true,
903 },
904 nocrt: true,
905 }
906
907 cc_library {
908 name: "libvndk_ext",
909 vendor: true,
910 vndk: {
911 enabled: true,
912 extends: "libvndk",
913 },
914 nocrt: true,
915 }
916
917 cc_library {
918 name: "libvndk2",
919 vendor_available: true,
920 vndk: {
921 enabled: true,
922 },
923 shared_libs: ["libvndk_ext"],
924 nocrt: true,
925 }
926 `)
927
928 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
929 // but target.vendor.shared_libs has not been supported yet.
930 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
931 cc_library {
932 name: "libvndk",
933 vendor_available: true,
934 vndk: {
935 enabled: true,
936 },
937 nocrt: true,
938 }
939
940 cc_library {
941 name: "libvndk_ext",
942 vendor: true,
943 vndk: {
944 enabled: true,
945 extends: "libvndk",
946 },
947 nocrt: true,
948 }
949
950 cc_library {
951 name: "libvndk2",
952 vendor_available: true,
953 vndk: {
954 enabled: true,
955 },
956 target: {
957 vendor: {
958 shared_libs: ["libvndk_ext"],
959 },
960 },
961 nocrt: true,
962 }
963 `)
964
965 testCcError(t, "dependency \".*\" of \".*\" missing variant", `
966 cc_library {
967 name: "libvndk_sp",
968 vendor_available: true,
969 vndk: {
970 enabled: true,
971 support_system_process: 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 support_system_process: true,
983 },
984 nocrt: true,
985 }
986
987 cc_library {
988 name: "libvndk_sp_2",
989 vendor_available: true,
990 vndk: {
991 enabled: true,
992 support_system_process: true,
993 },
994 shared_libs: ["libvndk_sp_ext"],
995 nocrt: true,
996 }
997 `)
998
999 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
1000 // but target.vendor.shared_libs has not been supported yet.
1001 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
1002 cc_library {
1003 name: "libvndk_sp",
1004 vendor_available: true,
1005 vndk: {
1006 enabled: true,
1007 },
1008 nocrt: true,
1009 }
1010
1011 cc_library {
1012 name: "libvndk_sp_ext",
1013 vendor: true,
1014 vndk: {
1015 enabled: true,
1016 extends: "libvndk_sp",
1017 },
1018 nocrt: true,
1019 }
1020
1021 cc_library {
1022 name: "libvndk_sp2",
1023 vendor_available: true,
1024 vndk: {
1025 enabled: true,
1026 },
1027 target: {
1028 vendor: {
1029 shared_libs: ["libvndk_sp_ext"],
1030 },
1031 },
1032 nocrt: true,
1033 }
1034 `)
1035}
1036
Colin Cross0af4b842015-04-30 16:36:18 -07001037var (
1038 str11 = "01234567891"
1039 str10 = str11[:10]
1040 str9 = str11[:9]
1041 str5 = str11[:5]
1042 str4 = str11[:4]
1043)
1044
1045var splitListForSizeTestCases = []struct {
1046 in []string
1047 out [][]string
1048 size int
1049}{
1050 {
1051 in: []string{str10},
1052 out: [][]string{{str10}},
1053 size: 10,
1054 },
1055 {
1056 in: []string{str9},
1057 out: [][]string{{str9}},
1058 size: 10,
1059 },
1060 {
1061 in: []string{str5},
1062 out: [][]string{{str5}},
1063 size: 10,
1064 },
1065 {
1066 in: []string{str11},
1067 out: nil,
1068 size: 10,
1069 },
1070 {
1071 in: []string{str10, str10},
1072 out: [][]string{{str10}, {str10}},
1073 size: 10,
1074 },
1075 {
1076 in: []string{str9, str10},
1077 out: [][]string{{str9}, {str10}},
1078 size: 10,
1079 },
1080 {
1081 in: []string{str10, str9},
1082 out: [][]string{{str10}, {str9}},
1083 size: 10,
1084 },
1085 {
1086 in: []string{str5, str4},
1087 out: [][]string{{str5, str4}},
1088 size: 10,
1089 },
1090 {
1091 in: []string{str5, str4, str5},
1092 out: [][]string{{str5, str4}, {str5}},
1093 size: 10,
1094 },
1095 {
1096 in: []string{str5, str4, str5, str4},
1097 out: [][]string{{str5, str4}, {str5, str4}},
1098 size: 10,
1099 },
1100 {
1101 in: []string{str5, str4, str5, str5},
1102 out: [][]string{{str5, str4}, {str5}, {str5}},
1103 size: 10,
1104 },
1105 {
1106 in: []string{str5, str5, str5, str4},
1107 out: [][]string{{str5}, {str5}, {str5, str4}},
1108 size: 10,
1109 },
1110 {
1111 in: []string{str9, str11},
1112 out: nil,
1113 size: 10,
1114 },
1115 {
1116 in: []string{str11, str9},
1117 out: nil,
1118 size: 10,
1119 },
1120}
1121
1122func TestSplitListForSize(t *testing.T) {
1123 for _, testCase := range splitListForSizeTestCases {
Colin Cross5b529592017-05-09 13:34:34 -07001124 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
1125
1126 var outStrings [][]string
1127
1128 if len(out) > 0 {
1129 outStrings = make([][]string, len(out))
1130 for i, o := range out {
1131 outStrings[i] = o.Strings()
1132 }
1133 }
1134
1135 if !reflect.DeepEqual(outStrings, testCase.out) {
Colin Cross0af4b842015-04-30 16:36:18 -07001136 t.Errorf("incorrect output:")
1137 t.Errorf(" input: %#v", testCase.in)
1138 t.Errorf(" size: %d", testCase.size)
1139 t.Errorf(" expected: %#v", testCase.out)
Colin Cross5b529592017-05-09 13:34:34 -07001140 t.Errorf(" got: %#v", outStrings)
Colin Cross0af4b842015-04-30 16:36:18 -07001141 }
1142 }
1143}
Jeff Gaston294356f2017-09-27 17:05:30 -07001144
1145var staticLinkDepOrderTestCases = []struct {
1146 // This is a string representation of a map[moduleName][]moduleDependency .
1147 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001148 inStatic string
1149
1150 // This is a string representation of a map[moduleName][]moduleDependency .
1151 // It models the dependencies declared in an Android.bp file.
1152 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -07001153
1154 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
1155 // The keys of allOrdered specify which modules we would like to check.
1156 // The values of allOrdered specify the expected result (of the transitive closure of all
1157 // dependencies) for each module to test
1158 allOrdered string
1159
1160 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
1161 // The keys of outOrdered specify which modules we would like to check.
1162 // The values of outOrdered specify the expected result (of the ordered linker command line)
1163 // for each module to test.
1164 outOrdered string
1165}{
1166 // Simple tests
1167 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001168 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -07001169 outOrdered: "",
1170 },
1171 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001172 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001173 outOrdered: "a:",
1174 },
1175 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001176 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001177 outOrdered: "a:b; b:",
1178 },
1179 // Tests of reordering
1180 {
1181 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001182 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -07001183 outOrdered: "a:b,c,d; b:d; c:d; d:",
1184 },
1185 {
1186 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001187 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001188 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
1189 },
1190 {
1191 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001192 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -07001193 outOrdered: "a:d,b,e,c; d:b; e:c",
1194 },
1195 {
1196 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001197 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -07001198 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
1199 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
1200 },
1201 {
1202 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001203 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 -07001204 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1205 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
1206 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001207 // shared dependencies
1208 {
1209 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
1210 // So, we don't actually have to check that a shared dependency of c will change the order
1211 // of a library that depends statically on b and on c. We only need to check that if c has
1212 // a shared dependency on b, that that shows up in allOrdered.
1213 inShared: "c:b",
1214 allOrdered: "c:b",
1215 outOrdered: "c:",
1216 },
1217 {
1218 // This test doesn't actually include any shared dependencies but it's a reminder of what
1219 // the second phase of the above test would look like
1220 inStatic: "a:b,c; c:b",
1221 allOrdered: "a:c,b; c:b",
1222 outOrdered: "a:c,b; c:b",
1223 },
Jeff Gaston294356f2017-09-27 17:05:30 -07001224 // tiebreakers for when two modules specifying different orderings and there is no dependency
1225 // to dictate an order
1226 {
1227 // 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 -08001228 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -07001229 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
1230 },
1231 {
1232 // 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 -08001233 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 -07001234 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
1235 },
1236 // Tests involving duplicate dependencies
1237 {
1238 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001239 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001240 outOrdered: "a:c,b",
1241 },
1242 {
1243 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001244 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001245 outOrdered: "a:d,c,b",
1246 },
1247 // Tests to confirm the nonexistence of infinite loops.
1248 // These cases should never happen, so as long as the test terminates and the
1249 // result is deterministic then that should be fine.
1250 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001251 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001252 outOrdered: "a:a",
1253 },
1254 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001255 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -07001256 allOrdered: "a:b,c; b:c,a; c:a,b",
1257 outOrdered: "a:b; b:c; c:a",
1258 },
1259 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001260 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -07001261 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
1262 outOrdered: "a:c,b; b:a,c; c:b,a",
1263 },
1264}
1265
1266// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
1267func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
1268 // convert from "a:b,c; d:e" to "a:b,c;d:e"
1269 strippedText := strings.Replace(text, " ", "", -1)
1270 if len(strippedText) < 1 {
1271 return []android.Path{}, make(map[android.Path][]android.Path, 0)
1272 }
1273 allDeps = make(map[android.Path][]android.Path, 0)
1274
1275 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
1276 moduleTexts := strings.Split(strippedText, ";")
1277
1278 outputForModuleName := func(moduleName string) android.Path {
1279 return android.PathForTesting(moduleName)
1280 }
1281
1282 for _, moduleText := range moduleTexts {
1283 // convert from "a:b,c" to ["a", "b,c"]
1284 components := strings.Split(moduleText, ":")
1285 if len(components) != 2 {
1286 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
1287 }
1288 moduleName := components[0]
1289 moduleOutput := outputForModuleName(moduleName)
1290 modulesInOrder = append(modulesInOrder, moduleOutput)
1291
1292 depString := components[1]
1293 // convert from "b,c" to ["b", "c"]
1294 depNames := strings.Split(depString, ",")
1295 if len(depString) < 1 {
1296 depNames = []string{}
1297 }
1298 var deps []android.Path
1299 for _, depName := range depNames {
1300 deps = append(deps, outputForModuleName(depName))
1301 }
1302 allDeps[moduleOutput] = deps
1303 }
1304 return modulesInOrder, allDeps
1305}
1306
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001307func TestLinkReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001308 for _, testCase := range staticLinkDepOrderTestCases {
1309 errs := []string{}
1310
1311 // parse testcase
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001312 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
Jeff Gaston294356f2017-09-27 17:05:30 -07001313 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
1314 if testCase.allOrdered == "" {
1315 // allow the test case to skip specifying allOrdered
1316 testCase.allOrdered = testCase.outOrdered
1317 }
1318 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001319 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
Jeff Gaston294356f2017-09-27 17:05:30 -07001320
1321 // For each module whose post-reordered dependencies were specified, validate that
1322 // reordering the inputs produces the expected outputs.
1323 for _, moduleName := range expectedModuleNames {
1324 moduleDeps := givenTransitiveDeps[moduleName]
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001325 givenSharedDeps := givenAllSharedDeps[moduleName]
1326 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
Jeff Gaston294356f2017-09-27 17:05:30 -07001327
1328 correctAllOrdered := expectedAllDeps[moduleName]
1329 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
1330 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001331 "\nin static:%q"+
1332 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001333 "\nmodule: %v"+
1334 "\nexpected: %s"+
1335 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001336 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001337 }
1338
1339 correctOutputDeps := expectedTransitiveDeps[moduleName]
1340 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
1341 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001342 "\nin static:%q"+
1343 "\nin shared:%q"+
Jeff Gaston294356f2017-09-27 17:05:30 -07001344 "\nmodule: %v"+
1345 "\nexpected: %s"+
1346 "\nactual: %s",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001347 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
Jeff Gaston294356f2017-09-27 17:05:30 -07001348 }
1349 }
1350
1351 if len(errs) > 0 {
1352 sort.Strings(errs)
1353 for _, err := range errs {
1354 t.Error(err)
1355 }
1356 }
1357 }
1358}
Logan Chienf3511742017-10-31 18:04:35 +08001359
Jeff Gaston294356f2017-09-27 17:05:30 -07001360func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
1361 for _, moduleName := range moduleNames {
1362 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
1363 output := module.outputFile.Path()
1364 paths = append(paths, output)
1365 }
1366 return paths
1367}
1368
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001369func TestStaticLibDepReordering(t *testing.T) {
Jeff Gaston294356f2017-09-27 17:05:30 -07001370 ctx := testCc(t, `
1371 cc_library {
1372 name: "a",
1373 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +09001374 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001375 }
1376 cc_library {
1377 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001378 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001379 }
1380 cc_library {
1381 name: "c",
1382 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001383 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001384 }
1385 cc_library {
1386 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +09001387 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -07001388 }
1389
1390 `)
1391
1392 variant := "android_arm64_armv8-a_core_static"
1393 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001394 actual := moduleA.depsInLinkOrder
Jeff Gaston294356f2017-09-27 17:05:30 -07001395 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
1396
1397 if !reflect.DeepEqual(actual, expected) {
1398 t.Errorf("staticDeps orderings were not propagated correctly"+
1399 "\nactual: %v"+
1400 "\nexpected: %v",
1401 actual,
1402 expected,
1403 )
1404 }
Jiyong Parkd08b6972017-09-26 10:50:54 +09001405}
Jeff Gaston294356f2017-09-27 17:05:30 -07001406
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001407func TestStaticLibDepReorderingWithShared(t *testing.T) {
1408 ctx := testCc(t, `
1409 cc_library {
1410 name: "a",
1411 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +09001412 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001413 }
1414 cc_library {
1415 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +09001416 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001417 }
1418 cc_library {
1419 name: "c",
1420 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +09001421 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -08001422 }
1423
1424 `)
1425
1426 variant := "android_arm64_armv8-a_core_static"
1427 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
1428 actual := moduleA.depsInLinkOrder
1429 expected := getOutputPaths(ctx, variant, []string{"c", "b"})
1430
1431 if !reflect.DeepEqual(actual, expected) {
1432 t.Errorf("staticDeps orderings did not account for shared libs"+
1433 "\nactual: %v"+
1434 "\nexpected: %v",
1435 actual,
1436 expected,
1437 )
1438 }
1439}
1440
Jiyong Parka46a4d52017-12-14 19:54:34 +09001441func TestLlndkHeaders(t *testing.T) {
1442 ctx := testCc(t, `
1443 llndk_headers {
1444 name: "libllndk_headers",
1445 export_include_dirs: ["my_include"],
1446 }
1447 llndk_library {
1448 name: "libllndk",
1449 export_llndk_headers: ["libllndk_headers"],
1450 }
1451 cc_library {
1452 name: "libvendor",
1453 shared_libs: ["libllndk"],
1454 vendor: true,
1455 srcs: ["foo.c"],
Logan Chienf3511742017-10-31 18:04:35 +08001456 no_libgcc: true,
1457 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001458 }
1459 `)
1460
1461 // _static variant is used since _shared reuses *.o from the static variant
1462 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
1463 cflags := cc.Args["cFlags"]
1464 if !strings.Contains(cflags, "-Imy_include") {
1465 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1466 }
1467}
1468
Logan Chien43d34c32017-12-20 01:17:32 +08001469func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1470 actual := module.Properties.AndroidMkRuntimeLibs
1471 if !reflect.DeepEqual(actual, expected) {
1472 t.Errorf("incorrect runtime_libs for shared libs"+
1473 "\nactual: %v"+
1474 "\nexpected: %v",
1475 actual,
1476 expected,
1477 )
1478 }
1479}
1480
1481const runtimeLibAndroidBp = `
1482 cc_library {
1483 name: "libvendor_available1",
1484 vendor_available: true,
1485 no_libgcc : true,
1486 nocrt : true,
1487 system_shared_libs : [],
1488 }
1489 cc_library {
1490 name: "libvendor_available2",
1491 vendor_available: true,
1492 runtime_libs: ["libvendor_available1"],
1493 no_libgcc : true,
1494 nocrt : true,
1495 system_shared_libs : [],
1496 }
1497 cc_library {
1498 name: "libvendor_available3",
1499 vendor_available: true,
1500 runtime_libs: ["libvendor_available1"],
1501 target: {
1502 vendor: {
1503 exclude_runtime_libs: ["libvendor_available1"],
1504 }
1505 },
1506 no_libgcc : true,
1507 nocrt : true,
1508 system_shared_libs : [],
1509 }
1510 cc_library {
1511 name: "libcore",
1512 runtime_libs: ["libvendor_available1"],
1513 no_libgcc : true,
1514 nocrt : true,
1515 system_shared_libs : [],
1516 }
1517 cc_library {
1518 name: "libvendor1",
1519 vendor: true,
1520 no_libgcc : true,
1521 nocrt : true,
1522 system_shared_libs : [],
1523 }
1524 cc_library {
1525 name: "libvendor2",
1526 vendor: true,
1527 runtime_libs: ["libvendor_available1", "libvendor1"],
1528 no_libgcc : true,
1529 nocrt : true,
1530 system_shared_libs : [],
1531 }
1532`
1533
1534func TestRuntimeLibs(t *testing.T) {
1535 ctx := testCc(t, runtimeLibAndroidBp)
1536
1537 // runtime_libs for core variants use the module names without suffixes.
1538 variant := "android_arm64_armv8-a_core_shared"
1539
1540 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1541 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1542
1543 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
1544 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1545
1546 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1547 // and vendor variants.
1548 variant = "android_arm64_armv8-a_vendor_shared"
1549
1550 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1551 checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
1552
1553 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1554 checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
1555}
1556
1557func TestExcludeRuntimeLibs(t *testing.T) {
1558 ctx := testCc(t, runtimeLibAndroidBp)
1559
1560 variant := "android_arm64_armv8-a_core_shared"
1561 module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1562 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1563
1564 variant = "android_arm64_armv8-a_vendor_shared"
1565 module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
1566 checkRuntimeLibs(t, nil, module)
1567}
1568
1569func TestRuntimeLibsNoVndk(t *testing.T) {
1570 ctx := testCcNoVndk(t, runtimeLibAndroidBp)
1571
1572 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
1573
1574 variant := "android_arm64_armv8-a_core_shared"
1575
1576 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1577 checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
1578
1579 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
1580 checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
1581}
1582
Jaewoong Jung5d19e1d2018-11-01 15:40:37 -07001583func checkStaticLibs(t *testing.T, expected []string, module *Module) {
1584 actual := module.Properties.AndroidMkStaticLibs
1585 if !reflect.DeepEqual(actual, expected) {
1586 t.Errorf("incorrect static_libs"+
1587 "\nactual: %v"+
1588 "\nexpected: %v",
1589 actual,
1590 expected,
1591 )
1592 }
1593}
1594
1595const staticLibAndroidBp = `
1596 cc_library {
1597 name: "lib1",
1598 }
1599 cc_binary {
1600 name: "bin1",
1601 static_libs: ["lib1"],
1602 }
1603 cc_library_host_static {
1604 name: "lib2",
1605 target: {
1606 windows: {
1607 enabled: true,
1608 },
1609 }
1610 }
1611 cc_binary_host {
1612 name: "bin2",
1613 static_libs: ["lib2"],
1614 stl: "libc++_static",
1615 target: {
1616 windows: {
1617 enabled: true,
1618 },
1619 },
1620 }
1621`
1622
1623func TestStaticLibs(t *testing.T) {
1624 ctx := testCc(t, staticLibAndroidBp)
1625
1626 // Check a device binary.
1627 variant := "android_arm64_armv8-a_core"
1628 module := ctx.ModuleForTests("bin1", variant).Module().(*Module)
1629 checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
1630
1631 // Check a host binary.
1632 variant = "linux_glibc_x86_64"
1633 module = ctx.ModuleForTests("bin2", variant).Module().(*Module)
1634 checkStaticLibs(t, []string{"lib2", "libc++_static"}, module)
1635
1636 // Check a host binary on Windows.
1637 variant = "windows_x86"
1638 module = ctx.ModuleForTests("bin2", variant).Module().(*Module)
1639 checkStaticLibs(t, []string{"lib2", "libc++_static", "libwinpthread"}, module)
1640}
1641
Jiyong Parkd08b6972017-09-26 10:50:54 +09001642var compilerFlagsTestCases = []struct {
1643 in string
1644 out bool
1645}{
1646 {
1647 in: "a",
1648 out: false,
1649 },
1650 {
1651 in: "-a",
1652 out: true,
1653 },
1654 {
1655 in: "-Ipath/to/something",
1656 out: false,
1657 },
1658 {
1659 in: "-isystempath/to/something",
1660 out: false,
1661 },
1662 {
1663 in: "--coverage",
1664 out: false,
1665 },
1666 {
1667 in: "-include a/b",
1668 out: true,
1669 },
1670 {
1671 in: "-include a/b c/d",
1672 out: false,
1673 },
1674 {
1675 in: "-DMACRO",
1676 out: true,
1677 },
1678 {
1679 in: "-DMAC RO",
1680 out: false,
1681 },
1682 {
1683 in: "-a -b",
1684 out: false,
1685 },
1686 {
1687 in: "-DMACRO=definition",
1688 out: true,
1689 },
1690 {
1691 in: "-DMACRO=defi nition",
1692 out: true, // TODO(jiyong): this should be false
1693 },
1694 {
1695 in: "-DMACRO(x)=x + 1",
1696 out: true,
1697 },
1698 {
1699 in: "-DMACRO=\"defi nition\"",
1700 out: true,
1701 },
1702}
1703
1704type mockContext struct {
1705 BaseModuleContext
1706 result bool
1707}
1708
1709func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1710 // CheckBadCompilerFlags calls this function when the flag should be rejected
1711 ctx.result = false
1712}
1713
1714func TestCompilerFlags(t *testing.T) {
1715 for _, testCase := range compilerFlagsTestCases {
1716 ctx := &mockContext{result: true}
1717 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1718 if ctx.result != testCase.out {
1719 t.Errorf("incorrect output:")
1720 t.Errorf(" input: %#v", testCase.in)
1721 t.Errorf(" expected: %#v", testCase.out)
1722 t.Errorf(" got: %#v", ctx.result)
1723 }
1724 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001725}
Jiyong Park374510b2018-03-19 18:23:01 +09001726
1727func TestVendorPublicLibraries(t *testing.T) {
1728 ctx := testCc(t, `
1729 cc_library_headers {
1730 name: "libvendorpublic_headers",
1731 export_include_dirs: ["my_include"],
1732 }
1733 vendor_public_library {
1734 name: "libvendorpublic",
1735 symbol_file: "",
1736 export_public_headers: ["libvendorpublic_headers"],
1737 }
1738 cc_library {
1739 name: "libvendorpublic",
1740 srcs: ["foo.c"],
1741 vendor: true,
1742 no_libgcc: true,
1743 nocrt: true,
1744 }
1745
1746 cc_library {
1747 name: "libsystem",
1748 shared_libs: ["libvendorpublic"],
1749 vendor: false,
1750 srcs: ["foo.c"],
1751 no_libgcc: true,
1752 nocrt: true,
1753 }
1754 cc_library {
1755 name: "libvendor",
1756 shared_libs: ["libvendorpublic"],
1757 vendor: true,
1758 srcs: ["foo.c"],
1759 no_libgcc: true,
1760 nocrt: true,
1761 }
1762 `)
1763
1764 variant := "android_arm64_armv8-a_core_shared"
1765
1766 // test if header search paths are correctly added
1767 // _static variant is used since _shared reuses *.o from the static variant
1768 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc")
1769 cflags := cc.Args["cFlags"]
1770 if !strings.Contains(cflags, "-Imy_include") {
1771 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
1772 }
1773
1774 // test if libsystem is linked to the stub
1775 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld")
1776 libflags := ld.Args["libFlags"]
1777 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
1778 if !strings.Contains(libflags, stubPaths[0].String()) {
1779 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
1780 }
1781
1782 // test if libvendor is linked to the real shared lib
1783 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
1784 libflags = ld.Args["libFlags"]
1785 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
1786 if !strings.Contains(libflags, stubPaths[0].String()) {
1787 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
1788 }
1789
1790}
Jiyong Park37b25202018-07-11 10:49:27 +09001791
1792func TestRecovery(t *testing.T) {
1793 ctx := testCc(t, `
1794 cc_library_shared {
1795 name: "librecovery",
1796 recovery: true,
1797 }
1798 cc_library_shared {
1799 name: "librecovery32",
1800 recovery: true,
1801 compile_multilib:"32",
1802 }
Jiyong Park5baac542018-08-28 09:55:37 +09001803 cc_library_shared {
1804 name: "libHalInRecovery",
1805 recovery_available: true,
1806 vendor: true,
1807 }
Jiyong Park37b25202018-07-11 10:49:27 +09001808 `)
1809
1810 variants := ctx.ModuleVariantsForTests("librecovery")
1811 const arm64 = "android_arm64_armv8-a_recovery_shared"
1812 if len(variants) != 1 || !android.InList(arm64, variants) {
1813 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1814 }
1815
1816 variants = ctx.ModuleVariantsForTests("librecovery32")
1817 if android.InList(arm64, variants) {
1818 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1819 }
Jiyong Park5baac542018-08-28 09:55:37 +09001820
1821 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1822 if !recoveryModule.Platform() {
1823 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1824 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09001825}
Jiyong Park5baac542018-08-28 09:55:37 +09001826
Jiyong Park7ed9de32018-10-15 22:25:07 +09001827func TestVersionedStubs(t *testing.T) {
1828 ctx := testCc(t, `
1829 cc_library_shared {
1830 name: "libFoo",
1831 stubs: {
1832 symbol_file: "foo.map.txt",
1833 versions: ["1", "2", "3"],
1834 },
1835 }
1836 cc_library_shared {
1837 name: "libBar",
1838 shared_libs: ["libFoo#1"],
1839 }`)
1840
1841 variants := ctx.ModuleVariantsForTests("libFoo")
1842 expectedVariants := []string{
1843 "android_arm64_armv8-a_core_shared",
1844 "android_arm64_armv8-a_core_shared_1",
1845 "android_arm64_armv8-a_core_shared_2",
1846 "android_arm64_armv8-a_core_shared_3",
1847 "android_arm_armv7-a-neon_core_shared",
1848 "android_arm_armv7-a-neon_core_shared_1",
1849 "android_arm_armv7-a-neon_core_shared_2",
1850 "android_arm_armv7-a-neon_core_shared_3",
1851 }
1852 variantsMismatch := false
1853 if len(variants) != len(expectedVariants) {
1854 variantsMismatch = true
1855 } else {
1856 for _, v := range expectedVariants {
1857 if !inList(v, variants) {
1858 variantsMismatch = false
1859 }
1860 }
1861 }
1862 if variantsMismatch {
1863 t.Errorf("variants of libFoo expected:\n")
1864 for _, v := range expectedVariants {
1865 t.Errorf("%q\n", v)
1866 }
1867 t.Errorf(", but got:\n")
1868 for _, v := range variants {
1869 t.Errorf("%q\n", v)
1870 }
1871 }
1872
1873 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld")
1874 libFlags := libBarLinkRule.Args["libFlags"]
1875 libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so"
1876 if !strings.Contains(libFlags, libFoo1StubPath) {
1877 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
1878 }
Jiyong Park37b25202018-07-11 10:49:27 +09001879}