blob: d4955c6152b0f947bcb4d955c6245701b4662c2c [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 (
Jeff Gaston294356f2017-09-27 17:05:30 -070018 "fmt"
Jiyong Park6a43f042017-10-12 23:05:00 +090019 "os"
Colin Cross74d1ec02015-04-28 13:30:13 -070020 "reflect"
Paul Duffin3cb603e2021-02-19 13:57:10 +000021 "regexp"
Cory Barker9cfcf6d2022-07-22 17:22:02 +000022 "runtime"
Jeff Gaston294356f2017-09-27 17:05:30 -070023 "strings"
Colin Cross74d1ec02015-04-28 13:30:13 -070024 "testing"
Colin Crosse1bb5d02019-09-24 14:55:04 -070025
Vinh Tran367d89d2023-04-28 11:21:25 -040026 "android/soong/aidl_library"
Colin Crosse1bb5d02019-09-24 14:55:04 -070027 "android/soong/android"
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +090028
29 "github.com/google/blueprint"
Colin Cross74d1ec02015-04-28 13:30:13 -070030)
31
Yu Liue4312402023-01-18 09:15:31 -080032func init() {
33 registerTestMutators(android.InitRegistrationContext)
34}
35
Jiyong Park6a43f042017-10-12 23:05:00 +090036func TestMain(m *testing.M) {
Paul Duffinc3e6ce02021-03-22 23:21:32 +000037 os.Exit(m.Run())
Jiyong Park6a43f042017-10-12 23:05:00 +090038}
39
Paul Duffin2e6f90e2021-03-22 23:20:25 +000040var prepareForCcTest = android.GroupFixturePreparers(
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +090041 PrepareForIntegrationTestWithCc,
42 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
43 variables.VendorApiLevel = StringPtr("202404")
44 }),
45)
46
Yu Liue4312402023-01-18 09:15:31 -080047var apexVariationName = "apex28"
48var apexVersion = "28"
49
50func registerTestMutators(ctx android.RegistrationContext) {
51 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
52 ctx.BottomUp("apex", testApexMutator).Parallel()
Yu Liue4312402023-01-18 09:15:31 -080053 })
54}
55
Yu Liue4312402023-01-18 09:15:31 -080056func testApexMutator(mctx android.BottomUpMutatorContext) {
57 modules := mctx.CreateVariations(apexVariationName)
58 apexInfo := android.ApexInfo{
59 ApexVariationName: apexVariationName,
60 MinSdkVersion: android.ApiLevelForTest(apexVersion),
61 }
62 mctx.SetVariationProvider(modules[0], android.ApexInfoProvider, apexInfo)
63}
64
Paul Duffin8567f222021-03-23 00:02:06 +000065// testCcWithConfig runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000066//
67// See testCc for an explanation as to how to stop using this deprecated method.
68//
69// deprecated
Colin Cross98be1bb2019-12-13 20:41:13 -080070func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext {
Colin Crosse1bb5d02019-09-24 14:55:04 -070071 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +000072 result := prepareForCcTest.RunTestWithConfig(t, config)
Paul Duffin02a3d652021-02-24 18:51:54 +000073 return result.TestContext
Jiyong Park6a43f042017-10-12 23:05:00 +090074}
75
Paul Duffin8567f222021-03-23 00:02:06 +000076// testCc runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000077//
Paul Duffin8567f222021-03-23 00:02:06 +000078// Do not add any new usages of this, instead use the prepareForCcTest directly as it makes it much
Paul Duffin02a3d652021-02-24 18:51:54 +000079// easier to customize the test behavior.
80//
81// If it is necessary to customize the behavior of an existing test that uses this then please first
Paul Duffin8567f222021-03-23 00:02:06 +000082// convert the test to using prepareForCcTest first and then in a following change add the
Paul Duffin02a3d652021-02-24 18:51:54 +000083// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
84// that it did not change the test behavior unexpectedly.
85//
86// deprecated
Logan Chienf3511742017-10-31 18:04:35 +080087func testCc(t *testing.T, bp string) *android.TestContext {
Logan Chiend3c59a22018-03-29 14:08:15 +080088 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +000089 result := prepareForCcTest.RunTestWithBp(t, bp)
Paul Duffin02a3d652021-02-24 18:51:54 +000090 return result.TestContext
Logan Chienf3511742017-10-31 18:04:35 +080091}
92
Paul Duffin8567f222021-03-23 00:02:06 +000093// testCcErrorWithConfig runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +000094//
95// See testCc for an explanation as to how to stop using this deprecated method.
96//
97// deprecated
Justin Yun5f7f7e82019-11-18 19:52:14 +090098func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) {
Logan Chiend3c59a22018-03-29 14:08:15 +080099 t.Helper()
Logan Chienf3511742017-10-31 18:04:35 +0800100
Paul Duffin8567f222021-03-23 00:02:06 +0000101 prepareForCcTest.
Paul Duffin02a3d652021-02-24 18:51:54 +0000102 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
103 RunTestWithConfig(t, config)
Logan Chienf3511742017-10-31 18:04:35 +0800104}
105
Paul Duffin8567f222021-03-23 00:02:06 +0000106// testCcError runs tests using the prepareForCcTest
Paul Duffin02a3d652021-02-24 18:51:54 +0000107//
108// See testCc for an explanation as to how to stop using this deprecated method.
109//
110// deprecated
Justin Yun5f7f7e82019-11-18 19:52:14 +0900111func testCcError(t *testing.T, pattern string, bp string) {
Jooyung Han479ca172020-10-19 18:51:07 +0900112 t.Helper()
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000113 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Justin Yun5f7f7e82019-11-18 19:52:14 +0900114 testCcErrorWithConfig(t, pattern, config)
115 return
116}
117
Logan Chienf3511742017-10-31 18:04:35 +0800118const (
Colin Cross7113d202019-11-20 16:39:12 -0800119 coreVariant = "android_arm64_armv8-a_shared"
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900120 vendorVariant = "android_vendor_arm64_armv8-a_shared"
121 productVariant = "android_product_arm64_armv8-a_shared"
Colin Crossfb0c16e2019-11-20 17:12:35 -0800122 recoveryVariant = "android_recovery_arm64_armv8-a_shared"
Logan Chienf3511742017-10-31 18:04:35 +0800123)
124
Paul Duffindb462dd2021-03-21 22:01:55 +0000125// Test that the PrepareForTestWithCcDefaultModules provides all the files that it uses by
126// running it in a fixture that requires all source files to exist.
127func TestPrepareForTestWithCcDefaultModules(t *testing.T) {
128 android.GroupFixturePreparers(
129 PrepareForTestWithCcDefaultModules,
130 android.PrepareForTestDisallowNonExistentPaths,
131 ).RunTest(t)
132}
133
Jiyong Park6a43f042017-10-12 23:05:00 +0900134func TestVendorSrc(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400135 t.Parallel()
Jiyong Park6a43f042017-10-12 23:05:00 +0900136 ctx := testCc(t, `
137 cc_library {
138 name: "libTest",
139 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -0700140 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +0800141 nocrt: true,
142 system_shared_libs: [],
Jiyong Park6a43f042017-10-12 23:05:00 +0900143 vendor_available: true,
144 target: {
145 vendor: {
146 srcs: ["bar.c"],
147 },
148 },
149 }
Jiyong Park6a43f042017-10-12 23:05:00 +0900150 `)
151
Logan Chienf3511742017-10-31 18:04:35 +0800152 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
Jiyong Park6a43f042017-10-12 23:05:00 +0900153 var objs []string
154 for _, o := range ld.Inputs {
155 objs = append(objs, o.Base())
156 }
Colin Cross95d33fe2018-01-03 13:40:46 -0800157 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
Jiyong Park6a43f042017-10-12 23:05:00 +0900158 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
159 }
160}
161
Justin Yun7f99ec72021-04-12 13:19:28 +0900162func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) {
163 mod := ctx.ModuleForTests(name, variant).Module().(*Module)
164 partitionDefined := false
165 checkPartition := func(specific bool, partition string) {
166 if specific {
167 if expected != partition && !partitionDefined {
168 // The variant is installed to the 'partition'
169 t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition)
170 }
171 partitionDefined = true
172 } else {
173 // The variant is not installed to the 'partition'
174 if expected == partition {
175 t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition)
176 }
177 }
178 }
179 socSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800180 return m.SocSpecific() || m.InstallInVendor()
Justin Yun7f99ec72021-04-12 13:19:28 +0900181 }
182 deviceSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800183 return m.DeviceSpecific() || m.InstallInOdm()
Justin Yun7f99ec72021-04-12 13:19:28 +0900184 }
185 productSpecific := func(m *Module) bool {
Colin Crossea30d852023-11-29 16:00:16 -0800186 return m.ProductSpecific() || m.InstallInProduct()
Justin Yun7f99ec72021-04-12 13:19:28 +0900187 }
188 systemExtSpecific := func(m *Module) bool {
189 return m.SystemExtSpecific()
190 }
191 checkPartition(socSpecific(mod), "vendor")
192 checkPartition(deviceSpecific(mod), "odm")
193 checkPartition(productSpecific(mod), "product")
194 checkPartition(systemExtSpecific(mod), "system_ext")
195 if !partitionDefined && expected != "system" {
196 t.Errorf("%s variant of %q is expected to be installed to %s partition,"+
197 " but installed to system partition", variant, name, expected)
198 }
199}
200
201func TestInstallPartition(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400202 t.Parallel()
Justin Yun7f99ec72021-04-12 13:19:28 +0900203 t.Helper()
204 ctx := prepareForCcTest.RunTestWithBp(t, `
205 cc_library {
206 name: "libsystem",
207 }
208 cc_library {
209 name: "libsystem_ext",
210 system_ext_specific: true,
211 }
212 cc_library {
213 name: "libproduct",
214 product_specific: true,
215 }
216 cc_library {
217 name: "libvendor",
218 vendor: true,
219 }
220 cc_library {
221 name: "libodm",
222 device_specific: true,
223 }
224 cc_library {
225 name: "liball_available",
226 vendor_available: true,
227 product_available: true,
228 }
229 cc_library {
230 name: "libsystem_ext_all_available",
231 system_ext_specific: true,
232 vendor_available: true,
233 product_available: true,
234 }
235 cc_library {
236 name: "liball_available_odm",
237 odm_available: true,
238 product_available: true,
239 }
240 cc_library {
241 name: "libproduct_vendoravailable",
242 product_specific: true,
243 vendor_available: true,
244 }
245 cc_library {
246 name: "libproduct_odmavailable",
247 product_specific: true,
248 odm_available: true,
249 }
250 `).TestContext
251
252 checkInstallPartition(t, ctx, "libsystem", coreVariant, "system")
253 checkInstallPartition(t, ctx, "libsystem_ext", coreVariant, "system_ext")
254 checkInstallPartition(t, ctx, "libproduct", productVariant, "product")
255 checkInstallPartition(t, ctx, "libvendor", vendorVariant, "vendor")
256 checkInstallPartition(t, ctx, "libodm", vendorVariant, "odm")
257
258 checkInstallPartition(t, ctx, "liball_available", coreVariant, "system")
259 checkInstallPartition(t, ctx, "liball_available", productVariant, "product")
260 checkInstallPartition(t, ctx, "liball_available", vendorVariant, "vendor")
261
262 checkInstallPartition(t, ctx, "libsystem_ext_all_available", coreVariant, "system_ext")
263 checkInstallPartition(t, ctx, "libsystem_ext_all_available", productVariant, "product")
264 checkInstallPartition(t, ctx, "libsystem_ext_all_available", vendorVariant, "vendor")
265
266 checkInstallPartition(t, ctx, "liball_available_odm", coreVariant, "system")
267 checkInstallPartition(t, ctx, "liball_available_odm", productVariant, "product")
268 checkInstallPartition(t, ctx, "liball_available_odm", vendorVariant, "odm")
269
270 checkInstallPartition(t, ctx, "libproduct_vendoravailable", productVariant, "product")
271 checkInstallPartition(t, ctx, "libproduct_vendoravailable", vendorVariant, "vendor")
272
273 checkInstallPartition(t, ctx, "libproduct_odmavailable", productVariant, "product")
274 checkInstallPartition(t, ctx, "libproduct_odmavailable", vendorVariant, "odm")
275}
276
Colin Crossf61d03d2023-11-02 16:56:39 -0700277func checkWriteFileOutput(t *testing.T, ctx *android.TestContext, params android.TestingBuildParams, expected []string) {
Jooyung Han2216fb12019-11-06 16:46:15 +0900278 t.Helper()
Colin Crossf61d03d2023-11-02 16:56:39 -0700279 content := android.ContentFromFileRuleForTests(t, ctx, params)
Colin Crosscf371cc2020-11-13 11:48:42 -0800280 actual := strings.FieldsFunc(content, func(r rune) bool { return r == '\n' })
Jooyung Han2216fb12019-11-06 16:46:15 +0900281 assertArrayString(t, actual, expected)
282}
283
Chris Parsons79d66a52020-06-05 17:26:16 -0400284func TestDataLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400285 t.Parallel()
Chris Parsons79d66a52020-06-05 17:26:16 -0400286 bp := `
287 cc_test_library {
288 name: "test_lib",
289 srcs: ["test_lib.cpp"],
290 gtest: false,
291 }
292
293 cc_test {
294 name: "main_test",
295 data_libs: ["test_lib"],
296 gtest: false,
297 }
Chris Parsons216e10a2020-07-09 17:12:52 -0400298 `
Chris Parsons79d66a52020-06-05 17:26:16 -0400299
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000300 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons79d66a52020-06-05 17:26:16 -0400301
302 ctx := testCcWithConfig(t, config)
303 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
304 testBinary := module.(*Module).linker.(*testBinary)
305 outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
306 if err != nil {
307 t.Errorf("Expected cc_test to produce output files, error: %s", err)
308 return
309 }
310 if len(outputFiles) != 1 {
311 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
312 return
313 }
314 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -0800315 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons79d66a52020-06-05 17:26:16 -0400316 return
317 }
318
319 outputPath := outputFiles[0].String()
Chris Parsons216e10a2020-07-09 17:12:52 -0400320 testBinaryPath := testBinary.dataPaths()[0].SrcPath.String()
Chris Parsons79d66a52020-06-05 17:26:16 -0400321
322 if !strings.HasSuffix(outputPath, "/main_test") {
323 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
324 return
325 }
326 if !strings.HasSuffix(testBinaryPath, "/test_lib.so") {
327 t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", testBinaryPath)
328 return
329 }
330}
331
Chris Parsons216e10a2020-07-09 17:12:52 -0400332func TestDataLibsRelativeInstallPath(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400333 t.Parallel()
Chris Parsons216e10a2020-07-09 17:12:52 -0400334 bp := `
335 cc_test_library {
336 name: "test_lib",
337 srcs: ["test_lib.cpp"],
338 relative_install_path: "foo/bar/baz",
339 gtest: false,
340 }
341
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400342 cc_binary {
343 name: "test_bin",
344 relative_install_path: "foo/bar/baz",
345 compile_multilib: "both",
346 }
347
Chris Parsons216e10a2020-07-09 17:12:52 -0400348 cc_test {
349 name: "main_test",
350 data_libs: ["test_lib"],
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400351 data_bins: ["test_bin"],
Chris Parsons216e10a2020-07-09 17:12:52 -0400352 gtest: false,
353 }
354 `
355
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000356 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons216e10a2020-07-09 17:12:52 -0400357
358 ctx := testCcWithConfig(t, config)
359 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
360 testBinary := module.(*Module).linker.(*testBinary)
361 outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
362 if err != nil {
363 t.Fatalf("Expected cc_test to produce output files, error: %s", err)
364 }
365 if len(outputFiles) != 1 {
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400366 t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles)
Chris Parsons216e10a2020-07-09 17:12:52 -0400367 }
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400368 if len(testBinary.dataPaths()) != 2 {
Colin Cross7e2e7942023-11-16 12:56:02 -0800369 t.Fatalf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons216e10a2020-07-09 17:12:52 -0400370 }
371
372 outputPath := outputFiles[0].String()
Chris Parsons216e10a2020-07-09 17:12:52 -0400373
374 if !strings.HasSuffix(outputPath, "/main_test") {
375 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
376 }
Colin Crossaa255532020-07-03 13:18:24 -0700377 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
Chris Parsons216e10a2020-07-09 17:12:52 -0400378 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
379 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
Chris Parsons1f6d90f2020-06-17 16:10:42 -0400380 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
Chris Parsons216e10a2020-07-09 17:12:52 -0400381 }
Ivan Lozano4e5f07d2021-11-04 14:09:38 -0400382 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][1], ":test_bin:foo/bar/baz") {
383 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_bin:foo/bar/baz`,"+
384 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][1])
385 }
Chris Parsons216e10a2020-07-09 17:12:52 -0400386}
387
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000388func TestTestBinaryTestSuites(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400389 t.Parallel()
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000390 bp := `
391 cc_test {
392 name: "main_test",
393 srcs: ["main_test.cpp"],
394 test_suites: [
395 "suite_1",
396 "suite_2",
397 ],
398 gtest: false,
399 }
400 `
401
402 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
403 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
404
405 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
406 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
407 if len(compatEntries) != 2 {
408 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
409 }
410 if compatEntries[0] != "suite_1" {
411 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
412 " but was '%s'", compatEntries[0])
413 }
414 if compatEntries[1] != "suite_2" {
415 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
416 " but was '%s'", compatEntries[1])
417 }
418}
419
420func TestTestLibraryTestSuites(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400421 t.Parallel()
Trevor Radcliffef389cb42022-03-24 21:06:14 +0000422 bp := `
423 cc_test_library {
424 name: "main_test_lib",
425 srcs: ["main_test_lib.cpp"],
426 test_suites: [
427 "suite_1",
428 "suite_2",
429 ],
430 gtest: false,
431 }
432 `
433
434 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
435 module := ctx.ModuleForTests("main_test_lib", "android_arm_armv7-a-neon_shared").Module()
436
437 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
438 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
439 if len(compatEntries) != 2 {
440 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
441 }
442 if compatEntries[0] != "suite_1" {
443 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
444 " but was '%s'", compatEntries[0])
445 }
446 if compatEntries[1] != "suite_2" {
447 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
448 " but was '%s'", compatEntries[1])
449 }
450}
451
Jooyung Hana70f0672019-01-18 15:20:43 +0900452func TestDoubleLoadbleDep(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400453 t.Parallel()
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900454 // okay to link : LLNDK -> double_loadable
Jooyung Hana70f0672019-01-18 15:20:43 +0900455 testCc(t, `
456 cc_library {
457 name: "libllndk",
458 shared_libs: ["libdoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700459 llndk: {
460 symbol_file: "libllndk.map.txt",
461 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900462 }
463
464 cc_library {
465 name: "libdoubleloadable",
466 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900467 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900468 double_loadable: true,
469 }
470 `)
Jooyung Hana70f0672019-01-18 15:20:43 +0900471 // okay to link : double_loadable -> double_loadable
472 testCc(t, `
473 cc_library {
474 name: "libdoubleloadable1",
475 shared_libs: ["libdoubleloadable2"],
476 vendor_available: true,
477 double_loadable: true,
478 }
479
480 cc_library {
481 name: "libdoubleloadable2",
482 vendor_available: true,
483 double_loadable: true,
484 }
485 `)
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900486 // okay to link : double_loadable -> double_loadable
Jooyung Hana70f0672019-01-18 15:20:43 +0900487 testCc(t, `
488 cc_library {
489 name: "libdoubleloadable",
490 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900491 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900492 double_loadable: true,
493 shared_libs: ["libnondoubleloadable"],
494 }
495
496 cc_library {
497 name: "libnondoubleloadable",
Justin Yunfd9e8042020-12-23 18:23:14 +0900498 vendor_available: true,
499 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900500 double_loadable: true,
501 }
502 `)
503 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable
504 testCc(t, `
505 cc_library {
506 name: "libllndk",
507 shared_libs: ["libcoreonly"],
Colin Cross203b4212021-04-26 17:19:41 -0700508 llndk: {
509 symbol_file: "libllndk.map.txt",
510 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900511 }
512
513 cc_library {
514 name: "libcoreonly",
515 shared_libs: ["libvendoravailable"],
516 }
517
518 // indirect dependency of LLNDK
519 cc_library {
520 name: "libvendoravailable",
521 vendor_available: true,
522 double_loadable: true,
523 }
524 `)
525}
526
527func TestDoubleLoadableDepError(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400528 t.Parallel()
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900529 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable lib.
Jooyung Hana70f0672019-01-18 15:20:43 +0900530 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
531 cc_library {
532 name: "libllndk",
533 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700534 llndk: {
535 symbol_file: "libllndk.map.txt",
536 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900537 }
538
539 cc_library {
540 name: "libnondoubleloadable",
541 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900542 product_available: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900543 }
544 `)
545
546 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
547 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
548 cc_library {
549 name: "libllndk",
Yi Konge7fe9912019-06-02 00:53:50 -0700550 no_libcrt: true,
Jooyung Hana70f0672019-01-18 15:20:43 +0900551 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700552 llndk: {
553 symbol_file: "libllndk.map.txt",
554 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900555 }
556
557 cc_library {
558 name: "libnondoubleloadable",
559 vendor_available: true,
560 }
561 `)
562
Jooyung Hana70f0672019-01-18 15:20:43 +0900563 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
564 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
565 cc_library {
566 name: "libllndk",
567 shared_libs: ["libcoreonly"],
Colin Cross203b4212021-04-26 17:19:41 -0700568 llndk: {
569 symbol_file: "libllndk.map.txt",
570 }
Jooyung Hana70f0672019-01-18 15:20:43 +0900571 }
572
573 cc_library {
574 name: "libcoreonly",
575 shared_libs: ["libvendoravailable"],
576 }
577
578 // indirect dependency of LLNDK
579 cc_library {
580 name: "libvendoravailable",
581 vendor_available: true,
582 }
583 `)
Jiyong Park0474e1f2021-01-14 14:26:06 +0900584
585 // The error is not from 'client' but from 'libllndk'
586 testCcError(t, "module \"libllndk\".* links a library \"libnondoubleloadable\".*double_loadable", `
587 cc_library {
588 name: "client",
589 vendor_available: true,
590 double_loadable: true,
591 shared_libs: ["libllndk"],
592 }
593 cc_library {
594 name: "libllndk",
595 shared_libs: ["libnondoubleloadable"],
Colin Cross203b4212021-04-26 17:19:41 -0700596 llndk: {
597 symbol_file: "libllndk.map.txt",
598 }
Jiyong Park0474e1f2021-01-14 14:26:06 +0900599 }
600 cc_library {
601 name: "libnondoubleloadable",
602 vendor_available: true,
603 }
604 `)
Logan Chiend3c59a22018-03-29 14:08:15 +0800605}
606
Jooyung Han38002912019-05-16 04:01:54 +0900607func TestMakeLinkType(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400608 t.Parallel()
Colin Cross98be1bb2019-12-13 20:41:13 -0800609 bp := `
610 cc_library {
Colin Cross98be1bb2019-12-13 20:41:13 -0800611 name: "libvendor",
612 vendor: true,
613 }
Colin Cross98be1bb2019-12-13 20:41:13 -0800614 vndk_prebuilt_shared {
615 name: "prevndk",
616 version: "27",
617 target_arch: "arm",
618 binder32bit: true,
619 vendor_available: true,
Justin Yun63e9ec72020-10-29 16:49:43 +0900620 product_available: true,
Colin Cross98be1bb2019-12-13 20:41:13 -0800621 vndk: {
622 enabled: true,
623 },
624 arch: {
625 arm: {
626 srcs: ["liba.so"],
627 },
628 },
629 }
630 cc_library {
631 name: "libllndk",
Colin Cross203b4212021-04-26 17:19:41 -0700632 llndk: {
633 symbol_file: "libllndk.map.txt",
634 }
Colin Cross98be1bb2019-12-13 20:41:13 -0800635 }
636 cc_library {
637 name: "libllndkprivate",
Colin Cross203b4212021-04-26 17:19:41 -0700638 llndk: {
639 symbol_file: "libllndkprivate.map.txt",
640 private: true,
641 }
Colin Cross78212242021-01-06 14:51:30 -0800642 }
Colin Cross78212242021-01-06 14:51:30 -0800643 llndk_libraries_txt {
644 name: "llndk.libraries.txt",
645 }
Colin Cross78212242021-01-06 14:51:30 -0800646 `
Colin Cross98be1bb2019-12-13 20:41:13 -0800647
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000648 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Jooyung Han38002912019-05-16 04:01:54 +0900649 // native:vndk
Colin Cross98be1bb2019-12-13 20:41:13 -0800650 ctx := testCcWithConfig(t, config)
Jooyung Han38002912019-05-16 04:01:54 +0900651
Colin Crossfb0c16e2019-11-20 17:12:35 -0800652 vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared"
Inseob Kim64c43952019-08-26 16:52:35 +0900653
Jooyung Han38002912019-05-16 04:01:54 +0900654 tests := []struct {
655 variant string
656 name string
657 expected string
658 }{
Jooyung Han38002912019-05-16 04:01:54 +0900659 {vendorVariant, "libvendor", "native:vendor"},
Colin Cross127bb8b2020-12-16 16:46:01 -0800660 {vendorVariant, "libllndk", "native:vndk"},
Inseob Kim64c43952019-08-26 16:52:35 +0900661 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
Jooyung Han38002912019-05-16 04:01:54 +0900662 {coreVariant, "libllndk", "native:platform"},
663 }
664 for _, test := range tests {
665 t.Run(test.name, func(t *testing.T) {
666 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
667 assertString(t, module.makeLinkType, test.expected)
668 })
669 }
670}
671
Jeff Gaston294356f2017-09-27 17:05:30 -0700672var staticLinkDepOrderTestCases = []struct {
673 // This is a string representation of a map[moduleName][]moduleDependency .
674 // It models the dependencies declared in an Android.bp file.
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800675 inStatic string
676
677 // This is a string representation of a map[moduleName][]moduleDependency .
678 // It models the dependencies declared in an Android.bp file.
679 inShared string
Jeff Gaston294356f2017-09-27 17:05:30 -0700680
681 // allOrdered is a string representation of a map[moduleName][]moduleDependency .
682 // The keys of allOrdered specify which modules we would like to check.
683 // The values of allOrdered specify the expected result (of the transitive closure of all
684 // dependencies) for each module to test
685 allOrdered string
686
687 // outOrdered is a string representation of a map[moduleName][]moduleDependency .
688 // The keys of outOrdered specify which modules we would like to check.
689 // The values of outOrdered specify the expected result (of the ordered linker command line)
690 // for each module to test.
691 outOrdered string
692}{
693 // Simple tests
694 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800695 inStatic: "",
Jeff Gaston294356f2017-09-27 17:05:30 -0700696 outOrdered: "",
697 },
698 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800699 inStatic: "a:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700700 outOrdered: "a:",
701 },
702 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800703 inStatic: "a:b; b:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700704 outOrdered: "a:b; b:",
705 },
706 // Tests of reordering
707 {
708 // diamond example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800709 inStatic: "a:d,b,c; b:d; c:d; d:",
Jeff Gaston294356f2017-09-27 17:05:30 -0700710 outOrdered: "a:b,c,d; b:d; c:d; d:",
711 },
712 {
713 // somewhat real example
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800714 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700715 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
716 },
717 {
718 // multiple reorderings
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800719 inStatic: "a:b,c,d,e; d:b; e:c",
Jeff Gaston294356f2017-09-27 17:05:30 -0700720 outOrdered: "a:d,b,e,c; d:b; e:c",
721 },
722 {
723 // should reorder without adding new transitive dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800724 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional",
Jeff Gaston294356f2017-09-27 17:05:30 -0700725 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
726 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional",
727 },
728 {
729 // multiple levels of dependencies
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800730 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 -0700731 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
732 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
733 },
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800734 // shared dependencies
735 {
736 // Note that this test doesn't recurse, to minimize the amount of logic it tests.
737 // So, we don't actually have to check that a shared dependency of c will change the order
738 // of a library that depends statically on b and on c. We only need to check that if c has
739 // a shared dependency on b, that that shows up in allOrdered.
740 inShared: "c:b",
741 allOrdered: "c:b",
742 outOrdered: "c:",
743 },
744 {
745 // This test doesn't actually include any shared dependencies but it's a reminder of what
746 // the second phase of the above test would look like
747 inStatic: "a:b,c; c:b",
748 allOrdered: "a:c,b; c:b",
749 outOrdered: "a:c,b; c:b",
750 },
Jeff Gaston294356f2017-09-27 17:05:30 -0700751 // tiebreakers for when two modules specifying different orderings and there is no dependency
752 // to dictate an order
753 {
754 // 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 -0800755 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
Jeff Gaston294356f2017-09-27 17:05:30 -0700756 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
757 },
758 {
759 // 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 -0800760 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 -0700761 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e",
762 },
763 // Tests involving duplicate dependencies
764 {
765 // simple duplicate
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800766 inStatic: "a:b,c,c,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700767 outOrdered: "a:c,b",
768 },
769 {
770 // duplicates with reordering
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800771 inStatic: "a:b,c,d,c; c:b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700772 outOrdered: "a:d,c,b",
773 },
774 // Tests to confirm the nonexistence of infinite loops.
775 // These cases should never happen, so as long as the test terminates and the
776 // result is deterministic then that should be fine.
777 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800778 inStatic: "a:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700779 outOrdered: "a:a",
780 },
781 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800782 inStatic: "a:b; b:c; c:a",
Jeff Gaston294356f2017-09-27 17:05:30 -0700783 allOrdered: "a:b,c; b:c,a; c:a,b",
784 outOrdered: "a:b; b:c; c:a",
785 },
786 {
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800787 inStatic: "a:b,c; b:c,a; c:a,b",
Jeff Gaston294356f2017-09-27 17:05:30 -0700788 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
789 outOrdered: "a:c,b; b:a,c; c:b,a",
790 },
791}
792
793// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
794func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
795 // convert from "a:b,c; d:e" to "a:b,c;d:e"
796 strippedText := strings.Replace(text, " ", "", -1)
797 if len(strippedText) < 1 {
798 return []android.Path{}, make(map[android.Path][]android.Path, 0)
799 }
800 allDeps = make(map[android.Path][]android.Path, 0)
801
802 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
803 moduleTexts := strings.Split(strippedText, ";")
804
805 outputForModuleName := func(moduleName string) android.Path {
806 return android.PathForTesting(moduleName)
807 }
808
809 for _, moduleText := range moduleTexts {
810 // convert from "a:b,c" to ["a", "b,c"]
811 components := strings.Split(moduleText, ":")
812 if len(components) != 2 {
813 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
814 }
815 moduleName := components[0]
816 moduleOutput := outputForModuleName(moduleName)
817 modulesInOrder = append(modulesInOrder, moduleOutput)
818
819 depString := components[1]
820 // convert from "b,c" to ["b", "c"]
821 depNames := strings.Split(depString, ",")
822 if len(depString) < 1 {
823 depNames = []string{}
824 }
825 var deps []android.Path
826 for _, depName := range depNames {
827 deps = append(deps, outputForModuleName(depName))
828 }
829 allDeps[moduleOutput] = deps
830 }
831 return modulesInOrder, allDeps
832}
833
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800834func TestStaticLibDepReordering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400835 t.Parallel()
Jeff Gaston294356f2017-09-27 17:05:30 -0700836 ctx := testCc(t, `
837 cc_library {
838 name: "a",
839 static_libs: ["b", "c", "d"],
Jiyong Park374510b2018-03-19 18:23:01 +0900840 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700841 }
842 cc_library {
843 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +0900844 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700845 }
846 cc_library {
847 name: "c",
848 static_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +0900849 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700850 }
851 cc_library {
852 name: "d",
Jiyong Park374510b2018-03-19 18:23:01 +0900853 stl: "none",
Jeff Gaston294356f2017-09-27 17:05:30 -0700854 }
855
856 `)
857
Colin Cross7113d202019-11-20 16:39:12 -0800858 variant := "android_arm64_armv8-a_static"
Jeff Gaston294356f2017-09-27 17:05:30 -0700859 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Colin Cross5a377182023-12-14 14:46:23 -0800860 staticLibInfo, _ := android.SingletonModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
861 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400862 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b", "d"})
Jeff Gaston294356f2017-09-27 17:05:30 -0700863
864 if !reflect.DeepEqual(actual, expected) {
865 t.Errorf("staticDeps orderings were not propagated correctly"+
866 "\nactual: %v"+
867 "\nexpected: %v",
868 actual,
869 expected,
870 )
871 }
Jiyong Parkd08b6972017-09-26 10:50:54 +0900872}
Jeff Gaston294356f2017-09-27 17:05:30 -0700873
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800874func TestStaticLibDepReorderingWithShared(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400875 t.Parallel()
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800876 ctx := testCc(t, `
877 cc_library {
878 name: "a",
879 static_libs: ["b", "c"],
Jiyong Park374510b2018-03-19 18:23:01 +0900880 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800881 }
882 cc_library {
883 name: "b",
Jiyong Park374510b2018-03-19 18:23:01 +0900884 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800885 }
886 cc_library {
887 name: "c",
888 shared_libs: ["b"],
Jiyong Park374510b2018-03-19 18:23:01 +0900889 stl: "none",
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800890 }
891
892 `)
893
Colin Cross7113d202019-11-20 16:39:12 -0800894 variant := "android_arm64_armv8-a_static"
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800895 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
Colin Cross5a377182023-12-14 14:46:23 -0800896 staticLibInfo, _ := android.SingletonModuleProvider(ctx, moduleA, StaticLibraryInfoProvider)
897 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop()
Ivan Lozanod67a6b02021-05-20 13:01:32 -0400898 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b"})
Jeff Gastonf5b6e8f2017-11-27 15:48:57 -0800899
900 if !reflect.DeepEqual(actual, expected) {
901 t.Errorf("staticDeps orderings did not account for shared libs"+
902 "\nactual: %v"+
903 "\nexpected: %v",
904 actual,
905 expected,
906 )
907 }
908}
909
Jooyung Hanb04a4992020-03-13 18:57:35 +0900910func checkEquals(t *testing.T, message string, expected, actual interface{}) {
Colin Crossd1f898e2020-08-18 18:35:15 -0700911 t.Helper()
Jooyung Hanb04a4992020-03-13 18:57:35 +0900912 if !reflect.DeepEqual(actual, expected) {
913 t.Errorf(message+
914 "\nactual: %v"+
915 "\nexpected: %v",
916 actual,
917 expected,
918 )
919 }
920}
921
Jooyung Han61b66e92020-03-21 14:21:46 +0000922func TestLlndkLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400923 t.Parallel()
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800924 result := prepareForCcTest.RunTestWithBp(t, `
925 cc_library {
926 name: "libllndk",
927 stubs: { versions: ["1", "2"] },
928 llndk: {
929 symbol_file: "libllndk.map.txt",
930 },
931 export_include_dirs: ["include"],
932 }
933
934 cc_prebuilt_library_shared {
935 name: "libllndkprebuilt",
936 stubs: { versions: ["1", "2"] },
937 llndk: {
938 symbol_file: "libllndkprebuilt.map.txt",
939 },
940 }
941
942 cc_library {
943 name: "libllndk_with_external_headers",
944 stubs: { versions: ["1", "2"] },
945 llndk: {
946 symbol_file: "libllndk.map.txt",
947 export_llndk_headers: ["libexternal_llndk_headers"],
948 },
949 header_libs: ["libexternal_headers"],
950 export_header_lib_headers: ["libexternal_headers"],
951 }
952 cc_library_headers {
953 name: "libexternal_headers",
954 export_include_dirs: ["include"],
955 vendor_available: true,
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900956 product_available: true,
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800957 }
958 cc_library_headers {
959 name: "libexternal_llndk_headers",
960 export_include_dirs: ["include_llndk"],
961 llndk: {
962 symbol_file: "libllndk.map.txt",
963 },
964 vendor_available: true,
965 }
966
967 cc_library {
968 name: "libllndk_with_override_headers",
969 stubs: { versions: ["1", "2"] },
970 llndk: {
971 symbol_file: "libllndk.map.txt",
972 override_export_include_dirs: ["include_llndk"],
973 },
974 export_include_dirs: ["include"],
975 }
976 `)
977 actual := result.ModuleVariantsForTests("libllndk")
978 for i := 0; i < len(actual); i++ {
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900979 if !strings.HasPrefix(actual[i], "android_vendor_") {
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800980 actual = append(actual[:i], actual[i+1:]...)
981 i--
982 }
983 }
984 expected := []string{
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900985 "android_vendor_arm64_armv8-a_shared",
986 "android_vendor_arm_armv7-a-neon_shared",
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800987 }
988 android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
989
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900990 params := result.ModuleForTests("libllndk", "android_vendor_arm_armv7-a-neon_shared").Description("generate stub")
Jooyung Han33eb6152024-03-11 15:46:48 +0900991 android.AssertSame(t, "use Vendor API level for default stubs", "202404", params.Args["apiLevel"])
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800992
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800993 checkExportedIncludeDirs := func(module, variant string, expectedDirs ...string) {
994 t.Helper()
995 m := result.ModuleForTests(module, variant).Module()
Colin Cross5a377182023-12-14 14:46:23 -0800996 f, _ := android.SingletonModuleProvider(result, m, FlagExporterInfoProvider)
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800997 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
998 expectedDirs, f.IncludeDirs)
999 }
1000
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001001 checkExportedIncludeDirs("libllndk", coreVariant, "include")
1002 checkExportedIncludeDirs("libllndk", vendorVariant, "include")
1003 checkExportedIncludeDirs("libllndk_with_external_headers", coreVariant, "include")
1004 checkExportedIncludeDirs("libllndk_with_external_headers", vendorVariant, "include_llndk")
1005 checkExportedIncludeDirs("libllndk_with_override_headers", coreVariant, "include")
1006 checkExportedIncludeDirs("libllndk_with_override_headers", vendorVariant, "include_llndk")
1007
1008 checkAbiLinkerIncludeDirs := func(module string) {
1009 t.Helper()
1010 coreModule := result.ModuleForTests(module, coreVariant)
1011 abiCheckFlags := ""
1012 for _, output := range coreModule.AllOutputs() {
1013 if strings.HasSuffix(output, ".so.llndk.lsdump") {
1014 abiCheckFlags = coreModule.Output(output).Args["exportedHeaderFlags"]
1015 }
1016 }
1017 vendorModule := result.ModuleForTests(module, vendorVariant).Module()
1018 vendorInfo, _ := android.SingletonModuleProvider(result, vendorModule, FlagExporterInfoProvider)
1019 android.AssertStringEquals(t, module+" has different exported include dirs for vendor variant and ABI check",
1020 android.JoinPathsWithPrefix(vendorInfo.IncludeDirs, "-I"), abiCheckFlags)
1021 }
1022 checkAbiLinkerIncludeDirs("libllndk")
1023 checkAbiLinkerIncludeDirs("libllndk_with_override_headers")
1024 checkAbiLinkerIncludeDirs("libllndk_with_external_headers")
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001025}
1026
Jiyong Parka46a4d52017-12-14 19:54:34 +09001027func TestLlndkHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001028 t.Parallel()
Jiyong Parka46a4d52017-12-14 19:54:34 +09001029 ctx := testCc(t, `
Colin Cross627280f2021-04-26 16:53:58 -07001030 cc_library_headers {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001031 name: "libllndk_headers",
1032 export_include_dirs: ["my_include"],
Colin Cross627280f2021-04-26 16:53:58 -07001033 llndk: {
1034 llndk_headers: true,
1035 },
Jiyong Parka46a4d52017-12-14 19:54:34 +09001036 }
1037 cc_library {
Colin Cross0477b422020-10-13 18:43:54 -07001038 name: "libllndk",
Colin Cross627280f2021-04-26 16:53:58 -07001039 llndk: {
1040 symbol_file: "libllndk.map.txt",
1041 export_llndk_headers: ["libllndk_headers"],
1042 }
Colin Cross0477b422020-10-13 18:43:54 -07001043 }
1044
1045 cc_library {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001046 name: "libvendor",
1047 shared_libs: ["libllndk"],
1048 vendor: true,
1049 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001050 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001051 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001052 }
1053 `)
1054
1055 // _static variant is used since _shared reuses *.o from the static variant
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001056 cc := ctx.ModuleForTests("libvendor", "android_vendor_arm_armv7-a-neon_static").Rule("cc")
Jiyong Parka46a4d52017-12-14 19:54:34 +09001057 cflags := cc.Args["cFlags"]
1058 if !strings.Contains(cflags, "-Imy_include") {
1059 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1060 }
1061}
1062
Logan Chien43d34c32017-12-20 01:17:32 +08001063func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1064 actual := module.Properties.AndroidMkRuntimeLibs
1065 if !reflect.DeepEqual(actual, expected) {
1066 t.Errorf("incorrect runtime_libs for shared libs"+
1067 "\nactual: %v"+
1068 "\nexpected: %v",
1069 actual,
1070 expected,
1071 )
1072 }
1073}
1074
1075const runtimeLibAndroidBp = `
1076 cc_library {
Justin Yun8a2600c2020-12-07 12:44:03 +09001077 name: "liball_available",
1078 vendor_available: true,
1079 product_available: true,
1080 no_libcrt : true,
1081 nocrt : true,
1082 system_shared_libs : [],
1083 }
1084 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001085 name: "libvendor_available1",
1086 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001087 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001088 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001089 nocrt : true,
1090 system_shared_libs : [],
1091 }
1092 cc_library {
1093 name: "libvendor_available2",
1094 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001095 runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001096 target: {
1097 vendor: {
Justin Yun8a2600c2020-12-07 12:44:03 +09001098 exclude_runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001099 }
1100 },
Yi Konge7fe9912019-06-02 00:53:50 -07001101 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001102 nocrt : true,
1103 system_shared_libs : [],
1104 }
1105 cc_library {
Justin Yuncbca3732021-02-03 19:24:13 +09001106 name: "libproduct_vendor",
1107 product_specific: true,
1108 vendor_available: true,
1109 no_libcrt : true,
1110 nocrt : true,
1111 system_shared_libs : [],
1112 }
1113 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001114 name: "libcore",
Justin Yun8a2600c2020-12-07 12:44:03 +09001115 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001116 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001117 nocrt : true,
1118 system_shared_libs : [],
1119 }
1120 cc_library {
1121 name: "libvendor1",
1122 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001123 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001124 nocrt : true,
1125 system_shared_libs : [],
1126 }
1127 cc_library {
1128 name: "libvendor2",
1129 vendor: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001130 runtime_libs: ["liball_available", "libvendor1", "libproduct_vendor"],
Justin Yun8a2600c2020-12-07 12:44:03 +09001131 no_libcrt : true,
1132 nocrt : true,
1133 system_shared_libs : [],
1134 }
1135 cc_library {
1136 name: "libproduct_available1",
1137 product_available: true,
1138 runtime_libs: ["liball_available"],
1139 no_libcrt : true,
1140 nocrt : true,
1141 system_shared_libs : [],
1142 }
1143 cc_library {
1144 name: "libproduct1",
1145 product_specific: true,
1146 no_libcrt : true,
1147 nocrt : true,
1148 system_shared_libs : [],
1149 }
1150 cc_library {
1151 name: "libproduct2",
1152 product_specific: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001153 runtime_libs: ["liball_available", "libproduct1", "libproduct_vendor"],
Yi Konge7fe9912019-06-02 00:53:50 -07001154 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001155 nocrt : true,
1156 system_shared_libs : [],
1157 }
1158`
1159
1160func TestRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001161 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001162 ctx := testCc(t, runtimeLibAndroidBp)
1163
1164 // runtime_libs for core variants use the module names without suffixes.
Colin Cross7113d202019-11-20 16:39:12 -08001165 variant := "android_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001166
Justin Yun8a2600c2020-12-07 12:44:03 +09001167 module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1168 checkRuntimeLibs(t, []string{"liball_available"}, module)
1169
1170 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1171 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001172
1173 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001174 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001175
1176 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1177 // and vendor variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001178 variant = "android_vendor_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001179
Justin Yun8a2600c2020-12-07 12:44:03 +09001180 module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1181 checkRuntimeLibs(t, []string{"liball_available.vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001182
1183 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
Justin Yuncbca3732021-02-03 19:24:13 +09001184 checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001185
1186 // runtime_libs for product variants have '.product' suffixes if the modules have both core
1187 // and product variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001188 variant = "android_product_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001189
1190 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1191 checkRuntimeLibs(t, []string{"liball_available.product"}, module)
1192
1193 module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
Justin Yund00f5ca2021-02-03 19:43:02 +09001194 checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001195}
1196
1197func TestExcludeRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001198 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001199 ctx := testCc(t, runtimeLibAndroidBp)
1200
Colin Cross7113d202019-11-20 16:39:12 -08001201 variant := "android_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001202 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1203 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001204
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001205 variant = "android_vendor_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001206 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
Logan Chien43d34c32017-12-20 01:17:32 +08001207 checkRuntimeLibs(t, nil, module)
1208}
1209
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001210func checkStaticLibs(t *testing.T, expected []string, module *Module) {
Jooyung Han03b51852020-02-26 22:45:42 +09001211 t.Helper()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001212 actual := module.Properties.AndroidMkStaticLibs
1213 if !reflect.DeepEqual(actual, expected) {
1214 t.Errorf("incorrect static_libs"+
1215 "\nactual: %v"+
1216 "\nexpected: %v",
1217 actual,
1218 expected,
1219 )
1220 }
1221}
1222
1223const staticLibAndroidBp = `
1224 cc_library {
1225 name: "lib1",
1226 }
1227 cc_library {
1228 name: "lib2",
1229 static_libs: ["lib1"],
1230 }
1231`
1232
1233func TestStaticLibDepExport(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001234 t.Parallel()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001235 ctx := testCc(t, staticLibAndroidBp)
1236
1237 // Check the shared version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001238 variant := "android_arm64_armv8-a_shared"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001239 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Colin Cross4c4c1be2022-02-10 11:41:18 -08001240 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001241
1242 // Check the static version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001243 variant = "android_arm64_armv8-a_static"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001244 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1245 // libc++_static is linked additionally.
Colin Cross4c4c1be2022-02-10 11:41:18 -08001246 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001247}
1248
Jiyong Parkd08b6972017-09-26 10:50:54 +09001249var compilerFlagsTestCases = []struct {
1250 in string
1251 out bool
1252}{
1253 {
1254 in: "a",
1255 out: false,
1256 },
1257 {
1258 in: "-a",
1259 out: true,
1260 },
1261 {
1262 in: "-Ipath/to/something",
1263 out: false,
1264 },
1265 {
1266 in: "-isystempath/to/something",
1267 out: false,
1268 },
1269 {
1270 in: "--coverage",
1271 out: false,
1272 },
1273 {
1274 in: "-include a/b",
1275 out: true,
1276 },
1277 {
1278 in: "-include a/b c/d",
1279 out: false,
1280 },
1281 {
1282 in: "-DMACRO",
1283 out: true,
1284 },
1285 {
1286 in: "-DMAC RO",
1287 out: false,
1288 },
1289 {
1290 in: "-a -b",
1291 out: false,
1292 },
1293 {
1294 in: "-DMACRO=definition",
1295 out: true,
1296 },
1297 {
1298 in: "-DMACRO=defi nition",
1299 out: true, // TODO(jiyong): this should be false
1300 },
1301 {
1302 in: "-DMACRO(x)=x + 1",
1303 out: true,
1304 },
1305 {
1306 in: "-DMACRO=\"defi nition\"",
1307 out: true,
1308 },
1309}
1310
1311type mockContext struct {
1312 BaseModuleContext
1313 result bool
1314}
1315
1316func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1317 // CheckBadCompilerFlags calls this function when the flag should be rejected
1318 ctx.result = false
1319}
1320
1321func TestCompilerFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001322 t.Parallel()
Jiyong Parkd08b6972017-09-26 10:50:54 +09001323 for _, testCase := range compilerFlagsTestCases {
1324 ctx := &mockContext{result: true}
1325 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1326 if ctx.result != testCase.out {
1327 t.Errorf("incorrect output:")
1328 t.Errorf(" input: %#v", testCase.in)
1329 t.Errorf(" expected: %#v", testCase.out)
1330 t.Errorf(" got: %#v", ctx.result)
1331 }
1332 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001333}
Jiyong Park374510b2018-03-19 18:23:01 +09001334
Jiyong Park37b25202018-07-11 10:49:27 +09001335func TestRecovery(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001336 t.Parallel()
Jiyong Park37b25202018-07-11 10:49:27 +09001337 ctx := testCc(t, `
1338 cc_library_shared {
1339 name: "librecovery",
1340 recovery: true,
1341 }
1342 cc_library_shared {
1343 name: "librecovery32",
1344 recovery: true,
1345 compile_multilib:"32",
1346 }
Jiyong Park5baac542018-08-28 09:55:37 +09001347 cc_library_shared {
1348 name: "libHalInRecovery",
1349 recovery_available: true,
1350 vendor: true,
1351 }
Jiyong Park37b25202018-07-11 10:49:27 +09001352 `)
1353
1354 variants := ctx.ModuleVariantsForTests("librecovery")
Colin Crossfb0c16e2019-11-20 17:12:35 -08001355 const arm64 = "android_recovery_arm64_armv8-a_shared"
Jiyong Park37b25202018-07-11 10:49:27 +09001356 if len(variants) != 1 || !android.InList(arm64, variants) {
1357 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1358 }
1359
1360 variants = ctx.ModuleVariantsForTests("librecovery32")
1361 if android.InList(arm64, variants) {
1362 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1363 }
Jiyong Park5baac542018-08-28 09:55:37 +09001364
1365 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1366 if !recoveryModule.Platform() {
1367 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1368 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09001369}
Jiyong Park5baac542018-08-28 09:55:37 +09001370
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001371func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001372 t.Parallel()
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001373 bp := `
1374 cc_prebuilt_test_library_shared {
1375 name: "test_lib",
1376 relative_install_path: "foo/bar/baz",
1377 srcs: ["srcpath/dontusethispath/baz.so"],
1378 }
1379
1380 cc_test {
1381 name: "main_test",
1382 data_libs: ["test_lib"],
1383 gtest: false,
1384 }
1385 `
1386
Paul Duffinc3e6ce02021-03-22 23:21:32 +00001387 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001388
1389 ctx := testCcWithConfig(t, config)
1390 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
1391 testBinary := module.(*Module).linker.(*testBinary)
1392 outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
1393 if err != nil {
1394 t.Fatalf("Expected cc_test to produce output files, error: %s", err)
1395 }
1396 if len(outputFiles) != 1 {
1397 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
1398 }
1399 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -08001400 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001401 }
1402
1403 outputPath := outputFiles[0].String()
1404
1405 if !strings.HasSuffix(outputPath, "/main_test") {
1406 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
1407 }
Colin Crossaa255532020-07-03 13:18:24 -07001408 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001409 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
1410 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
1411 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
1412 }
1413}
1414
Jiyong Park7ed9de32018-10-15 22:25:07 +09001415func TestVersionedStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001416 t.Parallel()
Jiyong Park7ed9de32018-10-15 22:25:07 +09001417 ctx := testCc(t, `
1418 cc_library_shared {
1419 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001420 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001421 stubs: {
1422 symbol_file: "foo.map.txt",
1423 versions: ["1", "2", "3"],
1424 },
1425 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001426
Jiyong Park7ed9de32018-10-15 22:25:07 +09001427 cc_library_shared {
1428 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001429 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001430 shared_libs: ["libFoo#1"],
1431 }`)
1432
1433 variants := ctx.ModuleVariantsForTests("libFoo")
1434 expectedVariants := []string{
Colin Cross7113d202019-11-20 16:39:12 -08001435 "android_arm64_armv8-a_shared",
1436 "android_arm64_armv8-a_shared_1",
1437 "android_arm64_armv8-a_shared_2",
1438 "android_arm64_armv8-a_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001439 "android_arm64_armv8-a_shared_current",
Colin Cross7113d202019-11-20 16:39:12 -08001440 "android_arm_armv7-a-neon_shared",
1441 "android_arm_armv7-a-neon_shared_1",
1442 "android_arm_armv7-a-neon_shared_2",
1443 "android_arm_armv7-a-neon_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001444 "android_arm_armv7-a-neon_shared_current",
Jiyong Park7ed9de32018-10-15 22:25:07 +09001445 }
1446 variantsMismatch := false
1447 if len(variants) != len(expectedVariants) {
1448 variantsMismatch = true
1449 } else {
1450 for _, v := range expectedVariants {
1451 if !inList(v, variants) {
1452 variantsMismatch = false
1453 }
1454 }
1455 }
1456 if variantsMismatch {
1457 t.Errorf("variants of libFoo expected:\n")
1458 for _, v := range expectedVariants {
1459 t.Errorf("%q\n", v)
1460 }
1461 t.Errorf(", but got:\n")
1462 for _, v := range variants {
1463 t.Errorf("%q\n", v)
1464 }
1465 }
1466
Colin Cross7113d202019-11-20 16:39:12 -08001467 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
Jiyong Park7ed9de32018-10-15 22:25:07 +09001468 libFlags := libBarLinkRule.Args["libFlags"]
Colin Cross7113d202019-11-20 16:39:12 -08001469 libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so"
Jiyong Park7ed9de32018-10-15 22:25:07 +09001470 if !strings.Contains(libFlags, libFoo1StubPath) {
1471 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
1472 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001473
Colin Cross7113d202019-11-20 16:39:12 -08001474 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc")
Jiyong Parkda732bd2018-11-02 18:23:15 +09001475 cFlags := libBarCompileRule.Args["cFlags"]
1476 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
1477 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
1478 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
1479 }
Jiyong Park37b25202018-07-11 10:49:27 +09001480}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001481
Liz Kammer48cdbeb2023-03-17 10:17:50 -04001482func TestStubsForLibraryInMultipleApexes(t *testing.T) {
1483 t.Parallel()
1484 ctx := testCc(t, `
1485 cc_library_shared {
1486 name: "libFoo",
1487 srcs: ["foo.c"],
1488 stubs: {
1489 symbol_file: "foo.map.txt",
1490 versions: ["current"],
1491 },
1492 apex_available: ["bar", "a1"],
1493 }
1494
1495 cc_library_shared {
1496 name: "libBar",
1497 srcs: ["bar.c"],
1498 shared_libs: ["libFoo"],
1499 apex_available: ["a1"],
1500 }
1501
1502 cc_library_shared {
1503 name: "libA1",
1504 srcs: ["a1.c"],
1505 shared_libs: ["libFoo"],
1506 apex_available: ["a1"],
1507 }
1508
1509 cc_library_shared {
1510 name: "libBarA1",
1511 srcs: ["bara1.c"],
1512 shared_libs: ["libFoo"],
1513 apex_available: ["bar", "a1"],
1514 }
1515
1516 cc_library_shared {
1517 name: "libAnyApex",
1518 srcs: ["anyApex.c"],
1519 shared_libs: ["libFoo"],
1520 apex_available: ["//apex_available:anyapex"],
1521 }
1522
1523 cc_library_shared {
1524 name: "libBaz",
1525 srcs: ["baz.c"],
1526 shared_libs: ["libFoo"],
1527 apex_available: ["baz"],
1528 }
1529
1530 cc_library_shared {
1531 name: "libQux",
1532 srcs: ["qux.c"],
1533 shared_libs: ["libFoo"],
1534 apex_available: ["qux", "bar"],
1535 }`)
1536
1537 variants := ctx.ModuleVariantsForTests("libFoo")
1538 expectedVariants := []string{
1539 "android_arm64_armv8-a_shared",
1540 "android_arm64_armv8-a_shared_current",
1541 "android_arm_armv7-a-neon_shared",
1542 "android_arm_armv7-a-neon_shared_current",
1543 }
1544 variantsMismatch := false
1545 if len(variants) != len(expectedVariants) {
1546 variantsMismatch = true
1547 } else {
1548 for _, v := range expectedVariants {
1549 if !inList(v, variants) {
1550 variantsMismatch = false
1551 }
1552 }
1553 }
1554 if variantsMismatch {
1555 t.Errorf("variants of libFoo expected:\n")
1556 for _, v := range expectedVariants {
1557 t.Errorf("%q\n", v)
1558 }
1559 t.Errorf(", but got:\n")
1560 for _, v := range variants {
1561 t.Errorf("%q\n", v)
1562 }
1563 }
1564
1565 linkAgainstFoo := []string{"libBarA1"}
1566 linkAgainstFooStubs := []string{"libBar", "libA1", "libBaz", "libQux", "libAnyApex"}
1567
1568 libFooPath := "libFoo/android_arm64_armv8-a_shared/libFoo.so"
1569 for _, lib := range linkAgainstFoo {
1570 libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
1571 libFlags := libLinkRule.Args["libFlags"]
1572 if !strings.Contains(libFlags, libFooPath) {
1573 t.Errorf("%q: %q is not found in %q", lib, libFooPath, libFlags)
1574 }
1575 }
1576
1577 libFooStubPath := "libFoo/android_arm64_armv8-a_shared_current/libFoo.so"
1578 for _, lib := range linkAgainstFooStubs {
1579 libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
1580 libFlags := libLinkRule.Args["libFlags"]
1581 if !strings.Contains(libFlags, libFooStubPath) {
1582 t.Errorf("%q: %q is not found in %q", lib, libFooStubPath, libFlags)
1583 }
1584 }
1585}
1586
Jooyung Hanb04a4992020-03-13 18:57:35 +09001587func TestVersioningMacro(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001588 t.Parallel()
Jooyung Hanb04a4992020-03-13 18:57:35 +09001589 for _, tc := range []struct{ moduleName, expected string }{
1590 {"libc", "__LIBC_API__"},
1591 {"libfoo", "__LIBFOO_API__"},
1592 {"libfoo@1", "__LIBFOO_1_API__"},
1593 {"libfoo-v1", "__LIBFOO_V1_API__"},
1594 {"libfoo.v1", "__LIBFOO_V1_API__"},
1595 } {
1596 checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName))
1597 }
1598}
1599
Liz Kammer83cf81b2022-09-22 08:24:20 -04001600func pathsToBase(paths android.Paths) []string {
1601 var ret []string
1602 for _, p := range paths {
1603 ret = append(ret, p.Base())
1604 }
1605 return ret
1606}
1607
1608func TestStaticLibArchiveArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001609 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001610 ctx := testCc(t, `
1611 cc_library_static {
1612 name: "foo",
1613 srcs: ["foo.c"],
1614 }
1615
1616 cc_library_static {
1617 name: "bar",
1618 srcs: ["bar.c"],
1619 }
1620
1621 cc_library_shared {
1622 name: "qux",
1623 srcs: ["qux.c"],
1624 }
1625
1626 cc_library_static {
1627 name: "baz",
1628 srcs: ["baz.c"],
1629 static_libs: ["foo"],
1630 shared_libs: ["qux"],
1631 whole_static_libs: ["bar"],
1632 }`)
1633
1634 variant := "android_arm64_armv8-a_static"
1635 arRule := ctx.ModuleForTests("baz", variant).Rule("ar")
1636
1637 // For static libraries, the object files of a whole static dep are included in the archive
1638 // directly
1639 if g, w := pathsToBase(arRule.Inputs), []string{"bar.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1640 t.Errorf("Expected input objects %q, got %q", w, g)
1641 }
1642
1643 // non whole static dependencies are not linked into the archive
1644 if len(arRule.Implicits) > 0 {
1645 t.Errorf("Expected 0 additional deps, got %q", arRule.Implicits)
1646 }
1647}
1648
1649func TestSharedLibLinkingArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001650 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001651 ctx := testCc(t, `
1652 cc_library_static {
1653 name: "foo",
1654 srcs: ["foo.c"],
1655 }
1656
1657 cc_library_static {
1658 name: "bar",
1659 srcs: ["bar.c"],
1660 }
1661
1662 cc_library_shared {
1663 name: "qux",
1664 srcs: ["qux.c"],
1665 }
1666
1667 cc_library_shared {
1668 name: "baz",
1669 srcs: ["baz.c"],
1670 static_libs: ["foo"],
1671 shared_libs: ["qux"],
1672 whole_static_libs: ["bar"],
1673 }`)
1674
1675 variant := "android_arm64_armv8-a_shared"
1676 linkRule := ctx.ModuleForTests("baz", variant).Rule("ld")
1677 libFlags := linkRule.Args["libFlags"]
1678 // When dynamically linking, we expect static dependencies to be found on the command line
1679 if expected := "foo.a"; !strings.Contains(libFlags, expected) {
1680 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1681 }
1682 // When dynamically linking, we expect whole static dependencies to be found on the command line
1683 if expected := "bar.a"; !strings.Contains(libFlags, expected) {
1684 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1685 }
1686
1687 // When dynamically linking, we expect shared dependencies to be found on the command line
1688 if expected := "qux.so"; !strings.Contains(libFlags, expected) {
1689 t.Errorf("Shared lib %q was not found in %q", expected, libFlags)
1690 }
1691
1692 // We should only have the objects from the shared library srcs, not the whole static dependencies
1693 if g, w := pathsToBase(linkRule.Inputs), []string{"baz.o"}; !reflect.DeepEqual(w, g) {
1694 t.Errorf("Expected input objects %q, got %q", w, g)
1695 }
1696}
1697
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001698func TestStaticExecutable(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001699 t.Parallel()
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001700 ctx := testCc(t, `
1701 cc_binary {
1702 name: "static_test",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +01001703 srcs: ["foo.c", "baz.o"],
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001704 static_executable: true,
1705 }`)
1706
Colin Cross7113d202019-11-20 16:39:12 -08001707 variant := "android_arm64_armv8-a"
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001708 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
1709 libFlags := binModuleRule.Args["libFlags"]
Ryan Prichardb49fe1b2019-10-11 15:03:34 -07001710 systemStaticLibs := []string{"libc.a", "libm.a"}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001711 for _, lib := range systemStaticLibs {
1712 if !strings.Contains(libFlags, lib) {
1713 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
1714 }
1715 }
1716 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
1717 for _, lib := range systemSharedLibs {
1718 if strings.Contains(libFlags, lib) {
1719 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
1720 }
1721 }
1722}
Jiyong Parke4bb9862019-02-01 00:31:10 +09001723
1724func TestStaticDepsOrderWithStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001725 t.Parallel()
Jiyong Parke4bb9862019-02-01 00:31:10 +09001726 ctx := testCc(t, `
1727 cc_binary {
1728 name: "mybin",
1729 srcs: ["foo.c"],
Colin Cross0de8a1e2020-09-18 14:15:30 -07001730 static_libs: ["libfooC", "libfooB"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001731 static_executable: true,
1732 stl: "none",
1733 }
1734
1735 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001736 name: "libfooB",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001737 srcs: ["foo.c"],
Colin Crossf9aabd72020-02-15 11:29:50 -08001738 shared_libs: ["libfooC"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001739 stl: "none",
1740 }
1741
1742 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001743 name: "libfooC",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001744 srcs: ["foo.c"],
1745 stl: "none",
1746 stubs: {
1747 versions: ["1"],
1748 },
1749 }`)
1750
Colin Cross0de8a1e2020-09-18 14:15:30 -07001751 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld")
1752 actual := mybin.Implicits[:2]
Ivan Lozanod67a6b02021-05-20 13:01:32 -04001753 expected := GetOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
Jiyong Parke4bb9862019-02-01 00:31:10 +09001754
1755 if !reflect.DeepEqual(actual, expected) {
1756 t.Errorf("staticDeps orderings were not propagated correctly"+
1757 "\nactual: %v"+
1758 "\nexpected: %v",
1759 actual,
1760 expected,
1761 )
1762 }
1763}
Jooyung Han38002912019-05-16 04:01:54 +09001764
Jooyung Hand48f3c32019-08-23 11:18:57 +09001765func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001766 t.Parallel()
Jooyung Hand48f3c32019-08-23 11:18:57 +09001767 testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
1768 cc_library {
1769 name: "libA",
1770 srcs: ["foo.c"],
1771 shared_libs: ["libB"],
1772 stl: "none",
1773 }
1774
1775 cc_library {
1776 name: "libB",
1777 srcs: ["foo.c"],
1778 enabled: false,
1779 stl: "none",
1780 }
1781 `)
1782}
1783
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001784func VerifyAFLFuzzTargetVariant(t *testing.T, variant string) {
1785 bp := `
1786 cc_fuzz {
Cory Barkera1da26f2022-06-07 20:12:06 +00001787 name: "test_afl_fuzz_target",
1788 srcs: ["foo.c"],
1789 host_supported: true,
1790 static_libs: [
1791 "afl_fuzz_static_lib",
1792 ],
1793 shared_libs: [
1794 "afl_fuzz_shared_lib",
1795 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001796 fuzzing_frameworks: {
1797 afl: true,
1798 libfuzzer: false,
1799 },
Cory Barkera1da26f2022-06-07 20:12:06 +00001800 }
1801 cc_library {
1802 name: "afl_fuzz_static_lib",
1803 host_supported: true,
1804 srcs: ["static_file.c"],
1805 }
1806 cc_library {
1807 name: "libfuzzer_only_static_lib",
1808 host_supported: true,
1809 srcs: ["static_file.c"],
1810 }
1811 cc_library {
1812 name: "afl_fuzz_shared_lib",
1813 host_supported: true,
1814 srcs: ["shared_file.c"],
1815 static_libs: [
1816 "second_static_lib",
1817 ],
1818 }
1819 cc_library_headers {
1820 name: "libafl_headers",
1821 vendor_available: true,
1822 host_supported: true,
1823 export_include_dirs: [
1824 "include",
1825 "instrumentation",
1826 ],
1827 }
1828 cc_object {
1829 name: "afl-compiler-rt",
1830 vendor_available: true,
1831 host_supported: true,
1832 cflags: [
1833 "-fPIC",
1834 ],
1835 srcs: [
1836 "instrumentation/afl-compiler-rt.o.c",
1837 ],
1838 }
1839 cc_library {
1840 name: "second_static_lib",
1841 host_supported: true,
1842 srcs: ["second_file.c"],
1843 }
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001844 cc_object {
Cory Barkera1da26f2022-06-07 20:12:06 +00001845 name: "aflpp_driver",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001846 host_supported: true,
Cory Barkera1da26f2022-06-07 20:12:06 +00001847 srcs: [
1848 "aflpp_driver.c",
1849 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001850 }`
1851
1852 testEnv := map[string]string{
1853 "FUZZ_FRAMEWORK": "AFL",
1854 }
1855
1856 ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp)
Cory Barkera1da26f2022-06-07 20:12:06 +00001857
1858 checkPcGuardFlag := func(
1859 modName string, variantName string, shouldHave bool) {
1860 cc := ctx.ModuleForTests(modName, variantName).Rule("cc")
1861
1862 cFlags, ok := cc.Args["cFlags"]
1863 if !ok {
1864 t.Errorf("Could not find cFlags for module %s and variant %s",
1865 modName, variantName)
1866 }
1867
1868 if strings.Contains(
1869 cFlags, "-fsanitize-coverage=trace-pc-guard") != shouldHave {
1870 t.Errorf("Flag was found: %t. Expected to find flag: %t. "+
1871 "Test failed for module %s and variant %s",
1872 !shouldHave, shouldHave, modName, variantName)
1873 }
1874 }
1875
Cory Barkera1da26f2022-06-07 20:12:06 +00001876 moduleName := "test_afl_fuzz_target"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001877 checkPcGuardFlag(moduleName, variant+"_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001878
1879 moduleName = "afl_fuzz_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001880 checkPcGuardFlag(moduleName, variant+"_static", false)
1881 checkPcGuardFlag(moduleName, variant+"_static_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001882
1883 moduleName = "second_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001884 checkPcGuardFlag(moduleName, variant+"_static", false)
1885 checkPcGuardFlag(moduleName, variant+"_static_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001886
1887 ctx.ModuleForTests("afl_fuzz_shared_lib",
1888 "android_arm64_armv8-a_shared").Rule("cc")
1889 ctx.ModuleForTests("afl_fuzz_shared_lib",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001890 "android_arm64_armv8-a_shared_fuzzer").Rule("cc")
1891}
1892
1893func TestAFLFuzzTargetForDevice(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001894 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001895 VerifyAFLFuzzTargetVariant(t, "android_arm64_armv8-a")
1896}
1897
1898func TestAFLFuzzTargetForLinuxHost(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001899 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001900 if runtime.GOOS != "linux" {
1901 t.Skip("requires linux")
1902 }
1903
1904 VerifyAFLFuzzTargetVariant(t, "linux_glibc_x86_64")
Cory Barkera1da26f2022-06-07 20:12:06 +00001905}
1906
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001907// Simple smoke test for the cc_fuzz target that ensures the rule compiles
1908// correctly.
1909func TestFuzzTarget(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001910 t.Parallel()
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001911 ctx := testCc(t, `
1912 cc_fuzz {
1913 name: "fuzz_smoke_test",
1914 srcs: ["foo.c"],
1915 }`)
1916
Paul Duffin075c4172019-12-19 19:06:13 +00001917 variant := "android_arm64_armv8-a_fuzzer"
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001918 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
1919}
1920
Jooyung Han38002912019-05-16 04:01:54 +09001921func assertString(t *testing.T, got, expected string) {
1922 t.Helper()
1923 if got != expected {
1924 t.Errorf("expected %q got %q", expected, got)
1925 }
1926}
1927
1928func assertArrayString(t *testing.T, got, expected []string) {
1929 t.Helper()
1930 if len(got) != len(expected) {
1931 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
1932 return
1933 }
1934 for i := range got {
1935 if got[i] != expected[i] {
1936 t.Errorf("expected %d-th %q (%q) got %q (%q)",
1937 i, expected[i], expected, got[i], got)
1938 return
1939 }
1940 }
1941}
Colin Crosse1bb5d02019-09-24 14:55:04 -07001942
Jooyung Han0302a842019-10-30 18:43:49 +09001943func assertMapKeys(t *testing.T, m map[string]string, expected []string) {
1944 t.Helper()
Cole Faust18994c72023-02-28 16:02:16 -08001945 assertArrayString(t, android.SortedKeys(m), expected)
Jooyung Han0302a842019-10-30 18:43:49 +09001946}
1947
Colin Crosse1bb5d02019-09-24 14:55:04 -07001948func TestDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001949 t.Parallel()
Colin Crosse1bb5d02019-09-24 14:55:04 -07001950 ctx := testCc(t, `
1951 cc_defaults {
1952 name: "defaults",
1953 srcs: ["foo.c"],
1954 static: {
1955 srcs: ["bar.c"],
1956 },
1957 shared: {
1958 srcs: ["baz.c"],
1959 },
1960 }
1961
1962 cc_library_static {
1963 name: "libstatic",
1964 defaults: ["defaults"],
1965 }
1966
1967 cc_library_shared {
1968 name: "libshared",
1969 defaults: ["defaults"],
1970 }
1971
1972 cc_library {
1973 name: "libboth",
1974 defaults: ["defaults"],
1975 }
1976
1977 cc_binary {
1978 name: "binary",
1979 defaults: ["defaults"],
1980 }`)
1981
Colin Cross7113d202019-11-20 16:39:12 -08001982 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001983 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1984 t.Errorf("libshared ld rule wanted %q, got %q", w, g)
1985 }
Colin Cross7113d202019-11-20 16:39:12 -08001986 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001987 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1988 t.Errorf("libboth ld rule wanted %q, got %q", w, g)
1989 }
Colin Cross7113d202019-11-20 16:39:12 -08001990 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001991 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
1992 t.Errorf("binary ld rule wanted %q, got %q", w, g)
1993 }
1994
Colin Cross7113d202019-11-20 16:39:12 -08001995 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07001996 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
1997 t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
1998 }
Colin Cross7113d202019-11-20 16:39:12 -08001999 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002000 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2001 t.Errorf("libboth ar rule wanted %q, got %q", w, g)
2002 }
2003}
Colin Crosseabaedd2020-02-06 17:01:55 -08002004
2005func TestProductVariableDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002006 t.Parallel()
Colin Crosseabaedd2020-02-06 17:01:55 -08002007 bp := `
2008 cc_defaults {
2009 name: "libfoo_defaults",
2010 srcs: ["foo.c"],
2011 cppflags: ["-DFOO"],
2012 product_variables: {
2013 debuggable: {
2014 cppflags: ["-DBAR"],
2015 },
2016 },
2017 }
2018
2019 cc_library {
2020 name: "libfoo",
2021 defaults: ["libfoo_defaults"],
2022 }
2023 `
2024
Paul Duffin8567f222021-03-23 00:02:06 +00002025 result := android.GroupFixturePreparers(
2026 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002027 android.PrepareForTestWithVariables,
Colin Crosseabaedd2020-02-06 17:01:55 -08002028
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002029 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2030 variables.Debuggable = BoolPtr(true)
2031 }),
2032 ).RunTestWithBp(t, bp)
Colin Crosseabaedd2020-02-06 17:01:55 -08002033
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002034 libfoo := result.Module("libfoo", "android_arm64_armv8-a_static").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +00002035 android.AssertStringListContains(t, "cppflags", libfoo.flags.Local.CppFlags, "-DBAR")
Colin Crosseabaedd2020-02-06 17:01:55 -08002036}
Colin Crosse4f6eba2020-09-22 18:11:25 -07002037
2038func TestEmptyWholeStaticLibsAllowMissingDependencies(t *testing.T) {
2039 t.Parallel()
2040 bp := `
2041 cc_library_static {
2042 name: "libfoo",
2043 srcs: ["foo.c"],
2044 whole_static_libs: ["libbar"],
2045 }
2046
2047 cc_library_static {
2048 name: "libbar",
2049 whole_static_libs: ["libmissing"],
2050 }
2051 `
2052
Paul Duffin8567f222021-03-23 00:02:06 +00002053 result := android.GroupFixturePreparers(
2054 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002055 android.PrepareForTestWithAllowMissingDependencies,
2056 ).RunTestWithBp(t, bp)
Colin Crosse4f6eba2020-09-22 18:11:25 -07002057
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002058 libbar := result.ModuleForTests("libbar", "android_arm64_armv8-a_static").Output("libbar.a")
Paul Duffine84b1332021-03-12 11:59:43 +00002059 android.AssertDeepEquals(t, "libbar rule", android.ErrorRule, libbar.Rule)
Colin Crosse4f6eba2020-09-22 18:11:25 -07002060
Paul Duffine84b1332021-03-12 11:59:43 +00002061 android.AssertStringDoesContain(t, "libbar error", libbar.Args["error"], "missing dependencies: libmissing")
Colin Crosse4f6eba2020-09-22 18:11:25 -07002062
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002063 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Output("libfoo.a")
Paul Duffine84b1332021-03-12 11:59:43 +00002064 android.AssertStringListContains(t, "libfoo.a dependencies", libfoo.Inputs.Strings(), libbar.Output.String())
Colin Crosse4f6eba2020-09-22 18:11:25 -07002065}
Colin Crosse9fe2942020-11-10 18:12:15 -08002066
2067func TestInstallSharedLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002068 t.Parallel()
Colin Crosse9fe2942020-11-10 18:12:15 -08002069 bp := `
2070 cc_binary {
2071 name: "bin",
2072 host_supported: true,
2073 shared_libs: ["libshared"],
2074 runtime_libs: ["libruntime"],
2075 srcs: [":gen"],
2076 }
2077
2078 cc_library_shared {
2079 name: "libshared",
2080 host_supported: true,
2081 shared_libs: ["libtransitive"],
2082 }
2083
2084 cc_library_shared {
2085 name: "libtransitive",
2086 host_supported: true,
2087 }
2088
2089 cc_library_shared {
2090 name: "libruntime",
2091 host_supported: true,
2092 }
2093
2094 cc_binary_host {
2095 name: "tool",
2096 srcs: ["foo.cpp"],
2097 }
2098
2099 genrule {
2100 name: "gen",
2101 tools: ["tool"],
2102 out: ["gen.cpp"],
2103 cmd: "$(location tool) $(out)",
2104 }
2105 `
2106
Paul Duffinc3e6ce02021-03-22 23:21:32 +00002107 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Colin Crosse9fe2942020-11-10 18:12:15 -08002108 ctx := testCcWithConfig(t, config)
2109
2110 hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install")
2111 hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install")
2112 hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install")
2113 hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install")
2114 hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install")
2115
2116 if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) {
2117 t.Errorf("expected host bin dependency %q, got %q", w, g)
2118 }
2119
2120 if g, w := hostBin.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2121 t.Errorf("expected host bin dependency %q, got %q", w, g)
2122 }
2123
2124 if g, w := hostShared.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2125 t.Errorf("expected host bin dependency %q, got %q", w, g)
2126 }
2127
2128 if g, w := hostBin.Implicits.Strings(), hostRuntime.Output.String(); !android.InList(w, g) {
2129 t.Errorf("expected host bin dependency %q, got %q", w, g)
2130 }
2131
2132 if g, w := hostBin.Implicits.Strings(), hostTool.Output.String(); android.InList(w, g) {
2133 t.Errorf("expected no host bin dependency %q, got %q", w, g)
2134 }
2135
2136 deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install")
2137 deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install")
2138 deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install")
2139 deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install")
2140
2141 if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) {
2142 t.Errorf("expected device bin dependency %q, got %q", w, g)
2143 }
2144
2145 if g, w := deviceBin.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2146 t.Errorf("expected device bin dependency %q, got %q", w, g)
2147 }
2148
2149 if g, w := deviceShared.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2150 t.Errorf("expected device bin dependency %q, got %q", w, g)
2151 }
2152
2153 if g, w := deviceBin.OrderOnly.Strings(), deviceRuntime.Output.String(); !android.InList(w, g) {
2154 t.Errorf("expected device bin dependency %q, got %q", w, g)
2155 }
2156
2157 if g, w := deviceBin.OrderOnly.Strings(), hostTool.Output.String(); android.InList(w, g) {
2158 t.Errorf("expected no device bin dependency %q, got %q", w, g)
2159 }
2160
2161}
Jiyong Park1ad8e162020-12-01 23:40:09 +09002162
2163func TestStubsLibReexportsHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002164 t.Parallel()
Jiyong Park1ad8e162020-12-01 23:40:09 +09002165 ctx := testCc(t, `
2166 cc_library_shared {
2167 name: "libclient",
2168 srcs: ["foo.c"],
2169 shared_libs: ["libfoo#1"],
2170 }
2171
2172 cc_library_shared {
2173 name: "libfoo",
2174 srcs: ["foo.c"],
2175 shared_libs: ["libbar"],
2176 export_shared_lib_headers: ["libbar"],
2177 stubs: {
2178 symbol_file: "foo.map.txt",
2179 versions: ["1", "2", "3"],
2180 },
2181 }
2182
2183 cc_library_shared {
2184 name: "libbar",
2185 export_include_dirs: ["include/libbar"],
2186 srcs: ["foo.c"],
2187 }`)
2188
2189 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2190
2191 if !strings.Contains(cFlags, "-Iinclude/libbar") {
2192 t.Errorf("expected %q in cflags, got %q", "-Iinclude/libbar", cFlags)
2193 }
2194}
Jooyung Hane197d8b2021-01-05 10:33:16 +09002195
Vinh Tran09581952023-05-16 16:03:20 -04002196func TestAidlLibraryWithHeaders(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002197 t.Parallel()
2198 ctx := android.GroupFixturePreparers(
2199 prepareForCcTest,
2200 aidl_library.PrepareForTestWithAidlLibrary,
2201 android.MockFS{
2202 "package_bar/Android.bp": []byte(`
2203 aidl_library {
2204 name: "bar",
2205 srcs: ["x/y/Bar.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002206 hdrs: ["x/HeaderBar.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002207 strip_import_prefix: "x",
2208 }
2209 `)}.AddToFixture(),
2210 android.MockFS{
2211 "package_foo/Android.bp": []byte(`
2212 aidl_library {
2213 name: "foo",
2214 srcs: ["a/b/Foo.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002215 hdrs: ["a/HeaderFoo.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002216 strip_import_prefix: "a",
2217 deps: ["bar"],
2218 }
2219 cc_library {
2220 name: "libfoo",
2221 aidl: {
2222 libs: ["foo"],
2223 }
2224 }
2225 `),
2226 }.AddToFixture(),
2227 ).RunTest(t).TestContext
2228
2229 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Vinh Tran09581952023-05-16 16:03:20 -04002230
2231 android.AssertPathsRelativeToTopEquals(
2232 t,
2233 "aidl headers",
2234 []string{
2235 "package_bar/x/HeaderBar.aidl",
2236 "package_foo/a/HeaderFoo.aidl",
2237 "package_foo/a/b/Foo.aidl",
2238 "out/soong/.intermediates/package_foo/libfoo/android_arm64_armv8-a_static/gen/aidl_library.sbox.textproto",
2239 },
2240 libfoo.Rule("aidl_library").Implicits,
2241 )
2242
Colin Crossf61d03d2023-11-02 16:56:39 -07002243 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl_library.sbox.textproto"))
Vinh Tran367d89d2023-04-28 11:21:25 -04002244 aidlCommand := manifest.Commands[0].GetCommand()
2245
2246 expectedAidlFlags := "-Ipackage_foo/a -Ipackage_bar/x"
2247 if !strings.Contains(aidlCommand, expectedAidlFlags) {
2248 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlags)
2249 }
2250
2251 outputs := strings.Join(libfoo.AllOutputs(), " ")
2252
Vinh Tran09581952023-05-16 16:03:20 -04002253 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BpFoo.h")
2254 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BnFoo.h")
2255 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/Foo.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002256 android.AssertStringDoesContain(t, "aidl-generated cpp", outputs, "b/Foo.cpp")
2257 // Confirm that the aidl header doesn't get compiled to cpp and h files
Vinh Tran09581952023-05-16 16:03:20 -04002258 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BpBar.h")
2259 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BnBar.h")
2260 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/Bar.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002261 android.AssertStringDoesNotContain(t, "aidl-generated cpp", outputs, "y/Bar.cpp")
2262}
2263
Jooyung Hane197d8b2021-01-05 10:33:16 +09002264func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002265 t.Parallel()
Vinh Tran367d89d2023-04-28 11:21:25 -04002266 ctx := android.GroupFixturePreparers(
2267 prepareForCcTest,
2268 aidl_library.PrepareForTestWithAidlLibrary,
2269 ).RunTestWithBp(t, `
Jooyung Hane197d8b2021-01-05 10:33:16 +09002270 cc_library {
2271 name: "libfoo",
2272 srcs: ["a/Foo.aidl"],
2273 aidl: { flags: ["-Werror"], },
2274 }
2275 `)
2276
2277 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Colin Crossf61d03d2023-11-02 16:56:39 -07002278 manifest := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, libfoo.Output("aidl.sbox.textproto"))
Jooyung Hane197d8b2021-01-05 10:33:16 +09002279 aidlCommand := manifest.Commands[0].GetCommand()
2280 expectedAidlFlag := "-Werror"
2281 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2282 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2283 }
2284}
Evgenii Stepanov193ac2e2020-04-28 15:09:12 -07002285
Jooyung Han07f70c02021-11-06 07:08:45 +09002286func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002287 t.Parallel()
Jooyung Han07f70c02021-11-06 07:08:45 +09002288 for _, tc := range []struct {
2289 name string
2290 sdkVersion string
2291 variant string
2292 expected string
2293 }{
2294 {
2295 name: "default is current",
2296 sdkVersion: "",
2297 variant: "android_arm64_armv8-a_static",
2298 expected: "platform_apis",
2299 },
2300 {
2301 name: "use sdk_version",
2302 sdkVersion: `sdk_version: "29"`,
2303 variant: "android_arm64_armv8-a_static",
2304 expected: "platform_apis",
2305 },
2306 {
2307 name: "use sdk_version(sdk variant)",
2308 sdkVersion: `sdk_version: "29"`,
2309 variant: "android_arm64_armv8-a_sdk_static",
2310 expected: "29",
2311 },
2312 {
2313 name: "use min_sdk_version",
2314 sdkVersion: `min_sdk_version: "29"`,
2315 variant: "android_arm64_armv8-a_static",
2316 expected: "29",
2317 },
2318 } {
2319 t.Run(tc.name, func(t *testing.T) {
2320 ctx := testCc(t, `
2321 cc_library {
2322 name: "libfoo",
2323 stl: "none",
2324 srcs: ["a/Foo.aidl"],
2325 `+tc.sdkVersion+`
2326 }
2327 `)
2328 libfoo := ctx.ModuleForTests("libfoo", tc.variant)
Colin Crossf61d03d2023-11-02 16:56:39 -07002329 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl.sbox.textproto"))
Jooyung Han07f70c02021-11-06 07:08:45 +09002330 aidlCommand := manifest.Commands[0].GetCommand()
2331 expectedAidlFlag := "--min_sdk_version=" + tc.expected
2332 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2333 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2334 }
2335 })
2336 }
2337}
2338
Vinh Tran09581952023-05-16 16:03:20 -04002339func TestInvalidAidlProp(t *testing.T) {
2340 t.Parallel()
2341
2342 testCases := []struct {
2343 description string
2344 bp string
2345 }{
2346 {
2347 description: "Invalid use of aidl.libs and aidl.include_dirs",
2348 bp: `
2349 cc_library {
2350 name: "foo",
2351 aidl: {
2352 libs: ["foo_aidl"],
2353 include_dirs: ["bar/include"],
2354 }
2355 }
2356 `,
2357 },
2358 {
2359 description: "Invalid use of aidl.libs and aidl.local_include_dirs",
2360 bp: `
2361 cc_library {
2362 name: "foo",
2363 aidl: {
2364 libs: ["foo_aidl"],
2365 local_include_dirs: ["include"],
2366 }
2367 }
2368 `,
2369 },
2370 }
2371
2372 for _, testCase := range testCases {
2373 t.Run(testCase.description, func(t *testing.T) {
2374 bp := `
2375 aidl_library {
2376 name: "foo_aidl",
2377 srcs: ["Foo.aidl"],
2378 } ` + testCase.bp
2379 android.GroupFixturePreparers(
2380 prepareForCcTest,
2381 aidl_library.PrepareForTestWithAidlLibrary.
2382 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("For aidl headers, please only use aidl.libs prop")),
2383 ).RunTestWithBp(t, bp)
2384 })
2385 }
2386}
2387
Jiyong Parka008fb02021-03-16 17:15:53 +09002388func TestMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002389 t.Parallel()
Jiyong Parka008fb02021-03-16 17:15:53 +09002390 ctx := testCc(t, `
2391 cc_library_shared {
2392 name: "libfoo",
2393 srcs: ["foo.c"],
2394 min_sdk_version: "29",
2395 }`)
2396
2397 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2398 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android29")
2399}
2400
Vinh Tranf1924742022-06-24 16:40:11 -04002401func TestNonDigitMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002402 t.Parallel()
Vinh Tranf1924742022-06-24 16:40:11 -04002403 bp := `
2404 cc_library_shared {
2405 name: "libfoo",
2406 srcs: ["foo.c"],
2407 min_sdk_version: "S",
2408 }
2409 `
2410 result := android.GroupFixturePreparers(
2411 prepareForCcTest,
2412 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2413 variables.Platform_version_active_codenames = []string{"UpsideDownCake", "Tiramisu"}
2414 }),
2415 ).RunTestWithBp(t, bp)
2416 ctx := result.TestContext
2417 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2418 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android31")
2419}
2420
Paul Duffin3cb603e2021-02-19 13:57:10 +00002421func TestIncludeDirsExporting(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002422 t.Parallel()
Paul Duffin3cb603e2021-02-19 13:57:10 +00002423
2424 // Trim spaces from the beginning, end and immediately after any newline characters. Leaves
2425 // embedded newline characters alone.
2426 trimIndentingSpaces := func(s string) string {
2427 return strings.TrimSpace(regexp.MustCompile("(^|\n)\\s+").ReplaceAllString(s, "$1"))
2428 }
2429
2430 checkPaths := func(t *testing.T, message string, expected string, paths android.Paths) {
2431 t.Helper()
2432 expected = trimIndentingSpaces(expected)
2433 actual := trimIndentingSpaces(strings.Join(android.FirstUniqueStrings(android.NormalizePathsForTesting(paths)), "\n"))
2434 if expected != actual {
2435 t.Errorf("%s: expected:\n%s\n actual:\n%s\n", message, expected, actual)
2436 }
2437 }
2438
2439 type exportedChecker func(t *testing.T, name string, exported FlagExporterInfo)
2440
2441 checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) {
2442 t.Helper()
Colin Cross5a377182023-12-14 14:46:23 -08002443 exported, _ := android.SingletonModuleProvider(ctx, module, FlagExporterInfoProvider)
Paul Duffin3cb603e2021-02-19 13:57:10 +00002444 name := module.Name()
2445
2446 for _, checker := range checkers {
2447 checker(t, name, exported)
2448 }
2449 }
2450
2451 expectedIncludeDirs := func(expectedPaths string) exportedChecker {
2452 return func(t *testing.T, name string, exported FlagExporterInfo) {
2453 t.Helper()
2454 checkPaths(t, fmt.Sprintf("%s: include dirs", name), expectedPaths, exported.IncludeDirs)
2455 }
2456 }
2457
2458 expectedSystemIncludeDirs := func(expectedPaths string) exportedChecker {
2459 return func(t *testing.T, name string, exported FlagExporterInfo) {
2460 t.Helper()
2461 checkPaths(t, fmt.Sprintf("%s: system include dirs", name), expectedPaths, exported.SystemIncludeDirs)
2462 }
2463 }
2464
2465 expectedGeneratedHeaders := func(expectedPaths string) exportedChecker {
2466 return func(t *testing.T, name string, exported FlagExporterInfo) {
2467 t.Helper()
2468 checkPaths(t, fmt.Sprintf("%s: generated headers", name), expectedPaths, exported.GeneratedHeaders)
2469 }
2470 }
2471
2472 expectedOrderOnlyDeps := func(expectedPaths string) exportedChecker {
2473 return func(t *testing.T, name string, exported FlagExporterInfo) {
2474 t.Helper()
2475 checkPaths(t, fmt.Sprintf("%s: order only deps", name), expectedPaths, exported.Deps)
2476 }
2477 }
2478
2479 genRuleModules := `
2480 genrule {
2481 name: "genrule_foo",
2482 cmd: "generate-foo",
2483 out: [
2484 "generated_headers/foo/generated_header.h",
2485 ],
2486 export_include_dirs: [
2487 "generated_headers",
2488 ],
2489 }
2490
2491 genrule {
2492 name: "genrule_bar",
2493 cmd: "generate-bar",
2494 out: [
2495 "generated_headers/bar/generated_header.h",
2496 ],
2497 export_include_dirs: [
2498 "generated_headers",
2499 ],
2500 }
2501 `
2502
2503 t.Run("ensure exported include dirs are not automatically re-exported from shared_libs", func(t *testing.T) {
2504 ctx := testCc(t, genRuleModules+`
2505 cc_library {
2506 name: "libfoo",
2507 srcs: ["foo.c"],
2508 export_include_dirs: ["foo/standard"],
2509 export_system_include_dirs: ["foo/system"],
2510 generated_headers: ["genrule_foo"],
2511 export_generated_headers: ["genrule_foo"],
2512 }
2513
2514 cc_library {
2515 name: "libbar",
2516 srcs: ["bar.c"],
2517 shared_libs: ["libfoo"],
2518 export_include_dirs: ["bar/standard"],
2519 export_system_include_dirs: ["bar/system"],
2520 generated_headers: ["genrule_bar"],
2521 export_generated_headers: ["genrule_bar"],
2522 }
2523 `)
2524 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2525 checkIncludeDirs(t, ctx, foo,
2526 expectedIncludeDirs(`
2527 foo/standard
2528 .intermediates/genrule_foo/gen/generated_headers
2529 `),
2530 expectedSystemIncludeDirs(`foo/system`),
2531 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2532 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2533 )
2534
2535 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2536 checkIncludeDirs(t, ctx, bar,
2537 expectedIncludeDirs(`
2538 bar/standard
2539 .intermediates/genrule_bar/gen/generated_headers
2540 `),
2541 expectedSystemIncludeDirs(`bar/system`),
2542 expectedGeneratedHeaders(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2543 expectedOrderOnlyDeps(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2544 )
2545 })
2546
2547 t.Run("ensure exported include dirs are automatically re-exported from whole_static_libs", func(t *testing.T) {
2548 ctx := testCc(t, genRuleModules+`
2549 cc_library {
2550 name: "libfoo",
2551 srcs: ["foo.c"],
2552 export_include_dirs: ["foo/standard"],
2553 export_system_include_dirs: ["foo/system"],
2554 generated_headers: ["genrule_foo"],
2555 export_generated_headers: ["genrule_foo"],
2556 }
2557
2558 cc_library {
2559 name: "libbar",
2560 srcs: ["bar.c"],
2561 whole_static_libs: ["libfoo"],
2562 export_include_dirs: ["bar/standard"],
2563 export_system_include_dirs: ["bar/system"],
2564 generated_headers: ["genrule_bar"],
2565 export_generated_headers: ["genrule_bar"],
2566 }
2567 `)
2568 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2569 checkIncludeDirs(t, ctx, foo,
2570 expectedIncludeDirs(`
2571 foo/standard
2572 .intermediates/genrule_foo/gen/generated_headers
2573 `),
2574 expectedSystemIncludeDirs(`foo/system`),
2575 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2576 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2577 )
2578
2579 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2580 checkIncludeDirs(t, ctx, bar,
2581 expectedIncludeDirs(`
2582 bar/standard
2583 foo/standard
2584 .intermediates/genrule_foo/gen/generated_headers
2585 .intermediates/genrule_bar/gen/generated_headers
2586 `),
2587 expectedSystemIncludeDirs(`
2588 bar/system
2589 foo/system
2590 `),
2591 expectedGeneratedHeaders(`
2592 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2593 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2594 `),
2595 expectedOrderOnlyDeps(`
2596 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2597 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2598 `),
2599 )
2600 })
2601
Paul Duffin3cb603e2021-02-19 13:57:10 +00002602 t.Run("ensure only aidl headers are exported", func(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002603 ctx := android.GroupFixturePreparers(
2604 prepareForCcTest,
2605 aidl_library.PrepareForTestWithAidlLibrary,
2606 ).RunTestWithBp(t, `
2607 aidl_library {
2608 name: "libfoo_aidl",
2609 srcs: ["x/y/Bar.aidl"],
2610 strip_import_prefix: "x",
2611 }
Paul Duffin3cb603e2021-02-19 13:57:10 +00002612 cc_library_shared {
2613 name: "libfoo",
2614 srcs: [
2615 "foo.c",
2616 "b.aidl",
2617 "a.proto",
2618 ],
2619 aidl: {
Vinh Tran367d89d2023-04-28 11:21:25 -04002620 libs: ["libfoo_aidl"],
Paul Duffin3cb603e2021-02-19 13:57:10 +00002621 export_aidl_headers: true,
2622 }
2623 }
Vinh Tran367d89d2023-04-28 11:21:25 -04002624 `).TestContext
Paul Duffin3cb603e2021-02-19 13:57:10 +00002625 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2626 checkIncludeDirs(t, ctx, foo,
2627 expectedIncludeDirs(`
2628 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl
Vinh Tran09581952023-05-16 16:03:20 -04002629 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library
Paul Duffin3cb603e2021-02-19 13:57:10 +00002630 `),
2631 expectedSystemIncludeDirs(``),
2632 expectedGeneratedHeaders(`
2633 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2634 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2635 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002636 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2637 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2638 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002639 `),
2640 expectedOrderOnlyDeps(`
2641 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2642 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2643 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002644 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2645 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2646 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002647 `),
2648 )
2649 })
2650
Paul Duffin3cb603e2021-02-19 13:57:10 +00002651 t.Run("ensure only proto headers are exported", func(t *testing.T) {
2652 ctx := testCc(t, genRuleModules+`
2653 cc_library_shared {
2654 name: "libfoo",
2655 srcs: [
2656 "foo.c",
2657 "b.aidl",
2658 "a.proto",
2659 ],
2660 proto: {
2661 export_proto_headers: true,
2662 }
2663 }
2664 `)
2665 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2666 checkIncludeDirs(t, ctx, foo,
2667 expectedIncludeDirs(`
2668 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto
2669 `),
2670 expectedSystemIncludeDirs(``),
2671 expectedGeneratedHeaders(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002672 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2673 `),
2674 expectedOrderOnlyDeps(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002675 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2676 `),
2677 )
2678 })
2679
Paul Duffin33056e82021-02-19 13:49:08 +00002680 t.Run("ensure only sysprop headers are exported", func(t *testing.T) {
Paul Duffin3cb603e2021-02-19 13:57:10 +00002681 ctx := testCc(t, genRuleModules+`
2682 cc_library_shared {
2683 name: "libfoo",
2684 srcs: [
2685 "foo.c",
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002686 "path/to/a.sysprop",
Paul Duffin3cb603e2021-02-19 13:57:10 +00002687 "b.aidl",
2688 "a.proto",
2689 ],
2690 }
2691 `)
2692 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2693 checkIncludeDirs(t, ctx, foo,
2694 expectedIncludeDirs(`
2695 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include
2696 `),
2697 expectedSystemIncludeDirs(``),
2698 expectedGeneratedHeaders(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002699 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002700 `),
2701 expectedOrderOnlyDeps(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002702 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
2703 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002704 `),
2705 )
2706 })
2707}
Colin Crossae628182021-06-14 16:52:28 -07002708
2709func TestIncludeDirectoryOrdering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002710 t.Parallel()
Liz Kammer08572c62021-09-30 10:11:04 -04002711 baseExpectedFlags := []string{
2712 "${config.ArmThumbCflags}",
2713 "${config.ArmCflags}",
2714 "${config.CommonGlobalCflags}",
2715 "${config.DeviceGlobalCflags}",
2716 "${config.ExternalCflags}",
2717 "${config.ArmToolchainCflags}",
2718 "${config.ArmArmv7ANeonCflags}",
2719 "${config.ArmGenericCflags}",
2720 "-target",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002721 "armv7a-linux-androideabi21",
Liz Kammer08572c62021-09-30 10:11:04 -04002722 }
2723
2724 expectedIncludes := []string{
2725 "external/foo/android_arm_export_include_dirs",
2726 "external/foo/lib32_export_include_dirs",
2727 "external/foo/arm_export_include_dirs",
2728 "external/foo/android_export_include_dirs",
2729 "external/foo/linux_export_include_dirs",
2730 "external/foo/export_include_dirs",
2731 "external/foo/android_arm_local_include_dirs",
2732 "external/foo/lib32_local_include_dirs",
2733 "external/foo/arm_local_include_dirs",
2734 "external/foo/android_local_include_dirs",
2735 "external/foo/linux_local_include_dirs",
2736 "external/foo/local_include_dirs",
2737 "external/foo",
2738 "external/foo/libheader1",
2739 "external/foo/libheader2",
2740 "external/foo/libwhole1",
2741 "external/foo/libwhole2",
2742 "external/foo/libstatic1",
2743 "external/foo/libstatic2",
2744 "external/foo/libshared1",
2745 "external/foo/libshared2",
2746 "external/foo/liblinux",
2747 "external/foo/libandroid",
2748 "external/foo/libarm",
2749 "external/foo/lib32",
2750 "external/foo/libandroid_arm",
2751 "defaults/cc/common/ndk_libc++_shared",
Liz Kammer08572c62021-09-30 10:11:04 -04002752 }
2753
2754 conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
2755 cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"}
2756
Elliott Hughesed4a27b2022-05-18 13:15:00 -07002757 cflags := []string{"-Werror", "-std=candcpp"}
Elliott Hughesfb294e32023-06-14 10:42:45 -07002758 cstd := []string{"-std=gnu17", "-std=conly"}
Elliott Hughesc79d9e32022-01-13 14:56:02 -08002759 cppstd := []string{"-std=gnu++20", "-std=cpp", "-fno-rtti"}
Liz Kammer08572c62021-09-30 10:11:04 -04002760
2761 lastIncludes := []string{
2762 "out/soong/ndk/sysroot/usr/include",
2763 "out/soong/ndk/sysroot/usr/include/arm-linux-androideabi",
2764 }
2765
2766 combineSlices := func(slices ...[]string) []string {
2767 var ret []string
2768 for _, s := range slices {
2769 ret = append(ret, s...)
2770 }
2771 return ret
2772 }
2773
2774 testCases := []struct {
2775 name string
2776 src string
2777 expected []string
2778 }{
2779 {
2780 name: "c",
2781 src: "foo.c",
Yi Kong13beeed2023-07-15 03:09:00 +09002782 expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
Liz Kammer08572c62021-09-30 10:11:04 -04002783 },
2784 {
2785 name: "cc",
2786 src: "foo.cc",
Yi Kong13beeed2023-07-15 03:09:00 +09002787 expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
Liz Kammer08572c62021-09-30 10:11:04 -04002788 },
2789 {
2790 name: "assemble",
2791 src: "foo.s",
Yi Kong13beeed2023-07-15 03:09:00 +09002792 expected: combineSlices(baseExpectedFlags, []string{"${config.CommonGlobalAsflags}"}, expectedIncludes, lastIncludes),
Liz Kammer08572c62021-09-30 10:11:04 -04002793 },
2794 }
2795
2796 for _, tc := range testCases {
2797 t.Run(tc.name, func(t *testing.T) {
2798 bp := fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002799 cc_library {
2800 name: "libfoo",
Liz Kammer08572c62021-09-30 10:11:04 -04002801 srcs: ["%s"],
Liz Kammer9dc65772021-12-16 11:38:50 -05002802 cflags: ["-std=candcpp"],
2803 conlyflags: ["-std=conly"],
2804 cppflags: ["-std=cpp"],
Colin Crossae628182021-06-14 16:52:28 -07002805 local_include_dirs: ["local_include_dirs"],
2806 export_include_dirs: ["export_include_dirs"],
2807 export_system_include_dirs: ["export_system_include_dirs"],
2808 static_libs: ["libstatic1", "libstatic2"],
2809 whole_static_libs: ["libwhole1", "libwhole2"],
2810 shared_libs: ["libshared1", "libshared2"],
2811 header_libs: ["libheader1", "libheader2"],
2812 target: {
2813 android: {
2814 shared_libs: ["libandroid"],
2815 local_include_dirs: ["android_local_include_dirs"],
2816 export_include_dirs: ["android_export_include_dirs"],
2817 },
2818 android_arm: {
2819 shared_libs: ["libandroid_arm"],
2820 local_include_dirs: ["android_arm_local_include_dirs"],
2821 export_include_dirs: ["android_arm_export_include_dirs"],
2822 },
2823 linux: {
2824 shared_libs: ["liblinux"],
2825 local_include_dirs: ["linux_local_include_dirs"],
2826 export_include_dirs: ["linux_export_include_dirs"],
2827 },
2828 },
2829 multilib: {
2830 lib32: {
2831 shared_libs: ["lib32"],
2832 local_include_dirs: ["lib32_local_include_dirs"],
2833 export_include_dirs: ["lib32_export_include_dirs"],
2834 },
2835 },
2836 arch: {
2837 arm: {
2838 shared_libs: ["libarm"],
2839 local_include_dirs: ["arm_local_include_dirs"],
2840 export_include_dirs: ["arm_export_include_dirs"],
2841 },
2842 },
2843 stl: "libc++",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002844 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002845 }
2846
2847 cc_library_headers {
2848 name: "libheader1",
2849 export_include_dirs: ["libheader1"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002850 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002851 stl: "none",
2852 }
2853
2854 cc_library_headers {
2855 name: "libheader2",
2856 export_include_dirs: ["libheader2"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002857 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002858 stl: "none",
2859 }
Liz Kammer08572c62021-09-30 10:11:04 -04002860 `, tc.src)
Colin Crossae628182021-06-14 16:52:28 -07002861
Liz Kammer08572c62021-09-30 10:11:04 -04002862 libs := []string{
2863 "libstatic1",
2864 "libstatic2",
2865 "libwhole1",
2866 "libwhole2",
2867 "libshared1",
2868 "libshared2",
2869 "libandroid",
2870 "libandroid_arm",
2871 "liblinux",
2872 "lib32",
2873 "libarm",
2874 }
Colin Crossae628182021-06-14 16:52:28 -07002875
Liz Kammer08572c62021-09-30 10:11:04 -04002876 for _, lib := range libs {
2877 bp += fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002878 cc_library {
2879 name: "%s",
2880 export_include_dirs: ["%s"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002881 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002882 stl: "none",
2883 }
2884 `, lib, lib)
Liz Kammer08572c62021-09-30 10:11:04 -04002885 }
2886
2887 ctx := android.GroupFixturePreparers(
2888 PrepareForIntegrationTestWithCc,
2889 android.FixtureAddTextFile("external/foo/Android.bp", bp),
2890 ).RunTest(t)
2891 // Use the arm variant instead of the arm64 variant so that it gets headers from
2892 // ndk_libandroid_support to test LateStaticLibs.
2893 cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"]
2894
2895 var includes []string
2896 flags := strings.Split(cflags, " ")
2897 for _, flag := range flags {
2898 if strings.HasPrefix(flag, "-I") {
2899 includes = append(includes, strings.TrimPrefix(flag, "-I"))
2900 } else if flag == "-isystem" {
2901 // skip isystem, include next
2902 } else if len(flag) > 0 {
2903 includes = append(includes, flag)
2904 }
2905 }
2906
2907 android.AssertArrayString(t, "includes", tc.expected, includes)
2908 })
Colin Crossae628182021-06-14 16:52:28 -07002909 }
2910
Colin Crossae628182021-06-14 16:52:28 -07002911}
Alixb5f6d9e2022-04-20 23:00:58 +00002912
zijunzhao933e3802023-01-12 07:26:20 +00002913func TestAddnoOverride64GlobalCflags(t *testing.T) {
2914 t.Parallel()
2915 ctx := testCc(t, `
2916 cc_library_shared {
2917 name: "libclient",
2918 srcs: ["foo.c"],
2919 shared_libs: ["libfoo#1"],
2920 }
2921
2922 cc_library_shared {
2923 name: "libfoo",
2924 srcs: ["foo.c"],
2925 shared_libs: ["libbar"],
2926 export_shared_lib_headers: ["libbar"],
2927 stubs: {
2928 symbol_file: "foo.map.txt",
2929 versions: ["1", "2", "3"],
2930 },
2931 }
2932
2933 cc_library_shared {
2934 name: "libbar",
2935 export_include_dirs: ["include/libbar"],
2936 srcs: ["foo.c"],
2937 }`)
2938
2939 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2940
2941 if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") {
2942 t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags)
2943 }
2944}
2945
Alixb5f6d9e2022-04-20 23:00:58 +00002946func TestCcBuildBrokenClangProperty(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002947 t.Parallel()
Alixb5f6d9e2022-04-20 23:00:58 +00002948 tests := []struct {
2949 name string
2950 clang bool
2951 BuildBrokenClangProperty bool
2952 err string
2953 }{
2954 {
2955 name: "error when clang is set to false",
2956 clang: false,
2957 err: "is no longer supported",
2958 },
2959 {
2960 name: "error when clang is set to true",
2961 clang: true,
2962 err: "property is deprecated, see Changes.md",
2963 },
2964 {
2965 name: "no error when BuildBrokenClangProperty is explicitly set to true",
2966 clang: true,
2967 BuildBrokenClangProperty: true,
2968 },
2969 }
2970
2971 for _, test := range tests {
2972 t.Run(test.name, func(t *testing.T) {
2973 bp := fmt.Sprintf(`
2974 cc_library {
2975 name: "foo",
2976 clang: %t,
2977 }`, test.clang)
2978
2979 if test.err == "" {
2980 android.GroupFixturePreparers(
2981 prepareForCcTest,
2982 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2983 if test.BuildBrokenClangProperty {
2984 variables.BuildBrokenClangProperty = test.BuildBrokenClangProperty
2985 }
2986 }),
2987 ).RunTestWithBp(t, bp)
2988 } else {
2989 prepareForCcTest.
2990 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
2991 RunTestWithBp(t, bp)
2992 }
2993 })
2994 }
2995}
Alix Espinoef47e542022-09-14 19:10:51 +00002996
2997func TestCcBuildBrokenClangAsFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002998 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00002999 tests := []struct {
3000 name string
3001 clangAsFlags []string
3002 BuildBrokenClangAsFlags bool
3003 err string
3004 }{
3005 {
3006 name: "error when clang_asflags is set",
3007 clangAsFlags: []string{"-a", "-b"},
3008 err: "clang_asflags: property is deprecated",
3009 },
3010 {
3011 name: "no error when BuildBrokenClangAsFlags is explicitly set to true",
3012 clangAsFlags: []string{"-a", "-b"},
3013 BuildBrokenClangAsFlags: true,
3014 },
3015 }
3016
3017 for _, test := range tests {
3018 t.Run(test.name, func(t *testing.T) {
3019 bp := fmt.Sprintf(`
3020 cc_library {
3021 name: "foo",
3022 clang_asflags: %s,
3023 }`, `["`+strings.Join(test.clangAsFlags, `","`)+`"]`)
3024
3025 if test.err == "" {
3026 android.GroupFixturePreparers(
3027 prepareForCcTest,
3028 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3029 if test.BuildBrokenClangAsFlags {
3030 variables.BuildBrokenClangAsFlags = test.BuildBrokenClangAsFlags
3031 }
3032 }),
3033 ).RunTestWithBp(t, bp)
3034 } else {
3035 prepareForCcTest.
3036 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3037 RunTestWithBp(t, bp)
3038 }
3039 })
3040 }
3041}
3042
3043func TestCcBuildBrokenClangCFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04003044 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00003045 tests := []struct {
3046 name string
3047 clangCFlags []string
3048 BuildBrokenClangCFlags bool
3049 err string
3050 }{
3051 {
3052 name: "error when clang_cflags is set",
3053 clangCFlags: []string{"-a", "-b"},
3054 err: "clang_cflags: property is deprecated",
3055 },
3056 {
3057 name: "no error when BuildBrokenClangCFlags is explicitly set to true",
3058 clangCFlags: []string{"-a", "-b"},
3059 BuildBrokenClangCFlags: true,
3060 },
3061 }
3062
3063 for _, test := range tests {
3064 t.Run(test.name, func(t *testing.T) {
3065 bp := fmt.Sprintf(`
3066 cc_library {
3067 name: "foo",
3068 clang_cflags: %s,
3069 }`, `["`+strings.Join(test.clangCFlags, `","`)+`"]`)
3070
3071 if test.err == "" {
3072 android.GroupFixturePreparers(
3073 prepareForCcTest,
3074 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3075 if test.BuildBrokenClangCFlags {
3076 variables.BuildBrokenClangCFlags = test.BuildBrokenClangCFlags
3077 }
3078 }),
3079 ).RunTestWithBp(t, bp)
3080 } else {
3081 prepareForCcTest.
3082 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3083 RunTestWithBp(t, bp)
3084 }
3085 })
3086 }
3087}
Wei Li5f5d2712023-12-11 15:40:29 -08003088
3089func TestStrippedAllOutputFile(t *testing.T) {
3090 t.Parallel()
3091 bp := `
3092 cc_library {
3093 name: "test_lib",
3094 srcs: ["test_lib.cpp"],
3095 dist: {
3096 targets: [ "dist_target" ],
3097 tag: "stripped_all",
3098 }
3099 }
3100 `
3101 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
3102 ctx := testCcWithConfig(t, config)
3103 module := ctx.ModuleForTests("test_lib", "android_arm_armv7-a-neon_shared").Module()
3104 outputFile, err := module.(android.OutputFileProducer).OutputFiles("stripped_all")
3105 if err != nil {
3106 t.Errorf("Expected cc_library to produce output files, error: %s", err)
3107 return
3108 }
3109 if !strings.HasSuffix(outputFile.Strings()[0], "/stripped_all/test_lib.so") {
3110 t.Errorf("Unexpected output file: %s", outputFile.Strings()[0])
3111 return
3112 }
3113}
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003114
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003115func TestImageVariants(t *testing.T) {
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003116 t.Parallel()
3117
3118 bp := `
3119 cc_binary {
3120 name: "binfoo",
3121 srcs: ["binfoo.cc"],
3122 vendor_available: true,
3123 product_available: true,
3124 shared_libs: ["libbar"]
3125 }
3126 cc_library {
3127 name: "libbar",
3128 srcs: ["libbar.cc"],
3129 vendor_available: true,
3130 product_available: true,
3131 }
3132 `
3133
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003134 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003135
3136 hasDep := func(m android.Module, wantDep android.Module) bool {
3137 t.Helper()
3138 var found bool
3139 ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
3140 if dep == wantDep {
3141 found = true
3142 }
3143 })
3144 return found
3145 }
3146
3147 testDepWithVariant := func(imageVariant string) {
3148 imageVariantStr := ""
3149 if imageVariant != "core" {
3150 imageVariantStr = "_" + imageVariant
3151 }
3152 binFooModule := ctx.ModuleForTests("binfoo", "android"+imageVariantStr+"_arm64_armv8-a").Module()
3153 libBarModule := ctx.ModuleForTests("libbar", "android"+imageVariantStr+"_arm64_armv8-a_shared").Module()
3154 android.AssertBoolEquals(t, "binfoo should have dependency on libbar with image variant "+imageVariant, true, hasDep(binFooModule, libBarModule))
3155 }
3156
3157 testDepWithVariant("core")
3158 testDepWithVariant("vendor")
3159 testDepWithVariant("product")
3160}
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003161
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003162func TestVendorSdkVersion(t *testing.T) {
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003163 t.Parallel()
3164
3165 bp := `
3166 cc_library {
3167 name: "libfoo",
3168 srcs: ["libfoo.cc"],
3169 vendor_available: true,
3170 }
3171
3172 cc_library {
3173 name: "libbar",
3174 srcs: ["libbar.cc"],
3175 vendor_available: true,
3176 min_sdk_version: "29",
3177 }
3178 `
3179
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003180 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003181 testSdkVersionFlag := func(module, version string) {
3182 flags := ctx.ModuleForTests(module, "android_vendor_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
3183 android.AssertStringDoesContain(t, "min sdk version", flags, "-target aarch64-linux-android"+version)
3184 }
3185
3186 testSdkVersionFlag("libfoo", "10000")
3187 testSdkVersionFlag("libbar", "29")
3188
3189 ctx = android.GroupFixturePreparers(
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003190 prepareForCcTest,
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003191 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3192 if variables.BuildFlags == nil {
3193 variables.BuildFlags = make(map[string]string)
3194 }
3195 variables.BuildFlags["RELEASE_BOARD_API_LEVEL_FROZEN"] = "true"
3196 }),
3197 ).RunTestWithBp(t, bp)
3198 testSdkVersionFlag("libfoo", "30")
3199 testSdkVersionFlag("libbar", "29")
3200}