blob: 026d291e04e52dd607ab896805add5d5da0002d6 [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"],
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +0800961 export_system_include_dirs: ["include_system_llndk"],
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800962 llndk: {
963 symbol_file: "libllndk.map.txt",
964 },
965 vendor_available: true,
966 }
967
968 cc_library {
969 name: "libllndk_with_override_headers",
970 stubs: { versions: ["1", "2"] },
971 llndk: {
972 symbol_file: "libllndk.map.txt",
973 override_export_include_dirs: ["include_llndk"],
974 },
975 export_include_dirs: ["include"],
976 }
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +0800977
978 cc_library {
979 name: "libllndk_with_system_headers",
980 llndk: {
981 symbol_file: "libllndk.map.txt",
982 export_llndk_headers: ["libexternal_llndk_headers"],
983 export_headers_as_system: true,
984 },
985 export_include_dirs: ["include"],
986 export_system_include_dirs: ["include_system"],
987 }
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800988 `)
989 actual := result.ModuleVariantsForTests("libllndk")
990 for i := 0; i < len(actual); i++ {
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900991 if !strings.HasPrefix(actual[i], "android_vendor_") {
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800992 actual = append(actual[:i], actual[i+1:]...)
993 i--
994 }
995 }
996 expected := []string{
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +0900997 "android_vendor_arm64_armv8-a_shared",
998 "android_vendor_arm_armv7-a-neon_shared",
Colin Cross0fb7fcd2021-03-02 11:00:07 -0800999 }
1000 android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
1001
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001002 params := result.ModuleForTests("libllndk", "android_vendor_arm_armv7-a-neon_shared").Description("generate stub")
Jooyung Han33eb6152024-03-11 15:46:48 +09001003 android.AssertSame(t, "use Vendor API level for default stubs", "202404", params.Args["apiLevel"])
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001004
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001005 checkExportedIncludeDirs := func(module, variant string, expectedSystemDirs []string, expectedDirs ...string) {
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001006 t.Helper()
1007 m := result.ModuleForTests(module, variant).Module()
Colin Cross5a377182023-12-14 14:46:23 -08001008 f, _ := android.SingletonModuleProvider(result, m, FlagExporterInfoProvider)
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001009 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
1010 expectedDirs, f.IncludeDirs)
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001011 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
1012 expectedSystemDirs, f.SystemIncludeDirs)
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001013 }
1014
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001015 checkExportedIncludeDirs("libllndk", coreVariant, nil, "include")
1016 checkExportedIncludeDirs("libllndk", vendorVariant, nil, "include")
1017 checkExportedIncludeDirs("libllndk_with_external_headers", coreVariant, nil, "include")
1018 checkExportedIncludeDirs("libllndk_with_external_headers", vendorVariant,
1019 []string{"include_system_llndk"}, "include_llndk")
1020 checkExportedIncludeDirs("libllndk_with_override_headers", coreVariant, nil, "include")
1021 checkExportedIncludeDirs("libllndk_with_override_headers", vendorVariant, nil, "include_llndk")
1022 checkExportedIncludeDirs("libllndk_with_system_headers", coreVariant, []string{"include_system"}, "include")
1023 checkExportedIncludeDirs("libllndk_with_system_headers", vendorVariant,
1024 []string{"include_system", "include", "include_system_llndk"}, "include_llndk")
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001025
1026 checkAbiLinkerIncludeDirs := func(module string) {
1027 t.Helper()
1028 coreModule := result.ModuleForTests(module, coreVariant)
1029 abiCheckFlags := ""
1030 for _, output := range coreModule.AllOutputs() {
1031 if strings.HasSuffix(output, ".so.llndk.lsdump") {
1032 abiCheckFlags = coreModule.Output(output).Args["exportedHeaderFlags"]
1033 }
1034 }
1035 vendorModule := result.ModuleForTests(module, vendorVariant).Module()
1036 vendorInfo, _ := android.SingletonModuleProvider(result, vendorModule, FlagExporterInfoProvider)
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001037 vendorDirs := android.Concat(vendorInfo.IncludeDirs, vendorInfo.SystemIncludeDirs)
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001038 android.AssertStringEquals(t, module+" has different exported include dirs for vendor variant and ABI check",
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001039 android.JoinPathsWithPrefix(vendorDirs, "-I"), abiCheckFlags)
Hsin-Yi Chen64b2d032024-03-29 19:12:35 +08001040 }
1041 checkAbiLinkerIncludeDirs("libllndk")
1042 checkAbiLinkerIncludeDirs("libllndk_with_override_headers")
1043 checkAbiLinkerIncludeDirs("libllndk_with_external_headers")
Hsin-Yi Chen5f228b02024-04-02 12:38:47 +08001044 checkAbiLinkerIncludeDirs("libllndk_with_system_headers")
Colin Cross0fb7fcd2021-03-02 11:00:07 -08001045}
1046
Jiyong Parka46a4d52017-12-14 19:54:34 +09001047func TestLlndkHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001048 t.Parallel()
Jiyong Parka46a4d52017-12-14 19:54:34 +09001049 ctx := testCc(t, `
Colin Cross627280f2021-04-26 16:53:58 -07001050 cc_library_headers {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001051 name: "libllndk_headers",
1052 export_include_dirs: ["my_include"],
Colin Cross627280f2021-04-26 16:53:58 -07001053 llndk: {
1054 llndk_headers: true,
1055 },
Jiyong Parka46a4d52017-12-14 19:54:34 +09001056 }
1057 cc_library {
Colin Cross0477b422020-10-13 18:43:54 -07001058 name: "libllndk",
Colin Cross627280f2021-04-26 16:53:58 -07001059 llndk: {
1060 symbol_file: "libllndk.map.txt",
1061 export_llndk_headers: ["libllndk_headers"],
1062 }
Colin Cross0477b422020-10-13 18:43:54 -07001063 }
1064
1065 cc_library {
Jiyong Parka46a4d52017-12-14 19:54:34 +09001066 name: "libvendor",
1067 shared_libs: ["libllndk"],
1068 vendor: true,
1069 srcs: ["foo.c"],
Yi Konge7fe9912019-06-02 00:53:50 -07001070 no_libcrt: true,
Logan Chienf3511742017-10-31 18:04:35 +08001071 nocrt: true,
Jiyong Parka46a4d52017-12-14 19:54:34 +09001072 }
1073 `)
1074
1075 // _static variant is used since _shared reuses *.o from the static variant
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001076 cc := ctx.ModuleForTests("libvendor", "android_vendor_arm_armv7-a-neon_static").Rule("cc")
Jiyong Parka46a4d52017-12-14 19:54:34 +09001077 cflags := cc.Args["cFlags"]
1078 if !strings.Contains(cflags, "-Imy_include") {
1079 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
1080 }
1081}
1082
Logan Chien43d34c32017-12-20 01:17:32 +08001083func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
1084 actual := module.Properties.AndroidMkRuntimeLibs
1085 if !reflect.DeepEqual(actual, expected) {
1086 t.Errorf("incorrect runtime_libs for shared libs"+
1087 "\nactual: %v"+
1088 "\nexpected: %v",
1089 actual,
1090 expected,
1091 )
1092 }
1093}
1094
1095const runtimeLibAndroidBp = `
1096 cc_library {
Justin Yun8a2600c2020-12-07 12:44:03 +09001097 name: "liball_available",
1098 vendor_available: true,
1099 product_available: true,
1100 no_libcrt : true,
1101 nocrt : true,
1102 system_shared_libs : [],
1103 }
1104 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001105 name: "libvendor_available1",
1106 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001107 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001108 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001109 nocrt : true,
1110 system_shared_libs : [],
1111 }
1112 cc_library {
1113 name: "libvendor_available2",
1114 vendor_available: true,
Justin Yun8a2600c2020-12-07 12:44:03 +09001115 runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001116 target: {
1117 vendor: {
Justin Yun8a2600c2020-12-07 12:44:03 +09001118 exclude_runtime_libs: ["liball_available"],
Logan Chien43d34c32017-12-20 01:17:32 +08001119 }
1120 },
Yi Konge7fe9912019-06-02 00:53:50 -07001121 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001122 nocrt : true,
1123 system_shared_libs : [],
1124 }
1125 cc_library {
Justin Yuncbca3732021-02-03 19:24:13 +09001126 name: "libproduct_vendor",
1127 product_specific: true,
1128 vendor_available: true,
1129 no_libcrt : true,
1130 nocrt : true,
1131 system_shared_libs : [],
1132 }
1133 cc_library {
Logan Chien43d34c32017-12-20 01:17:32 +08001134 name: "libcore",
Justin Yun8a2600c2020-12-07 12:44:03 +09001135 runtime_libs: ["liball_available"],
Yi Konge7fe9912019-06-02 00:53:50 -07001136 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001137 nocrt : true,
1138 system_shared_libs : [],
1139 }
1140 cc_library {
1141 name: "libvendor1",
1142 vendor: true,
Yi Konge7fe9912019-06-02 00:53:50 -07001143 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001144 nocrt : true,
1145 system_shared_libs : [],
1146 }
1147 cc_library {
1148 name: "libvendor2",
1149 vendor: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001150 runtime_libs: ["liball_available", "libvendor1", "libproduct_vendor"],
Justin Yun8a2600c2020-12-07 12:44:03 +09001151 no_libcrt : true,
1152 nocrt : true,
1153 system_shared_libs : [],
1154 }
1155 cc_library {
1156 name: "libproduct_available1",
1157 product_available: true,
1158 runtime_libs: ["liball_available"],
1159 no_libcrt : true,
1160 nocrt : true,
1161 system_shared_libs : [],
1162 }
1163 cc_library {
1164 name: "libproduct1",
1165 product_specific: true,
1166 no_libcrt : true,
1167 nocrt : true,
1168 system_shared_libs : [],
1169 }
1170 cc_library {
1171 name: "libproduct2",
1172 product_specific: true,
Justin Yuncbca3732021-02-03 19:24:13 +09001173 runtime_libs: ["liball_available", "libproduct1", "libproduct_vendor"],
Yi Konge7fe9912019-06-02 00:53:50 -07001174 no_libcrt : true,
Logan Chien43d34c32017-12-20 01:17:32 +08001175 nocrt : true,
1176 system_shared_libs : [],
1177 }
1178`
1179
1180func TestRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001181 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001182 ctx := testCc(t, runtimeLibAndroidBp)
1183
1184 // runtime_libs for core variants use the module names without suffixes.
Colin Cross7113d202019-11-20 16:39:12 -08001185 variant := "android_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001186
Justin Yun8a2600c2020-12-07 12:44:03 +09001187 module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1188 checkRuntimeLibs(t, []string{"liball_available"}, module)
1189
1190 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1191 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001192
1193 module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001194 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001195
1196 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
1197 // and vendor variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001198 variant = "android_vendor_arm64_armv8-a_shared"
Logan Chien43d34c32017-12-20 01:17:32 +08001199
Justin Yun8a2600c2020-12-07 12:44:03 +09001200 module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
1201 checkRuntimeLibs(t, []string{"liball_available.vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001202
1203 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
Justin Yuncbca3732021-02-03 19:24:13 +09001204 checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module)
Justin Yun8a2600c2020-12-07 12:44:03 +09001205
1206 // runtime_libs for product variants have '.product' suffixes if the modules have both core
1207 // and product variants.
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001208 variant = "android_product_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001209
1210 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
1211 checkRuntimeLibs(t, []string{"liball_available.product"}, module)
1212
1213 module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
Justin Yund00f5ca2021-02-03 19:43:02 +09001214 checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001215}
1216
1217func TestExcludeRuntimeLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001218 t.Parallel()
Logan Chien43d34c32017-12-20 01:17:32 +08001219 ctx := testCc(t, runtimeLibAndroidBp)
1220
Colin Cross7113d202019-11-20 16:39:12 -08001221 variant := "android_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001222 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
1223 checkRuntimeLibs(t, []string{"liball_available"}, module)
Logan Chien43d34c32017-12-20 01:17:32 +08001224
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09001225 variant = "android_vendor_arm64_armv8-a_shared"
Justin Yun8a2600c2020-12-07 12:44:03 +09001226 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
Logan Chien43d34c32017-12-20 01:17:32 +08001227 checkRuntimeLibs(t, nil, module)
1228}
1229
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001230func checkStaticLibs(t *testing.T, expected []string, module *Module) {
Jooyung Han03b51852020-02-26 22:45:42 +09001231 t.Helper()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001232 actual := module.Properties.AndroidMkStaticLibs
1233 if !reflect.DeepEqual(actual, expected) {
1234 t.Errorf("incorrect static_libs"+
1235 "\nactual: %v"+
1236 "\nexpected: %v",
1237 actual,
1238 expected,
1239 )
1240 }
1241}
1242
1243const staticLibAndroidBp = `
1244 cc_library {
1245 name: "lib1",
1246 }
1247 cc_library {
1248 name: "lib2",
1249 static_libs: ["lib1"],
1250 }
1251`
1252
1253func TestStaticLibDepExport(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001254 t.Parallel()
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001255 ctx := testCc(t, staticLibAndroidBp)
1256
1257 // Check the shared version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001258 variant := "android_arm64_armv8-a_shared"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001259 module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
Colin Cross4c4c1be2022-02-10 11:41:18 -08001260 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001261
1262 // Check the static version of lib2.
Colin Cross7113d202019-11-20 16:39:12 -08001263 variant = "android_arm64_armv8-a_static"
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001264 module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
1265 // libc++_static is linked additionally.
Colin Cross4c4c1be2022-02-10 11:41:18 -08001266 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins"}, module)
Jaewoong Jung16c7d3d2018-11-16 01:19:56 +00001267}
1268
Jiyong Parkd08b6972017-09-26 10:50:54 +09001269var compilerFlagsTestCases = []struct {
1270 in string
1271 out bool
1272}{
1273 {
1274 in: "a",
1275 out: false,
1276 },
1277 {
1278 in: "-a",
1279 out: true,
1280 },
1281 {
1282 in: "-Ipath/to/something",
1283 out: false,
1284 },
1285 {
1286 in: "-isystempath/to/something",
1287 out: false,
1288 },
1289 {
1290 in: "--coverage",
1291 out: false,
1292 },
1293 {
1294 in: "-include a/b",
1295 out: true,
1296 },
1297 {
1298 in: "-include a/b c/d",
1299 out: false,
1300 },
1301 {
1302 in: "-DMACRO",
1303 out: true,
1304 },
1305 {
1306 in: "-DMAC RO",
1307 out: false,
1308 },
1309 {
1310 in: "-a -b",
1311 out: false,
1312 },
1313 {
1314 in: "-DMACRO=definition",
1315 out: true,
1316 },
1317 {
1318 in: "-DMACRO=defi nition",
1319 out: true, // TODO(jiyong): this should be false
1320 },
1321 {
1322 in: "-DMACRO(x)=x + 1",
1323 out: true,
1324 },
1325 {
1326 in: "-DMACRO=\"defi nition\"",
1327 out: true,
1328 },
1329}
1330
1331type mockContext struct {
1332 BaseModuleContext
1333 result bool
1334}
1335
1336func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
1337 // CheckBadCompilerFlags calls this function when the flag should be rejected
1338 ctx.result = false
1339}
1340
1341func TestCompilerFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001342 t.Parallel()
Jiyong Parkd08b6972017-09-26 10:50:54 +09001343 for _, testCase := range compilerFlagsTestCases {
1344 ctx := &mockContext{result: true}
1345 CheckBadCompilerFlags(ctx, "", []string{testCase.in})
1346 if ctx.result != testCase.out {
1347 t.Errorf("incorrect output:")
1348 t.Errorf(" input: %#v", testCase.in)
1349 t.Errorf(" expected: %#v", testCase.out)
1350 t.Errorf(" got: %#v", ctx.result)
1351 }
1352 }
Jeff Gaston294356f2017-09-27 17:05:30 -07001353}
Jiyong Park374510b2018-03-19 18:23:01 +09001354
Jiyong Park37b25202018-07-11 10:49:27 +09001355func TestRecovery(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001356 t.Parallel()
Jiyong Park37b25202018-07-11 10:49:27 +09001357 ctx := testCc(t, `
1358 cc_library_shared {
1359 name: "librecovery",
1360 recovery: true,
1361 }
1362 cc_library_shared {
1363 name: "librecovery32",
1364 recovery: true,
1365 compile_multilib:"32",
1366 }
Jiyong Park5baac542018-08-28 09:55:37 +09001367 cc_library_shared {
1368 name: "libHalInRecovery",
1369 recovery_available: true,
1370 vendor: true,
1371 }
Jiyong Park37b25202018-07-11 10:49:27 +09001372 `)
1373
1374 variants := ctx.ModuleVariantsForTests("librecovery")
Colin Crossfb0c16e2019-11-20 17:12:35 -08001375 const arm64 = "android_recovery_arm64_armv8-a_shared"
Jiyong Park37b25202018-07-11 10:49:27 +09001376 if len(variants) != 1 || !android.InList(arm64, variants) {
1377 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
1378 }
1379
1380 variants = ctx.ModuleVariantsForTests("librecovery32")
1381 if android.InList(arm64, variants) {
1382 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
1383 }
Jiyong Park5baac542018-08-28 09:55:37 +09001384
1385 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
1386 if !recoveryModule.Platform() {
1387 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
1388 }
Jiyong Park7ed9de32018-10-15 22:25:07 +09001389}
Jiyong Park5baac542018-08-28 09:55:37 +09001390
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001391func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001392 t.Parallel()
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001393 bp := `
1394 cc_prebuilt_test_library_shared {
1395 name: "test_lib",
1396 relative_install_path: "foo/bar/baz",
1397 srcs: ["srcpath/dontusethispath/baz.so"],
1398 }
1399
1400 cc_test {
1401 name: "main_test",
1402 data_libs: ["test_lib"],
1403 gtest: false,
1404 }
1405 `
1406
Paul Duffinc3e6ce02021-03-22 23:21:32 +00001407 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001408
1409 ctx := testCcWithConfig(t, config)
1410 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
1411 testBinary := module.(*Module).linker.(*testBinary)
1412 outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
1413 if err != nil {
1414 t.Fatalf("Expected cc_test to produce output files, error: %s", err)
1415 }
1416 if len(outputFiles) != 1 {
1417 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
1418 }
1419 if len(testBinary.dataPaths()) != 1 {
Colin Cross7e2e7942023-11-16 12:56:02 -08001420 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths())
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001421 }
1422
1423 outputPath := outputFiles[0].String()
1424
1425 if !strings.HasSuffix(outputPath, "/main_test") {
1426 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
1427 }
Colin Crossaa255532020-07-03 13:18:24 -07001428 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
Chris Parsons1f6d90f2020-06-17 16:10:42 -04001429 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
1430 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
1431 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
1432 }
1433}
1434
Jiyong Park7ed9de32018-10-15 22:25:07 +09001435func TestVersionedStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001436 t.Parallel()
Jiyong Park7ed9de32018-10-15 22:25:07 +09001437 ctx := testCc(t, `
1438 cc_library_shared {
1439 name: "libFoo",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001440 srcs: ["foo.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001441 stubs: {
1442 symbol_file: "foo.map.txt",
1443 versions: ["1", "2", "3"],
1444 },
1445 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001446
Jiyong Park7ed9de32018-10-15 22:25:07 +09001447 cc_library_shared {
1448 name: "libBar",
Jiyong Parkda732bd2018-11-02 18:23:15 +09001449 srcs: ["bar.c"],
Jiyong Park7ed9de32018-10-15 22:25:07 +09001450 shared_libs: ["libFoo#1"],
1451 }`)
1452
1453 variants := ctx.ModuleVariantsForTests("libFoo")
1454 expectedVariants := []string{
Colin Cross7113d202019-11-20 16:39:12 -08001455 "android_arm64_armv8-a_shared",
1456 "android_arm64_armv8-a_shared_1",
1457 "android_arm64_armv8-a_shared_2",
1458 "android_arm64_armv8-a_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001459 "android_arm64_armv8-a_shared_current",
Colin Cross7113d202019-11-20 16:39:12 -08001460 "android_arm_armv7-a-neon_shared",
1461 "android_arm_armv7-a-neon_shared_1",
1462 "android_arm_armv7-a-neon_shared_2",
1463 "android_arm_armv7-a-neon_shared_3",
Jiyong Parkd4a3a132021-03-17 20:21:35 +09001464 "android_arm_armv7-a-neon_shared_current",
Jiyong Park7ed9de32018-10-15 22:25:07 +09001465 }
1466 variantsMismatch := false
1467 if len(variants) != len(expectedVariants) {
1468 variantsMismatch = true
1469 } else {
1470 for _, v := range expectedVariants {
1471 if !inList(v, variants) {
1472 variantsMismatch = false
1473 }
1474 }
1475 }
1476 if variantsMismatch {
1477 t.Errorf("variants of libFoo expected:\n")
1478 for _, v := range expectedVariants {
1479 t.Errorf("%q\n", v)
1480 }
1481 t.Errorf(", but got:\n")
1482 for _, v := range variants {
1483 t.Errorf("%q\n", v)
1484 }
1485 }
1486
Colin Cross7113d202019-11-20 16:39:12 -08001487 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
Jiyong Park7ed9de32018-10-15 22:25:07 +09001488 libFlags := libBarLinkRule.Args["libFlags"]
Colin Cross7113d202019-11-20 16:39:12 -08001489 libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so"
Jiyong Park7ed9de32018-10-15 22:25:07 +09001490 if !strings.Contains(libFlags, libFoo1StubPath) {
1491 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
1492 }
Jiyong Parkda732bd2018-11-02 18:23:15 +09001493
Colin Cross7113d202019-11-20 16:39:12 -08001494 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc")
Jiyong Parkda732bd2018-11-02 18:23:15 +09001495 cFlags := libBarCompileRule.Args["cFlags"]
1496 libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
1497 if !strings.Contains(cFlags, libFoo1VersioningMacro) {
1498 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
1499 }
Jiyong Park37b25202018-07-11 10:49:27 +09001500}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001501
Liz Kammer48cdbeb2023-03-17 10:17:50 -04001502func TestStubsForLibraryInMultipleApexes(t *testing.T) {
1503 t.Parallel()
1504 ctx := testCc(t, `
1505 cc_library_shared {
1506 name: "libFoo",
1507 srcs: ["foo.c"],
1508 stubs: {
1509 symbol_file: "foo.map.txt",
1510 versions: ["current"],
1511 },
1512 apex_available: ["bar", "a1"],
1513 }
1514
1515 cc_library_shared {
1516 name: "libBar",
1517 srcs: ["bar.c"],
1518 shared_libs: ["libFoo"],
1519 apex_available: ["a1"],
1520 }
1521
1522 cc_library_shared {
1523 name: "libA1",
1524 srcs: ["a1.c"],
1525 shared_libs: ["libFoo"],
1526 apex_available: ["a1"],
1527 }
1528
1529 cc_library_shared {
1530 name: "libBarA1",
1531 srcs: ["bara1.c"],
1532 shared_libs: ["libFoo"],
1533 apex_available: ["bar", "a1"],
1534 }
1535
1536 cc_library_shared {
1537 name: "libAnyApex",
1538 srcs: ["anyApex.c"],
1539 shared_libs: ["libFoo"],
1540 apex_available: ["//apex_available:anyapex"],
1541 }
1542
1543 cc_library_shared {
1544 name: "libBaz",
1545 srcs: ["baz.c"],
1546 shared_libs: ["libFoo"],
1547 apex_available: ["baz"],
1548 }
1549
1550 cc_library_shared {
1551 name: "libQux",
1552 srcs: ["qux.c"],
1553 shared_libs: ["libFoo"],
1554 apex_available: ["qux", "bar"],
1555 }`)
1556
1557 variants := ctx.ModuleVariantsForTests("libFoo")
1558 expectedVariants := []string{
1559 "android_arm64_armv8-a_shared",
1560 "android_arm64_armv8-a_shared_current",
1561 "android_arm_armv7-a-neon_shared",
1562 "android_arm_armv7-a-neon_shared_current",
1563 }
1564 variantsMismatch := false
1565 if len(variants) != len(expectedVariants) {
1566 variantsMismatch = true
1567 } else {
1568 for _, v := range expectedVariants {
1569 if !inList(v, variants) {
1570 variantsMismatch = false
1571 }
1572 }
1573 }
1574 if variantsMismatch {
1575 t.Errorf("variants of libFoo expected:\n")
1576 for _, v := range expectedVariants {
1577 t.Errorf("%q\n", v)
1578 }
1579 t.Errorf(", but got:\n")
1580 for _, v := range variants {
1581 t.Errorf("%q\n", v)
1582 }
1583 }
1584
1585 linkAgainstFoo := []string{"libBarA1"}
1586 linkAgainstFooStubs := []string{"libBar", "libA1", "libBaz", "libQux", "libAnyApex"}
1587
1588 libFooPath := "libFoo/android_arm64_armv8-a_shared/libFoo.so"
1589 for _, lib := range linkAgainstFoo {
1590 libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
1591 libFlags := libLinkRule.Args["libFlags"]
1592 if !strings.Contains(libFlags, libFooPath) {
1593 t.Errorf("%q: %q is not found in %q", lib, libFooPath, libFlags)
1594 }
1595 }
1596
1597 libFooStubPath := "libFoo/android_arm64_armv8-a_shared_current/libFoo.so"
1598 for _, lib := range linkAgainstFooStubs {
1599 libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
1600 libFlags := libLinkRule.Args["libFlags"]
1601 if !strings.Contains(libFlags, libFooStubPath) {
1602 t.Errorf("%q: %q is not found in %q", lib, libFooStubPath, libFlags)
1603 }
1604 }
1605}
1606
Jooyung Hanb04a4992020-03-13 18:57:35 +09001607func TestVersioningMacro(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001608 t.Parallel()
Jooyung Hanb04a4992020-03-13 18:57:35 +09001609 for _, tc := range []struct{ moduleName, expected string }{
1610 {"libc", "__LIBC_API__"},
1611 {"libfoo", "__LIBFOO_API__"},
1612 {"libfoo@1", "__LIBFOO_1_API__"},
1613 {"libfoo-v1", "__LIBFOO_V1_API__"},
1614 {"libfoo.v1", "__LIBFOO_V1_API__"},
1615 } {
1616 checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName))
1617 }
1618}
1619
Liz Kammer83cf81b2022-09-22 08:24:20 -04001620func pathsToBase(paths android.Paths) []string {
1621 var ret []string
1622 for _, p := range paths {
1623 ret = append(ret, p.Base())
1624 }
1625 return ret
1626}
1627
1628func TestStaticLibArchiveArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001629 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001630 ctx := testCc(t, `
1631 cc_library_static {
1632 name: "foo",
1633 srcs: ["foo.c"],
1634 }
1635
1636 cc_library_static {
1637 name: "bar",
1638 srcs: ["bar.c"],
1639 }
1640
1641 cc_library_shared {
1642 name: "qux",
1643 srcs: ["qux.c"],
1644 }
1645
1646 cc_library_static {
1647 name: "baz",
1648 srcs: ["baz.c"],
1649 static_libs: ["foo"],
1650 shared_libs: ["qux"],
1651 whole_static_libs: ["bar"],
1652 }`)
1653
1654 variant := "android_arm64_armv8-a_static"
1655 arRule := ctx.ModuleForTests("baz", variant).Rule("ar")
1656
1657 // For static libraries, the object files of a whole static dep are included in the archive
1658 // directly
1659 if g, w := pathsToBase(arRule.Inputs), []string{"bar.o", "baz.o"}; !reflect.DeepEqual(w, g) {
1660 t.Errorf("Expected input objects %q, got %q", w, g)
1661 }
1662
1663 // non whole static dependencies are not linked into the archive
1664 if len(arRule.Implicits) > 0 {
1665 t.Errorf("Expected 0 additional deps, got %q", arRule.Implicits)
1666 }
1667}
1668
1669func TestSharedLibLinkingArgs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001670 t.Parallel()
Liz Kammer83cf81b2022-09-22 08:24:20 -04001671 ctx := testCc(t, `
1672 cc_library_static {
1673 name: "foo",
1674 srcs: ["foo.c"],
1675 }
1676
1677 cc_library_static {
1678 name: "bar",
1679 srcs: ["bar.c"],
1680 }
1681
1682 cc_library_shared {
1683 name: "qux",
1684 srcs: ["qux.c"],
1685 }
1686
1687 cc_library_shared {
1688 name: "baz",
1689 srcs: ["baz.c"],
1690 static_libs: ["foo"],
1691 shared_libs: ["qux"],
1692 whole_static_libs: ["bar"],
1693 }`)
1694
1695 variant := "android_arm64_armv8-a_shared"
1696 linkRule := ctx.ModuleForTests("baz", variant).Rule("ld")
1697 libFlags := linkRule.Args["libFlags"]
1698 // When dynamically linking, we expect static dependencies to be found on the command line
1699 if expected := "foo.a"; !strings.Contains(libFlags, expected) {
1700 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1701 }
1702 // When dynamically linking, we expect whole static dependencies to be found on the command line
1703 if expected := "bar.a"; !strings.Contains(libFlags, expected) {
1704 t.Errorf("Static lib %q was not found in %q", expected, libFlags)
1705 }
1706
1707 // When dynamically linking, we expect shared dependencies to be found on the command line
1708 if expected := "qux.so"; !strings.Contains(libFlags, expected) {
1709 t.Errorf("Shared lib %q was not found in %q", expected, libFlags)
1710 }
1711
1712 // We should only have the objects from the shared library srcs, not the whole static dependencies
1713 if g, w := pathsToBase(linkRule.Inputs), []string{"baz.o"}; !reflect.DeepEqual(w, g) {
1714 t.Errorf("Expected input objects %q, got %q", w, g)
1715 }
1716}
1717
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001718func TestStaticExecutable(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001719 t.Parallel()
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001720 ctx := testCc(t, `
1721 cc_binary {
1722 name: "static_test",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +01001723 srcs: ["foo.c", "baz.o"],
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001724 static_executable: true,
1725 }`)
1726
Colin Cross7113d202019-11-20 16:39:12 -08001727 variant := "android_arm64_armv8-a"
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001728 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
1729 libFlags := binModuleRule.Args["libFlags"]
Ryan Prichardb49fe1b2019-10-11 15:03:34 -07001730 systemStaticLibs := []string{"libc.a", "libm.a"}
Jaewoong Jung232c07c2018-12-18 11:08:25 -08001731 for _, lib := range systemStaticLibs {
1732 if !strings.Contains(libFlags, lib) {
1733 t.Errorf("Static lib %q was not found in %q", lib, libFlags)
1734 }
1735 }
1736 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
1737 for _, lib := range systemSharedLibs {
1738 if strings.Contains(libFlags, lib) {
1739 t.Errorf("Shared lib %q was found in %q", lib, libFlags)
1740 }
1741 }
1742}
Jiyong Parke4bb9862019-02-01 00:31:10 +09001743
1744func TestStaticDepsOrderWithStubs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001745 t.Parallel()
Jiyong Parke4bb9862019-02-01 00:31:10 +09001746 ctx := testCc(t, `
1747 cc_binary {
1748 name: "mybin",
1749 srcs: ["foo.c"],
Colin Cross0de8a1e2020-09-18 14:15:30 -07001750 static_libs: ["libfooC", "libfooB"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001751 static_executable: true,
1752 stl: "none",
1753 }
1754
1755 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001756 name: "libfooB",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001757 srcs: ["foo.c"],
Colin Crossf9aabd72020-02-15 11:29:50 -08001758 shared_libs: ["libfooC"],
Jiyong Parke4bb9862019-02-01 00:31:10 +09001759 stl: "none",
1760 }
1761
1762 cc_library {
Colin Crossf9aabd72020-02-15 11:29:50 -08001763 name: "libfooC",
Jiyong Parke4bb9862019-02-01 00:31:10 +09001764 srcs: ["foo.c"],
1765 stl: "none",
1766 stubs: {
1767 versions: ["1"],
1768 },
1769 }`)
1770
Colin Cross0de8a1e2020-09-18 14:15:30 -07001771 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld")
1772 actual := mybin.Implicits[:2]
Ivan Lozanod67a6b02021-05-20 13:01:32 -04001773 expected := GetOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
Jiyong Parke4bb9862019-02-01 00:31:10 +09001774
1775 if !reflect.DeepEqual(actual, expected) {
1776 t.Errorf("staticDeps orderings were not propagated correctly"+
1777 "\nactual: %v"+
1778 "\nexpected: %v",
1779 actual,
1780 expected,
1781 )
1782 }
1783}
Jooyung Han38002912019-05-16 04:01:54 +09001784
Jooyung Hand48f3c32019-08-23 11:18:57 +09001785func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001786 t.Parallel()
Jooyung Hand48f3c32019-08-23 11:18:57 +09001787 testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
1788 cc_library {
1789 name: "libA",
1790 srcs: ["foo.c"],
1791 shared_libs: ["libB"],
1792 stl: "none",
1793 }
1794
1795 cc_library {
1796 name: "libB",
1797 srcs: ["foo.c"],
1798 enabled: false,
1799 stl: "none",
1800 }
1801 `)
1802}
1803
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001804func VerifyAFLFuzzTargetVariant(t *testing.T, variant string) {
1805 bp := `
1806 cc_fuzz {
Cory Barkera1da26f2022-06-07 20:12:06 +00001807 name: "test_afl_fuzz_target",
1808 srcs: ["foo.c"],
1809 host_supported: true,
1810 static_libs: [
1811 "afl_fuzz_static_lib",
1812 ],
1813 shared_libs: [
1814 "afl_fuzz_shared_lib",
1815 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001816 fuzzing_frameworks: {
1817 afl: true,
1818 libfuzzer: false,
1819 },
Cory Barkera1da26f2022-06-07 20:12:06 +00001820 }
1821 cc_library {
1822 name: "afl_fuzz_static_lib",
1823 host_supported: true,
1824 srcs: ["static_file.c"],
1825 }
1826 cc_library {
1827 name: "libfuzzer_only_static_lib",
1828 host_supported: true,
1829 srcs: ["static_file.c"],
1830 }
1831 cc_library {
1832 name: "afl_fuzz_shared_lib",
1833 host_supported: true,
1834 srcs: ["shared_file.c"],
1835 static_libs: [
1836 "second_static_lib",
1837 ],
1838 }
1839 cc_library_headers {
1840 name: "libafl_headers",
1841 vendor_available: true,
1842 host_supported: true,
1843 export_include_dirs: [
1844 "include",
1845 "instrumentation",
1846 ],
1847 }
1848 cc_object {
1849 name: "afl-compiler-rt",
1850 vendor_available: true,
1851 host_supported: true,
1852 cflags: [
1853 "-fPIC",
1854 ],
1855 srcs: [
1856 "instrumentation/afl-compiler-rt.o.c",
1857 ],
1858 }
1859 cc_library {
1860 name: "second_static_lib",
1861 host_supported: true,
1862 srcs: ["second_file.c"],
1863 }
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001864 cc_object {
Cory Barkera1da26f2022-06-07 20:12:06 +00001865 name: "aflpp_driver",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001866 host_supported: true,
Cory Barkera1da26f2022-06-07 20:12:06 +00001867 srcs: [
1868 "aflpp_driver.c",
1869 ],
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001870 }`
1871
1872 testEnv := map[string]string{
1873 "FUZZ_FRAMEWORK": "AFL",
1874 }
1875
1876 ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp)
Cory Barkera1da26f2022-06-07 20:12:06 +00001877
1878 checkPcGuardFlag := func(
1879 modName string, variantName string, shouldHave bool) {
1880 cc := ctx.ModuleForTests(modName, variantName).Rule("cc")
1881
1882 cFlags, ok := cc.Args["cFlags"]
1883 if !ok {
1884 t.Errorf("Could not find cFlags for module %s and variant %s",
1885 modName, variantName)
1886 }
1887
1888 if strings.Contains(
1889 cFlags, "-fsanitize-coverage=trace-pc-guard") != shouldHave {
1890 t.Errorf("Flag was found: %t. Expected to find flag: %t. "+
1891 "Test failed for module %s and variant %s",
1892 !shouldHave, shouldHave, modName, variantName)
1893 }
1894 }
1895
Cory Barkera1da26f2022-06-07 20:12:06 +00001896 moduleName := "test_afl_fuzz_target"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001897 checkPcGuardFlag(moduleName, variant+"_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001898
1899 moduleName = "afl_fuzz_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001900 checkPcGuardFlag(moduleName, variant+"_static", false)
1901 checkPcGuardFlag(moduleName, variant+"_static_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001902
1903 moduleName = "second_static_lib"
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001904 checkPcGuardFlag(moduleName, variant+"_static", false)
1905 checkPcGuardFlag(moduleName, variant+"_static_fuzzer", true)
Cory Barkera1da26f2022-06-07 20:12:06 +00001906
1907 ctx.ModuleForTests("afl_fuzz_shared_lib",
1908 "android_arm64_armv8-a_shared").Rule("cc")
1909 ctx.ModuleForTests("afl_fuzz_shared_lib",
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001910 "android_arm64_armv8-a_shared_fuzzer").Rule("cc")
1911}
1912
1913func TestAFLFuzzTargetForDevice(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001914 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001915 VerifyAFLFuzzTargetVariant(t, "android_arm64_armv8-a")
1916}
1917
1918func TestAFLFuzzTargetForLinuxHost(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001919 t.Parallel()
Cory Barker9cfcf6d2022-07-22 17:22:02 +00001920 if runtime.GOOS != "linux" {
1921 t.Skip("requires linux")
1922 }
1923
1924 VerifyAFLFuzzTargetVariant(t, "linux_glibc_x86_64")
Cory Barkera1da26f2022-06-07 20:12:06 +00001925}
1926
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001927// Simple smoke test for the cc_fuzz target that ensures the rule compiles
1928// correctly.
1929func TestFuzzTarget(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001930 t.Parallel()
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001931 ctx := testCc(t, `
1932 cc_fuzz {
1933 name: "fuzz_smoke_test",
1934 srcs: ["foo.c"],
1935 }`)
1936
Paul Duffin075c4172019-12-19 19:06:13 +00001937 variant := "android_arm64_armv8-a_fuzzer"
Mitch Phillipsda9a4632019-07-15 09:34:09 -07001938 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
1939}
1940
Jooyung Han38002912019-05-16 04:01:54 +09001941func assertString(t *testing.T, got, expected string) {
1942 t.Helper()
1943 if got != expected {
1944 t.Errorf("expected %q got %q", expected, got)
1945 }
1946}
1947
1948func assertArrayString(t *testing.T, got, expected []string) {
1949 t.Helper()
1950 if len(got) != len(expected) {
1951 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
1952 return
1953 }
1954 for i := range got {
1955 if got[i] != expected[i] {
1956 t.Errorf("expected %d-th %q (%q) got %q (%q)",
1957 i, expected[i], expected, got[i], got)
1958 return
1959 }
1960 }
1961}
Colin Crosse1bb5d02019-09-24 14:55:04 -07001962
Jooyung Han0302a842019-10-30 18:43:49 +09001963func assertMapKeys(t *testing.T, m map[string]string, expected []string) {
1964 t.Helper()
Cole Faust18994c72023-02-28 16:02:16 -08001965 assertArrayString(t, android.SortedKeys(m), expected)
Jooyung Han0302a842019-10-30 18:43:49 +09001966}
1967
Colin Crosse1bb5d02019-09-24 14:55:04 -07001968func TestDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04001969 t.Parallel()
Colin Crosse1bb5d02019-09-24 14:55:04 -07001970 ctx := testCc(t, `
1971 cc_defaults {
1972 name: "defaults",
1973 srcs: ["foo.c"],
1974 static: {
1975 srcs: ["bar.c"],
1976 },
1977 shared: {
1978 srcs: ["baz.c"],
1979 },
1980 }
1981
1982 cc_library_static {
1983 name: "libstatic",
1984 defaults: ["defaults"],
1985 }
1986
1987 cc_library_shared {
1988 name: "libshared",
1989 defaults: ["defaults"],
1990 }
1991
1992 cc_library {
1993 name: "libboth",
1994 defaults: ["defaults"],
1995 }
1996
1997 cc_binary {
1998 name: "binary",
1999 defaults: ["defaults"],
2000 }`)
2001
Colin Cross7113d202019-11-20 16:39:12 -08002002 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002003 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2004 t.Errorf("libshared ld rule wanted %q, got %q", w, g)
2005 }
Colin Cross7113d202019-11-20 16:39:12 -08002006 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002007 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
2008 t.Errorf("libboth ld rule wanted %q, got %q", w, g)
2009 }
Colin Cross7113d202019-11-20 16:39:12 -08002010 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002011 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
2012 t.Errorf("binary ld rule wanted %q, got %q", w, g)
2013 }
2014
Colin Cross7113d202019-11-20 16:39:12 -08002015 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002016 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2017 t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
2018 }
Colin Cross7113d202019-11-20 16:39:12 -08002019 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar")
Colin Crosse1bb5d02019-09-24 14:55:04 -07002020 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
2021 t.Errorf("libboth ar rule wanted %q, got %q", w, g)
2022 }
2023}
Colin Crosseabaedd2020-02-06 17:01:55 -08002024
2025func TestProductVariableDefaults(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002026 t.Parallel()
Colin Crosseabaedd2020-02-06 17:01:55 -08002027 bp := `
2028 cc_defaults {
2029 name: "libfoo_defaults",
2030 srcs: ["foo.c"],
2031 cppflags: ["-DFOO"],
2032 product_variables: {
2033 debuggable: {
2034 cppflags: ["-DBAR"],
2035 },
2036 },
2037 }
2038
2039 cc_library {
2040 name: "libfoo",
2041 defaults: ["libfoo_defaults"],
2042 }
2043 `
2044
Paul Duffin8567f222021-03-23 00:02:06 +00002045 result := android.GroupFixturePreparers(
2046 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002047 android.PrepareForTestWithVariables,
Colin Crosseabaedd2020-02-06 17:01:55 -08002048
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002049 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2050 variables.Debuggable = BoolPtr(true)
2051 }),
2052 ).RunTestWithBp(t, bp)
Colin Crosseabaedd2020-02-06 17:01:55 -08002053
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002054 libfoo := result.Module("libfoo", "android_arm64_armv8-a_static").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +00002055 android.AssertStringListContains(t, "cppflags", libfoo.flags.Local.CppFlags, "-DBAR")
Colin Crosseabaedd2020-02-06 17:01:55 -08002056}
Colin Crosse4f6eba2020-09-22 18:11:25 -07002057
2058func TestEmptyWholeStaticLibsAllowMissingDependencies(t *testing.T) {
2059 t.Parallel()
2060 bp := `
2061 cc_library_static {
2062 name: "libfoo",
2063 srcs: ["foo.c"],
2064 whole_static_libs: ["libbar"],
2065 }
2066
2067 cc_library_static {
2068 name: "libbar",
2069 whole_static_libs: ["libmissing"],
2070 }
2071 `
2072
Paul Duffin8567f222021-03-23 00:02:06 +00002073 result := android.GroupFixturePreparers(
2074 prepareForCcTest,
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002075 android.PrepareForTestWithAllowMissingDependencies,
2076 ).RunTestWithBp(t, bp)
Colin Crosse4f6eba2020-09-22 18:11:25 -07002077
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002078 libbar := result.ModuleForTests("libbar", "android_arm64_armv8-a_static").Output("libbar.a")
Paul Duffine84b1332021-03-12 11:59:43 +00002079 android.AssertDeepEquals(t, "libbar rule", android.ErrorRule, libbar.Rule)
Colin Crosse4f6eba2020-09-22 18:11:25 -07002080
Paul Duffine84b1332021-03-12 11:59:43 +00002081 android.AssertStringDoesContain(t, "libbar error", libbar.Args["error"], "missing dependencies: libmissing")
Colin Crosse4f6eba2020-09-22 18:11:25 -07002082
Paul Duffin7d8a8ad2021-03-07 15:58:39 +00002083 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Output("libfoo.a")
Paul Duffine84b1332021-03-12 11:59:43 +00002084 android.AssertStringListContains(t, "libfoo.a dependencies", libfoo.Inputs.Strings(), libbar.Output.String())
Colin Crosse4f6eba2020-09-22 18:11:25 -07002085}
Colin Crosse9fe2942020-11-10 18:12:15 -08002086
2087func TestInstallSharedLibs(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002088 t.Parallel()
Colin Crosse9fe2942020-11-10 18:12:15 -08002089 bp := `
2090 cc_binary {
2091 name: "bin",
2092 host_supported: true,
2093 shared_libs: ["libshared"],
2094 runtime_libs: ["libruntime"],
2095 srcs: [":gen"],
2096 }
2097
2098 cc_library_shared {
2099 name: "libshared",
2100 host_supported: true,
2101 shared_libs: ["libtransitive"],
2102 }
2103
2104 cc_library_shared {
2105 name: "libtransitive",
2106 host_supported: true,
2107 }
2108
2109 cc_library_shared {
2110 name: "libruntime",
2111 host_supported: true,
2112 }
2113
2114 cc_binary_host {
2115 name: "tool",
2116 srcs: ["foo.cpp"],
2117 }
2118
2119 genrule {
2120 name: "gen",
2121 tools: ["tool"],
2122 out: ["gen.cpp"],
2123 cmd: "$(location tool) $(out)",
2124 }
2125 `
2126
Paul Duffinc3e6ce02021-03-22 23:21:32 +00002127 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Colin Crosse9fe2942020-11-10 18:12:15 -08002128 ctx := testCcWithConfig(t, config)
2129
2130 hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install")
2131 hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install")
2132 hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install")
2133 hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install")
2134 hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install")
2135
2136 if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) {
2137 t.Errorf("expected host bin dependency %q, got %q", w, g)
2138 }
2139
2140 if g, w := hostBin.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2141 t.Errorf("expected host bin dependency %q, got %q", w, g)
2142 }
2143
2144 if g, w := hostShared.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
2145 t.Errorf("expected host bin dependency %q, got %q", w, g)
2146 }
2147
2148 if g, w := hostBin.Implicits.Strings(), hostRuntime.Output.String(); !android.InList(w, g) {
2149 t.Errorf("expected host bin dependency %q, got %q", w, g)
2150 }
2151
2152 if g, w := hostBin.Implicits.Strings(), hostTool.Output.String(); android.InList(w, g) {
2153 t.Errorf("expected no host bin dependency %q, got %q", w, g)
2154 }
2155
2156 deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install")
2157 deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install")
2158 deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install")
2159 deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install")
2160
2161 if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) {
2162 t.Errorf("expected device bin dependency %q, got %q", w, g)
2163 }
2164
2165 if g, w := deviceBin.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2166 t.Errorf("expected device bin dependency %q, got %q", w, g)
2167 }
2168
2169 if g, w := deviceShared.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
2170 t.Errorf("expected device bin dependency %q, got %q", w, g)
2171 }
2172
2173 if g, w := deviceBin.OrderOnly.Strings(), deviceRuntime.Output.String(); !android.InList(w, g) {
2174 t.Errorf("expected device bin dependency %q, got %q", w, g)
2175 }
2176
2177 if g, w := deviceBin.OrderOnly.Strings(), hostTool.Output.String(); android.InList(w, g) {
2178 t.Errorf("expected no device bin dependency %q, got %q", w, g)
2179 }
2180
2181}
Jiyong Park1ad8e162020-12-01 23:40:09 +09002182
2183func TestStubsLibReexportsHeaders(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002184 t.Parallel()
Jiyong Park1ad8e162020-12-01 23:40:09 +09002185 ctx := testCc(t, `
2186 cc_library_shared {
2187 name: "libclient",
2188 srcs: ["foo.c"],
2189 shared_libs: ["libfoo#1"],
2190 }
2191
2192 cc_library_shared {
2193 name: "libfoo",
2194 srcs: ["foo.c"],
2195 shared_libs: ["libbar"],
2196 export_shared_lib_headers: ["libbar"],
2197 stubs: {
2198 symbol_file: "foo.map.txt",
2199 versions: ["1", "2", "3"],
2200 },
2201 }
2202
2203 cc_library_shared {
2204 name: "libbar",
2205 export_include_dirs: ["include/libbar"],
2206 srcs: ["foo.c"],
2207 }`)
2208
2209 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2210
2211 if !strings.Contains(cFlags, "-Iinclude/libbar") {
2212 t.Errorf("expected %q in cflags, got %q", "-Iinclude/libbar", cFlags)
2213 }
2214}
Jooyung Hane197d8b2021-01-05 10:33:16 +09002215
Vinh Tran09581952023-05-16 16:03:20 -04002216func TestAidlLibraryWithHeaders(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002217 t.Parallel()
2218 ctx := android.GroupFixturePreparers(
2219 prepareForCcTest,
2220 aidl_library.PrepareForTestWithAidlLibrary,
2221 android.MockFS{
2222 "package_bar/Android.bp": []byte(`
2223 aidl_library {
2224 name: "bar",
2225 srcs: ["x/y/Bar.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002226 hdrs: ["x/HeaderBar.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002227 strip_import_prefix: "x",
2228 }
2229 `)}.AddToFixture(),
2230 android.MockFS{
2231 "package_foo/Android.bp": []byte(`
2232 aidl_library {
2233 name: "foo",
2234 srcs: ["a/b/Foo.aidl"],
Vinh Tran09581952023-05-16 16:03:20 -04002235 hdrs: ["a/HeaderFoo.aidl"],
Vinh Tran367d89d2023-04-28 11:21:25 -04002236 strip_import_prefix: "a",
2237 deps: ["bar"],
2238 }
2239 cc_library {
2240 name: "libfoo",
2241 aidl: {
2242 libs: ["foo"],
2243 }
2244 }
2245 `),
2246 }.AddToFixture(),
2247 ).RunTest(t).TestContext
2248
2249 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Vinh Tran09581952023-05-16 16:03:20 -04002250
2251 android.AssertPathsRelativeToTopEquals(
2252 t,
2253 "aidl headers",
2254 []string{
2255 "package_bar/x/HeaderBar.aidl",
2256 "package_foo/a/HeaderFoo.aidl",
2257 "package_foo/a/b/Foo.aidl",
2258 "out/soong/.intermediates/package_foo/libfoo/android_arm64_armv8-a_static/gen/aidl_library.sbox.textproto",
2259 },
2260 libfoo.Rule("aidl_library").Implicits,
2261 )
2262
Colin Crossf61d03d2023-11-02 16:56:39 -07002263 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl_library.sbox.textproto"))
Vinh Tran367d89d2023-04-28 11:21:25 -04002264 aidlCommand := manifest.Commands[0].GetCommand()
2265
2266 expectedAidlFlags := "-Ipackage_foo/a -Ipackage_bar/x"
2267 if !strings.Contains(aidlCommand, expectedAidlFlags) {
2268 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlags)
2269 }
2270
2271 outputs := strings.Join(libfoo.AllOutputs(), " ")
2272
Vinh Tran09581952023-05-16 16:03:20 -04002273 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BpFoo.h")
2274 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BnFoo.h")
2275 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/Foo.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002276 android.AssertStringDoesContain(t, "aidl-generated cpp", outputs, "b/Foo.cpp")
2277 // Confirm that the aidl header doesn't get compiled to cpp and h files
Vinh Tran09581952023-05-16 16:03:20 -04002278 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BpBar.h")
2279 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BnBar.h")
2280 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/Bar.h")
Vinh Tran367d89d2023-04-28 11:21:25 -04002281 android.AssertStringDoesNotContain(t, "aidl-generated cpp", outputs, "y/Bar.cpp")
2282}
2283
Jooyung Hane197d8b2021-01-05 10:33:16 +09002284func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002285 t.Parallel()
Vinh Tran367d89d2023-04-28 11:21:25 -04002286 ctx := android.GroupFixturePreparers(
2287 prepareForCcTest,
2288 aidl_library.PrepareForTestWithAidlLibrary,
2289 ).RunTestWithBp(t, `
Jooyung Hane197d8b2021-01-05 10:33:16 +09002290 cc_library {
2291 name: "libfoo",
2292 srcs: ["a/Foo.aidl"],
2293 aidl: { flags: ["-Werror"], },
2294 }
2295 `)
2296
2297 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
Colin Crossf61d03d2023-11-02 16:56:39 -07002298 manifest := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, libfoo.Output("aidl.sbox.textproto"))
Jooyung Hane197d8b2021-01-05 10:33:16 +09002299 aidlCommand := manifest.Commands[0].GetCommand()
2300 expectedAidlFlag := "-Werror"
2301 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2302 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2303 }
2304}
Evgenii Stepanov193ac2e2020-04-28 15:09:12 -07002305
Jooyung Han07f70c02021-11-06 07:08:45 +09002306func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002307 t.Parallel()
Jooyung Han07f70c02021-11-06 07:08:45 +09002308 for _, tc := range []struct {
2309 name string
2310 sdkVersion string
2311 variant string
2312 expected string
2313 }{
2314 {
2315 name: "default is current",
2316 sdkVersion: "",
2317 variant: "android_arm64_armv8-a_static",
2318 expected: "platform_apis",
2319 },
2320 {
2321 name: "use sdk_version",
2322 sdkVersion: `sdk_version: "29"`,
2323 variant: "android_arm64_armv8-a_static",
2324 expected: "platform_apis",
2325 },
2326 {
2327 name: "use sdk_version(sdk variant)",
2328 sdkVersion: `sdk_version: "29"`,
2329 variant: "android_arm64_armv8-a_sdk_static",
2330 expected: "29",
2331 },
2332 {
2333 name: "use min_sdk_version",
2334 sdkVersion: `min_sdk_version: "29"`,
2335 variant: "android_arm64_armv8-a_static",
2336 expected: "29",
2337 },
2338 } {
2339 t.Run(tc.name, func(t *testing.T) {
2340 ctx := testCc(t, `
2341 cc_library {
2342 name: "libfoo",
2343 stl: "none",
2344 srcs: ["a/Foo.aidl"],
2345 `+tc.sdkVersion+`
2346 }
2347 `)
2348 libfoo := ctx.ModuleForTests("libfoo", tc.variant)
Colin Crossf61d03d2023-11-02 16:56:39 -07002349 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl.sbox.textproto"))
Jooyung Han07f70c02021-11-06 07:08:45 +09002350 aidlCommand := manifest.Commands[0].GetCommand()
2351 expectedAidlFlag := "--min_sdk_version=" + tc.expected
2352 if !strings.Contains(aidlCommand, expectedAidlFlag) {
2353 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
2354 }
2355 })
2356 }
2357}
2358
Vinh Tran09581952023-05-16 16:03:20 -04002359func TestInvalidAidlProp(t *testing.T) {
2360 t.Parallel()
2361
2362 testCases := []struct {
2363 description string
2364 bp string
2365 }{
2366 {
2367 description: "Invalid use of aidl.libs and aidl.include_dirs",
2368 bp: `
2369 cc_library {
2370 name: "foo",
2371 aidl: {
2372 libs: ["foo_aidl"],
2373 include_dirs: ["bar/include"],
2374 }
2375 }
2376 `,
2377 },
2378 {
2379 description: "Invalid use of aidl.libs and aidl.local_include_dirs",
2380 bp: `
2381 cc_library {
2382 name: "foo",
2383 aidl: {
2384 libs: ["foo_aidl"],
2385 local_include_dirs: ["include"],
2386 }
2387 }
2388 `,
2389 },
2390 }
2391
2392 for _, testCase := range testCases {
2393 t.Run(testCase.description, func(t *testing.T) {
2394 bp := `
2395 aidl_library {
2396 name: "foo_aidl",
2397 srcs: ["Foo.aidl"],
2398 } ` + testCase.bp
2399 android.GroupFixturePreparers(
2400 prepareForCcTest,
2401 aidl_library.PrepareForTestWithAidlLibrary.
2402 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("For aidl headers, please only use aidl.libs prop")),
2403 ).RunTestWithBp(t, bp)
2404 })
2405 }
2406}
2407
Jiyong Parka008fb02021-03-16 17:15:53 +09002408func TestMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002409 t.Parallel()
Jiyong Parka008fb02021-03-16 17:15:53 +09002410 ctx := testCc(t, `
2411 cc_library_shared {
2412 name: "libfoo",
2413 srcs: ["foo.c"],
2414 min_sdk_version: "29",
2415 }`)
2416
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-android29")
2419}
2420
Vinh Tranf1924742022-06-24 16:40:11 -04002421func TestNonDigitMinSdkVersionInClangTriple(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002422 t.Parallel()
Vinh Tranf1924742022-06-24 16:40:11 -04002423 bp := `
2424 cc_library_shared {
2425 name: "libfoo",
2426 srcs: ["foo.c"],
2427 min_sdk_version: "S",
2428 }
2429 `
2430 result := android.GroupFixturePreparers(
2431 prepareForCcTest,
2432 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
2433 variables.Platform_version_active_codenames = []string{"UpsideDownCake", "Tiramisu"}
2434 }),
2435 ).RunTestWithBp(t, bp)
2436 ctx := result.TestContext
2437 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2438 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android31")
2439}
2440
Paul Duffin3cb603e2021-02-19 13:57:10 +00002441func TestIncludeDirsExporting(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002442 t.Parallel()
Paul Duffin3cb603e2021-02-19 13:57:10 +00002443
2444 // Trim spaces from the beginning, end and immediately after any newline characters. Leaves
2445 // embedded newline characters alone.
2446 trimIndentingSpaces := func(s string) string {
2447 return strings.TrimSpace(regexp.MustCompile("(^|\n)\\s+").ReplaceAllString(s, "$1"))
2448 }
2449
2450 checkPaths := func(t *testing.T, message string, expected string, paths android.Paths) {
2451 t.Helper()
2452 expected = trimIndentingSpaces(expected)
2453 actual := trimIndentingSpaces(strings.Join(android.FirstUniqueStrings(android.NormalizePathsForTesting(paths)), "\n"))
2454 if expected != actual {
2455 t.Errorf("%s: expected:\n%s\n actual:\n%s\n", message, expected, actual)
2456 }
2457 }
2458
2459 type exportedChecker func(t *testing.T, name string, exported FlagExporterInfo)
2460
2461 checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) {
2462 t.Helper()
Colin Cross5a377182023-12-14 14:46:23 -08002463 exported, _ := android.SingletonModuleProvider(ctx, module, FlagExporterInfoProvider)
Paul Duffin3cb603e2021-02-19 13:57:10 +00002464 name := module.Name()
2465
2466 for _, checker := range checkers {
2467 checker(t, name, exported)
2468 }
2469 }
2470
2471 expectedIncludeDirs := func(expectedPaths string) exportedChecker {
2472 return func(t *testing.T, name string, exported FlagExporterInfo) {
2473 t.Helper()
2474 checkPaths(t, fmt.Sprintf("%s: include dirs", name), expectedPaths, exported.IncludeDirs)
2475 }
2476 }
2477
2478 expectedSystemIncludeDirs := func(expectedPaths string) exportedChecker {
2479 return func(t *testing.T, name string, exported FlagExporterInfo) {
2480 t.Helper()
2481 checkPaths(t, fmt.Sprintf("%s: system include dirs", name), expectedPaths, exported.SystemIncludeDirs)
2482 }
2483 }
2484
2485 expectedGeneratedHeaders := func(expectedPaths string) exportedChecker {
2486 return func(t *testing.T, name string, exported FlagExporterInfo) {
2487 t.Helper()
2488 checkPaths(t, fmt.Sprintf("%s: generated headers", name), expectedPaths, exported.GeneratedHeaders)
2489 }
2490 }
2491
2492 expectedOrderOnlyDeps := func(expectedPaths string) exportedChecker {
2493 return func(t *testing.T, name string, exported FlagExporterInfo) {
2494 t.Helper()
2495 checkPaths(t, fmt.Sprintf("%s: order only deps", name), expectedPaths, exported.Deps)
2496 }
2497 }
2498
2499 genRuleModules := `
2500 genrule {
2501 name: "genrule_foo",
2502 cmd: "generate-foo",
2503 out: [
2504 "generated_headers/foo/generated_header.h",
2505 ],
2506 export_include_dirs: [
2507 "generated_headers",
2508 ],
2509 }
2510
2511 genrule {
2512 name: "genrule_bar",
2513 cmd: "generate-bar",
2514 out: [
2515 "generated_headers/bar/generated_header.h",
2516 ],
2517 export_include_dirs: [
2518 "generated_headers",
2519 ],
2520 }
2521 `
2522
2523 t.Run("ensure exported include dirs are not automatically re-exported from shared_libs", func(t *testing.T) {
2524 ctx := testCc(t, genRuleModules+`
2525 cc_library {
2526 name: "libfoo",
2527 srcs: ["foo.c"],
2528 export_include_dirs: ["foo/standard"],
2529 export_system_include_dirs: ["foo/system"],
2530 generated_headers: ["genrule_foo"],
2531 export_generated_headers: ["genrule_foo"],
2532 }
2533
2534 cc_library {
2535 name: "libbar",
2536 srcs: ["bar.c"],
2537 shared_libs: ["libfoo"],
2538 export_include_dirs: ["bar/standard"],
2539 export_system_include_dirs: ["bar/system"],
2540 generated_headers: ["genrule_bar"],
2541 export_generated_headers: ["genrule_bar"],
2542 }
2543 `)
2544 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2545 checkIncludeDirs(t, ctx, foo,
2546 expectedIncludeDirs(`
2547 foo/standard
2548 .intermediates/genrule_foo/gen/generated_headers
2549 `),
2550 expectedSystemIncludeDirs(`foo/system`),
2551 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2552 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2553 )
2554
2555 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2556 checkIncludeDirs(t, ctx, bar,
2557 expectedIncludeDirs(`
2558 bar/standard
2559 .intermediates/genrule_bar/gen/generated_headers
2560 `),
2561 expectedSystemIncludeDirs(`bar/system`),
2562 expectedGeneratedHeaders(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2563 expectedOrderOnlyDeps(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
2564 )
2565 })
2566
2567 t.Run("ensure exported include dirs are automatically re-exported from whole_static_libs", func(t *testing.T) {
2568 ctx := testCc(t, genRuleModules+`
2569 cc_library {
2570 name: "libfoo",
2571 srcs: ["foo.c"],
2572 export_include_dirs: ["foo/standard"],
2573 export_system_include_dirs: ["foo/system"],
2574 generated_headers: ["genrule_foo"],
2575 export_generated_headers: ["genrule_foo"],
2576 }
2577
2578 cc_library {
2579 name: "libbar",
2580 srcs: ["bar.c"],
2581 whole_static_libs: ["libfoo"],
2582 export_include_dirs: ["bar/standard"],
2583 export_system_include_dirs: ["bar/system"],
2584 generated_headers: ["genrule_bar"],
2585 export_generated_headers: ["genrule_bar"],
2586 }
2587 `)
2588 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2589 checkIncludeDirs(t, ctx, foo,
2590 expectedIncludeDirs(`
2591 foo/standard
2592 .intermediates/genrule_foo/gen/generated_headers
2593 `),
2594 expectedSystemIncludeDirs(`foo/system`),
2595 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2596 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
2597 )
2598
2599 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
2600 checkIncludeDirs(t, ctx, bar,
2601 expectedIncludeDirs(`
2602 bar/standard
2603 foo/standard
2604 .intermediates/genrule_foo/gen/generated_headers
2605 .intermediates/genrule_bar/gen/generated_headers
2606 `),
2607 expectedSystemIncludeDirs(`
2608 bar/system
2609 foo/system
2610 `),
2611 expectedGeneratedHeaders(`
2612 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2613 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2614 `),
2615 expectedOrderOnlyDeps(`
2616 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
2617 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
2618 `),
2619 )
2620 })
2621
Paul Duffin3cb603e2021-02-19 13:57:10 +00002622 t.Run("ensure only aidl headers are exported", func(t *testing.T) {
Vinh Tran367d89d2023-04-28 11:21:25 -04002623 ctx := android.GroupFixturePreparers(
2624 prepareForCcTest,
2625 aidl_library.PrepareForTestWithAidlLibrary,
2626 ).RunTestWithBp(t, `
2627 aidl_library {
2628 name: "libfoo_aidl",
2629 srcs: ["x/y/Bar.aidl"],
2630 strip_import_prefix: "x",
2631 }
Paul Duffin3cb603e2021-02-19 13:57:10 +00002632 cc_library_shared {
2633 name: "libfoo",
2634 srcs: [
2635 "foo.c",
2636 "b.aidl",
2637 "a.proto",
2638 ],
2639 aidl: {
Vinh Tran367d89d2023-04-28 11:21:25 -04002640 libs: ["libfoo_aidl"],
Paul Duffin3cb603e2021-02-19 13:57:10 +00002641 export_aidl_headers: true,
2642 }
2643 }
Vinh Tran367d89d2023-04-28 11:21:25 -04002644 `).TestContext
Paul Duffin3cb603e2021-02-19 13:57:10 +00002645 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2646 checkIncludeDirs(t, ctx, foo,
2647 expectedIncludeDirs(`
2648 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl
Vinh Tran09581952023-05-16 16:03:20 -04002649 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library
Paul Duffin3cb603e2021-02-19 13:57:10 +00002650 `),
2651 expectedSystemIncludeDirs(``),
2652 expectedGeneratedHeaders(`
2653 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2654 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2655 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002656 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2657 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2658 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002659 `),
2660 expectedOrderOnlyDeps(`
2661 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
2662 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
2663 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
Vinh Tran09581952023-05-16 16:03:20 -04002664 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h
2665 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h
2666 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002667 `),
2668 )
2669 })
2670
Paul Duffin3cb603e2021-02-19 13:57:10 +00002671 t.Run("ensure only proto headers are exported", func(t *testing.T) {
2672 ctx := testCc(t, genRuleModules+`
2673 cc_library_shared {
2674 name: "libfoo",
2675 srcs: [
2676 "foo.c",
2677 "b.aidl",
2678 "a.proto",
2679 ],
2680 proto: {
2681 export_proto_headers: true,
2682 }
2683 }
2684 `)
2685 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2686 checkIncludeDirs(t, ctx, foo,
2687 expectedIncludeDirs(`
2688 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto
2689 `),
2690 expectedSystemIncludeDirs(``),
2691 expectedGeneratedHeaders(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002692 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2693 `),
2694 expectedOrderOnlyDeps(`
Paul Duffin3cb603e2021-02-19 13:57:10 +00002695 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
2696 `),
2697 )
2698 })
2699
Paul Duffin33056e82021-02-19 13:49:08 +00002700 t.Run("ensure only sysprop headers are exported", func(t *testing.T) {
Paul Duffin3cb603e2021-02-19 13:57:10 +00002701 ctx := testCc(t, genRuleModules+`
2702 cc_library_shared {
2703 name: "libfoo",
2704 srcs: [
2705 "foo.c",
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002706 "path/to/a.sysprop",
Paul Duffin3cb603e2021-02-19 13:57:10 +00002707 "b.aidl",
2708 "a.proto",
2709 ],
2710 }
2711 `)
2712 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
2713 checkIncludeDirs(t, ctx, foo,
2714 expectedIncludeDirs(`
2715 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include
2716 `),
2717 expectedSystemIncludeDirs(``),
2718 expectedGeneratedHeaders(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002719 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002720 `),
2721 expectedOrderOnlyDeps(`
Trevor Radcliffe3092a8e2022-08-24 15:25:25 +00002722 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
2723 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/path/to/a.sysprop.h
Paul Duffin3cb603e2021-02-19 13:57:10 +00002724 `),
2725 )
2726 })
2727}
Colin Crossae628182021-06-14 16:52:28 -07002728
2729func TestIncludeDirectoryOrdering(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002730 t.Parallel()
Liz Kammer08572c62021-09-30 10:11:04 -04002731 baseExpectedFlags := []string{
2732 "${config.ArmThumbCflags}",
2733 "${config.ArmCflags}",
2734 "${config.CommonGlobalCflags}",
2735 "${config.DeviceGlobalCflags}",
2736 "${config.ExternalCflags}",
2737 "${config.ArmToolchainCflags}",
2738 "${config.ArmArmv7ANeonCflags}",
2739 "${config.ArmGenericCflags}",
2740 "-target",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002741 "armv7a-linux-androideabi21",
Liz Kammer08572c62021-09-30 10:11:04 -04002742 }
2743
2744 expectedIncludes := []string{
2745 "external/foo/android_arm_export_include_dirs",
2746 "external/foo/lib32_export_include_dirs",
2747 "external/foo/arm_export_include_dirs",
2748 "external/foo/android_export_include_dirs",
2749 "external/foo/linux_export_include_dirs",
2750 "external/foo/export_include_dirs",
2751 "external/foo/android_arm_local_include_dirs",
2752 "external/foo/lib32_local_include_dirs",
2753 "external/foo/arm_local_include_dirs",
2754 "external/foo/android_local_include_dirs",
2755 "external/foo/linux_local_include_dirs",
2756 "external/foo/local_include_dirs",
2757 "external/foo",
2758 "external/foo/libheader1",
2759 "external/foo/libheader2",
2760 "external/foo/libwhole1",
2761 "external/foo/libwhole2",
2762 "external/foo/libstatic1",
2763 "external/foo/libstatic2",
2764 "external/foo/libshared1",
2765 "external/foo/libshared2",
2766 "external/foo/liblinux",
2767 "external/foo/libandroid",
2768 "external/foo/libarm",
2769 "external/foo/lib32",
2770 "external/foo/libandroid_arm",
2771 "defaults/cc/common/ndk_libc++_shared",
Liz Kammer08572c62021-09-30 10:11:04 -04002772 }
2773
2774 conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
2775 cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"}
2776
Elliott Hughesed4a27b2022-05-18 13:15:00 -07002777 cflags := []string{"-Werror", "-std=candcpp"}
Elliott Hughesfb294e32023-06-14 10:42:45 -07002778 cstd := []string{"-std=gnu17", "-std=conly"}
Elliott Hughesc79d9e32022-01-13 14:56:02 -08002779 cppstd := []string{"-std=gnu++20", "-std=cpp", "-fno-rtti"}
Liz Kammer08572c62021-09-30 10:11:04 -04002780
2781 lastIncludes := []string{
2782 "out/soong/ndk/sysroot/usr/include",
2783 "out/soong/ndk/sysroot/usr/include/arm-linux-androideabi",
2784 }
2785
2786 combineSlices := func(slices ...[]string) []string {
2787 var ret []string
2788 for _, s := range slices {
2789 ret = append(ret, s...)
2790 }
2791 return ret
2792 }
2793
2794 testCases := []struct {
2795 name string
2796 src string
2797 expected []string
2798 }{
2799 {
2800 name: "c",
2801 src: "foo.c",
Yi Kong13beeed2023-07-15 03:09:00 +09002802 expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
Liz Kammer08572c62021-09-30 10:11:04 -04002803 },
2804 {
2805 name: "cc",
2806 src: "foo.cc",
Yi Kong13beeed2023-07-15 03:09:00 +09002807 expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
Liz Kammer08572c62021-09-30 10:11:04 -04002808 },
2809 {
2810 name: "assemble",
2811 src: "foo.s",
Yi Kong13beeed2023-07-15 03:09:00 +09002812 expected: combineSlices(baseExpectedFlags, []string{"${config.CommonGlobalAsflags}"}, expectedIncludes, lastIncludes),
Liz Kammer08572c62021-09-30 10:11:04 -04002813 },
2814 }
2815
2816 for _, tc := range testCases {
2817 t.Run(tc.name, func(t *testing.T) {
2818 bp := fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002819 cc_library {
2820 name: "libfoo",
Liz Kammer08572c62021-09-30 10:11:04 -04002821 srcs: ["%s"],
Liz Kammer9dc65772021-12-16 11:38:50 -05002822 cflags: ["-std=candcpp"],
2823 conlyflags: ["-std=conly"],
2824 cppflags: ["-std=cpp"],
Colin Crossae628182021-06-14 16:52:28 -07002825 local_include_dirs: ["local_include_dirs"],
2826 export_include_dirs: ["export_include_dirs"],
2827 export_system_include_dirs: ["export_system_include_dirs"],
2828 static_libs: ["libstatic1", "libstatic2"],
2829 whole_static_libs: ["libwhole1", "libwhole2"],
2830 shared_libs: ["libshared1", "libshared2"],
2831 header_libs: ["libheader1", "libheader2"],
2832 target: {
2833 android: {
2834 shared_libs: ["libandroid"],
2835 local_include_dirs: ["android_local_include_dirs"],
2836 export_include_dirs: ["android_export_include_dirs"],
2837 },
2838 android_arm: {
2839 shared_libs: ["libandroid_arm"],
2840 local_include_dirs: ["android_arm_local_include_dirs"],
2841 export_include_dirs: ["android_arm_export_include_dirs"],
2842 },
2843 linux: {
2844 shared_libs: ["liblinux"],
2845 local_include_dirs: ["linux_local_include_dirs"],
2846 export_include_dirs: ["linux_export_include_dirs"],
2847 },
2848 },
2849 multilib: {
2850 lib32: {
2851 shared_libs: ["lib32"],
2852 local_include_dirs: ["lib32_local_include_dirs"],
2853 export_include_dirs: ["lib32_export_include_dirs"],
2854 },
2855 },
2856 arch: {
2857 arm: {
2858 shared_libs: ["libarm"],
2859 local_include_dirs: ["arm_local_include_dirs"],
2860 export_include_dirs: ["arm_export_include_dirs"],
2861 },
2862 },
2863 stl: "libc++",
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002864 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002865 }
2866
2867 cc_library_headers {
2868 name: "libheader1",
2869 export_include_dirs: ["libheader1"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002870 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002871 stl: "none",
2872 }
2873
2874 cc_library_headers {
2875 name: "libheader2",
2876 export_include_dirs: ["libheader2"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002877 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002878 stl: "none",
2879 }
Liz Kammer08572c62021-09-30 10:11:04 -04002880 `, tc.src)
Colin Crossae628182021-06-14 16:52:28 -07002881
Liz Kammer08572c62021-09-30 10:11:04 -04002882 libs := []string{
2883 "libstatic1",
2884 "libstatic2",
2885 "libwhole1",
2886 "libwhole2",
2887 "libshared1",
2888 "libshared2",
2889 "libandroid",
2890 "libandroid_arm",
2891 "liblinux",
2892 "lib32",
2893 "libarm",
2894 }
Colin Crossae628182021-06-14 16:52:28 -07002895
Liz Kammer08572c62021-09-30 10:11:04 -04002896 for _, lib := range libs {
2897 bp += fmt.Sprintf(`
Colin Crossae628182021-06-14 16:52:28 -07002898 cc_library {
2899 name: "%s",
2900 export_include_dirs: ["%s"],
Dan Albert6bfb6bb2022-08-17 20:11:57 +00002901 sdk_version: "minimum",
Colin Crossae628182021-06-14 16:52:28 -07002902 stl: "none",
2903 }
2904 `, lib, lib)
Liz Kammer08572c62021-09-30 10:11:04 -04002905 }
2906
2907 ctx := android.GroupFixturePreparers(
2908 PrepareForIntegrationTestWithCc,
2909 android.FixtureAddTextFile("external/foo/Android.bp", bp),
2910 ).RunTest(t)
2911 // Use the arm variant instead of the arm64 variant so that it gets headers from
2912 // ndk_libandroid_support to test LateStaticLibs.
2913 cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"]
2914
2915 var includes []string
2916 flags := strings.Split(cflags, " ")
2917 for _, flag := range flags {
2918 if strings.HasPrefix(flag, "-I") {
2919 includes = append(includes, strings.TrimPrefix(flag, "-I"))
2920 } else if flag == "-isystem" {
2921 // skip isystem, include next
2922 } else if len(flag) > 0 {
2923 includes = append(includes, flag)
2924 }
2925 }
2926
2927 android.AssertArrayString(t, "includes", tc.expected, includes)
2928 })
Colin Crossae628182021-06-14 16:52:28 -07002929 }
2930
Colin Crossae628182021-06-14 16:52:28 -07002931}
Alixb5f6d9e2022-04-20 23:00:58 +00002932
zijunzhao933e3802023-01-12 07:26:20 +00002933func TestAddnoOverride64GlobalCflags(t *testing.T) {
2934 t.Parallel()
2935 ctx := testCc(t, `
2936 cc_library_shared {
2937 name: "libclient",
2938 srcs: ["foo.c"],
2939 shared_libs: ["libfoo#1"],
2940 }
2941
2942 cc_library_shared {
2943 name: "libfoo",
2944 srcs: ["foo.c"],
2945 shared_libs: ["libbar"],
2946 export_shared_lib_headers: ["libbar"],
2947 stubs: {
2948 symbol_file: "foo.map.txt",
2949 versions: ["1", "2", "3"],
2950 },
2951 }
2952
2953 cc_library_shared {
2954 name: "libbar",
2955 export_include_dirs: ["include/libbar"],
2956 srcs: ["foo.c"],
2957 }`)
2958
2959 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
2960
2961 if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") {
2962 t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags)
2963 }
2964}
2965
Alixb5f6d9e2022-04-20 23:00:58 +00002966func TestCcBuildBrokenClangProperty(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04002967 t.Parallel()
Alixb5f6d9e2022-04-20 23:00:58 +00002968 tests := []struct {
2969 name string
2970 clang bool
2971 BuildBrokenClangProperty bool
2972 err string
2973 }{
2974 {
2975 name: "error when clang is set to false",
2976 clang: false,
2977 err: "is no longer supported",
2978 },
2979 {
2980 name: "error when clang is set to true",
2981 clang: true,
2982 err: "property is deprecated, see Changes.md",
2983 },
2984 {
2985 name: "no error when BuildBrokenClangProperty is explicitly set to true",
2986 clang: true,
2987 BuildBrokenClangProperty: true,
2988 },
2989 }
2990
2991 for _, test := range tests {
2992 t.Run(test.name, func(t *testing.T) {
2993 bp := fmt.Sprintf(`
2994 cc_library {
2995 name: "foo",
2996 clang: %t,
2997 }`, test.clang)
2998
2999 if test.err == "" {
3000 android.GroupFixturePreparers(
3001 prepareForCcTest,
3002 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3003 if test.BuildBrokenClangProperty {
3004 variables.BuildBrokenClangProperty = test.BuildBrokenClangProperty
3005 }
3006 }),
3007 ).RunTestWithBp(t, bp)
3008 } else {
3009 prepareForCcTest.
3010 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3011 RunTestWithBp(t, bp)
3012 }
3013 })
3014 }
3015}
Alix Espinoef47e542022-09-14 19:10:51 +00003016
3017func TestCcBuildBrokenClangAsFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04003018 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00003019 tests := []struct {
3020 name string
3021 clangAsFlags []string
3022 BuildBrokenClangAsFlags bool
3023 err string
3024 }{
3025 {
3026 name: "error when clang_asflags is set",
3027 clangAsFlags: []string{"-a", "-b"},
3028 err: "clang_asflags: property is deprecated",
3029 },
3030 {
3031 name: "no error when BuildBrokenClangAsFlags is explicitly set to true",
3032 clangAsFlags: []string{"-a", "-b"},
3033 BuildBrokenClangAsFlags: true,
3034 },
3035 }
3036
3037 for _, test := range tests {
3038 t.Run(test.name, func(t *testing.T) {
3039 bp := fmt.Sprintf(`
3040 cc_library {
3041 name: "foo",
3042 clang_asflags: %s,
3043 }`, `["`+strings.Join(test.clangAsFlags, `","`)+`"]`)
3044
3045 if test.err == "" {
3046 android.GroupFixturePreparers(
3047 prepareForCcTest,
3048 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3049 if test.BuildBrokenClangAsFlags {
3050 variables.BuildBrokenClangAsFlags = test.BuildBrokenClangAsFlags
3051 }
3052 }),
3053 ).RunTestWithBp(t, bp)
3054 } else {
3055 prepareForCcTest.
3056 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3057 RunTestWithBp(t, bp)
3058 }
3059 })
3060 }
3061}
3062
3063func TestCcBuildBrokenClangCFlags(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -04003064 t.Parallel()
Alix Espinoef47e542022-09-14 19:10:51 +00003065 tests := []struct {
3066 name string
3067 clangCFlags []string
3068 BuildBrokenClangCFlags bool
3069 err string
3070 }{
3071 {
3072 name: "error when clang_cflags is set",
3073 clangCFlags: []string{"-a", "-b"},
3074 err: "clang_cflags: property is deprecated",
3075 },
3076 {
3077 name: "no error when BuildBrokenClangCFlags is explicitly set to true",
3078 clangCFlags: []string{"-a", "-b"},
3079 BuildBrokenClangCFlags: true,
3080 },
3081 }
3082
3083 for _, test := range tests {
3084 t.Run(test.name, func(t *testing.T) {
3085 bp := fmt.Sprintf(`
3086 cc_library {
3087 name: "foo",
3088 clang_cflags: %s,
3089 }`, `["`+strings.Join(test.clangCFlags, `","`)+`"]`)
3090
3091 if test.err == "" {
3092 android.GroupFixturePreparers(
3093 prepareForCcTest,
3094 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3095 if test.BuildBrokenClangCFlags {
3096 variables.BuildBrokenClangCFlags = test.BuildBrokenClangCFlags
3097 }
3098 }),
3099 ).RunTestWithBp(t, bp)
3100 } else {
3101 prepareForCcTest.
3102 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
3103 RunTestWithBp(t, bp)
3104 }
3105 })
3106 }
3107}
Wei Li5f5d2712023-12-11 15:40:29 -08003108
3109func TestStrippedAllOutputFile(t *testing.T) {
3110 t.Parallel()
3111 bp := `
3112 cc_library {
3113 name: "test_lib",
3114 srcs: ["test_lib.cpp"],
3115 dist: {
3116 targets: [ "dist_target" ],
3117 tag: "stripped_all",
3118 }
3119 }
3120 `
3121 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
3122 ctx := testCcWithConfig(t, config)
3123 module := ctx.ModuleForTests("test_lib", "android_arm_armv7-a-neon_shared").Module()
3124 outputFile, err := module.(android.OutputFileProducer).OutputFiles("stripped_all")
3125 if err != nil {
3126 t.Errorf("Expected cc_library to produce output files, error: %s", err)
3127 return
3128 }
3129 if !strings.HasSuffix(outputFile.Strings()[0], "/stripped_all/test_lib.so") {
3130 t.Errorf("Unexpected output file: %s", outputFile.Strings()[0])
3131 return
3132 }
3133}
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003134
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003135func TestImageVariants(t *testing.T) {
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003136 t.Parallel()
3137
3138 bp := `
3139 cc_binary {
3140 name: "binfoo",
3141 srcs: ["binfoo.cc"],
3142 vendor_available: true,
3143 product_available: true,
3144 shared_libs: ["libbar"]
3145 }
3146 cc_library {
3147 name: "libbar",
3148 srcs: ["libbar.cc"],
3149 vendor_available: true,
3150 product_available: true,
3151 }
3152 `
3153
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003154 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +09003155
3156 hasDep := func(m android.Module, wantDep android.Module) bool {
3157 t.Helper()
3158 var found bool
3159 ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
3160 if dep == wantDep {
3161 found = true
3162 }
3163 })
3164 return found
3165 }
3166
3167 testDepWithVariant := func(imageVariant string) {
3168 imageVariantStr := ""
3169 if imageVariant != "core" {
3170 imageVariantStr = "_" + imageVariant
3171 }
3172 binFooModule := ctx.ModuleForTests("binfoo", "android"+imageVariantStr+"_arm64_armv8-a").Module()
3173 libBarModule := ctx.ModuleForTests("libbar", "android"+imageVariantStr+"_arm64_armv8-a_shared").Module()
3174 android.AssertBoolEquals(t, "binfoo should have dependency on libbar with image variant "+imageVariant, true, hasDep(binFooModule, libBarModule))
3175 }
3176
3177 testDepWithVariant("core")
3178 testDepWithVariant("vendor")
3179 testDepWithVariant("product")
3180}
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003181
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003182func TestVendorSdkVersion(t *testing.T) {
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003183 t.Parallel()
3184
3185 bp := `
3186 cc_library {
3187 name: "libfoo",
3188 srcs: ["libfoo.cc"],
3189 vendor_available: true,
3190 }
3191
3192 cc_library {
3193 name: "libbar",
3194 srcs: ["libbar.cc"],
3195 vendor_available: true,
3196 min_sdk_version: "29",
3197 }
3198 `
3199
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003200 ctx := prepareForCcTest.RunTestWithBp(t, bp)
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003201 testSdkVersionFlag := func(module, version string) {
3202 flags := ctx.ModuleForTests(module, "android_vendor_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
3203 android.AssertStringDoesContain(t, "min sdk version", flags, "-target aarch64-linux-android"+version)
3204 }
3205
3206 testSdkVersionFlag("libfoo", "10000")
3207 testSdkVersionFlag("libbar", "29")
3208
3209 ctx = android.GroupFixturePreparers(
Kiyoung Kim0d1c1e62024-03-26 16:33:58 +09003210 prepareForCcTest,
Yi-Yo Chiang88960aa2024-01-19 15:02:29 +08003211 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3212 if variables.BuildFlags == nil {
3213 variables.BuildFlags = make(map[string]string)
3214 }
3215 variables.BuildFlags["RELEASE_BOARD_API_LEVEL_FROZEN"] = "true"
3216 }),
3217 ).RunTestWithBp(t, bp)
3218 testSdkVersionFlag("libfoo", "30")
3219 testSdkVersionFlag("libbar", "29")
3220}
kellyhungd62ea302024-05-19 21:16:07 +08003221
3222func TestClangVerify(t *testing.T) {
3223 t.Parallel()
3224
3225 ctx := testCc(t, `
3226 cc_library {
3227 name: "lib_no_clang_verify",
3228 srcs: ["libnocv.cc"],
3229 }
3230
3231 cc_library {
3232 name: "lib_clang_verify",
3233 srcs: ["libcv.cc"],
3234 clang_verify: true,
3235 }
3236 `)
3237
3238 module := ctx.ModuleForTests("lib_no_clang_verify", "android_arm64_armv8-a_shared")
3239
3240 cFlags_no_cv := module.Rule("cc").Args["cFlags"]
3241 if strings.Contains(cFlags_no_cv, "-Xclang") || strings.Contains(cFlags_no_cv, "-verify") {
3242 t.Errorf("expected %q not in cflags, got %q", "-Xclang -verify", cFlags_no_cv)
3243 }
3244
3245 cFlags_cv := ctx.ModuleForTests("lib_clang_verify", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
3246 if strings.Contains(cFlags_cv, "-Xclang") && strings.Contains(cFlags_cv, "-verify") {
3247 t.Errorf("expected %q in cflags, got %q", "-Xclang -verify", cFlags_cv)
3248 }
3249}